diff --git a/packages/affine/data-view/src/widget-presets/views-bar/index.ts b/packages/affine/data-view/src/widget-presets/views-bar/index.ts index f70ddd57c977..0b80af948f29 100644 --- a/packages/affine/data-view/src/widget-presets/views-bar/index.ts +++ b/packages/affine/data-view/src/widget-presets/views-bar/index.ts @@ -1,5 +1,11 @@ -import { createUniComponentFromWebComponent } from '../../core/index.js'; +import { + createUniComponentFromWebComponent, + type DataViewWidgetProps, +} from '../../core/index.js'; import { DataViewHeaderViews } from './views-view.js'; -export const widgetViewsBar = - createUniComponentFromWebComponent(DataViewHeaderViews); +export const widgetViewsBar = createUniComponentFromWebComponent< + DataViewWidgetProps & { + onChangeView?: (viewId: string) => void; + } +>(DataViewHeaderViews); diff --git a/packages/affine/data-view/src/widget-presets/views-bar/views-view.ts b/packages/affine/data-view/src/widget-presets/views-bar/views-view.ts index 681734649ce0..dbcf8a1fbb0e 100644 --- a/packages/affine/data-view/src/widget-presets/views-bar/views-view.ts +++ b/packages/affine/data-view/src/widget-presets/views-bar/views-view.ts @@ -15,6 +15,7 @@ import { PlusIcon, } from '@blocksuite/icons/lit'; import { css, html } from 'lit'; +import { property } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { WidgetBase } from '../../core/widget/widget-base.js'; @@ -275,6 +276,7 @@ export class DataViewHeaderViews extends WidgetBase { _clickView(event: MouseEvent, id: string) { if (this.viewManager.currentViewId$.value !== id) { this.viewManager.setCurrentView(id); + this.onChangeView?.(id); return; } this.openViewOption( @@ -291,6 +293,9 @@ export class DataViewHeaderViews extends WidgetBase { > `; } + + @property({ attribute: false }) + accessor onChangeView: ((id: string) => void) | undefined; } declare global { diff --git a/packages/blocks/src/database-block/database-block.ts b/packages/blocks/src/database-block/database-block.ts index 9f0b7806de80..c501a30a3da5 100644 --- a/packages/blocks/src/database-block/database-block.ts +++ b/packages/blocks/src/database-block/database-block.ts @@ -56,6 +56,7 @@ import { HostContextKey } from './context/host-context.js'; import { DatabaseBlockDataSource } from './data-source.js'; import { BlockRenderer } from './detail-panel/block-renderer.js'; import { NoteRenderer } from './detail-panel/note-renderer.js'; +import { currentViewStorage } from './utils/current-view.js'; import { getSingleDocIdFromText } from './utils/title-doc.js'; export class DatabaseBlockComponent extends CaptionedBlockComponent< @@ -230,7 +231,12 @@ export class DatabaseBlockComponent extends CaptionedBlockComponent< class="database-header-bar" >
- ${renderUniLit(widgetPresets.viewBar, props)} + ${renderUniLit(widgetPresets.viewBar, { + ...props, + onChangeView: id => { + currentViewStorage.setCurrentView(this.blockId, id); + }, + })}
${renderUniLit(this.toolsWidget, props)} @@ -330,6 +336,10 @@ export class DatabaseBlockComponent extends CaptionedBlockComponent< if (!this._dataSource) { this._dataSource = new DatabaseBlockDataSource(this.model); this._dataSource.contextSet(HostContextKey, this.host); + const id = currentViewStorage.getCurrentView(this.model.id); + if (id) { + this.dataSource.viewManager.setCurrentView(id); + } } return this._dataSource; } diff --git a/packages/blocks/src/database-block/utils/current-view.ts b/packages/blocks/src/database-block/utils/current-view.ts new file mode 100644 index 000000000000..8a1f9f5af2ff --- /dev/null +++ b/packages/blocks/src/database-block/utils/current-view.ts @@ -0,0 +1,51 @@ +import { z } from 'zod'; + +const currentViewListSchema = z.array( + z.object({ + blockId: z.string(), + viewId: z.string(), + }) +); +const maxLength = 20; +const currentViewListKey = 'blocksuite:databaseBlock:view:currentViewList'; +const createCurrentViewStorage = () => { + const getList = () => { + const string = localStorage.getItem(currentViewListKey); + if (!string) { + return; + } + try { + const result = currentViewListSchema.safeParse(JSON.parse(string)); + if (result.success) { + return result.data; + } + } catch (_) { + // do nothing + } + return; + }; + const saveList = () => { + localStorage.setItem(currentViewListKey, JSON.stringify(list)); + }; + + const list = getList() ?? []; + + return { + getCurrentView: (blockId: string) => { + return list.find(item => item.blockId === blockId)?.viewId; + }, + setCurrentView: (blockId: string, viewId: string) => { + const configIndex = list.findIndex(item => item.blockId === blockId); + if (configIndex >= 0) { + list.splice(configIndex, 1); + } + if (list.length >= maxLength) { + list.pop(); + } + list.unshift({ blockId, viewId }); + saveList(); + }, + }; +}; + +export const currentViewStorage = createCurrentViewStorage();