mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-07 01:09:54 +08:00
refactor(editor): move database selection into the corresponding view (#9752)
This commit is contained in:
@@ -1,4 +1,8 @@
|
|||||||
import { BlockRenderer, NoteRenderer } from '@blocksuite/affine-block-database';
|
import {
|
||||||
|
BlockRenderer,
|
||||||
|
DatabaseSelection,
|
||||||
|
NoteRenderer,
|
||||||
|
} from '@blocksuite/affine-block-database';
|
||||||
import { CaptionedBlockComponent } from '@blocksuite/affine-components/caption';
|
import { CaptionedBlockComponent } from '@blocksuite/affine-components/caption';
|
||||||
import {
|
import {
|
||||||
menu,
|
menu,
|
||||||
@@ -26,7 +30,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
createRecordDetail,
|
createRecordDetail,
|
||||||
createUniComponentFromWebComponent,
|
createUniComponentFromWebComponent,
|
||||||
DatabaseSelection,
|
|
||||||
type DataSource,
|
type DataSource,
|
||||||
DataView,
|
DataView,
|
||||||
dataViewCommonStyle,
|
dataViewCommonStyle,
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
createRecordDetail,
|
createRecordDetail,
|
||||||
createUniComponentFromWebComponent,
|
createUniComponentFromWebComponent,
|
||||||
DatabaseSelection,
|
|
||||||
DataView,
|
DataView,
|
||||||
dataViewCommonStyle,
|
dataViewCommonStyle,
|
||||||
type DataViewInstance,
|
type DataViewInstance,
|
||||||
@@ -55,6 +54,7 @@ import { DatabaseBlockDataSource } from './data-source.js';
|
|||||||
import type { DatabaseBlockService } from './database-service.js';
|
import type { DatabaseBlockService } from './database-service.js';
|
||||||
import { BlockRenderer } from './detail-panel/block-renderer.js';
|
import { BlockRenderer } from './detail-panel/block-renderer.js';
|
||||||
import { NoteRenderer } from './detail-panel/note-renderer.js';
|
import { NoteRenderer } from './detail-panel/note-renderer.js';
|
||||||
|
import { DatabaseSelection } from './selection.js';
|
||||||
import { currentViewStorage } from './utils/current-view.js';
|
import { currentViewStorage } from './utils/current-view.js';
|
||||||
import { getSingleDocIdFromText } from './utils/title-doc.js';
|
import { getSingleDocIdFromText } from './utils/title-doc.js';
|
||||||
|
|
||||||
|
|||||||
@@ -13,4 +13,5 @@ export * from './detail-panel/note-renderer';
|
|||||||
export * from './properties';
|
export * from './properties';
|
||||||
export * from './properties/rich-text/cell-renderer';
|
export * from './properties/rich-text/cell-renderer';
|
||||||
export * from './properties/utils';
|
export * from './properties/utils';
|
||||||
|
export * from './selection.js';
|
||||||
export * from './utils/block-utils';
|
export * from './utils/block-utils';
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import type { DataViewSelection } from '@blocksuite/data-view';
|
||||||
|
import {
|
||||||
|
KanbanViewSelectionWithTypeSchema,
|
||||||
|
TableViewSelectionWithTypeSchema,
|
||||||
|
} from '@blocksuite/data-view/view-presets';
|
||||||
|
import { BaseSelection, SelectionExtension } from '@blocksuite/store';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
const ViewSelectionSchema = z.union([
|
||||||
|
TableViewSelectionWithTypeSchema,
|
||||||
|
KanbanViewSelectionWithTypeSchema,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const DatabaseSelectionSchema = z.object({
|
||||||
|
blockId: z.string(),
|
||||||
|
viewSelection: ViewSelectionSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
export class DatabaseSelection extends BaseSelection {
|
||||||
|
static override group = 'note';
|
||||||
|
|
||||||
|
static override type = 'database';
|
||||||
|
|
||||||
|
readonly viewSelection: DataViewSelection;
|
||||||
|
|
||||||
|
get viewId() {
|
||||||
|
return this.viewSelection.viewId;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor({
|
||||||
|
blockId,
|
||||||
|
viewSelection,
|
||||||
|
}: {
|
||||||
|
blockId: string;
|
||||||
|
viewSelection: DataViewSelection;
|
||||||
|
}) {
|
||||||
|
super({
|
||||||
|
blockId,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.viewSelection = viewSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
static override fromJSON(json: Record<string, unknown>): DatabaseSelection {
|
||||||
|
const { blockId, viewSelection } = DatabaseSelectionSchema.parse(json);
|
||||||
|
return new DatabaseSelection({
|
||||||
|
blockId,
|
||||||
|
viewSelection: viewSelection,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
override equals(other: BaseSelection): boolean {
|
||||||
|
if (!(other instanceof DatabaseSelection)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.blockId === other.blockId;
|
||||||
|
}
|
||||||
|
|
||||||
|
override toJSON(): Record<string, unknown> {
|
||||||
|
return {
|
||||||
|
type: 'database',
|
||||||
|
blockId: this.blockId,
|
||||||
|
viewSelection: this.viewSelection,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
namespace BlockSuite {
|
||||||
|
interface Selection {
|
||||||
|
database: typeof DatabaseSelection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DatabaseSelectionExtension = SelectionExtension(DatabaseSelection);
|
||||||
@@ -5,5 +5,4 @@ export * from '../group-by/matcher.js';
|
|||||||
export type { GroupByConfig } from '../group-by/types.js';
|
export type { GroupByConfig } from '../group-by/types.js';
|
||||||
export type { GroupRenderProps } from '../group-by/types.js';
|
export type { GroupRenderProps } from '../group-by/types.js';
|
||||||
export * from './css-variable.js';
|
export * from './css-variable.js';
|
||||||
export * from './selection-schema.js';
|
|
||||||
export * from './types.js';
|
export * from './types.js';
|
||||||
|
|||||||
@@ -1,133 +0,0 @@
|
|||||||
import { BaseSelection, SelectionExtension } from '@blocksuite/store';
|
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
import type { DataViewSelection, GetDataViewSelection } from '../types.js';
|
|
||||||
|
|
||||||
const TableViewSelectionSchema = z.union([
|
|
||||||
z.object({
|
|
||||||
viewId: z.string(),
|
|
||||||
type: z.literal('table'),
|
|
||||||
selectionType: z.literal('area'),
|
|
||||||
rowsSelection: z.object({
|
|
||||||
start: z.number(),
|
|
||||||
end: z.number(),
|
|
||||||
}),
|
|
||||||
columnsSelection: z.object({
|
|
||||||
start: z.number(),
|
|
||||||
end: z.number(),
|
|
||||||
}),
|
|
||||||
focus: z.object({
|
|
||||||
rowIndex: z.number(),
|
|
||||||
columnIndex: z.number(),
|
|
||||||
}),
|
|
||||||
isEditing: z.boolean(),
|
|
||||||
}),
|
|
||||||
z.object({
|
|
||||||
viewId: z.string(),
|
|
||||||
type: z.literal('table'),
|
|
||||||
selectionType: z.literal('row'),
|
|
||||||
rows: z.array(
|
|
||||||
z.object({ id: z.string(), groupKey: z.string().optional() })
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const KanbanCellSelectionSchema = z.object({
|
|
||||||
selectionType: z.literal('cell'),
|
|
||||||
groupKey: z.string(),
|
|
||||||
cardId: z.string(),
|
|
||||||
columnId: z.string(),
|
|
||||||
isEditing: z.boolean(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const KanbanCardSelectionSchema = z.object({
|
|
||||||
selectionType: z.literal('card'),
|
|
||||||
cards: z.array(
|
|
||||||
z.object({
|
|
||||||
groupKey: z.string(),
|
|
||||||
cardId: z.string(),
|
|
||||||
})
|
|
||||||
),
|
|
||||||
});
|
|
||||||
|
|
||||||
const KanbanGroupSelectionSchema = z.object({
|
|
||||||
selectionType: z.literal('group'),
|
|
||||||
groupKeys: z.array(z.string()),
|
|
||||||
});
|
|
||||||
|
|
||||||
const DatabaseSelectionSchema = z.object({
|
|
||||||
blockId: z.string(),
|
|
||||||
viewSelection: z.union([
|
|
||||||
TableViewSelectionSchema,
|
|
||||||
KanbanCellSelectionSchema,
|
|
||||||
KanbanCardSelectionSchema,
|
|
||||||
KanbanGroupSelectionSchema,
|
|
||||||
]),
|
|
||||||
});
|
|
||||||
|
|
||||||
export class DatabaseSelection extends BaseSelection {
|
|
||||||
static override group = 'note';
|
|
||||||
|
|
||||||
static override type = 'database';
|
|
||||||
|
|
||||||
readonly viewSelection: DataViewSelection;
|
|
||||||
|
|
||||||
get viewId() {
|
|
||||||
return this.viewSelection.viewId;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor({
|
|
||||||
blockId,
|
|
||||||
viewSelection,
|
|
||||||
}: {
|
|
||||||
blockId: string;
|
|
||||||
viewSelection: DataViewSelection;
|
|
||||||
}) {
|
|
||||||
super({
|
|
||||||
blockId,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.viewSelection = viewSelection;
|
|
||||||
}
|
|
||||||
|
|
||||||
static override fromJSON(json: Record<string, unknown>): DatabaseSelection {
|
|
||||||
DatabaseSelectionSchema.parse(json);
|
|
||||||
return new DatabaseSelection({
|
|
||||||
blockId: json.blockId as string,
|
|
||||||
viewSelection: json.viewSelection as DataViewSelection,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
override equals(other: BaseSelection): boolean {
|
|
||||||
if (!(other instanceof DatabaseSelection)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return this.blockId === other.blockId;
|
|
||||||
}
|
|
||||||
|
|
||||||
getSelection<T extends DataViewSelection['type']>(
|
|
||||||
type: T
|
|
||||||
): GetDataViewSelection<T> | undefined {
|
|
||||||
return this.viewSelection.type === type
|
|
||||||
? (this.viewSelection as GetDataViewSelection<T>)
|
|
||||||
: undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
override toJSON(): Record<string, unknown> {
|
|
||||||
return {
|
|
||||||
type: 'database',
|
|
||||||
blockId: this.blockId,
|
|
||||||
viewSelection: this.viewSelection,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
namespace BlockSuite {
|
|
||||||
interface Selection {
|
|
||||||
database: typeof DatabaseSelection;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DatabaseSelectionExtension = SelectionExtension(DatabaseSelection);
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import type { KanbanCardSelection } from '../../view-presets';
|
||||||
import type { KanbanCard } from '../../view-presets/kanban/pc/card.js';
|
import type { KanbanCard } from '../../view-presets/kanban/pc/card.js';
|
||||||
import { KanbanCell } from '../../view-presets/kanban/pc/cell.js';
|
import { KanbanCell } from '../../view-presets/kanban/pc/cell.js';
|
||||||
import type { KanbanCardSelection } from '../../view-presets/kanban/types.js';
|
|
||||||
import type { RecordDetail } from './detail.js';
|
import type { RecordDetail } from './detail.js';
|
||||||
import { RecordField } from './field.js';
|
import { RecordField } from './field.js';
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
import type { KanbanViewSelectionWithType } from '../view-presets/kanban/types.js';
|
import type {
|
||||||
import type { TableViewSelectionWithType } from '../view-presets/table/types.js';
|
KanbanViewSelectionWithType,
|
||||||
|
TableViewSelectionWithType,
|
||||||
|
} from '../view-presets';
|
||||||
|
|
||||||
export type DataViewSelection =
|
export type DataViewSelection =
|
||||||
| TableViewSelectionWithType
|
| TableViewSelectionWithType
|
||||||
| KanbanViewSelectionWithType;
|
| KanbanViewSelectionWithType;
|
||||||
export type GetDataViewSelection<
|
|
||||||
K extends DataViewSelection['type'],
|
|
||||||
T = DataViewSelection,
|
|
||||||
> = T extends {
|
|
||||||
type: K;
|
|
||||||
}
|
|
||||||
? T
|
|
||||||
: never;
|
|
||||||
export type DataViewSelectionState = DataViewSelection | undefined;
|
export type DataViewSelectionState = DataViewSelection | undefined;
|
||||||
export type PropertyDataUpdater<
|
export type PropertyDataUpdater<
|
||||||
Data extends Record<string, unknown> = Record<string, unknown>,
|
Data extends Record<string, unknown> = Record<string, unknown>,
|
||||||
@@ -20,7 +14,3 @@ export type PropertyDataUpdater<
|
|||||||
export interface DatabaseFlags {
|
export interface DatabaseFlags {
|
||||||
enable_number_formatting: boolean;
|
enable_number_formatting: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultDatabaseFlags: Readonly<DatabaseFlags> = {
|
|
||||||
enable_number_formatting: false,
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ export * from './define.js';
|
|||||||
export * from './kanban-view-manager.js';
|
export * from './kanban-view-manager.js';
|
||||||
export * from './pc/kanban-view.js';
|
export * from './pc/kanban-view.js';
|
||||||
export * from './renderer.js';
|
export * from './renderer.js';
|
||||||
|
export * from './selection.js';
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { type DataViewInstance, renderUniLit } from '../../../core/index.js';
|
|||||||
import { sortable } from '../../../core/utils/wc-dnd/sort/sort-context.js';
|
import { sortable } from '../../../core/utils/wc-dnd/sort/sort-context.js';
|
||||||
import { DataViewBase } from '../../../core/view/data-view-base.js';
|
import { DataViewBase } from '../../../core/view/data-view-base.js';
|
||||||
import type { KanbanSingleView } from '../kanban-view-manager.js';
|
import type { KanbanSingleView } from '../kanban-view-manager.js';
|
||||||
import type { KanbanViewSelectionWithType } from '../types.js';
|
import type { KanbanViewSelectionWithType } from '../selection';
|
||||||
|
|
||||||
const styles = css`
|
const styles = css`
|
||||||
mobile-data-view-kanban {
|
mobile-data-view-kanban {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import type {
|
|||||||
import { renderUniLit } from '../../../core/utils/uni-component/uni-component.js';
|
import { renderUniLit } from '../../../core/utils/uni-component/uni-component.js';
|
||||||
import type { Property } from '../../../core/view-manager/property.js';
|
import type { Property } from '../../../core/view-manager/property.js';
|
||||||
import type { KanbanSingleView } from '../kanban-view-manager.js';
|
import type { KanbanSingleView } from '../kanban-view-manager.js';
|
||||||
import type { KanbanViewSelection } from '../types.js';
|
import type { KanbanViewSelection } from '../selection';
|
||||||
|
|
||||||
const styles = css`
|
const styles = css`
|
||||||
affine-data-view-kanban-cell {
|
affine-data-view-kanban-cell {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { UIEventStateContext } from '@blocksuite/block-std';
|
import type { UIEventStateContext } from '@blocksuite/block-std';
|
||||||
import type { ReactiveController } from 'lit';
|
import type { ReactiveController } from 'lit';
|
||||||
|
|
||||||
import type { KanbanViewSelectionWithType } from '../../types.js';
|
import type { KanbanViewSelectionWithType } from '../../selection';
|
||||||
import type { DataViewKanban } from '../kanban-view.js';
|
import type { DataViewKanban } from '../kanban-view.js';
|
||||||
|
|
||||||
export class KanbanClipboardController implements ReactiveController {
|
export class KanbanClipboardController implements ReactiveController {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import type {
|
|||||||
KanbanGroupSelection,
|
KanbanGroupSelection,
|
||||||
KanbanViewSelection,
|
KanbanViewSelection,
|
||||||
KanbanViewSelectionWithType,
|
KanbanViewSelectionWithType,
|
||||||
} from '../../types.js';
|
} from '../../selection';
|
||||||
import { KanbanCard } from '../card.js';
|
import { KanbanCard } from '../card.js';
|
||||||
import { KanbanCell } from '../cell.js';
|
import { KanbanCell } from '../cell.js';
|
||||||
import type { KanbanGroup } from '../group.js';
|
import type { KanbanGroup } from '../group.js';
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import {
|
|||||||
import { horizontalListSortingStrategy } from '../../../core/utils/wc-dnd/sort/strategies/index.js';
|
import { horizontalListSortingStrategy } from '../../../core/utils/wc-dnd/sort/strategies/index.js';
|
||||||
import { DataViewBase } from '../../../core/view/data-view-base.js';
|
import { DataViewBase } from '../../../core/view/data-view-base.js';
|
||||||
import type { KanbanSingleView } from '../kanban-view-manager.js';
|
import type { KanbanSingleView } from '../kanban-view-manager.js';
|
||||||
import type { KanbanViewSelectionWithType } from '../types.js';
|
import type { KanbanViewSelectionWithType } from '../selection';
|
||||||
import { KanbanClipboardController } from './controller/clipboard.js';
|
import { KanbanClipboardController } from './controller/clipboard.js';
|
||||||
import { KanbanDragController } from './controller/drag.js';
|
import { KanbanDragController } from './controller/drag.js';
|
||||||
import { KanbanHotkeysController } from './controller/hotkeys.js';
|
import { KanbanHotkeysController } from './controller/hotkeys.js';
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const KanbanViewTypeSchema = z.object({
|
||||||
|
viewId: z.string(),
|
||||||
|
type: z.literal('kanban'),
|
||||||
|
});
|
||||||
|
export const KanbanCellSelectionSchema = z.object({
|
||||||
|
selectionType: z.literal('cell'),
|
||||||
|
groupKey: z.string(),
|
||||||
|
cardId: z.string(),
|
||||||
|
columnId: z.string(),
|
||||||
|
isEditing: z.boolean(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const KanbanCardSelectionCardSchema = z.object({
|
||||||
|
groupKey: z.string(),
|
||||||
|
cardId: z.string(),
|
||||||
|
});
|
||||||
|
export const KanbanCardSelectionSchema = z.object({
|
||||||
|
selectionType: z.literal('card'),
|
||||||
|
cards: z
|
||||||
|
.tuple([KanbanCardSelectionCardSchema])
|
||||||
|
.rest(KanbanCardSelectionCardSchema),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const KanbanGroupSelectionSchema = z.object({
|
||||||
|
selectionType: z.literal('group'),
|
||||||
|
groupKeys: z.tuple([z.string()]).rest(z.string()),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const KanbanViewSelectionSchema = z.union([
|
||||||
|
KanbanCellSelectionSchema,
|
||||||
|
KanbanCardSelectionSchema,
|
||||||
|
KanbanGroupSelectionSchema,
|
||||||
|
]);
|
||||||
|
export const KanbanViewSelectionWithTypeSchema = z.union([
|
||||||
|
z.intersection(KanbanViewTypeSchema, KanbanCellSelectionSchema),
|
||||||
|
z.intersection(KanbanViewTypeSchema, KanbanCardSelectionSchema),
|
||||||
|
z.intersection(KanbanViewTypeSchema, KanbanGroupSelectionSchema),
|
||||||
|
]);
|
||||||
|
export type KanbanCellSelection = z.TypeOf<typeof KanbanCellSelectionSchema>;
|
||||||
|
export type KanbanCardSelectionCard = z.TypeOf<
|
||||||
|
typeof KanbanCardSelectionCardSchema
|
||||||
|
>;
|
||||||
|
export type KanbanCardSelection = z.TypeOf<typeof KanbanCardSelectionSchema>;
|
||||||
|
export type KanbanGroupSelection = z.TypeOf<typeof KanbanGroupSelectionSchema>;
|
||||||
|
export type KanbanViewSelection = z.TypeOf<typeof KanbanViewSelectionSchema>;
|
||||||
|
export type KanbanViewSelectionWithType = z.TypeOf<
|
||||||
|
typeof KanbanViewSelectionWithTypeSchema
|
||||||
|
>;
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
type WithKanbanViewType<T> = T extends unknown
|
|
||||||
? {
|
|
||||||
viewId: string;
|
|
||||||
type: 'kanban';
|
|
||||||
} & T
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type KanbanCellSelection = {
|
|
||||||
selectionType: 'cell';
|
|
||||||
groupKey: string;
|
|
||||||
cardId: string;
|
|
||||||
columnId: string;
|
|
||||||
isEditing: boolean;
|
|
||||||
};
|
|
||||||
export type KanbanCardSelectionCard = {
|
|
||||||
groupKey: string;
|
|
||||||
cardId: string;
|
|
||||||
};
|
|
||||||
export type KanbanCardSelection = {
|
|
||||||
selectionType: 'card';
|
|
||||||
cards: [KanbanCardSelectionCard, ...KanbanCardSelectionCard[]];
|
|
||||||
};
|
|
||||||
export type KanbanGroupSelection = {
|
|
||||||
selectionType: 'group';
|
|
||||||
groupKeys: [string, ...string[]];
|
|
||||||
};
|
|
||||||
export type KanbanViewSelection =
|
|
||||||
| KanbanCellSelection
|
|
||||||
| KanbanCardSelection
|
|
||||||
| KanbanGroupSelection;
|
|
||||||
export type KanbanViewSelectionWithType =
|
|
||||||
WithKanbanViewType<KanbanViewSelection>;
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from './define.js';
|
export * from './define.js';
|
||||||
export * from './pc/table-view.js';
|
export * from './pc/table-view.js';
|
||||||
export * from './renderer.js';
|
export * from './renderer.js';
|
||||||
|
export * from './selection.js';
|
||||||
export * from './table-view-manager.js';
|
export * from './table-view-manager.js';
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import {
|
|||||||
renderUniLit,
|
renderUniLit,
|
||||||
type SingleView,
|
type SingleView,
|
||||||
} from '../../../core/index.js';
|
} from '../../../core/index.js';
|
||||||
|
import { TableViewAreaSelection } from '../selection';
|
||||||
import type { TableColumn } from '../table-view-manager.js';
|
import type { TableColumn } from '../table-view-manager.js';
|
||||||
import { TableAreaSelection } from '../types.js';
|
|
||||||
|
|
||||||
export class MobileTableCell extends SignalWatcher(
|
export class MobileTableCell extends SignalWatcher(
|
||||||
WithDisposable(ShadowlessElement)
|
WithDisposable(ShadowlessElement)
|
||||||
@@ -78,7 +78,7 @@ export class MobileTableCell extends SignalWatcher(
|
|||||||
setSelection({
|
setSelection({
|
||||||
viewId,
|
viewId,
|
||||||
type: 'table',
|
type: 'table',
|
||||||
...TableAreaSelection.create({
|
...TableViewAreaSelection.create({
|
||||||
groupKey: this.groupKey,
|
groupKey: this.groupKey,
|
||||||
focus: {
|
focus: {
|
||||||
rowIndex: this.rowIndex,
|
rowIndex: this.rowIndex,
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ import { GroupTitle } from '../../../core/group-by/group-title.js';
|
|||||||
import type { GroupData } from '../../../core/group-by/trait.js';
|
import type { GroupData } from '../../../core/group-by/trait.js';
|
||||||
import { LEFT_TOOL_BAR_WIDTH } from '../consts.js';
|
import { LEFT_TOOL_BAR_WIDTH } from '../consts.js';
|
||||||
import type { DataViewTable } from '../pc/table-view.js';
|
import type { DataViewTable } from '../pc/table-view.js';
|
||||||
|
import { TableViewAreaSelection } from '../selection';
|
||||||
import type { TableSingleView } from '../table-view-manager.js';
|
import type { TableSingleView } from '../table-view-manager.js';
|
||||||
import { TableAreaSelection } from '../types.js';
|
|
||||||
|
|
||||||
const styles = css`
|
const styles = css`
|
||||||
.data-view-table-group-add-row {
|
.data-view-table-group-add-row {
|
||||||
@@ -57,7 +57,7 @@ export class MobileTableGroup extends SignalWatcher(
|
|||||||
const index = this.view.properties$.value.findIndex(
|
const index = this.view.properties$.value.findIndex(
|
||||||
v => v.type$.value === 'title'
|
v => v.type$.value === 'title'
|
||||||
);
|
);
|
||||||
selectionController.selection = TableAreaSelection.create({
|
selectionController.selection = TableViewAreaSelection.create({
|
||||||
groupKey: this.group?.key,
|
groupKey: this.group?.key,
|
||||||
focus: {
|
focus: {
|
||||||
rowIndex: this.rows.length - 1,
|
rowIndex: this.rows.length - 1,
|
||||||
@@ -75,7 +75,7 @@ export class MobileTableGroup extends SignalWatcher(
|
|||||||
const index = this.view.properties$.value.findIndex(
|
const index = this.view.properties$.value.findIndex(
|
||||||
v => v.type$.value === 'title'
|
v => v.type$.value === 'title'
|
||||||
);
|
);
|
||||||
selectionController.selection = TableAreaSelection.create({
|
selectionController.selection = TableViewAreaSelection.create({
|
||||||
groupKey: this.group?.key,
|
groupKey: this.group?.key,
|
||||||
focus: {
|
focus: {
|
||||||
rowIndex: 0,
|
rowIndex: 0,
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ import type { DataViewInstance } from '../../../core/index.js';
|
|||||||
import { renderUniLit } from '../../../core/utils/uni-component/uni-component.js';
|
import { renderUniLit } from '../../../core/utils/uni-component/uni-component.js';
|
||||||
import { DataViewBase } from '../../../core/view/data-view-base.js';
|
import { DataViewBase } from '../../../core/view/data-view-base.js';
|
||||||
import { LEFT_TOOL_BAR_WIDTH } from '../consts.js';
|
import { LEFT_TOOL_BAR_WIDTH } from '../consts.js';
|
||||||
|
import type { TableViewSelectionWithType } from '../selection';
|
||||||
import type { TableSingleView } from '../table-view-manager.js';
|
import type { TableSingleView } from '../table-view-manager.js';
|
||||||
import type { TableViewSelectionWithType } from '../types.js';
|
|
||||||
|
|
||||||
export class MobileDataViewTable extends DataViewBase<
|
export class MobileDataViewTable extends DataViewBase<
|
||||||
TableSingleView,
|
TableSingleView,
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ import type {
|
|||||||
DataViewCellLifeCycle,
|
DataViewCellLifeCycle,
|
||||||
} from '../../../core/property/index.js';
|
} from '../../../core/property/index.js';
|
||||||
import type { SingleView } from '../../../core/view-manager/single-view.js';
|
import type { SingleView } from '../../../core/view-manager/single-view.js';
|
||||||
import type { TableColumn } from '../table-view-manager.js';
|
|
||||||
import {
|
import {
|
||||||
TableAreaSelection,
|
TableViewAreaSelection,
|
||||||
type TableViewSelectionWithType,
|
type TableViewSelectionWithType,
|
||||||
} from '../types.js';
|
} from '../selection';
|
||||||
|
import type { TableColumn } from '../table-view-manager.js';
|
||||||
|
|
||||||
export class DatabaseCellContainer extends SignalWatcher(
|
export class DatabaseCellContainer extends SignalWatcher(
|
||||||
WithDisposable(ShadowlessElement)
|
WithDisposable(ShadowlessElement)
|
||||||
@@ -63,7 +63,7 @@ export class DatabaseCellContainer extends SignalWatcher(
|
|||||||
if (selectionView) {
|
if (selectionView) {
|
||||||
const selection = selectionView.selection;
|
const selection = selectionView.selection;
|
||||||
if (selection && this.isSelected(selection) && editing) {
|
if (selection && this.isSelected(selection) && editing) {
|
||||||
selectionView.selection = TableAreaSelection.create({
|
selectionView.selection = TableViewAreaSelection.create({
|
||||||
groupKey: this.groupKey,
|
groupKey: this.groupKey,
|
||||||
focus: {
|
focus: {
|
||||||
rowIndex: this.rowIndex,
|
rowIndex: this.rowIndex,
|
||||||
@@ -72,7 +72,7 @@ export class DatabaseCellContainer extends SignalWatcher(
|
|||||||
isEditing: true,
|
isEditing: true,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
selectionView.selection = TableAreaSelection.create({
|
selectionView.selection = TableViewAreaSelection.create({
|
||||||
groupKey: this.groupKey,
|
groupKey: this.groupKey,
|
||||||
focus: {
|
focus: {
|
||||||
rowIndex: this.rowIndex,
|
rowIndex: this.rowIndex,
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import type { ReactiveController } from 'lit';
|
|||||||
import type { Cell } from '../../../../core/view-manager/cell.js';
|
import type { Cell } from '../../../../core/view-manager/cell.js';
|
||||||
import type { Row } from '../../../../core/view-manager/row.js';
|
import type { Row } from '../../../../core/view-manager/row.js';
|
||||||
import {
|
import {
|
||||||
TableAreaSelection,
|
TableViewAreaSelection,
|
||||||
TableRowSelection,
|
TableViewRowSelection,
|
||||||
type TableViewSelection,
|
type TableViewSelection,
|
||||||
type TableViewSelectionWithType,
|
type TableViewSelectionWithType,
|
||||||
} from '../../types.js';
|
} from '../../selection';
|
||||||
import type { DataViewTable } from '../table-view.js';
|
import type { DataViewTable } from '../table-view.js';
|
||||||
|
|
||||||
const BLOCKSUITE_DATABASE_TABLE = 'blocksuite/database/table';
|
const BLOCKSUITE_DATABASE_TABLE = 'blocksuite/database/table';
|
||||||
@@ -85,7 +85,7 @@ export class TableClipboardController implements ReactiveController {
|
|||||||
if (!clipboardData) return;
|
if (!clipboardData) return;
|
||||||
|
|
||||||
const tableSelection = this.host.selectionController.selection;
|
const tableSelection = this.host.selectionController.selection;
|
||||||
if (TableRowSelection.is(tableSelection)) {
|
if (TableViewRowSelection.is(tableSelection)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (tableSelection) {
|
if (tableSelection) {
|
||||||
@@ -196,8 +196,8 @@ function getSelectedArea(
|
|||||||
table: DataViewTable
|
table: DataViewTable
|
||||||
): SelectedArea | undefined {
|
): SelectedArea | undefined {
|
||||||
const view = table.props.view;
|
const view = table.props.view;
|
||||||
if (TableRowSelection.is(selection)) {
|
if (TableViewRowSelection.is(selection)) {
|
||||||
const rows = TableRowSelection.rows(selection)
|
const rows = TableViewRowSelection.rows(selection)
|
||||||
.map(row => {
|
.map(row => {
|
||||||
const y =
|
const y =
|
||||||
table.selectionController
|
table.selectionController
|
||||||
@@ -255,11 +255,11 @@ type SelectedArea = {
|
|||||||
}[];
|
}[];
|
||||||
|
|
||||||
function getTargetRangeFromSelection(
|
function getTargetRangeFromSelection(
|
||||||
selection: TableAreaSelection,
|
selection: TableViewAreaSelection,
|
||||||
data: JsonAreaData
|
data: JsonAreaData
|
||||||
) {
|
) {
|
||||||
const { rowsSelection, columnsSelection, focus } = selection;
|
const { rowsSelection, columnsSelection, focus } = selection;
|
||||||
return TableAreaSelection.isFocus(selection)
|
return TableViewAreaSelection.isFocus(selection)
|
||||||
? {
|
? {
|
||||||
row: {
|
row: {
|
||||||
start: focus.rowIndex,
|
start: focus.rowIndex,
|
||||||
@@ -285,7 +285,7 @@ function getTargetRangeFromSelection(
|
|||||||
function pasteToCells(
|
function pasteToCells(
|
||||||
table: DataViewTable,
|
table: DataViewTable,
|
||||||
rows: JsonAreaData,
|
rows: JsonAreaData,
|
||||||
selection: TableAreaSelection
|
selection: TableViewAreaSelection
|
||||||
) {
|
) {
|
||||||
const srcRowLength = rows.length;
|
const srcRowLength = rows.length;
|
||||||
const srcColumnLength = rows[0]?.length ?? 0;
|
const srcColumnLength = rows[0]?.length ?? 0;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { createRef, ref } from 'lit/directives/ref.js';
|
|||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { t } from '../../../../core/index.js';
|
import { t } from '../../../../core/index.js';
|
||||||
import type { TableAreaSelection } from '../../types.js';
|
import type { TableViewAreaSelection } from '../../selection';
|
||||||
import type { DataViewTable } from '../table-view.js';
|
import type { DataViewTable } from '../table-view.js';
|
||||||
|
|
||||||
export class DragToFillElement extends ShadowlessElement {
|
export class DragToFillElement extends ShadowlessElement {
|
||||||
@@ -50,7 +50,7 @@ export class DragToFillElement extends ShadowlessElement {
|
|||||||
|
|
||||||
export function fillSelectionWithFocusCellData(
|
export function fillSelectionWithFocusCellData(
|
||||||
host: DataViewTable,
|
host: DataViewTable,
|
||||||
selection: TableAreaSelection
|
selection: TableViewAreaSelection
|
||||||
) {
|
) {
|
||||||
const { groupKey, rowsSelection, columnsSelection, focus } = selection;
|
const { groupKey, rowsSelection, columnsSelection, focus } = selection;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { popupTargetFromElement } from '@blocksuite/affine-components/context-menu';
|
import { popupTargetFromElement } from '@blocksuite/affine-components/context-menu';
|
||||||
import type { ReactiveController } from 'lit';
|
import type { ReactiveController } from 'lit';
|
||||||
|
|
||||||
import { TableAreaSelection, TableRowSelection } from '../../types.js';
|
import { TableViewAreaSelection, TableViewRowSelection } from '../../selection';
|
||||||
import { popRowMenu } from '../menu.js';
|
import { popRowMenu } from '../menu.js';
|
||||||
import type { DataViewTable } from '../table-view.js';
|
import type { DataViewTable } from '../table-view.js';
|
||||||
|
|
||||||
@@ -22,8 +22,8 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
if (!selection) {
|
if (!selection) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (TableRowSelection.is(selection)) {
|
if (TableViewRowSelection.is(selection)) {
|
||||||
const rows = TableRowSelection.rowsIds(selection);
|
const rows = TableViewRowSelection.rowsIds(selection);
|
||||||
this.selectionController.selection = undefined;
|
this.selectionController.selection = undefined;
|
||||||
this.host.props.view.rowDelete(rows);
|
this.host.props.view.rowDelete(rows);
|
||||||
return;
|
return;
|
||||||
@@ -73,23 +73,24 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
if (!selection) {
|
if (!selection) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (TableRowSelection.is(selection)) {
|
if (TableViewRowSelection.is(selection)) {
|
||||||
const result = this.selectionController.rowsToArea(
|
const result = this.selectionController.rowsToArea(
|
||||||
selection.rows.map(v => v.id)
|
selection.rows.map(v => v.id)
|
||||||
);
|
);
|
||||||
if (result) {
|
if (result) {
|
||||||
this.selectionController.selection = TableAreaSelection.create({
|
this.selectionController.selection =
|
||||||
groupKey: result.groupKey,
|
TableViewAreaSelection.create({
|
||||||
focus: {
|
groupKey: result.groupKey,
|
||||||
rowIndex: result.start,
|
focus: {
|
||||||
columnIndex: 0,
|
rowIndex: result.start,
|
||||||
},
|
columnIndex: 0,
|
||||||
rowsSelection: {
|
},
|
||||||
start: result.start,
|
rowsSelection: {
|
||||||
end: result.end,
|
start: result.start,
|
||||||
},
|
end: result.end,
|
||||||
isEditing: false,
|
},
|
||||||
});
|
isEditing: false,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this.selectionController.selection = undefined;
|
this.selectionController.selection = undefined;
|
||||||
}
|
}
|
||||||
@@ -112,23 +113,24 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
if (!selection) {
|
if (!selection) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (TableRowSelection.is(selection)) {
|
if (TableViewRowSelection.is(selection)) {
|
||||||
const result = this.selectionController.rowsToArea(
|
const result = this.selectionController.rowsToArea(
|
||||||
selection.rows.map(v => v.id)
|
selection.rows.map(v => v.id)
|
||||||
);
|
);
|
||||||
if (result) {
|
if (result) {
|
||||||
this.selectionController.selection = TableAreaSelection.create({
|
this.selectionController.selection =
|
||||||
groupKey: result.groupKey,
|
TableViewAreaSelection.create({
|
||||||
focus: {
|
groupKey: result.groupKey,
|
||||||
rowIndex: result.start,
|
focus: {
|
||||||
columnIndex: 0,
|
rowIndex: result.start,
|
||||||
},
|
columnIndex: 0,
|
||||||
rowsSelection: {
|
},
|
||||||
start: result.start,
|
rowsSelection: {
|
||||||
end: result.end,
|
start: result.start,
|
||||||
},
|
end: result.end,
|
||||||
isEditing: false,
|
},
|
||||||
});
|
isEditing: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else if (selection.isEditing) {
|
} else if (selection.isEditing) {
|
||||||
return false;
|
return false;
|
||||||
@@ -145,7 +147,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
const selection = this.selectionController.selection;
|
const selection = this.selectionController.selection;
|
||||||
if (
|
if (
|
||||||
!selection ||
|
!selection ||
|
||||||
TableRowSelection.is(selection) ||
|
TableViewRowSelection.is(selection) ||
|
||||||
selection.isEditing
|
selection.isEditing
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
@@ -167,7 +169,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
const selection = this.selectionController.selection;
|
const selection = this.selectionController.selection;
|
||||||
if (
|
if (
|
||||||
!selection ||
|
!selection ||
|
||||||
TableRowSelection.is(selection) ||
|
TableViewRowSelection.is(selection) ||
|
||||||
selection.isEditing
|
selection.isEditing
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
@@ -180,7 +182,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
const selection = this.selectionController.selection;
|
const selection = this.selectionController.selection;
|
||||||
if (
|
if (
|
||||||
!selection ||
|
!selection ||
|
||||||
TableRowSelection.is(selection) ||
|
TableViewRowSelection.is(selection) ||
|
||||||
selection.isEditing
|
selection.isEditing
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
@@ -193,7 +195,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
const selection = this.selectionController.selection;
|
const selection = this.selectionController.selection;
|
||||||
if (
|
if (
|
||||||
!selection ||
|
!selection ||
|
||||||
TableRowSelection.is(selection) ||
|
TableViewRowSelection.is(selection) ||
|
||||||
selection.isEditing
|
selection.isEditing
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
@@ -206,7 +208,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
const selection = this.selectionController.selection;
|
const selection = this.selectionController.selection;
|
||||||
if (
|
if (
|
||||||
!selection ||
|
!selection ||
|
||||||
TableRowSelection.is(selection) ||
|
TableViewRowSelection.is(selection) ||
|
||||||
selection.isEditing
|
selection.isEditing
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
@@ -221,7 +223,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TableRowSelection.is(selection)) {
|
if (TableViewRowSelection.is(selection)) {
|
||||||
this.selectionController.navigateRowSelection('up', false);
|
this.selectionController.navigateRowSelection('up', false);
|
||||||
} else if (selection.isEditing) {
|
} else if (selection.isEditing) {
|
||||||
return false;
|
return false;
|
||||||
@@ -238,7 +240,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TableRowSelection.is(selection)) {
|
if (TableViewRowSelection.is(selection)) {
|
||||||
this.selectionController.navigateRowSelection('down', false);
|
this.selectionController.navigateRowSelection('down', false);
|
||||||
} else if (selection.isEditing) {
|
} else if (selection.isEditing) {
|
||||||
return false;
|
return false;
|
||||||
@@ -256,7 +258,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TableRowSelection.is(selection)) {
|
if (TableViewRowSelection.is(selection)) {
|
||||||
this.selectionController.navigateRowSelection('up', true);
|
this.selectionController.navigateRowSelection('up', true);
|
||||||
} else if (selection.isEditing) {
|
} else if (selection.isEditing) {
|
||||||
return false;
|
return false;
|
||||||
@@ -274,7 +276,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TableRowSelection.is(selection)) {
|
if (TableViewRowSelection.is(selection)) {
|
||||||
this.selectionController.navigateRowSelection('down', true);
|
this.selectionController.navigateRowSelection('down', true);
|
||||||
} else if (selection.isEditing) {
|
} else if (selection.isEditing) {
|
||||||
return false;
|
return false;
|
||||||
@@ -290,7 +292,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
const selection = this.selectionController.selection;
|
const selection = this.selectionController.selection;
|
||||||
if (
|
if (
|
||||||
!selection ||
|
!selection ||
|
||||||
TableRowSelection.is(selection) ||
|
TableViewRowSelection.is(selection) ||
|
||||||
selection.isEditing ||
|
selection.isEditing ||
|
||||||
this.selectionController.isRowSelection()
|
this.selectionController.isRowSelection()
|
||||||
) {
|
) {
|
||||||
@@ -307,7 +309,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
const selection = this.selectionController.selection;
|
const selection = this.selectionController.selection;
|
||||||
if (
|
if (
|
||||||
!selection ||
|
!selection ||
|
||||||
TableRowSelection.is(selection) ||
|
TableViewRowSelection.is(selection) ||
|
||||||
selection.isEditing ||
|
selection.isEditing ||
|
||||||
this.selectionController.isRowSelection()
|
this.selectionController.isRowSelection()
|
||||||
) {
|
) {
|
||||||
@@ -322,7 +324,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
|
|
||||||
'Mod-a': context => {
|
'Mod-a': context => {
|
||||||
const selection = this.selectionController.selection;
|
const selection = this.selectionController.selection;
|
||||||
if (TableRowSelection.is(selection)) {
|
if (TableViewRowSelection.is(selection)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (selection?.isEditing) {
|
if (selection?.isEditing) {
|
||||||
@@ -330,7 +332,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
}
|
}
|
||||||
if (selection) {
|
if (selection) {
|
||||||
context.get('keyboardState').raw.preventDefault();
|
context.get('keyboardState').raw.preventDefault();
|
||||||
this.selectionController.selection = TableRowSelection.create({
|
this.selectionController.selection = TableViewRowSelection.create({
|
||||||
rows:
|
rows:
|
||||||
this.host.props.view.groupTrait.groupsDataList$.value?.flatMap(
|
this.host.props.view.groupTrait.groupsDataList$.value?.flatMap(
|
||||||
group =>
|
group =>
|
||||||
@@ -350,7 +352,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
if (!selection) {
|
if (!selection) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (TableRowSelection.is(selection)) {
|
if (TableViewRowSelection.is(selection)) {
|
||||||
// open multi-rows context-menu
|
// open multi-rows context-menu
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -368,7 +370,7 @@ export class TableHotkeysController implements ReactiveController {
|
|||||||
id: cell.rowId,
|
id: cell.rowId,
|
||||||
groupKey: selection.groupKey,
|
groupKey: selection.groupKey,
|
||||||
};
|
};
|
||||||
this.selectionController.selection = TableRowSelection.create({
|
this.selectionController.selection = TableViewRowSelection.create({
|
||||||
rows: [row],
|
rows: [row],
|
||||||
});
|
});
|
||||||
popRowMenu(
|
popRowMenu(
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ import {
|
|||||||
type CellFocus,
|
type CellFocus,
|
||||||
type MultiSelection,
|
type MultiSelection,
|
||||||
RowWithGroup,
|
RowWithGroup,
|
||||||
TableAreaSelection,
|
TableViewAreaSelection,
|
||||||
TableRowSelection,
|
TableViewRowSelection,
|
||||||
type TableViewSelection,
|
type TableViewSelection,
|
||||||
type TableViewSelectionWithType,
|
type TableViewSelectionWithType,
|
||||||
} from '../../types.js';
|
} from '../../selection';
|
||||||
import type { DatabaseCellContainer } from '../cell.js';
|
import type { DatabaseCellContainer } from '../cell.js';
|
||||||
import type { TableRow } from '../row/row.js';
|
import type { TableRow } from '../row/row.js';
|
||||||
import type { DataViewTable } from '../table-view.js';
|
import type { DataViewTable } from '../table-view.js';
|
||||||
@@ -240,7 +240,7 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
const index = this.host.props.view.properties$.value.findIndex(
|
const index = this.host.props.view.properties$.value.findIndex(
|
||||||
v => v.type$.value === 'title'
|
v => v.type$.value === 'title'
|
||||||
);
|
);
|
||||||
this.selection = TableAreaSelection.create({
|
this.selection = TableViewAreaSelection.create({
|
||||||
groupKey: groupKey,
|
groupKey: groupKey,
|
||||||
focus: {
|
focus: {
|
||||||
rowIndex: rows?.findIndex(v => v === id) ?? 0,
|
rowIndex: rows?.findIndex(v => v === id) ?? 0,
|
||||||
@@ -279,7 +279,7 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
areaToRows(selection: TableAreaSelection) {
|
areaToRows(selection: TableViewAreaSelection) {
|
||||||
const rows = this.rows(selection.groupKey) ?? [];
|
const rows = this.rows(selection.groupKey) ?? [];
|
||||||
const ids = Array.from({
|
const ids = Array.from({
|
||||||
length: selection.rowsSelection.end - selection.rowsSelection.start + 1,
|
length: selection.rowsSelection.end - selection.rowsSelection.start + 1,
|
||||||
@@ -350,7 +350,7 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
focusFirstCell() {
|
focusFirstCell() {
|
||||||
this.selection = TableAreaSelection.create({
|
this.selection = TableViewAreaSelection.create({
|
||||||
focus: {
|
focus: {
|
||||||
rowIndex: 0,
|
rowIndex: 0,
|
||||||
columnIndex: 0,
|
columnIndex: 0,
|
||||||
@@ -359,7 +359,7 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
focusToArea(selection: TableAreaSelection) {
|
focusToArea(selection: TableViewAreaSelection) {
|
||||||
return {
|
return {
|
||||||
...selection,
|
...selection,
|
||||||
rowsSelection: selection.rowsSelection ?? {
|
rowsSelection: selection.rowsSelection ?? {
|
||||||
@@ -371,7 +371,7 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
end: selection.focus.columnIndex,
|
end: selection.focus.columnIndex,
|
||||||
},
|
},
|
||||||
isEditing: false,
|
isEditing: false,
|
||||||
} satisfies TableAreaSelection;
|
} satisfies TableViewAreaSelection;
|
||||||
}
|
}
|
||||||
|
|
||||||
focusToCell(position: 'left' | 'right' | 'up' | 'down') {
|
focusToCell(position: 'left' | 'right' | 'up' | 'down') {
|
||||||
@@ -544,7 +544,7 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
navigateRowSelection(direction: 'up' | 'down', append = false) {
|
navigateRowSelection(direction: 'up' | 'down', append = false) {
|
||||||
if (!TableRowSelection.is(this.selection)) return;
|
if (!TableViewRowSelection.is(this.selection)) return;
|
||||||
const rows = this.selection.rows;
|
const rows = this.selection.rows;
|
||||||
const lastRow = rows[rows.length - 1];
|
const lastRow = rows[rows.length - 1];
|
||||||
if (!lastRow) return;
|
if (!lastRow) return;
|
||||||
@@ -593,7 +593,7 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
} else {
|
} else {
|
||||||
const target = direction === 'up' ? prevRow : nextRow;
|
const target = direction === 'up' ? prevRow : nextRow;
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
this.selection = TableRowSelection.create({
|
this.selection = TableViewRowSelection.create({
|
||||||
rows: [target],
|
rows: [target],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -619,7 +619,7 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
}) {
|
}) {
|
||||||
const key = (r: RowWithGroup) => `${r.id}.${r.groupKey ? r.groupKey : ''}`;
|
const key = (r: RowWithGroup) => `${r.id}.${r.groupKey ? r.groupKey : ''}`;
|
||||||
const rows = new Set(
|
const rows = new Set(
|
||||||
TableRowSelection.rows(this.selection).map(r => key(r))
|
TableViewRowSelection.rows(this.selection).map(r => key(r))
|
||||||
);
|
);
|
||||||
remove.forEach(row => rows.delete(key(row)));
|
remove.forEach(row => rows.delete(key(row)));
|
||||||
add.forEach(row => rows.add(key(row)));
|
add.forEach(row => rows.add(key(row)));
|
||||||
@@ -634,7 +634,7 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
this.selection = TableRowSelection.create({
|
this.selection = TableViewRowSelection.create({
|
||||||
rows: result,
|
rows: result,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -826,7 +826,7 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
row: MultiSelection;
|
row: MultiSelection;
|
||||||
column: MultiSelection;
|
column: MultiSelection;
|
||||||
}) => {
|
}) => {
|
||||||
this.selection = TableAreaSelection.create({
|
this.selection = TableViewAreaSelection.create({
|
||||||
groupKey: groupKey,
|
groupKey: groupKey,
|
||||||
rowsSelection: selection.row,
|
rowsSelection: selection.row,
|
||||||
columnsSelection: selection.column,
|
columnsSelection: selection.column,
|
||||||
@@ -881,7 +881,7 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
this.__dragToFillElement.dragging = false;
|
this.__dragToFillElement.dragging = false;
|
||||||
fillSelectionWithFocusCellData(
|
fillSelectionWithFocusCellData(
|
||||||
this.host,
|
this.host,
|
||||||
TableAreaSelection.create({
|
TableViewAreaSelection.create({
|
||||||
groupKey: groupKey,
|
groupKey: groupKey,
|
||||||
rowsSelection: selection.row,
|
rowsSelection: selection.row,
|
||||||
columnsSelection: selection.column,
|
columnsSelection: selection.column,
|
||||||
@@ -921,7 +921,7 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
id: rowId,
|
id: rowId,
|
||||||
groupKey,
|
groupKey,
|
||||||
};
|
};
|
||||||
const isSelected = TableRowSelection.includes(this.selection, row);
|
const isSelected = TableViewRowSelection.includes(this.selection, row);
|
||||||
this.rowSelectionChange({
|
this.rowSelectionChange({
|
||||||
add: isSelected ? [] : [row],
|
add: isSelected ? [] : [row],
|
||||||
remove: isSelected ? [row] : [],
|
remove: isSelected ? [row] : [],
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ import { createDndContext } from '../../../core/utils/wc-dnd/dnd-context.js';
|
|||||||
import { defaultActivators } from '../../../core/utils/wc-dnd/sensors/index.js';
|
import { defaultActivators } from '../../../core/utils/wc-dnd/sensors/index.js';
|
||||||
import { linearMove } from '../../../core/utils/wc-dnd/utils/linear-move.js';
|
import { linearMove } from '../../../core/utils/wc-dnd/utils/linear-move.js';
|
||||||
import { LEFT_TOOL_BAR_WIDTH } from '../consts.js';
|
import { LEFT_TOOL_BAR_WIDTH } from '../consts.js';
|
||||||
|
import { TableViewAreaSelection } from '../selection';
|
||||||
import type { TableSingleView } from '../table-view-manager.js';
|
import type { TableSingleView } from '../table-view-manager.js';
|
||||||
import { TableAreaSelection } from '../types.js';
|
|
||||||
import { DataViewColumnPreview } from './header/column-renderer.js';
|
import { DataViewColumnPreview } from './header/column-renderer.js';
|
||||||
import { getVerticalIndicator } from './header/vertical-indicator.js';
|
import { getVerticalIndicator } from './header/vertical-indicator.js';
|
||||||
import type { DataViewTable } from './table-view.js';
|
import type { DataViewTable } from './table-view.js';
|
||||||
@@ -74,7 +74,7 @@ export class TableGroup extends SignalWatcher(
|
|||||||
const index = this.view.properties$.value.findIndex(
|
const index = this.view.properties$.value.findIndex(
|
||||||
v => v.type$.value === 'title'
|
v => v.type$.value === 'title'
|
||||||
);
|
);
|
||||||
selectionController.selection = TableAreaSelection.create({
|
selectionController.selection = TableViewAreaSelection.create({
|
||||||
groupKey: this.group?.key,
|
groupKey: this.group?.key,
|
||||||
focus: {
|
focus: {
|
||||||
rowIndex: this.rows.length - 1,
|
rowIndex: this.rows.length - 1,
|
||||||
@@ -92,7 +92,7 @@ export class TableGroup extends SignalWatcher(
|
|||||||
const index = this.view.properties$.value.findIndex(
|
const index = this.view.properties$.value.findIndex(
|
||||||
v => v.type$.value === 'title'
|
v => v.type$.value === 'title'
|
||||||
);
|
);
|
||||||
selectionController.selection = TableAreaSelection.create({
|
selectionController.selection = TableViewAreaSelection.create({
|
||||||
groupKey: this.group?.key,
|
groupKey: this.group?.key,
|
||||||
focus: {
|
focus: {
|
||||||
rowIndex: 0,
|
rowIndex: 0,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
import { html } from 'lit';
|
import { html } from 'lit';
|
||||||
|
|
||||||
import type { DataViewRenderer } from '../../../core/data-view.js';
|
import type { DataViewRenderer } from '../../../core/data-view.js';
|
||||||
import { TableRowSelection } from '../types.js';
|
import { TableViewRowSelection } from '../selection';
|
||||||
import type { TableSelectionController } from './controller/selection.js';
|
import type { TableSelectionController } from './controller/selection.js';
|
||||||
|
|
||||||
export const openDetail = (
|
export const openDetail = (
|
||||||
@@ -38,11 +38,11 @@ export const popRowMenu = (
|
|||||||
selectionController: TableSelectionController
|
selectionController: TableSelectionController
|
||||||
) => {
|
) => {
|
||||||
const selection = selectionController.selection;
|
const selection = selectionController.selection;
|
||||||
if (!TableRowSelection.is(selection)) {
|
if (!TableViewRowSelection.is(selection)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (selection.rows.length > 1) {
|
if (selection.rows.length > 1) {
|
||||||
const rows = TableRowSelection.rowsIds(selection);
|
const rows = TableViewRowSelection.rowsIds(selection);
|
||||||
popFilterableSimpleMenu(ele, [
|
popFilterableSimpleMenu(ele, [
|
||||||
menu.group({
|
menu.group({
|
||||||
name: '',
|
name: '',
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import { property } from 'lit/decorators.js';
|
|||||||
import { classMap } from 'lit/directives/class-map.js';
|
import { classMap } from 'lit/directives/class-map.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TableRowSelection,
|
TableViewRowSelection,
|
||||||
type TableViewSelectionWithType,
|
type TableViewSelectionWithType,
|
||||||
} from '../../types.js';
|
} from '../../selection';
|
||||||
|
|
||||||
export class RowSelectCheckbox extends SignalWatcher(
|
export class RowSelectCheckbox extends SignalWatcher(
|
||||||
WithDisposable(ShadowlessElement)
|
WithDisposable(ShadowlessElement)
|
||||||
@@ -49,7 +49,7 @@ export class RowSelectCheckbox extends SignalWatcher(
|
|||||||
if (!selection || selection.selectionType !== 'row') {
|
if (!selection || selection.selectionType !== 'row') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return TableRowSelection.includes(selection, {
|
return TableViewRowSelection.includes(selection, {
|
||||||
id: this.rowId,
|
id: this.rowId,
|
||||||
groupKey: this.groupKey,
|
groupKey: this.groupKey,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,8 +9,11 @@ import { styleMap } from 'lit/directives/style-map.js';
|
|||||||
import { html } from 'lit/static-html.js';
|
import { html } from 'lit/static-html.js';
|
||||||
|
|
||||||
import type { DataViewRenderer } from '../../../../core/data-view.js';
|
import type { DataViewRenderer } from '../../../../core/data-view.js';
|
||||||
|
import {
|
||||||
|
TableViewRowSelection,
|
||||||
|
type TableViewSelection,
|
||||||
|
} from '../../selection';
|
||||||
import type { TableSingleView } from '../../table-view-manager.js';
|
import type { TableSingleView } from '../../table-view-manager.js';
|
||||||
import { TableRowSelection, type TableViewSelection } from '../../types.js';
|
|
||||||
import { openDetail, popRowMenu } from '../menu.js';
|
import { openDetail, popRowMenu } from '../menu.js';
|
||||||
|
|
||||||
export class TableRow extends SignalWatcher(WithDisposable(ShadowlessElement)) {
|
export class TableRow extends SignalWatcher(WithDisposable(ShadowlessElement)) {
|
||||||
@@ -133,8 +136,8 @@ export class TableRow extends SignalWatcher(WithDisposable(ShadowlessElement)) {
|
|||||||
const ele = e.target as HTMLElement;
|
const ele = e.target as HTMLElement;
|
||||||
const cell = ele.closest('affine-database-cell-container');
|
const cell = ele.closest('affine-database-cell-container');
|
||||||
const row = { id: this.rowId, groupKey: this.groupKey };
|
const row = { id: this.rowId, groupKey: this.groupKey };
|
||||||
if (!TableRowSelection.includes(selection.selection, row)) {
|
if (!TableViewRowSelection.includes(selection.selection, row)) {
|
||||||
selection.selection = TableRowSelection.create({
|
selection.selection = TableViewRowSelection.create({
|
||||||
rows: [row],
|
rows: [row],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -201,7 +204,7 @@ export class TableRow extends SignalWatcher(WithDisposable(ShadowlessElement)) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setSelection(
|
this.setSelection(
|
||||||
TableRowSelection.create({
|
TableViewRowSelection.create({
|
||||||
rows: [{ id: this.rowId, groupKey: this.groupKey }],
|
rows: [{ id: this.rowId, groupKey: this.groupKey }],
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -214,14 +217,14 @@ export class TableRow extends SignalWatcher(WithDisposable(ShadowlessElement)) {
|
|||||||
const ele = e.currentTarget as HTMLElement;
|
const ele = e.currentTarget as HTMLElement;
|
||||||
const selection = this.selectionController.selection;
|
const selection = this.selectionController.selection;
|
||||||
if (
|
if (
|
||||||
!TableRowSelection.is(selection) ||
|
!TableViewRowSelection.is(selection) ||
|
||||||
!selection.rows.some(
|
!selection.rows.some(
|
||||||
row => row.id === this.rowId && row.groupKey === this.groupKey
|
row => row.id === this.rowId && row.groupKey === this.groupKey
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
const row = { id: this.rowId, groupKey: this.groupKey };
|
const row = { id: this.rowId, groupKey: this.groupKey };
|
||||||
this.setSelection(
|
this.setSelection(
|
||||||
TableRowSelection.create({
|
TableViewRowSelection.create({
|
||||||
rows: [row],
|
rows: [row],
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import type { DataViewInstance } from '../../../core/index.js';
|
|||||||
import { renderUniLit } from '../../../core/utils/uni-component/uni-component.js';
|
import { renderUniLit } from '../../../core/utils/uni-component/uni-component.js';
|
||||||
import { DataViewBase } from '../../../core/view/data-view-base.js';
|
import { DataViewBase } from '../../../core/view/data-view-base.js';
|
||||||
import { LEFT_TOOL_BAR_WIDTH } from '../consts.js';
|
import { LEFT_TOOL_BAR_WIDTH } from '../consts.js';
|
||||||
|
import type { TableViewSelectionWithType } from '../selection';
|
||||||
import type { TableSingleView } from '../table-view-manager.js';
|
import type { TableSingleView } from '../table-view-manager.js';
|
||||||
import type { TableViewSelectionWithType } from '../types.js';
|
|
||||||
import { TableClipboardController } from './controller/clipboard.js';
|
import { TableClipboardController } from './controller/clipboard.js';
|
||||||
import { TableDragController } from './controller/drag.js';
|
import { TableDragController } from './controller/drag.js';
|
||||||
import { TableHotkeysController } from './controller/hotkeys.js';
|
import { TableHotkeysController } from './controller/hotkeys.js';
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const TableViewTypeSchema = z.object({
|
||||||
|
viewId: z.string(),
|
||||||
|
type: z.literal('table'),
|
||||||
|
});
|
||||||
|
export const RangeSchema = z.object({
|
||||||
|
start: z.number(),
|
||||||
|
end: z.number(),
|
||||||
|
});
|
||||||
|
export const FocusSchema = z.object({
|
||||||
|
rowIndex: z.number(),
|
||||||
|
columnIndex: z.number(),
|
||||||
|
});
|
||||||
|
export const TableViewAreaSelectionSchema = z.object({
|
||||||
|
selectionType: z.literal('area'),
|
||||||
|
groupKey: z.string().optional(),
|
||||||
|
rowsSelection: RangeSchema,
|
||||||
|
columnsSelection: RangeSchema,
|
||||||
|
focus: FocusSchema,
|
||||||
|
isEditing: z.boolean(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const RowWithGroupSchema = z.object({
|
||||||
|
id: z.string(),
|
||||||
|
groupKey: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const TableViewRowSelectionSchema = z.object({
|
||||||
|
selectionType: z.literal('row'),
|
||||||
|
rows: z.array(RowWithGroupSchema),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const TableViewSelectionSchema = z.union([
|
||||||
|
TableViewAreaSelectionSchema,
|
||||||
|
TableViewRowSelectionSchema,
|
||||||
|
]);
|
||||||
|
export const TableViewSelectionWithTypeSchema = z.union([
|
||||||
|
z.intersection(TableViewTypeSchema, TableViewAreaSelectionSchema),
|
||||||
|
z.intersection(TableViewTypeSchema, TableViewRowSelectionSchema),
|
||||||
|
]);
|
||||||
|
export type RowWithGroup = z.TypeOf<typeof RowWithGroupSchema>;
|
||||||
|
export const RowWithGroup = {
|
||||||
|
equal(a?: RowWithGroup, b?: RowWithGroup) {
|
||||||
|
if (a == null || b == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return a.id === b.id && a.groupKey === b.groupKey;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export type TableViewRowSelection = z.TypeOf<
|
||||||
|
typeof TableViewRowSelectionSchema
|
||||||
|
>;
|
||||||
|
export const TableViewRowSelection = {
|
||||||
|
rows: (selection?: TableViewSelection): RowWithGroup[] => {
|
||||||
|
if (selection?.selectionType === 'row') {
|
||||||
|
return selection.rows;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
rowsIds: (selection?: TableViewSelection): string[] => {
|
||||||
|
return TableViewRowSelection.rows(selection).map(v => v.id);
|
||||||
|
},
|
||||||
|
includes(
|
||||||
|
selection: TableViewSelection | undefined,
|
||||||
|
row: RowWithGroup
|
||||||
|
): boolean {
|
||||||
|
if (!selection) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return TableViewRowSelection.rows(selection).some(v =>
|
||||||
|
RowWithGroup.equal(v, row)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
create(options: { rows: RowWithGroup[] }): TableViewRowSelection {
|
||||||
|
return {
|
||||||
|
selectionType: 'row',
|
||||||
|
rows: options.rows,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
is(selection?: TableViewSelection): selection is TableViewRowSelection {
|
||||||
|
return selection?.selectionType === 'row';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export type TableViewAreaSelection = z.TypeOf<
|
||||||
|
typeof TableViewAreaSelectionSchema
|
||||||
|
>;
|
||||||
|
export const TableViewAreaSelection = {
|
||||||
|
create: (options: {
|
||||||
|
groupKey?: string;
|
||||||
|
focus: CellFocus;
|
||||||
|
rowsSelection?: MultiSelection;
|
||||||
|
columnsSelection?: MultiSelection;
|
||||||
|
isEditing: boolean;
|
||||||
|
}): TableViewAreaSelection => {
|
||||||
|
return {
|
||||||
|
...options,
|
||||||
|
selectionType: 'area',
|
||||||
|
rowsSelection: options.rowsSelection ?? {
|
||||||
|
start: options.focus.rowIndex,
|
||||||
|
end: options.focus.rowIndex,
|
||||||
|
},
|
||||||
|
columnsSelection: options.columnsSelection ?? {
|
||||||
|
start: options.focus.columnIndex,
|
||||||
|
end: options.focus.columnIndex,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
isFocus(selection: TableViewAreaSelection) {
|
||||||
|
return (
|
||||||
|
selection.focus.rowIndex === selection.rowsSelection.start &&
|
||||||
|
selection.focus.rowIndex === selection.rowsSelection.end &&
|
||||||
|
selection.focus.columnIndex === selection.columnsSelection.start &&
|
||||||
|
selection.focus.columnIndex === selection.columnsSelection.end
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export type CellFocus = z.TypeOf<typeof FocusSchema>;
|
||||||
|
export type MultiSelection = z.TypeOf<typeof RangeSchema>;
|
||||||
|
export type TableViewSelection = z.TypeOf<typeof TableViewSelectionSchema>;
|
||||||
|
export type TableViewSelectionWithType = z.TypeOf<
|
||||||
|
typeof TableViewSelectionWithTypeSchema
|
||||||
|
>;
|
||||||
@@ -10,108 +10,3 @@ export interface Column<
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type StatCalcOpType = string | undefined;
|
export type StatCalcOpType = string | undefined;
|
||||||
|
|
||||||
type WithTableViewType<T> = T extends unknown
|
|
||||||
? {
|
|
||||||
viewId: string;
|
|
||||||
type: 'table';
|
|
||||||
} & T
|
|
||||||
: never;
|
|
||||||
export type RowWithGroup = {
|
|
||||||
id: string;
|
|
||||||
groupKey?: string;
|
|
||||||
};
|
|
||||||
export const RowWithGroup = {
|
|
||||||
equal(a?: RowWithGroup, b?: RowWithGroup) {
|
|
||||||
if (a == null || b == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return a.id === b.id && a.groupKey === b.groupKey;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
export type TableRowSelection = {
|
|
||||||
selectionType: 'row';
|
|
||||||
rows: RowWithGroup[];
|
|
||||||
};
|
|
||||||
export const TableRowSelection = {
|
|
||||||
rows: (selection?: TableViewSelection): RowWithGroup[] => {
|
|
||||||
if (selection?.selectionType === 'row') {
|
|
||||||
return selection.rows;
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
},
|
|
||||||
rowsIds: (selection?: TableViewSelection): string[] => {
|
|
||||||
return TableRowSelection.rows(selection).map(v => v.id);
|
|
||||||
},
|
|
||||||
includes(
|
|
||||||
selection: TableViewSelection | undefined,
|
|
||||||
row: RowWithGroup
|
|
||||||
): boolean {
|
|
||||||
if (!selection) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return TableRowSelection.rows(selection).some(v =>
|
|
||||||
RowWithGroup.equal(v, row)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
create(options: { rows: RowWithGroup[] }): TableRowSelection {
|
|
||||||
return {
|
|
||||||
selectionType: 'row',
|
|
||||||
rows: options.rows,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
is(selection?: TableViewSelection): selection is TableRowSelection {
|
|
||||||
return selection?.selectionType === 'row';
|
|
||||||
},
|
|
||||||
};
|
|
||||||
export type TableAreaSelection = {
|
|
||||||
selectionType: 'area';
|
|
||||||
groupKey?: string;
|
|
||||||
rowsSelection: MultiSelection;
|
|
||||||
columnsSelection: MultiSelection;
|
|
||||||
focus: CellFocus;
|
|
||||||
isEditing: boolean;
|
|
||||||
};
|
|
||||||
export const TableAreaSelection = {
|
|
||||||
create: (options: {
|
|
||||||
groupKey?: string;
|
|
||||||
focus: CellFocus;
|
|
||||||
rowsSelection?: MultiSelection;
|
|
||||||
columnsSelection?: MultiSelection;
|
|
||||||
isEditing: boolean;
|
|
||||||
}): TableAreaSelection => {
|
|
||||||
return {
|
|
||||||
...options,
|
|
||||||
selectionType: 'area',
|
|
||||||
rowsSelection: options.rowsSelection ?? {
|
|
||||||
start: options.focus.rowIndex,
|
|
||||||
end: options.focus.rowIndex,
|
|
||||||
},
|
|
||||||
columnsSelection: options.columnsSelection ?? {
|
|
||||||
start: options.focus.columnIndex,
|
|
||||||
end: options.focus.columnIndex,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
isFocus(selection: TableAreaSelection) {
|
|
||||||
return (
|
|
||||||
selection.focus.rowIndex === selection.rowsSelection.start &&
|
|
||||||
selection.focus.rowIndex === selection.rowsSelection.end &&
|
|
||||||
selection.focus.columnIndex === selection.columnsSelection.start &&
|
|
||||||
selection.focus.columnIndex === selection.columnsSelection.end
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CellFocus = {
|
|
||||||
rowIndex: number;
|
|
||||||
columnIndex: number;
|
|
||||||
};
|
|
||||||
export type MultiSelection = {
|
|
||||||
start: number;
|
|
||||||
end: number;
|
|
||||||
};
|
|
||||||
export type TableViewSelection = TableAreaSelection | TableRowSelection;
|
|
||||||
export type TableViewSelectionWithType = WithTableViewType<
|
|
||||||
TableAreaSelection | TableRowSelection
|
|
||||||
>;
|
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ import { AttachmentBlockSpec } from '@blocksuite/affine-block-attachment';
|
|||||||
import { BookmarkBlockSpec } from '@blocksuite/affine-block-bookmark';
|
import { BookmarkBlockSpec } from '@blocksuite/affine-block-bookmark';
|
||||||
import { CodeBlockSpec } from '@blocksuite/affine-block-code';
|
import { CodeBlockSpec } from '@blocksuite/affine-block-code';
|
||||||
import { DataViewBlockSpec } from '@blocksuite/affine-block-data-view';
|
import { DataViewBlockSpec } from '@blocksuite/affine-block-data-view';
|
||||||
import { DatabaseBlockSpec } from '@blocksuite/affine-block-database';
|
import {
|
||||||
|
DatabaseBlockSpec,
|
||||||
|
DatabaseSelectionExtension,
|
||||||
|
} from '@blocksuite/affine-block-database';
|
||||||
import { DividerBlockSpec } from '@blocksuite/affine-block-divider';
|
import { DividerBlockSpec } from '@blocksuite/affine-block-divider';
|
||||||
import { EdgelessTextBlockSpec } from '@blocksuite/affine-block-edgeless-text';
|
import { EdgelessTextBlockSpec } from '@blocksuite/affine-block-edgeless-text';
|
||||||
import { EmbedExtensions } from '@blocksuite/affine-block-embed';
|
import { EmbedExtensions } from '@blocksuite/affine-block-embed';
|
||||||
@@ -44,7 +47,6 @@ import {
|
|||||||
SurfaceSelectionExtension,
|
SurfaceSelectionExtension,
|
||||||
TextSelectionExtension,
|
TextSelectionExtension,
|
||||||
} from '@blocksuite/block-std';
|
} from '@blocksuite/block-std';
|
||||||
import { DatabaseSelectionExtension } from '@blocksuite/data-view';
|
|
||||||
import type { ExtensionType } from '@blocksuite/store';
|
import type { ExtensionType } from '@blocksuite/store';
|
||||||
|
|
||||||
import { AdapterFactoryExtensions } from '../_common/adapters/extension.js';
|
import { AdapterFactoryExtensions } from '../_common/adapters/extension.js';
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { DatabaseSelection } from '@blocksuite/affine-block-database';
|
||||||
import { HoverController } from '@blocksuite/affine-components/hover';
|
import { HoverController } from '@blocksuite/affine-components/hover';
|
||||||
import type { RichText } from '@blocksuite/affine-components/rich-text';
|
import type { RichText } from '@blocksuite/affine-components/rich-text';
|
||||||
import { isFormatSupported } from '@blocksuite/affine-components/rich-text';
|
import { isFormatSupported } from '@blocksuite/affine-components/rich-text';
|
||||||
@@ -15,7 +16,6 @@ import {
|
|||||||
TextSelection,
|
TextSelection,
|
||||||
WidgetComponent,
|
WidgetComponent,
|
||||||
} from '@blocksuite/block-std';
|
} from '@blocksuite/block-std';
|
||||||
import { DatabaseSelection } from '@blocksuite/data-view';
|
|
||||||
import {
|
import {
|
||||||
assertExists,
|
assertExists,
|
||||||
DisposableGroup,
|
DisposableGroup,
|
||||||
|
|||||||
Reference in New Issue
Block a user