From 278aa8f7a09486912e85d6c16ce66417e5dea416 Mon Sep 17 00:00:00 2001 From: zzj3720 <17165520+zzj3720@users.noreply.github.com> Date: Wed, 14 May 2025 16:41:55 +0000 Subject: [PATCH] fix(editor): remove the fixation of created-by and created-time (#12260) close: BS-3474, BS-3153 ## Summary by CodeRabbit - **New Features** - Enhanced property addition to support specifying both type and name for new properties across databases and views. - Added context menu for selecting property type when adding new columns in table headers. - Introduced `addToGroup` functions to various group-by configurations for consistent grouping behavior. - **Bug Fixes** - Improved grouping logic to treat empty arrays as ungrouped in multi-member group configurations. - Refined grouping behavior to respect explicit group addition settings. - Ensured grouping operations only occur when both group key and row ID are present. - **Tests** - Updated test expectations to align with revised default column naming conventions. - Adjusted test utilities to accommodate the updated property addition method. - Improved typing simulation in column type selection for more reliable test execution. - **Improvements** - Introduced a new root component rendering on the share page to enhance UI integration. - Refined default property naming logic for clearer and more consistent column titles. - Simplified created-time and created-by property configurations for better maintainability. --- .../blocks/data-view/src/data-source.ts | 6 +- .../affine/blocks/database/src/data-source.ts | 48 ++++++++++----- .../src/properties/created-time/define.ts | 7 +-- .../data-view/src/core/data-source/base.ts | 10 ++- .../data-view/src/core/detail/detail.ts | 5 +- .../data-view/src/core/group-by/define.ts | 10 ++- .../data-view/src/core/group-by/trait.ts | 13 +++- .../data-view/src/core/group-by/types.ts | 10 +-- .../src/core/view-manager/single-view.ts | 15 ++++- .../group/top/header/column-header.ts | 61 +++++++++++++++---- .../view-presets/table/table-view-manager.ts | 2 +- .../playground/apps/starter/data/database.ts | 13 ++-- .../database-block/group-by/index.tsx | 3 +- .../properties/created-by/define.ts | 7 +-- .../pages/workspace/share/share-page.tsx | 3 +- .../e2e/blocksuite/database/utils.ts | 6 +- tests/blocksuite/e2e/database/column.spec.ts | 2 +- .../blocksuite/e2e/database/database.spec.ts | 4 +- tests/blocksuite/e2e/utils/actions/misc.ts | 4 +- 19 files changed, 158 insertions(+), 71 deletions(-) diff --git a/blocksuite/affine/blocks/data-view/src/data-source.ts b/blocksuite/affine/blocks/data-view/src/data-source.ts index e631f3d883..c5ec2cc51b 100644 --- a/blocksuite/affine/blocks/data-view/src/data-source.ts +++ b/blocksuite/affine/blocks/data-view/src/data-source.ts @@ -171,8 +171,12 @@ export class BlockQueryDataSource extends DataSourceBase { propertyAdd( insertToPosition: InsertToPosition, - type: string | undefined + ops?: { + type?: string; + name?: string; + } ): string { + const { type } = ops ?? {}; const doc = this.block.store; doc.captureSync(); const column = DatabaseBlockDataSource.propertiesMap.value[ diff --git a/blocksuite/affine/blocks/database/src/data-source.ts b/blocksuite/affine/blocks/database/src/data-source.ts index e97fbf0cd9..3301d38192 100644 --- a/blocksuite/affine/blocks/database/src/data-source.ts +++ b/blocksuite/affine/blocks/database/src/data-source.ts @@ -56,10 +56,12 @@ type SpacialProperty = { valueSet: (rowId: string, propertyId: string, value: unknown) => void; valueGet: (rowId: string, propertyId: string) => unknown; }; + export class DatabaseBlockDataSource extends DataSourceBase { override get parentProvider() { return this._model.store.provider; } + spacialProperties: Record = { 'created-time': { valueSet: () => {}, @@ -101,11 +103,17 @@ export class DatabaseBlockDataSource extends DataSourceBase { }, }, }; - isSpacialProperty(propertyId: string): boolean { - return this.spacialProperties[propertyId] !== undefined; + + isSpacialProperty(propertyType: string): boolean { + return this.spacialProperties[propertyType] !== undefined; } - spacialValueGet(rowId: string, propertyId: string): unknown { - return this.spacialProperties[propertyId]?.valueGet(rowId, propertyId); + + spacialValueGet( + rowId: string, + propertyId: string, + propertyType: string + ): unknown { + return this.spacialProperties[propertyType]?.valueGet(rowId, propertyId); } static externalProperties = signal([]); @@ -213,16 +221,20 @@ export class DatabaseBlockDataSource extends DataSourceBase { return this._model.children[this._model.childMap.value.get(rowId) ?? -1]; } - private newPropertyName() { + private newPropertyName(prefix = 'Column'): string { let i = 1; - while ( - this._model.props.columns$.value.some( - column => column.name === `Column ${i}` - ) - ) { + const hasSameName = (name: string) => { + return this._model.props.columns$.value.some( + column => column.name === name + ); + }; + while (true) { + let name = i === 1 ? prefix : `${prefix} ${i}`; + if (!hasSameName(name)) { + return name; + } i++; } - return `Column ${i}`; } cellValueChange(rowId: string, propertyId: string, value: unknown): void { @@ -257,14 +269,14 @@ export class DatabaseBlockDataSource extends DataSourceBase { cellValueGet(rowId: string, propertyId: string): unknown { if (this.isSpacialProperty(propertyId)) { - return this.spacialValueGet(rowId, propertyId); + return this.spacialValueGet(rowId, propertyId, propertyId); } const type = this.propertyTypeGet(propertyId); if (!type) { return; } - if (type === 'title') { - return this.spacialValueGet(rowId, 'title'); + if (this.isSpacialProperty(type)) { + return this.spacialValueGet(rowId, propertyId, type); } const meta = this.propertyMetaGet(type); if (!meta) { @@ -283,9 +295,13 @@ export class DatabaseBlockDataSource extends DataSourceBase { propertyAdd( insertToPosition: InsertToPosition, - type?: string + ops?: { + type?: string; + name?: string; + } ): string | undefined { this.doc.captureSync(); + const { type, name } = ops ?? {}; const property = this.propertyMetaGet( type ?? propertyPresets.multiSelectPropertyConfig.type ); @@ -295,7 +311,7 @@ export class DatabaseBlockDataSource extends DataSourceBase { const result = addProperty( this._model, insertToPosition, - property.create(this.newPropertyName()) + property.create(this.newPropertyName(name)) ); return result; } diff --git a/blocksuite/affine/blocks/database/src/properties/created-time/define.ts b/blocksuite/affine/blocks/database/src/properties/created-time/define.ts index dafc264ad7..e211d19c9c 100644 --- a/blocksuite/affine/blocks/database/src/properties/created-time/define.ts +++ b/blocksuite/affine/blocks/database/src/properties/created-time/define.ts @@ -24,12 +24,7 @@ export const createdTimePropertyModelConfig = createdTimeColumnType.modelConfig( return { value: null }; }, toJson: ({ value }) => value, - fromJson: ({ value }) => value, - }, - fixed: { - defaultData: {}, - defaultShow: false, - defaultOrder: 'end', + setValue: () => {}, }, } ); diff --git a/blocksuite/affine/data-view/src/core/data-source/base.ts b/blocksuite/affine/data-view/src/core/data-source/base.ts index ac5cd8b083..814dfe01a8 100644 --- a/blocksuite/affine/data-view/src/core/data-source/base.ts +++ b/blocksuite/affine/data-view/src/core/data-source/base.ts @@ -61,7 +61,10 @@ export interface DataSource { propertyMetaGet(type: string): PropertyMetaConfig | undefined; propertyAdd( insertToPosition: InsertToPosition, - type?: string + ops?: { + type?: string; + name?: string; + } ): string | undefined; propertyDuplicate(propertyId: string): string | undefined; @@ -179,7 +182,10 @@ export abstract class DataSourceBase implements DataSource { abstract propertyAdd( insertToPosition: InsertToPosition, - type?: string + ops?: { + type?: string; + name?: string; + } ): string | undefined; abstract propertyDataGet(propertyId: string): Record; diff --git a/blocksuite/affine/data-view/src/core/detail/detail.ts b/blocksuite/affine/data-view/src/core/detail/detail.ts index 1947cc367e..35d100606f 100644 --- a/blocksuite/affine/data-view/src/core/detail/detail.ts +++ b/blocksuite/affine/data-view/src/core/detail/detail.ts @@ -122,7 +122,10 @@ export class RecordDetail extends SignalWatcher( name: meta.config.name, prefix: renderUniLit(meta.renderer.icon), select: () => { - this.view.propertyAdd('end', meta.type); + this.view.propertyAdd('end', { + type: meta.type, + name: meta.config.name, + }); }, }); }), diff --git a/blocksuite/affine/data-view/src/core/group-by/define.ts b/blocksuite/affine/data-view/src/core/group-by/define.ts index a72c54113c..345e209225 100644 --- a/blocksuite/affine/data-view/src/core/group-by/define.ts +++ b/blocksuite/affine/data-view/src/core/group-by/define.ts @@ -8,6 +8,7 @@ import { NumberGroupView } from './renderer/number-group.js'; import { SelectGroupView } from './renderer/select-group.js'; import { StringGroupView } from './renderer/string-group.js'; import type { GroupByConfig } from './types.js'; + export const createGroupByConfig = < Data extends Record, MatchType extends TypeInstance, @@ -25,7 +26,7 @@ export const groupByMatchers = [ createGroupByConfig({ name: 'select', matchType: t.tag.instance(), - groupName: (type, value) => { + groupName: (type, value: string | null) => { if (t.tag.is(type) && type.data) { return type.data.find(v => v.id === value)?.value ?? ''; } @@ -54,6 +55,7 @@ export const groupByMatchers = [ }, ]; }, + addToGroup: v => v, view: createUniComponentFromWebComponent(SelectGroupView), }), createGroupByConfig({ @@ -106,7 +108,7 @@ export const groupByMatchers = [ createGroupByConfig({ name: 'text', matchType: t.string.instance(), - groupName: (_type, value) => { + groupName: (_type, value: string | null) => { return `${value ?? ''}`; }, defaultKeys: _type => { @@ -123,6 +125,7 @@ export const groupByMatchers = [ }, ]; }, + addToGroup: v => v, view: createUniComponentFromWebComponent(StringGroupView), }), createGroupByConfig({ @@ -151,7 +154,7 @@ export const groupByMatchers = [ createGroupByConfig({ name: 'boolean', matchType: t.boolean.instance(), - groupName: (_type, value) => { + groupName: (_type, value: boolean | null) => { return `${value?.toString() ?? ''}`; }, defaultKeys: _type => { @@ -176,6 +179,7 @@ export const groupByMatchers = [ }, ]; }, + addToGroup: v => v, view: createUniComponentFromWebComponent(BooleanGroupView), }), ]; diff --git a/blocksuite/affine/data-view/src/core/group-by/trait.ts b/blocksuite/affine/data-view/src/core/group-by/trait.ts index 2758cd09cc..7fa752caca 100644 --- a/blocksuite/affine/data-view/src/core/group-by/trait.ts +++ b/blocksuite/affine/data-view/src/core/group-by/trait.ts @@ -31,6 +31,7 @@ export class Group< Data extends Record = Record, > { rows: Row[] = []; + constructor( public readonly key: string, public readonly value: JsonValue, @@ -57,6 +58,7 @@ export class Group< get tType() { return this.groupInfo.tType; } + get view() { return this.config.view; } @@ -185,7 +187,10 @@ export class GroupTrait { if (!groupMap || !groupInfo) { return; } - const addTo = groupInfo.config.addToGroup ?? (value => value); + const addTo = groupInfo.config.addToGroup; + if (addTo === false) { + return; + } const v = groupMap[key]?.value; if (v != null) { const newValue = addTo( @@ -268,8 +273,10 @@ export class GroupTrait { this.view.cellGetOrCreate(rowId, propertyId).jsonValue$.value ); } - const addTo = - this.groupInfo$.value?.config.addToGroup ?? (value => value); + const addTo = this.groupInfo$.value?.config.addToGroup; + if (addTo === false || addTo == null) { + return; + } newValue = addTo(groupMap[toGroupKey]?.value ?? null, newValue); this.view.cellGetOrCreate(rowId, propertyId).jsonValueSet(newValue); } diff --git a/blocksuite/affine/data-view/src/core/group-by/types.ts b/blocksuite/affine/data-view/src/core/group-by/types.ts index 906736793d..ace0f5cbc3 100644 --- a/blocksuite/affine/data-view/src/core/group-by/types.ts +++ b/blocksuite/affine/data-view/src/core/group-by/types.ts @@ -9,7 +9,10 @@ export interface GroupRenderProps< group: Group; readonly: boolean; } - +type AddToGroup = ( + value: GroupValue | null, + oldValue: ValueTypeOf | null +) => ValueTypeOf | null; export type GroupByConfig< Data extends NonNullable = NonNullable, MatchType extends TypeInstance = TypeInstance, @@ -29,10 +32,7 @@ export type GroupByConfig< key: string; value: GroupValue | null; }[]; - addToGroup?: ( - value: GroupValue | null, - oldValue: ValueTypeOf | null - ) => ValueTypeOf | null; + addToGroup: AddToGroup | false; removeFromGroup?: ( value: GroupValue | null, oldValue: ValueTypeOf | null diff --git a/blocksuite/affine/data-view/src/core/view-manager/single-view.ts b/blocksuite/affine/data-view/src/core/view-manager/single-view.ts index 593f1fd5b3..6777c5dc5a 100644 --- a/blocksuite/affine/data-view/src/core/view-manager/single-view.ts +++ b/blocksuite/affine/data-view/src/core/view-manager/single-view.ts @@ -58,7 +58,10 @@ export interface SingleView { propertyAdd( toAfterOfProperty: InsertToPosition, - type?: string + ops?: { + type?: string; + name?: string; + } ): string | undefined; serviceGet(key: GeneralServiceIdentifier): T | null; @@ -236,8 +239,14 @@ export abstract class SingleViewBase< }); } - propertyAdd(position: InsertToPosition, type?: string): string | undefined { - const id = this.dataSource.propertyAdd(position, type); + propertyAdd( + position: InsertToPosition, + ops?: { + type?: string; + name?: string; + } + ): string | undefined { + const id = this.dataSource.propertyAdd(position, ops); if (!id) { return; } diff --git a/blocksuite/affine/data-view/src/view-presets/table/pc-virtual/group/top/header/column-header.ts b/blocksuite/affine/data-view/src/view-presets/table/pc-virtual/group/top/header/column-header.ts index ad94518f1c..cfef40ff76 100644 --- a/blocksuite/affine/data-view/src/view-presets/table/pc-virtual/group/top/header/column-header.ts +++ b/blocksuite/affine/data-view/src/view-presets/table/pc-virtual/group/top/header/column-header.ts @@ -1,3 +1,8 @@ +import { + menu, + popMenu, + popupTargetFromElement, +} from '@blocksuite/affine-components/context-menu'; import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit'; import { PlusIcon } from '@blocksuite/icons/lit'; import { ShadowlessElement } from '@blocksuite/std'; @@ -7,6 +12,7 @@ import { repeat } from 'lit/directives/repeat.js'; import { styleMap } from 'lit/directives/style-map.js'; import { html } from 'lit/static-html.js'; +import { renderUniLit } from '../../../../../../core'; import type { TableSingleView } from '../../../../table-view-manager'; import * as styles from './column-header-css'; @@ -15,19 +21,50 @@ export class VirtualTableHeader extends SignalWatcher( ) { private readonly _onAddColumn = (e: MouseEvent) => { if (this.readonly) return; - this.tableViewManager.propertyAdd('end'); const ele = e.currentTarget as HTMLElement; - requestAnimationFrame(() => { - this.editLastColumnTitle(); - ele.scrollIntoView({ block: 'nearest', inline: 'nearest' }); + popMenu(popupTargetFromElement(ele), { + options: { + title: { + text: 'Property type', + }, + items: [ + menu.group({ + items: this.tableViewManager.propertyMetas$.value.map(config => { + return menu.action({ + name: config.config.name, + prefix: renderUniLit(config.renderer.icon), + select: () => { + const id = this.tableViewManager.propertyAdd('end', { + type: config.type, + name: config.config.name, + }); + if (id) { + requestAnimationFrame(() => { + ele.scrollIntoView({ + block: 'nearest', + inline: 'nearest', + }); + this.openPropertyMenuById(id); + }); + } + }, + }); + }), + }), + ], + }, }); }; - editLastColumnTitle = () => { - const columns = this.querySelectorAll('affine-database-header-column'); - const column = columns.item(columns.length - 1); - column.scrollIntoView({ block: 'nearest', inline: 'nearest' }); - column.editTitle(); + openPropertyMenuById = (id: string) => { + const column = this.querySelectorAll('virtual-database-header-column'); + for (const item of column) { + if (item.dataset.columnId === id) { + item.scrollIntoView({ block: 'nearest', inline: 'nearest' }); + item.editTitle(); + return; + } + } }; private get readonly() { @@ -44,7 +81,7 @@ export class VirtualTableHeader extends SignalWatcher(
${this.readonly ? nothing - : html`
`} + : html`
`} ${repeat( this.tableViewManager.properties$.value, column => column.id, @@ -54,14 +91,14 @@ export class VirtualTableHeader extends SignalWatcher( border: index === 0 ? 'none' : undefined, }); return html` - + >
`; } diff --git a/blocksuite/affine/data-view/src/view-presets/table/table-view-manager.ts b/blocksuite/affine/data-view/src/view-presets/table/table-view-manager.ts index 70dd58f704..86f1bf18d2 100644 --- a/blocksuite/affine/data-view/src/view-presets/table/table-view-manager.ts +++ b/blocksuite/affine/data-view/src/view-presets/table/table-view-manager.ts @@ -241,7 +241,7 @@ export class TableSingleView extends SingleViewBase { }); } - if (groupKey) { + if (groupKey && id) { this.groupTrait.addToGroup(id, groupKey); } return id; diff --git a/blocksuite/playground/apps/starter/data/database.ts b/blocksuite/playground/apps/starter/data/database.ts index 9d174ce12c..9e32ea798c 100644 --- a/blocksuite/playground/apps/starter/data/database.ts +++ b/blocksuite/playground/apps/starter/data/database.ts @@ -45,10 +45,10 @@ export const database: InitFn = (collection: Workspace, id: string) => { const datasource = new DatabaseBlockDataSource(database); datasource.viewManager.viewAdd('table'); database.props.title = new Text(title); - const richTextId = datasource.propertyAdd( - 'end', - databaseBlockProperties.richTextColumnConfig.type - ); + const richTextId = datasource.propertyAdd('end', { + type: databaseBlockProperties.richTextColumnConfig.type, + name: 'Rich Text', + }); Object.values([ propertyPresets.multiSelectPropertyConfig, propertyPresets.datePropertyConfig, @@ -57,7 +57,10 @@ export const database: InitFn = (collection: Workspace, id: string) => { propertyPresets.checkboxPropertyConfig, propertyPresets.progressPropertyConfig, ]).forEach(column => { - datasource.propertyAdd('end', column.type); + datasource.propertyAdd('end', { + type: column.type, + name: column.config.name, + }); }); if (group) { const groupTrait = diff --git a/packages/frontend/core/src/blocksuite/database-block/group-by/index.tsx b/packages/frontend/core/src/blocksuite/database-block/group-by/index.tsx index a5cc7831d7..69669e267b 100644 --- a/packages/frontend/core/src/blocksuite/database-block/group-by/index.tsx +++ b/packages/frontend/core/src/blocksuite/database-block/group-by/index.tsx @@ -97,6 +97,7 @@ export const groupByConfigList = [ }, ]; }, + addToGroup: v => v, view: uniReactRoot.createUniComponent(MemberGroupView), }), createGroupByConfig({ @@ -122,7 +123,7 @@ export const groupByConfigList = [ return [ungroups]; }, valuesGroup: (value, _type) => { - if (!Array.isArray(value)) { + if (!Array.isArray(value) || value.length === 0) { return [ungroups]; } return value.map(id => ({ diff --git a/packages/frontend/core/src/blocksuite/database-block/properties/created-by/define.ts b/packages/frontend/core/src/blocksuite/database-block/properties/created-by/define.ts index ac5b54fb61..97404c93f6 100644 --- a/packages/frontend/core/src/blocksuite/database-block/properties/created-by/define.ts +++ b/packages/frontend/core/src/blocksuite/database-block/properties/created-by/define.ts @@ -16,11 +16,6 @@ export const createdByPropertyModelConfig = createdByColumnType.modelConfig({ schema: zod.object({}), default: () => ({}), }, - fixed: { - defaultData: {}, - defaultOrder: 'end', - defaultShow: false, - }, rawValue: { schema: zod.string().nullable(), default: () => null, @@ -29,7 +24,7 @@ export const createdByPropertyModelConfig = createdByColumnType.modelConfig({ return { value: null }; }, toJson: ({ value }) => value, - fromJson: ({ value }) => value, + setValue: () => {}, }, jsonValue: { schema: zod.string().nullable(), diff --git a/packages/frontend/core/src/desktop/pages/workspace/share/share-page.tsx b/packages/frontend/core/src/desktop/pages/workspace/share/share-page.tsx index 8d48618710..9d00d98ec9 100644 --- a/packages/frontend/core/src/desktop/pages/workspace/share/share-page.tsx +++ b/packages/frontend/core/src/desktop/pages/workspace/share/share-page.tsx @@ -1,4 +1,4 @@ -import { Scrollable } from '@affine/component'; +import { Scrollable, uniReactRoot } from '@affine/component'; import type { AffineEditorContainer } from '@affine/core/blocksuite/block-suite-editor'; import { EditorOutlineViewer } from '@affine/core/blocksuite/outline-viewer'; import { useActiveBlocksuiteEditor } from '@affine/core/components/hooks/use-block-suite-editor'; @@ -269,6 +269,7 @@ const SharePageInner = ({
+ diff --git a/tests/affine-local/e2e/blocksuite/database/utils.ts b/tests/affine-local/e2e/blocksuite/database/utils.ts index 8a4deb0b1f..21a9678651 100644 --- a/tests/affine-local/e2e/blocksuite/database/utils.ts +++ b/tests/affine-local/e2e/blocksuite/database/utils.ts @@ -79,8 +79,12 @@ export async function selectColumnType( const typeMenu = page.locator('affine-menu').getByText('Type'); await page.waitForTimeout(100); await typeMenu.hover(); + await page.mouse.move(0, 0); await page.waitForTimeout(100); - await page.keyboard.type(columnType); + for (const char of columnType.split('')) { + await page.keyboard.type(char); + await page.waitForTimeout(10); + } await page.waitForTimeout(100); for (let i = 0; i < nth; i++) { await page.keyboard.press('ArrowDown'); diff --git a/tests/blocksuite/e2e/database/column.spec.ts b/tests/blocksuite/e2e/database/column.spec.ts index 6ab6b333b8..162d996d69 100644 --- a/tests/blocksuite/e2e/database/column.spec.ts +++ b/tests/blocksuite/e2e/database/column.spec.ts @@ -65,7 +65,7 @@ test.describe('column operations', () => { await initDatabaseDynamicRowWithData(page, '123', true); await pressEscape(page); const { text: title1 } = await getDatabaseHeaderColumn(page, 1); - expect(title1).toBe('Column 1'); + expect(title1).toBe('Column'); const selected = getDatabaseCell(page, { rowIndex: 0, diff --git a/tests/blocksuite/e2e/database/database.spec.ts b/tests/blocksuite/e2e/database/database.spec.ts index 295271c251..836f672519 100644 --- a/tests/blocksuite/e2e/database/database.spec.ts +++ b/tests/blocksuite/e2e/database/database.spec.ts @@ -90,7 +90,7 @@ test('edit column title', async ({ page }) => { expect(await column.innerText()).toBe('1'); await undoByClick(page); - expect(await column.innerText()).toBe('Column 1'); + expect(await column.innerText()).toBe('Column'); }); test('should modify the value when the input loses focus', async ({ page }) => { @@ -359,7 +359,7 @@ test('should title column support quick renaming', async ({ page }) => { expect(await textElement.innerText()).toBe('123'); await undoByClick(page); - expect(await textElement.innerText()).toBe('Column 1'); + expect(await textElement.innerText()).toBe('Column'); await textElement.click(); await waitNextFrame(page); await selectAllByKeyboard(page); diff --git a/tests/blocksuite/e2e/utils/actions/misc.ts b/tests/blocksuite/e2e/utils/actions/misc.ts index d9ddd4333b..5691660a78 100644 --- a/tests/blocksuite/e2e/utils/actions/misc.ts +++ b/tests/blocksuite/e2e/utils/actions/misc.ts @@ -392,7 +392,9 @@ export async function initKanbanViewState( return rowId; }); config.columns.forEach(column => { - const columnId = datasource.propertyAdd('end', column.type); + const columnId = datasource.propertyAdd('end', { + type: column.type, + }); if (!columnId) { return; }