fix(editor): remove the fixation of created-by and created-time (#12260)

close: BS-3474, BS-3153

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## 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.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
zzj3720
2025-05-14 16:41:55 +00:00
parent afa984da54
commit 278aa8f7a0
19 changed files with 158 additions and 71 deletions
@@ -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<string, unknown>;
@@ -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,
});
},
});
}),
@@ -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<string, unknown>,
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),
}),
];
@@ -31,6 +31,7 @@ export class Group<
Data extends Record<string, unknown> = Record<string, unknown>,
> {
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);
}
@@ -9,7 +9,10 @@ export interface GroupRenderProps<
group: Group<unknown, JsonValue, Data>;
readonly: boolean;
}
type AddToGroup<GroupValue, MatchType> = (
value: GroupValue | null,
oldValue: ValueTypeOf<MatchType> | null
) => ValueTypeOf<MatchType> | null;
export type GroupByConfig<
Data extends NonNullable<unknown> = NonNullable<unknown>,
MatchType extends TypeInstance = TypeInstance,
@@ -29,10 +32,7 @@ export type GroupByConfig<
key: string;
value: GroupValue | null;
}[];
addToGroup?: (
value: GroupValue | null,
oldValue: ValueTypeOf<MatchType> | null
) => ValueTypeOf<MatchType> | null;
addToGroup: AddToGroup<GroupValue, MatchType> | false;
removeFromGroup?: (
value: GroupValue | null,
oldValue: ValueTypeOf<MatchType> | null
@@ -58,7 +58,10 @@ export interface SingleView {
propertyAdd(
toAfterOfProperty: InsertToPosition,
type?: string
ops?: {
type?: string;
name?: string;
}
): string | undefined;
serviceGet<T>(key: GeneralServiceIdentifier<T>): 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;
}
@@ -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(
<div class="${styles.columnHeader} database-row">
${this.readonly
? nothing
: html`<div class="data-view-table-left-bar"></div>`}
: html` <div class="data-view-table-left-bar"></div>`}
${repeat(
this.tableViewManager.properties$.value,
column => column.id,
@@ -54,14 +91,14 @@ export class VirtualTableHeader extends SignalWatcher(
border: index === 0 ? 'none' : undefined,
});
return html`
<affine-database-header-column
<virtual-database-header-column
style="${style}"
data-column-id="${column.id}"
data-column-index="${index}"
class="${styles.column} ${styles.cell}"
.column="${column}"
.tableViewManager="${this.tableViewManager}"
></affine-database-header-column>
></virtual-database-header-column>
<div class="cell-divider" style="height: auto;"></div>
`;
}
@@ -241,7 +241,7 @@ export class TableSingleView extends SingleViewBase<TableViewData> {
});
}
if (groupKey) {
if (groupKey && id) {
this.groupTrait.addToGroup(id, groupKey);
}
return id;