mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-19 02:56:23 +08:00
fix(editor): database behavier (#14394)
fix #13459 fix #13707 fix #13924 #### PR Dependency Tree * **PR #14394** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Improved URL paste: text is split into segments, inserted correctly, and single-URL pastes create linked-page references. * **UI Improvements** * Redesigned layout selector with compact dynamic options. * Number-format options are always available in table headers and mobile menus. * **Bug Fixes** * More consistent paste behavior for mixed text+URL content. * Prevented recursive selection updates when exiting edit mode. * **Tests** * Added tests for URL splitting, paste insertion, number formatting, and selection behavior. * **Chores** * Removed number-formatting feature flag; formatting now applied by default. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -22,7 +22,6 @@ import { html } from 'lit/static-html.js';
|
||||
import { dataViewCommonStyle } from './common/css-variable.js';
|
||||
import type { DataSource } from './data-source/index.js';
|
||||
import type { DataViewSelection } from './types.js';
|
||||
import { cacheComputed } from './utils/cache.js';
|
||||
import { renderUniLit } from './utils/uni-component/index.js';
|
||||
import type { DataViewUILogicBase } from './view/data-view-base.js';
|
||||
import type { SingleView } from './view-manager/single-view.js';
|
||||
@@ -75,12 +74,38 @@ export class DataViewRootUILogic {
|
||||
|
||||
return new (logic(view))(this, view);
|
||||
}
|
||||
private readonly views$ = cacheComputed(this.viewManager.views$, viewId =>
|
||||
this.createDataViewUILogic(viewId)
|
||||
);
|
||||
private readonly _viewsCache = new Map<
|
||||
string,
|
||||
{ mode: string; logic: DataViewUILogicBase }
|
||||
>();
|
||||
|
||||
private readonly views$ = computed(() => {
|
||||
const viewDataList = this.dataSource.viewDataList$.value;
|
||||
const validIds = new Set(viewDataList.map(viewData => viewData.id));
|
||||
|
||||
for (const cachedId of this._viewsCache.keys()) {
|
||||
if (!validIds.has(cachedId)) {
|
||||
this._viewsCache.delete(cachedId);
|
||||
}
|
||||
}
|
||||
|
||||
return viewDataList.map(viewData => {
|
||||
const cached = this._viewsCache.get(viewData.id);
|
||||
if (cached && cached.mode === viewData.mode) {
|
||||
return cached.logic;
|
||||
}
|
||||
const logic = this.createDataViewUILogic(viewData.id);
|
||||
this._viewsCache.set(viewData.id, {
|
||||
mode: viewData.mode,
|
||||
logic,
|
||||
});
|
||||
return logic;
|
||||
});
|
||||
});
|
||||
|
||||
private readonly viewsMap$ = computed(() => {
|
||||
return Object.fromEntries(
|
||||
this.views$.list.value.map(logic => [logic.view.id, logic])
|
||||
this.views$.value.map(logic => [logic.view.id, logic])
|
||||
);
|
||||
});
|
||||
private readonly _uiRef = signal<DataViewRootUI>();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { KanbanCardSelection } from '../../view-presets';
|
||||
import type { KanbanCard } from '../../view-presets/kanban/pc/card.js';
|
||||
import { KanbanCell } from '../../view-presets/kanban/pc/cell.js';
|
||||
import type { RecordDetail } from './detail.js';
|
||||
import { RecordField } from './field.js';
|
||||
|
||||
type DetailViewSelection = {
|
||||
@@ -9,16 +8,39 @@ type DetailViewSelection = {
|
||||
isEditing: boolean;
|
||||
};
|
||||
|
||||
type DetailSelectionHost = {
|
||||
querySelector: (selector: string) => unknown;
|
||||
};
|
||||
|
||||
const isSameDetailSelection = (
|
||||
current?: DetailViewSelection,
|
||||
next?: DetailViewSelection
|
||||
) => {
|
||||
if (!current && !next) {
|
||||
return true;
|
||||
}
|
||||
if (!current || !next) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
current.propertyId === next.propertyId &&
|
||||
current.isEditing === next.isEditing
|
||||
);
|
||||
};
|
||||
|
||||
export class DetailSelection {
|
||||
_selection?: DetailViewSelection;
|
||||
|
||||
onSelect = (selection?: DetailViewSelection) => {
|
||||
if (isSameDetailSelection(this._selection, selection)) {
|
||||
return;
|
||||
}
|
||||
const old = this._selection;
|
||||
this._selection = selection;
|
||||
if (old) {
|
||||
this.blur(old);
|
||||
}
|
||||
this._selection = selection;
|
||||
if (selection) {
|
||||
if (selection && isSameDetailSelection(this._selection, selection)) {
|
||||
this.focus(selection);
|
||||
}
|
||||
};
|
||||
@@ -49,7 +71,7 @@ export class DetailSelection {
|
||||
}
|
||||
}
|
||||
|
||||
constructor(private readonly viewEle: RecordDetail) {}
|
||||
constructor(private readonly viewEle: DetailSelectionHost) {}
|
||||
|
||||
blur(selection: DetailViewSelection) {
|
||||
const container = this.getFocusCellContainer(selection);
|
||||
@@ -111,8 +133,10 @@ export class DetailSelection {
|
||||
}
|
||||
|
||||
focusFirstCell() {
|
||||
const firstId = this.viewEle.querySelector('affine-data-view-record-field')
|
||||
?.column.id;
|
||||
const firstField = this.viewEle.querySelector(
|
||||
'affine-data-view-record-field'
|
||||
) as RecordField | undefined;
|
||||
const firstId = firstField?.column.id;
|
||||
if (firstId) {
|
||||
this.selection = {
|
||||
propertyId: firstId,
|
||||
@@ -144,11 +168,12 @@ export class DetailSelection {
|
||||
|
||||
getSelectCard(selection: KanbanCardSelection) {
|
||||
const { groupKey, cardId } = selection.cards[0];
|
||||
const group = this.viewEle.querySelector(
|
||||
`affine-data-view-kanban-group[data-key="${groupKey}"]`
|
||||
) as HTMLElement | undefined;
|
||||
|
||||
return this.viewEle
|
||||
.querySelector(`affine-data-view-kanban-group[data-key="${groupKey}"]`)
|
||||
?.querySelector(
|
||||
`affine-data-view-kanban-card[data-card-id="${cardId}"]`
|
||||
) as KanbanCard | undefined;
|
||||
return group?.querySelector(
|
||||
`affine-data-view-kanban-card[data-card-id="${cardId}"]`
|
||||
) as KanbanCard | undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,5 @@ export type PropertyDataUpdater<
|
||||
> = (data: Data) => Partial<Data>;
|
||||
|
||||
export interface DatabaseFlags {
|
||||
enable_number_formatting: boolean;
|
||||
enable_table_virtual_scroll: boolean;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user