@formicoidea/labre-core 0.48.0 → 0.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/dist/_pkgs/affine-block-data-view/configs/slash-menu.js +3 -1
  2. package/dist/_pkgs/affine-block-data-view/view.d.ts +17 -1
  3. package/dist/_pkgs/affine-block-data-view/view.js +21 -2
  4. package/dist/_pkgs/affine-block-database/commands.d.ts +2 -2
  5. package/dist/_pkgs/affine-block-database/commands.js +3 -3
  6. package/dist/_pkgs/affine-block-database/components/values-banner.d.ts +28 -0
  7. package/dist/_pkgs/affine-block-database/components/values-banner.js +199 -0
  8. package/dist/_pkgs/affine-block-database/configs/slash-menu.d.ts +6 -1
  9. package/dist/_pkgs/affine-block-database/configs/slash-menu.js +57 -70
  10. package/dist/_pkgs/affine-block-database/data-source.d.ts +9 -5
  11. package/dist/_pkgs/affine-block-database/data-source.js +11 -7
  12. package/dist/_pkgs/affine-block-database/database-block-styles.d.ts +2 -0
  13. package/dist/_pkgs/affine-block-database/database-block-styles.js +15 -0
  14. package/dist/_pkgs/affine-block-database/database-block.d.ts +23 -0
  15. package/dist/_pkgs/affine-block-database/database-block.js +141 -19
  16. package/dist/_pkgs/affine-block-database/effects.js +2 -0
  17. package/dist/_pkgs/affine-block-database/external-data-source.d.ts +69 -2
  18. package/dist/_pkgs/affine-block-database/external-data-source.js +88 -16
  19. package/dist/_pkgs/affine-block-database/index.d.ts +2 -0
  20. package/dist/_pkgs/affine-block-database/index.js +2 -0
  21. package/dist/_pkgs/affine-block-database/linked-view.d.ts +38 -0
  22. package/dist/_pkgs/affine-block-database/linked-view.js +109 -0
  23. package/dist/_pkgs/affine-block-database/properties/index.d.ts +2 -0
  24. package/dist/_pkgs/affine-block-database/properties/index.js +2 -0
  25. package/dist/_pkgs/affine-block-database/properties/text/hosted.d.ts +15 -0
  26. package/dist/_pkgs/affine-block-database/properties/text/hosted.js +24 -0
  27. package/dist/_pkgs/affine-block-database/properties/title/hosted.d.ts +16 -0
  28. package/dist/_pkgs/affine-block-database/properties/title/hosted.js +42 -0
  29. package/dist/_pkgs/affine-block-database/service/index.d.ts +3 -0
  30. package/dist/_pkgs/affine-block-database/service/index.js +3 -0
  31. package/dist/_pkgs/affine-block-database/service/new-row-menu.d.ts +49 -0
  32. package/dist/_pkgs/affine-block-database/service/new-row-menu.js +21 -0
  33. package/dist/_pkgs/affine-block-database/service/open-row.d.ts +77 -0
  34. package/dist/_pkgs/affine-block-database/service/open-row.js +62 -0
  35. package/dist/_pkgs/affine-block-database/service/properties-panel.d.ts +23 -0
  36. package/dist/_pkgs/affine-block-database/service/properties-panel.js +33 -0
  37. package/dist/_pkgs/affine-block-database/translations.d.ts +10 -0
  38. package/dist/_pkgs/affine-block-database/translations.js +35 -0
  39. package/dist/_pkgs/affine-block-database/view-creation.d.ts +10 -0
  40. package/dist/_pkgs/affine-block-database/view-creation.js +14 -0
  41. package/dist/_pkgs/affine-block-database/view.d.ts +31 -1
  42. package/dist/_pkgs/affine-block-database/view.js +44 -5
  43. package/dist/_pkgs/affine-block-database/views/index.d.ts +30 -3
  44. package/dist/_pkgs/affine-block-database/views/index.js +44 -3
  45. package/dist/_pkgs/affine-components/date-picker/date-picker.d.ts +20 -0
  46. package/dist/_pkgs/affine-components/date-picker/date-picker.js +60 -26
  47. package/dist/_pkgs/affine-components/date-picker/style.js +1 -0
  48. package/dist/_pkgs/affine-components/translations.d.ts +4 -0
  49. package/dist/_pkgs/affine-components/translations.js +26 -0
  50. package/dist/_pkgs/affine-fragment-doc-title/doc-title.d.ts +18 -0
  51. package/dist/_pkgs/affine-fragment-doc-title/doc-title.js +41 -2
  52. package/dist/_pkgs/affine-fragment-doc-title/title-band/band-cell.d.ts +8 -0
  53. package/dist/_pkgs/affine-fragment-doc-title/title-band/band-cell.js +12 -0
  54. package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.d.ts +5 -0
  55. package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.js +44 -4
  56. package/dist/_pkgs/affine-model/blocks/database/types.d.ts +16 -0
  57. package/dist/_pkgs/affine-model/blocks/database/types.js +5 -1
  58. package/dist/_pkgs/affine-shared/services/data-source-picker-service.d.ts +139 -0
  59. package/dist/_pkgs/affine-shared/services/data-source-picker-service.js +22 -0
  60. package/dist/_pkgs/affine-shared/services/index.d.ts +1 -0
  61. package/dist/_pkgs/affine-shared/services/index.js +1 -0
  62. package/dist/_pkgs/affine-shared/services/telemetry-service/database.d.ts +59 -0
  63. package/dist/_pkgs/affine-shared/services/title-band-service.d.ts +24 -0
  64. package/dist/_pkgs/data-view/core/component/cell-status/cell-status-css.d.ts +2 -0
  65. package/dist/_pkgs/data-view/core/component/cell-status/cell-status-css.js +16 -0
  66. package/dist/_pkgs/data-view/core/component/cell-status/cell-status.d.ts +10 -0
  67. package/dist/_pkgs/data-view/core/component/cell-status/cell-status.js +23 -0
  68. package/dist/_pkgs/data-view/core/component/index.d.ts +1 -0
  69. package/dist/_pkgs/data-view/core/component/index.js +1 -0
  70. package/dist/_pkgs/data-view/core/component/overflow/fit.d.ts +26 -0
  71. package/dist/_pkgs/data-view/core/component/overflow/fit.js +48 -0
  72. package/dist/_pkgs/data-view/core/component/overflow/overflow.d.ts +26 -3
  73. package/dist/_pkgs/data-view/core/component/overflow/overflow.js +84 -31
  74. package/dist/_pkgs/data-view/core/component/tags/colors.d.ts +7 -0
  75. package/dist/_pkgs/data-view/core/component/tags/colors.js +22 -10
  76. package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.d.ts +18 -0
  77. package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.js +63 -21
  78. package/dist/_pkgs/data-view/core/data-source/base.d.ts +5 -1
  79. package/dist/_pkgs/data-view/core/data-source/base.js +7 -1
  80. package/dist/_pkgs/data-view/core/data-source/hydration.d.ts +44 -0
  81. package/dist/_pkgs/data-view/core/data-source/hydration.js +31 -0
  82. package/dist/_pkgs/data-view/core/data-source/index.d.ts +1 -0
  83. package/dist/_pkgs/data-view/core/data-source/index.js +1 -0
  84. package/dist/_pkgs/data-view/core/data-view.d.ts +22 -2
  85. package/dist/_pkgs/data-view/core/data-view.js +14 -0
  86. package/dist/_pkgs/data-view/core/effect.js +2 -0
  87. package/dist/_pkgs/data-view/core/group-by/collapsed-state.d.ts +3 -0
  88. package/dist/_pkgs/data-view/core/group-by/collapsed-state.js +59 -0
  89. package/dist/_pkgs/data-view/core/group-by/group-properties.d.ts +21 -0
  90. package/dist/_pkgs/data-view/core/group-by/group-properties.js +38 -0
  91. package/dist/_pkgs/data-view/core/group-by/group-title.js +4 -0
  92. package/dist/_pkgs/data-view/core/group-by/group-visibility.d.ts +40 -0
  93. package/dist/_pkgs/data-view/core/group-by/group-visibility.js +291 -0
  94. package/dist/_pkgs/data-view/core/group-by/setting.d.ts +11 -3
  95. package/dist/_pkgs/data-view/core/group-by/setting.js +81 -8
  96. package/dist/_pkgs/data-view/core/group-by/trait.d.ts +22 -0
  97. package/dist/_pkgs/data-view/core/group-by/trait.js +62 -1
  98. package/dist/_pkgs/data-view/core/index.d.ts +3 -0
  99. package/dist/_pkgs/data-view/core/index.js +3 -0
  100. package/dist/_pkgs/data-view/core/property/base-cell.d.ts +15 -1
  101. package/dist/_pkgs/data-view/core/property/base-cell.js +28 -3
  102. package/dist/_pkgs/data-view/core/property/standalone-cell.d.ts +15 -1
  103. package/dist/_pkgs/data-view/core/property/standalone-cell.js +19 -1
  104. package/dist/_pkgs/data-view/core/telemetry.d.ts +16 -0
  105. package/dist/_pkgs/data-view/core/telemetry.js +22 -0
  106. package/dist/_pkgs/data-view/core/utils/new-tab-click.d.ts +2 -0
  107. package/dist/_pkgs/data-view/core/utils/new-tab-click.js +4 -0
  108. package/dist/_pkgs/data-view/core/utils/wording.d.ts +11 -0
  109. package/dist/_pkgs/data-view/core/utils/wording.js +9 -0
  110. package/dist/_pkgs/data-view/core/view/data-view.d.ts +7 -0
  111. package/dist/_pkgs/data-view/core/view/default-name.d.ts +10 -0
  112. package/dist/_pkgs/data-view/core/view/default-name.js +14 -0
  113. package/dist/_pkgs/data-view/core/view/index.d.ts +2 -0
  114. package/dist/_pkgs/data-view/core/view/index.js +2 -0
  115. package/dist/_pkgs/data-view/core/view/open-in.d.ts +27 -0
  116. package/dist/_pkgs/data-view/core/view/open-in.js +39 -0
  117. package/dist/_pkgs/data-view/core/view-manager/cell.d.ts +5 -0
  118. package/dist/_pkgs/data-view/core/view-manager/cell.js +11 -0
  119. package/dist/_pkgs/data-view/core/view-manager/index.d.ts +3 -0
  120. package/dist/_pkgs/data-view/core/view-manager/index.js +3 -0
  121. package/dist/_pkgs/data-view/core/view-manager/new-row-menu-opener.d.ts +18 -0
  122. package/dist/_pkgs/data-view/core/view-manager/new-row-menu-opener.js +2 -0
  123. package/dist/_pkgs/data-view/core/view-manager/properties-panel-opener.d.ts +8 -0
  124. package/dist/_pkgs/data-view/core/view-manager/properties-panel-opener.js +9 -0
  125. package/dist/_pkgs/data-view/core/view-manager/property.d.ts +8 -0
  126. package/dist/_pkgs/data-view/core/view-manager/single-view.d.ts +28 -1
  127. package/dist/_pkgs/data-view/core/view-manager/single-view.js +45 -1
  128. package/dist/_pkgs/data-view/core/view-manager/view-creation.d.ts +49 -0
  129. package/dist/_pkgs/data-view/core/view-manager/view-creation.js +40 -0
  130. package/dist/_pkgs/data-view/core/view-manager/view-manager.d.ts +6 -2
  131. package/dist/_pkgs/data-view/core/view-manager/view-manager.js +2 -2
  132. package/dist/_pkgs/data-view/property-presets/date/cell-renderer.d.ts +2 -0
  133. package/dist/_pkgs/data-view/property-presets/date/cell-renderer.js +11 -2
  134. package/dist/_pkgs/data-view/property-presets/multi-select/cell-renderer.js +2 -0
  135. package/dist/_pkgs/data-view/property-presets/select/cell-renderer.js +2 -0
  136. package/dist/_pkgs/data-view/translations.d.ts +55 -0
  137. package/dist/_pkgs/data-view/translations.js +181 -0
  138. package/dist/_pkgs/data-view/view-presets/calendar/define.js +3 -1
  139. package/dist/_pkgs/data-view/view-presets/convert.js +2 -0
  140. package/dist/_pkgs/data-view/view-presets/effect.js +4 -0
  141. package/dist/_pkgs/data-view/view-presets/flat/flat-converts.d.ts +2 -0
  142. package/dist/_pkgs/data-view/view-presets/flat/flat-converts.js +35 -0
  143. package/dist/_pkgs/data-view/view-presets/flat/flat-view-manager.d.ts +79 -0
  144. package/dist/_pkgs/data-view/view-presets/flat/flat-view-manager.js +194 -0
  145. package/dist/_pkgs/data-view/view-presets/flat/flat-view-ui.d.ts +56 -0
  146. package/dist/_pkgs/data-view/view-presets/flat/flat-view-ui.js +266 -0
  147. package/dist/_pkgs/data-view/view-presets/gallery/define.d.ts +14 -0
  148. package/dist/_pkgs/data-view/view-presets/gallery/define.js +15 -0
  149. package/dist/_pkgs/data-view/view-presets/gallery/effect.d.ts +1 -0
  150. package/dist/_pkgs/data-view/view-presets/gallery/effect.js +4 -0
  151. package/dist/_pkgs/data-view/view-presets/gallery/gallery-view.d.ts +27 -0
  152. package/dist/_pkgs/data-view/view-presets/gallery/gallery-view.js +179 -0
  153. package/dist/_pkgs/data-view/view-presets/gallery/index.d.ts +2 -0
  154. package/dist/_pkgs/data-view/view-presets/gallery/index.js +2 -0
  155. package/dist/_pkgs/data-view/view-presets/gallery/renderer.d.ts +1 -0
  156. package/dist/_pkgs/data-view/view-presets/gallery/renderer.js +11 -0
  157. package/dist/_pkgs/data-view/view-presets/index.d.ts +5 -0
  158. package/dist/_pkgs/data-view/view-presets/index.js +7 -0
  159. package/dist/_pkgs/data-view/view-presets/kanban/define.js +3 -1
  160. package/dist/_pkgs/data-view/view-presets/kanban/kanban-view-manager.js +5 -53
  161. package/dist/_pkgs/data-view/view-presets/kanban/mobile/card.js +8 -1
  162. package/dist/_pkgs/data-view/view-presets/kanban/mobile/cell.js +6 -1
  163. package/dist/_pkgs/data-view/view-presets/kanban/mobile/group.d.ts +4 -2
  164. package/dist/_pkgs/data-view/view-presets/kanban/mobile/group.js +52 -6
  165. package/dist/_pkgs/data-view/view-presets/kanban/mobile/kanban-view-ui-logic.js +5 -1
  166. package/dist/_pkgs/data-view/view-presets/kanban/pc/card.js +2 -0
  167. package/dist/_pkgs/data-view/view-presets/kanban/pc/cell.js +4 -0
  168. package/dist/_pkgs/data-view/view-presets/kanban/pc/group.d.ts +4 -2
  169. package/dist/_pkgs/data-view/view-presets/kanban/pc/group.js +51 -6
  170. package/dist/_pkgs/data-view/view-presets/kanban/pc/kanban-view-ui-logic.js +5 -1
  171. package/dist/_pkgs/data-view/view-presets/list/define.d.ts +14 -0
  172. package/dist/_pkgs/data-view/view-presets/list/define.js +15 -0
  173. package/dist/_pkgs/data-view/view-presets/list/effect.d.ts +1 -0
  174. package/dist/_pkgs/data-view/view-presets/list/effect.js +4 -0
  175. package/dist/_pkgs/data-view/view-presets/list/index.d.ts +2 -0
  176. package/dist/_pkgs/data-view/view-presets/list/index.js +2 -0
  177. package/dist/_pkgs/data-view/view-presets/list/list-view.d.ts +24 -0
  178. package/dist/_pkgs/data-view/view-presets/list/list-view.js +194 -0
  179. package/dist/_pkgs/data-view/view-presets/list/renderer.d.ts +1 -0
  180. package/dist/_pkgs/data-view/view-presets/list/renderer.js +11 -0
  181. package/dist/_pkgs/data-view/view-presets/table/collapsed-state.d.ts +3 -14
  182. package/dist/_pkgs/data-view/view-presets/table/collapsed-state.js +6 -30
  183. package/dist/_pkgs/data-view/view-presets/table/consts.d.ts +2 -0
  184. package/dist/_pkgs/data-view/view-presets/table/consts.js +2 -0
  185. package/dist/_pkgs/data-view/view-presets/table/define.js +3 -1
  186. package/dist/_pkgs/data-view/view-presets/table/mobile/cell.js +4 -1
  187. package/dist/_pkgs/data-view/view-presets/table/mobile/column-header.js +2 -2
  188. package/dist/_pkgs/data-view/view-presets/table/mobile/group.d.ts +3 -1
  189. package/dist/_pkgs/data-view/view-presets/table/mobile/group.js +20 -5
  190. package/dist/_pkgs/data-view/view-presets/table/mobile/row.js +10 -2
  191. package/dist/_pkgs/data-view/view-presets/table/mobile/table-view-ui-logic.js +4 -1
  192. package/dist/_pkgs/data-view/view-presets/table/pc/cell.js +4 -1
  193. package/dist/_pkgs/data-view/view-presets/table/pc/controller/hotkeys.js +1 -1
  194. package/dist/_pkgs/data-view/view-presets/table/pc/group.d.ts +3 -1
  195. package/dist/_pkgs/data-view/view-presets/table/pc/group.js +20 -5
  196. package/dist/_pkgs/data-view/view-presets/table/pc/menu.d.ts +1 -1
  197. package/dist/_pkgs/data-view/view-presets/table/pc/menu.js +2 -1
  198. package/dist/_pkgs/data-view/view-presets/table/pc/row/row.js +3 -2
  199. package/dist/_pkgs/data-view/view-presets/table/pc/table-view-ui-logic.js +4 -1
  200. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/controller/hotkeys.js +1 -1
  201. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/bottom/stats/column-stats-column.js +5 -1
  202. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/top/group-title.js +22 -19
  203. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/row/cell.js +4 -1
  204. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/table-view-ui-logic.js +7 -2
  205. package/dist/_pkgs/data-view/view-presets/table/stats/column-stats-column.js +5 -1
  206. package/dist/_pkgs/data-view/view-presets/table/table-view-manager.js +5 -53
  207. package/dist/_pkgs/data-view/widget-presets/tools/presets/table-add-row/add-row.d.ts +1 -0
  208. package/dist/_pkgs/data-view/widget-presets/tools/presets/table-add-row/add-row.js +60 -2
  209. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-options.d.ts +18 -1
  210. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-options.js +121 -124
  211. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-settings.d.ts +43 -0
  212. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-settings.js +187 -0
  213. package/dist/_pkgs/data-view/widget-presets/views-bar/views-view.d.ts +36 -3
  214. package/dist/_pkgs/data-view/widget-presets/views-bar/views-view.js +187 -59
  215. package/dist/extensions/view.d.ts +2 -2
  216. package/dist/extensions/view.js +10 -3
  217. package/dist/flags.d.ts +8 -4
  218. package/dist/flags.js +8 -4
  219. package/dist/frameworks.d.ts +27 -0
  220. package/dist/frameworks.js +28 -0
  221. package/dist/translations.js +13 -1
  222. package/package.json +5 -1
@@ -9,14 +9,29 @@ export declare class DatabaseBlockComponent extends CaptionedBlockComponent<Data
9
9
  private _dataSource?;
10
10
  private _dataViewRootLogic?;
11
11
  private _sourceVersion;
12
+ /**
13
+ * Every database event leaves here, with the block's id and nothing about
14
+ * its rows (telemetry README, "Databases"): the root's `eventTrace`, and
15
+ * the source's `DataViewEventTraceKey` for code that holds only a view.
16
+ */
17
+ private readonly traceDatabaseEvent;
12
18
  private _buildDataSource;
13
19
  get dataSource(): DataSourceBase;
14
20
  private rebuildDataSource;
21
+ /**
22
+ * A row that is a document opens where the host says, in the view's
23
+ * `openIn` mode (ADR 0035 §9a, B9); without an opener, or for a row that is
24
+ * a block, the caller keeps the peek view and the side detail of 0.48.
25
+ * Every row open passes here once, so `DatabaseRowOpened` leaves from here
26
+ * (B17), whichever path then opens the row.
27
+ */
28
+ private openRowThroughHost;
15
29
  private readonly renderTitle;
16
30
  createTemplate: (data: {
17
31
  view: SingleView;
18
32
  rowId: string;
19
33
  }, openDoc: (docId: string) => void) => import("lit-html").TemplateResult;
34
+ private renderViewBar;
20
35
  headerWidget: DataViewWidget;
21
36
  indicator: DropIndicator;
22
37
  onDrag: (evt: MouseEvent, id: string) => (() => void);
@@ -27,10 +42,18 @@ export declare class DatabaseBlockComponent extends CaptionedBlockComponent<Data
27
42
  get optionsConfig(): DatabaseViewExtensionOptions;
28
43
  get isCommentHighlighted(): boolean;
29
44
  get topContenteditableElement(): BlockComponent<import("../store/index.js").BlockModel<object>, import("../std/index.js").BlockService, string> | null;
45
+ private readonly renderSourceMissing;
30
46
  private renderDatabaseOps;
31
47
  connectedCallback(): void;
32
48
  disconnectedCallback(): void;
33
49
  listenFullWidthChange(): void;
50
+ /**
51
+ * Puts the caret on the current view's first cell, where the view has one
52
+ * (table, kanban; the other presets ignore it): what the page title's
53
+ * Enter and ArrowDown reach when this block is the page's body
54
+ * (`<doc-title .bodyBlockId>`, a database's full page, ADR 0035 B13).
55
+ */
56
+ focusFirstCell(): void;
34
57
  private get dataViewRootLogic();
35
58
  private _buildDataViewRootLogic;
36
59
  renderBlock(): import("lit-html").TemplateResult<1>;
@@ -4,9 +4,9 @@ import { DropIndicator } from '../affine-components/drop-indicator/index.js';
4
4
  import { PeekViewProvider } from '../affine-components/peek/index.js';
5
5
  import { toast } from '../affine-components/toast/index.js';
6
6
  import { EDGELESS_TOP_CONTENTEDITABLE_SELECTOR } from '../affine-shared/consts/index.js';
7
- import { BlockCommentManager, CommentProviderIdentifier, DocModeProvider, NotificationProvider, TelemetryProvider, TOAST_COPIED_TO_CLIPBOARD, translateKey, } from '../affine-shared/services/index.js';
7
+ import { BlockCommentManager, CommentProviderIdentifier, DocModeProvider, NotificationProvider, PropertiesPanelProvider, TelemetryProvider, TOAST_COPIED_TO_CLIPBOARD, translateKey, } from '../affine-shared/services/index.js';
8
8
  import { getDropResult } from '../affine-widget-drag-handle/index.js';
9
- import { createRecordDetail, createUniComponentFromWebComponent, DataViewRootUILogic, defineUniComponent, ExternalGroupByConfigProvider, renderUniLit, uniMap, } from '../data-view/index.js';
9
+ import { createRecordDetail, createUniComponentFromWebComponent, DataViewRootUILogic, DataViewEventTraceKey, defineUniComponent, ExternalGroupByConfigProvider, NewRowMenuOpenerKey, PropertiesPanelOpenerKey, renderUniLit, traceViewEvent, uniMap, ViewCreationOffKey, } from '../data-view/index.js';
10
10
  import { CalendarExternalSourceProvider } from '../data-view/view-presets/index.js';
11
11
  import { widgetPresets } from '../data-view/widget-presets/index.js';
12
12
  import { Rect } from '../global/gfx/index.js';
@@ -22,13 +22,16 @@ import { popSideDetail } from './components/layout.js';
22
22
  import { DatabaseConfigExtension } from './config.js';
23
23
  import { EditorHostKey } from './context/host-context.js';
24
24
  import { DatabaseBlockDataSource } from './data-source.js';
25
- import { databaseBlockStyles, databaseContentStyles, databaseHeaderBarStyles, databaseHeaderContainerStyles, databaseOpsStyles, databaseTitleRowStyles, databaseTitleStyles, databaseToolbarRowStyles, databaseViewBarContainerStyles, } from './database-block-styles.js';
25
+ import { HostedDataSourceBase } from './external-data-source.js';
26
+ import { databaseBlockStyles, databaseContentStyles, databaseHeaderBarStyles, databaseHeaderContainerStyles, databaseOpsStyles, databaseSourceMissingHintStyles, databaseSourceMissingStyles, databaseTitleRowStyles, databaseTitleStyles, databaseToolbarRowStyles, databaseViewBarContainerStyles, } from './database-block-styles.js';
26
27
  import { BlockRenderer } from './detail-panel/block-renderer.js';
27
28
  import { NoteRenderer } from './detail-panel/note-renderer.js';
28
29
  import { DatabaseSelection } from './selection.js';
29
- import { DatabaseDataSourceProvider } from './service/index.js';
30
+ import { databaseOpenRowRequest, DatabaseDataSourceProvider, DatabaseNewRowMenuProvider, DatabaseOpenRowProvider, openDatabasePropertiesPanel, rowOpenedParams, } from './service/index.js';
31
+ import { DATABASE_NEW_RECORD_MORE, DATABASE_SOURCE_MISSING, DATABASE_SOURCE_MISSING_HINT, } from './translations.js';
30
32
  import { currentViewStorage } from './utils/current-view.js';
31
33
  import { getSingleDocIdFromText } from './utils/title-doc.js';
34
+ import { DatabaseViewCreationIdentifier } from './view-creation.js';
32
35
  export class DatabaseBlockComponent extends CaptionedBlockComponent {
33
36
  constructor() {
34
37
  super(...arguments);
@@ -94,6 +97,18 @@ export class DatabaseBlockComponent extends CaptionedBlockComponent {
94
97
  // forcing Lit to tear the old one down (disposing its listeners) and mount a
95
98
  // fresh one bound to the new source.
96
99
  this._sourceVersion = 0;
100
+ /**
101
+ * Every database event leaves here, with the block's id and nothing about
102
+ * its rows (telemetry README, "Databases"): the root's `eventTrace`, and
103
+ * the source's `DataViewEventTraceKey` for code that holds only a view.
104
+ */
105
+ this.traceDatabaseEvent = (key, params) => {
106
+ const telemetryService = this.std.getOptional(TelemetryProvider);
107
+ telemetryService?.track(key, {
108
+ ...params,
109
+ blockId: this.blockId,
110
+ });
111
+ };
97
112
  this.renderTitle = (dataViewLogic) => {
98
113
  return html ` <affine-database-title
99
114
  class="${databaseTitleStyles}"
@@ -125,17 +140,15 @@ export class DatabaseBlockComponent extends CaptionedBlockComponent {
125
140
  ${this.renderTitle(props.dataViewLogic)} ${this.renderDatabaseOps()}
126
141
  </div>
127
142
  <div class="${databaseToolbarRowStyles} ${databaseHeaderBarStyles}">
128
- <div class="${databaseViewBarContainerStyles}">
129
- ${renderUniLit(widgetPresets.viewBar, {
130
- ...props,
131
- onChangeView: id => {
132
- currentViewStorage.setCurrentView(this.blockId, id);
133
- },
134
- })}
135
- </div>
143
+ ${this.renderViewBar(props)}
136
144
  ${renderUniLit(this.toolsWidget, props)}
137
145
  </div>
138
146
  ${renderUniLit(widgetPresets.quickSettingBar, props)}
147
+ <affine-database-values-banner
148
+ .dataSource="${this.dataSource}"
149
+ .std="${this.std}"
150
+ .trace="${this.traceDatabaseEvent}"
151
+ ></affine-database-values-banner>
139
152
  </div>
140
153
  `;
141
154
  });
@@ -201,6 +214,20 @@ export class DatabaseBlockComponent extends CaptionedBlockComponent {
201
214
  widgetPresets.tools.viewOptions,
202
215
  widgetPresets.tools.tableAddRow,
203
216
  ],
217
+ gallery: [
218
+ widgetPresets.tools.filter,
219
+ widgetPresets.tools.sort,
220
+ widgetPresets.tools.search,
221
+ widgetPresets.tools.viewOptions,
222
+ widgetPresets.tools.tableAddRow,
223
+ ],
224
+ list: [
225
+ widgetPresets.tools.filter,
226
+ widgetPresets.tools.sort,
227
+ widgetPresets.tools.search,
228
+ widgetPresets.tools.viewOptions,
229
+ widgetPresets.tools.tableAddRow,
230
+ ],
204
231
  });
205
232
  this.viewSelection$ = computed(() => {
206
233
  const databaseSelection = this.selection.value.find((selection) => {
@@ -212,11 +239,63 @@ export class DatabaseBlockComponent extends CaptionedBlockComponent {
212
239
  return databaseSelection?.viewSelection;
213
240
  });
214
241
  this.virtualPadding$ = signal(0);
242
+ // ADR 0035 §7: a view whose source the host cannot resolve keeps the title
243
+ // and the view bar, so another view can be picked, and draws this instead of
244
+ // its tools and body: nothing to filter, add or edit, and nothing rewritten.
245
+ this.renderSourceMissing = (dataViewLogic) => {
246
+ const dataSource = this.dataSource;
247
+ if (!(dataSource instanceof HostedDataSourceBase))
248
+ return undefined;
249
+ if (!dataSource.sourceMissing$.value)
250
+ return undefined;
251
+ return html `<div class="${databaseHeaderContainerStyles}">
252
+ <div class="${databaseTitleRowStyles}">
253
+ ${this.renderTitle(dataViewLogic)}
254
+ </div>
255
+ <div class="${databaseToolbarRowStyles} ${databaseHeaderBarStyles}">
256
+ ${this.renderViewBar({ dataViewLogic })}
257
+ </div>
258
+ </div>
259
+ <div
260
+ class="${databaseSourceMissingStyles}"
261
+ data-testid="database-source-missing"
262
+ role="status"
263
+ >
264
+ <div>${translateKey(this.std, ...DATABASE_SOURCE_MISSING)}</div>
265
+ <div class="${databaseSourceMissingHintStyles}">
266
+ ${translateKey(this.std, ...DATABASE_SOURCE_MISSING_HINT)}
267
+ </div>
268
+ </div>`;
269
+ };
215
270
  this.#useZeroWidth_accessor_storage = true;
216
271
  }
217
272
  _buildDataSource() {
218
273
  const initFn = (dataSource) => {
219
274
  dataSource.serviceSet(EditorHostKey, this.host);
275
+ dataSource.serviceSet(DataViewEventTraceKey, this.traceDatabaseEvent);
276
+ // With a host properties panel, the view options' "Properties" opens
277
+ // it (ADR 0035 §9b); without, the data-view's popover stays.
278
+ if (this.std.getOptional(PropertiesPanelProvider)) {
279
+ dataSource.serviceSet(PropertiesPanelOpenerKey, viewId => {
280
+ openDatabasePropertiesPanel(this.std, this.model, viewId);
281
+ });
282
+ }
283
+ // With a host menu beside "New" (its templates), the header draws a
284
+ // chevron that opens it; the main part still adds a row (`rowAdd`).
285
+ const newRowMenu = this.std.getOptional(DatabaseNewRowMenuProvider);
286
+ if (newRowMenu) {
287
+ dataSource.serviceSet(NewRowMenuOpenerKey, {
288
+ label: () => translateKey(this.std, ...DATABASE_NEW_RECORD_MORE),
289
+ canOpen: viewId => newRowMenu.canOpen?.({ blockId: this.model.id, viewId }) ?? true,
290
+ open: (anchor, viewId) => {
291
+ newRowMenu.open({ anchor, blockId: this.model.id, viewId });
292
+ },
293
+ });
294
+ }
295
+ // `{ database: false }` takes view creation away, never the views.
296
+ if (!this.std.getOptional(DatabaseViewCreationIdentifier)) {
297
+ dataSource.serviceSet(ViewCreationOffKey, true);
298
+ }
220
299
  this.std.provider
221
300
  .getAll(ExternalGroupByConfigProvider)
222
301
  .forEach(config => {
@@ -251,6 +330,43 @@ export class DatabaseBlockComponent extends CaptionedBlockComponent {
251
330
  this._sourceVersion++;
252
331
  this.requestUpdate();
253
332
  }
333
+ /**
334
+ * A row that is a document opens where the host says, in the view's
335
+ * `openIn` mode (ADR 0035 §9a, B9); without an opener, or for a row that is
336
+ * a block, the caller keeps the peek view and the side detail of 0.48.
337
+ * Every row open passes here once, so `DatabaseRowOpened` leaves from here
338
+ * (B17), whichever path then opens the row.
339
+ */
340
+ openRowThroughHost(data) {
341
+ const opener = this.std.getOptional(DatabaseOpenRowProvider);
342
+ const source = this.dataSource;
343
+ const viewData = source.viewDataGet(data.view.id);
344
+ const rowsAreDocuments = source instanceof HostedDataSourceBase && source.rowsAreDocuments;
345
+ const request = databaseOpenRowRequest({
346
+ hasOpener: !!opener,
347
+ rowsAreDocuments,
348
+ rowId: data.rowId,
349
+ viewId: data.view.id,
350
+ blockId: this.blockId,
351
+ openIn: viewData?.openIn,
352
+ newTab: data.newTab,
353
+ });
354
+ traceViewEvent(data.view, 'DatabaseRowOpened', rowOpenedParams(request, rowsAreDocuments, data.newTab));
355
+ if (!opener || !request)
356
+ return false;
357
+ opener.open(request);
358
+ return true;
359
+ }
360
+ renderViewBar(props) {
361
+ return html `<div class="${databaseViewBarContainerStyles}">
362
+ ${renderUniLit(widgetPresets.viewBar, {
363
+ ...props,
364
+ onChangeView: id => {
365
+ currentViewStorage.setCurrentView(this.blockId, id);
366
+ },
367
+ })}
368
+ </div>`;
369
+ }
254
370
  get optionsConfig() {
255
371
  return {
256
372
  configure: (_model, options) => options,
@@ -310,6 +426,15 @@ export class DatabaseBlockComponent extends CaptionedBlockComponent {
310
426
  this.virtualPadding$.value = Math.max(0, padding - 72);
311
427
  }));
312
428
  }
429
+ /**
430
+ * Puts the caret on the current view's first cell, where the view has one
431
+ * (table, kanban; the other presets ignore it): what the page title's
432
+ * Enter and ArrowDown reach when this block is the page's body
433
+ * (`<doc-title .bodyBlockId>`, a database's full page, ADR 0035 B13).
434
+ */
435
+ focusFirstCell() {
436
+ this._dataViewRootLogic?.focusFirstCell();
437
+ }
313
438
  get dataViewRootLogic() {
314
439
  if (!this._dataViewRootLogic) {
315
440
  this._dataViewRootLogic = this._buildDataViewRootLogic();
@@ -337,6 +462,7 @@ export class DatabaseBlockComponent extends CaptionedBlockComponent {
337
462
  setSelection: this.setSelection,
338
463
  dataSource: this.dataSource,
339
464
  headerWidget: this.headerWidget,
465
+ viewPlaceholder: this.renderSourceMissing,
340
466
  onDrag: this.onDrag,
341
467
  clipboard: this.std.clipboard,
342
468
  dnd: this.std.dnd,
@@ -351,15 +477,11 @@ export class DatabaseBlockComponent extends CaptionedBlockComponent {
351
477
  }
352
478
  },
353
479
  },
354
- eventTrace: (key, params) => {
355
- const telemetryService = this.std.getOptional(TelemetryProvider);
356
- telemetryService?.track(key, {
357
- ...params,
358
- blockId: this.blockId,
359
- });
360
- },
480
+ eventTrace: this.traceDatabaseEvent,
361
481
  detailPanelConfig: {
362
482
  openDetailPanel: (target, data) => {
483
+ if (this.openRowThroughHost(data))
484
+ return Promise.resolve();
363
485
  const peekViewService = this.std.getOptional(PeekViewProvider);
364
486
  if (peekViewService) {
365
487
  const openDoc = (docId) => {
@@ -1,5 +1,6 @@
1
1
  import { CenterPeek } from './components/layout.js';
2
2
  import { DatabaseTitle } from './components/title/index.js';
3
+ import { DatabaseValuesBanner } from './components/values-banner.js';
3
4
  import { DatabaseBlockComponent } from './database-block.js';
4
5
  import { DatabaseDndPreviewBlockComponent } from './database-dnd-preview-block.js';
5
6
  import { BlockRenderer } from './detail-panel/block-renderer.js';
@@ -11,6 +12,7 @@ import { IconCell } from './properties/title/icon.js';
11
12
  import { HeaderAreaTextCell } from './properties/title/text.js';
12
13
  export function effects() {
13
14
  customElements.define('affine-database-title', DatabaseTitle);
15
+ customElements.define('affine-database-values-banner', DatabaseValuesBanner);
14
16
  customElements.define('data-view-header-area-icon', IconCell);
15
17
  customElements.define('affine-database-link-cell', LinkCell);
16
18
  customElements.define('data-view-header-area-text', HeaderAreaTextCell);
@@ -3,6 +3,22 @@ import type { InsertToPosition } from '../affine-shared/utils/index.js';
3
3
  import { type DatabaseFlags, DataSourceBase, type DataViewDataType, type PropertyMetaConfig, type TypeInstance, type ViewManager, type ViewMeta } from '../data-view/index.js';
4
4
  import { DisposableGroup } from '../global/disposable/index.js';
5
5
  import { type ReadonlySignal } from '@preact/signals-core';
6
+ /**
7
+ * One source of a hosted database, as `resolveSource` answers it (ADR 0035
8
+ * §7, issue B1): the `affine:database` block that owns its schema
9
+ * (`props.columns`) and its ordered row ids. Where the host keeps its sources
10
+ * is the host's format; the library never reads it.
11
+ */
12
+ export interface HostedSource {
13
+ schema: DatabaseBlockModel;
14
+ rows: ReadonlySignal<string[]>;
15
+ }
16
+ /**
17
+ * `sourceId` is the current view's stored `sourceId` (ADR 0035 §8), absent
18
+ * for every view stored before 0.49. `null`: no such source, and the view
19
+ * draws "Source not found" instead of its body (never an error).
20
+ */
21
+ export type ResolveHostedSource = (sourceId: string | undefined) => HostedSource | null;
6
22
  /**
7
23
  * Intermediate base for `affine:database` data sources whose **view config**
8
24
  * keeps living in the block model blob (`model.props.views`) while the **data
@@ -23,13 +39,58 @@ import { type ReadonlySignal } from '@preact/signals-core';
23
39
  * computeds re-run. Defining `rows$`/`properties$` here (not as instance fields
24
40
  * reassigned in a subclass constructor) also avoids the "reassign after super"
25
41
  * dance.
42
+ *
43
+ * Sources (ADR 0035 §7, B1): the views live in `hostModel.props.views`; each
44
+ * view reads the source its `sourceId` names, through `resolveSource`. The
45
+ * data layer answers for the CURRENT view's source ({@link source$},
46
+ * {@link schema$}, {@link rows$}): one view is drawn at a time, and property
47
+ * ids never collide across sources (host-generated uuids). Without
48
+ * `resolveSource` the block has one implicit source, itself, whatever a view
49
+ * says: the 0.48 behaviour, which `ExternalDataSourceBase(model)` keeps.
50
+ *
51
+ * Rows that are documents (B15): a source whose rows are documents says so
52
+ * with {@link rowsAreDocuments}, answers each title from its own store with
53
+ * {@link titleOf}, and returns `hostedTitleColumnConfig` from
54
+ * `propertyMetaGet('title')`, so a title is a plain string and no row's
55
+ * document is loaded to draw it.
26
56
  */
27
- export declare abstract class ExternalDataSourceBase extends DataSourceBase {
57
+ export declare abstract class HostedDataSourceBase extends DataSourceBase {
58
+ /** The block that hosts the views (and, without `resolveSource`, the data). */
28
59
  protected readonly _model: DatabaseBlockModel;
60
+ private readonly _resolveSource;
29
61
  /** Bumped by {@link invalidate} to re-run the data-layer computeds. */
30
62
  protected readonly revision: import("@preact/signals-core").Signal<number>;
31
63
  protected readonly disposables: DisposableGroup;
32
- constructor(model: DatabaseBlockModel);
64
+ constructor(hostModel: DatabaseBlockModel, resolveSource?: ResolveHostedSource);
65
+ get hostModel(): DatabaseBlockModel;
66
+ /** The current view's stored `sourceId`; `undefined` reads the implicit source. */
67
+ readonly currentSourceId$: ReadonlySignal<string | undefined>;
68
+ private readonly _implicitRows$;
69
+ /**
70
+ * Whether views name the source they read: a `resolveSource` was given.
71
+ * Without it there is one implicit source, the block, whatever `sourceId`
72
+ * a view stores, so chrome that lists sources has nothing to list.
73
+ */
74
+ get resolvesSources(): boolean;
75
+ /**
76
+ * Any source, by the `sourceId` a view would store, resolved the way the
77
+ * current view's is ({@link source$}); `null` when there is no such source.
78
+ * Read by chrome that lists the sources of the views (the "+ view" menu of
79
+ * `@labre/affine-database-editor`, ADR 0035 B11). Writes nothing.
80
+ */
81
+ sourceOf(sourceId: string | undefined): HostedSource | null;
82
+ /** The current view's source; `null` when `resolveSource` knows none. */
83
+ readonly source$: ReadonlySignal<HostedSource | null>;
84
+ readonly schema$: ReadonlySignal<DatabaseBlockModel | null>;
85
+ readonly sourceMissing$: ReadonlySignal<boolean>;
86
+ /** Each row is a document (ADR 0035 §9a, §9f). Read-only. */
87
+ get rowsAreDocuments(): boolean;
88
+ /**
89
+ * A document row's title from the source's own store, read for the `title`
90
+ * property when {@link rowsAreDocuments}; `undefined` falls back to
91
+ * `getCellValue`.
92
+ */
93
+ protected titleOf(_rowId: string): string | undefined;
33
94
  /** Notify the view layer that the underlying data changed. */
34
95
  protected invalidate(): void;
35
96
  dispose(): void;
@@ -67,3 +128,9 @@ export declare abstract class ExternalDataSourceBase extends DataSourceBase {
67
128
  viewMetaGet(type: string): ViewMeta;
68
129
  viewMetaGetById(viewId: string): ViewMeta | undefined;
69
130
  }
131
+ /**
132
+ * The 0.48 name, kept so a host source written against it compiles unchanged:
133
+ * `new ExternalDataSourceBase(model)` is a hosted source with one implicit
134
+ * source, the block itself.
135
+ */
136
+ export { HostedDataSourceBase as ExternalDataSourceBase };
@@ -1,11 +1,9 @@
1
1
  import { FeatureFlagService } from '../affine-shared/services/index.js';
2
2
  import { DataSourceBase, ViewManagerBase, } from '../data-view/index.js';
3
3
  import { DisposableGroup } from '../global/disposable/index.js';
4
- import { IS_MOBILE } from '../global/env/index.js';
5
- import { BlockSuiteError, ErrorCode } from '../global/exceptions/index.js';
6
4
  import { computed, signal } from '@preact/signals-core';
7
5
  import { deleteView, duplicateView, moveViewTo, updateView, } from './utils/block-utils.js';
8
- import { databaseBlockViewConverts, databaseBlockViewMap, databaseBlockViews, } from './views/index.js';
6
+ import { databaseBlockViewConverts, databaseBlockViewMetaGet, databaseBlockViews, } from './views/index.js';
9
7
  /**
10
8
  * Intermediate base for `affine:database` data sources whose **view config**
11
9
  * keeps living in the block model blob (`model.props.views`) while the **data
@@ -26,18 +24,49 @@ import { databaseBlockViewConverts, databaseBlockViewMap, databaseBlockViews, }
26
24
  * computeds re-run. Defining `rows$`/`properties$` here (not as instance fields
27
25
  * reassigned in a subclass constructor) also avoids the "reassign after super"
28
26
  * dance.
27
+ *
28
+ * Sources (ADR 0035 §7, B1): the views live in `hostModel.props.views`; each
29
+ * view reads the source its `sourceId` names, through `resolveSource`. The
30
+ * data layer answers for the CURRENT view's source ({@link source$},
31
+ * {@link schema$}, {@link rows$}): one view is drawn at a time, and property
32
+ * ids never collide across sources (host-generated uuids). Without
33
+ * `resolveSource` the block has one implicit source, itself, whatever a view
34
+ * says: the 0.48 behaviour, which `ExternalDataSourceBase(model)` keeps.
35
+ *
36
+ * Rows that are documents (B15): a source whose rows are documents says so
37
+ * with {@link rowsAreDocuments}, answers each title from its own store with
38
+ * {@link titleOf}, and returns `hostedTitleColumnConfig` from
39
+ * `propertyMetaGet('title')`, so a title is a plain string and no row's
40
+ * document is loaded to draw it.
29
41
  */
30
- export class ExternalDataSourceBase extends DataSourceBase {
31
- constructor(model) {
42
+ export class HostedDataSourceBase extends DataSourceBase {
43
+ constructor(hostModel, resolveSource) {
32
44
  super();
33
45
  /** Bumped by {@link invalidate} to re-run the data-layer computeds. */
34
46
  this.revision = signal(0);
35
47
  this.disposables = new DisposableGroup();
36
- // --- reactive bridge over the data contract -----------------------------
37
- this.rows$ = computed(() => {
48
+ /** The current view's stored `sourceId`; `undefined` reads the implicit source. */
49
+ this.currentSourceId$ = computed(() => {
50
+ const viewId = this.viewManager.currentViewId$.value;
51
+ if (!viewId)
52
+ return undefined;
53
+ const view = this.viewDataGet(viewId);
54
+ return view?.sourceId;
55
+ });
56
+ this._implicitRows$ = computed(() => {
38
57
  void this.revision.value;
39
58
  return this.getRows();
40
59
  });
60
+ /** The current view's source; `null` when `resolveSource` knows none. */
61
+ // Without `resolveSource` the current view is not read at all: the
62
+ // implicit source does not depend on it.
63
+ this.source$ = computed(() => this._resolveSource
64
+ ? this.sourceOf(this.currentSourceId$.value)
65
+ : this.sourceOf(undefined));
66
+ this.schema$ = computed(() => this.source$.value?.schema ?? null);
67
+ this.sourceMissing$ = computed(() => this.source$.value === null);
68
+ // --- reactive bridge over the data contract -----------------------------
69
+ this.rows$ = computed(() => this.source$.value?.rows.value ?? []);
41
70
  this.properties$ = computed(() => {
42
71
  void this.revision.value;
43
72
  return this.getProperties();
@@ -58,10 +87,10 @@ export class ExternalDataSourceBase extends DataSourceBase {
58
87
  enable_table_virtual_scroll: featureFlagService.getFlag('enable_table_virtual_scroll') ?? false,
59
88
  };
60
89
  });
90
+ // Mobile edits too (ADR 0035 §1, B5): the table and kanban presets ship
91
+ // their own touch renderers, chosen by `DataViewRootUILogic`.
61
92
  this.readonly$ = computed(() => {
62
- return (this._model.store.readonly ||
63
- // TODO(@L-Sun): use block level readonly
64
- IS_MOBILE);
93
+ return this._model.store.readonly;
65
94
  });
66
95
  this.viewConverts = databaseBlockViewConverts;
67
96
  this.viewMetas = databaseBlockViews;
@@ -69,7 +98,43 @@ export class ExternalDataSourceBase extends DataSourceBase {
69
98
  this.viewDataList$ = computed(() => {
70
99
  return this._model.props.views$.value;
71
100
  });
72
- this._model = model;
101
+ this._model = hostModel;
102
+ this._resolveSource = resolveSource;
103
+ }
104
+ get hostModel() {
105
+ return this._model;
106
+ }
107
+ /**
108
+ * Whether views name the source they read: a `resolveSource` was given.
109
+ * Without it there is one implicit source, the block, whatever `sourceId`
110
+ * a view stores, so chrome that lists sources has nothing to list.
111
+ */
112
+ get resolvesSources() {
113
+ return this._resolveSource !== undefined;
114
+ }
115
+ /**
116
+ * Any source, by the `sourceId` a view would store, resolved the way the
117
+ * current view's is ({@link source$}); `null` when there is no such source.
118
+ * Read by chrome that lists the sources of the views (the "+ view" menu of
119
+ * `@labre/affine-database-editor`, ADR 0035 B11). Writes nothing.
120
+ */
121
+ sourceOf(sourceId) {
122
+ if (!this._resolveSource) {
123
+ return { schema: this._model, rows: this._implicitRows$ };
124
+ }
125
+ return this._resolveSource(sourceId);
126
+ }
127
+ /** Each row is a document (ADR 0035 §9a, §9f). Read-only. */
128
+ get rowsAreDocuments() {
129
+ return false;
130
+ }
131
+ /**
132
+ * A document row's title from the source's own store, read for the `title`
133
+ * property when {@link rowsAreDocuments}; `undefined` falls back to
134
+ * `getCellValue`.
135
+ */
136
+ titleOf(_rowId) {
137
+ return undefined;
73
138
  }
74
139
  /** Notify the view layer that the underlying data changed. */
75
140
  invalidate() {
@@ -86,6 +151,11 @@ export class ExternalDataSourceBase extends DataSourceBase {
86
151
  }
87
152
  cellValueGet(rowId, propertyId) {
88
153
  void this.revision.value;
154
+ if (this.rowsAreDocuments && this.getPropertyType(propertyId) === 'title') {
155
+ const title = this.titleOf(rowId);
156
+ if (title !== undefined)
157
+ return title;
158
+ }
89
159
  return this.getCellValue(rowId, propertyId);
90
160
  }
91
161
  propertyTypeGet(propertyId) {
@@ -128,11 +198,7 @@ export class ExternalDataSourceBase extends DataSourceBase {
128
198
  updateView(this._model, id, updater);
129
199
  }
130
200
  viewMetaGet(type) {
131
- const view = databaseBlockViewMap[type];
132
- if (!view) {
133
- throw new BlockSuiteError(ErrorCode.DatabaseBlockError, `Unknown view type: ${type}`);
134
- }
135
- return view;
201
+ return databaseBlockViewMetaGet(type);
136
202
  }
137
203
  viewMetaGetById(viewId) {
138
204
  const view = this.viewDataGet(viewId);
@@ -142,3 +208,9 @@ export class ExternalDataSourceBase extends DataSourceBase {
142
208
  return this.viewMetaGet(view.mode);
143
209
  }
144
210
  }
211
+ /**
212
+ * The 0.48 name, kept so a host source written against it compiles unchanged:
213
+ * `new ExternalDataSourceBase(model)` is a hosted source with one implicit
214
+ * source, the block itself.
215
+ */
216
+ export { HostedDataSourceBase as ExternalDataSourceBase };
@@ -12,5 +12,7 @@ export * from './properties/rich-text/cell-renderer.js';
12
12
  export * from './selection.js';
13
13
  export * from './service/index.js';
14
14
  export * from './utils/block-utils.js';
15
+ export * from './view-creation.js';
15
16
  export * from './views/index.js';
16
17
  export * from '../data-view/index.js';
18
+ export * from './linked-view.js';
@@ -12,5 +12,7 @@ export * from './properties/rich-text/cell-renderer.js';
12
12
  export * from './selection.js';
13
13
  export * from './service/index.js';
14
14
  export * from './utils/block-utils.js';
15
+ export * from './view-creation.js';
15
16
  export * from './views/index.js';
16
17
  export * from '../data-view/index.js';
18
+ export * from './linked-view.js';
@@ -0,0 +1,38 @@
1
+ import { type DataSourcePickerDatabase, type DataSourcePickerService } from '../affine-shared/services/index.js';
2
+ import type { BlockStdScope } from '../std/index.js';
3
+ import { type BlockModel } from '../store/index.js';
4
+ /**
5
+ * A view of a host database inserted into a document (ADR 0035 §5, §9c,
6
+ * issue B12): an `affine:database` block whose `externalSourceId` is the
7
+ * database the host listed and whose one view reads the chosen source
8
+ * (`sourceId`). No new prop, no new flavour: the shape every hosted database
9
+ * already has (labre ADR-0046 §3).
10
+ *
11
+ * The view's preset data comes from the preset's own `defaultData`, computed
12
+ * over the host's data source with the new view current, so a board groups by
13
+ * a property of the source it reads. One gesture, one undo step: the block
14
+ * and its view are written without a `captureSync` between them.
15
+ *
16
+ * Returns the new block's id, or `null` when nothing was written (read-only
17
+ * document, the anchor gone, no host data source).
18
+ */
19
+ export declare function insertLinkedDatabaseView(std: BlockStdScope, options: {
20
+ /** The block the view goes after. */
21
+ after: BlockModel;
22
+ database: Pick<DataSourcePickerDatabase, 'id' | 'title'>;
23
+ sourceId: string;
24
+ viewType: string;
25
+ /** Drop `after` when it is an empty paragraph (a slash entry's line). */
26
+ removeEmptyLine?: boolean;
27
+ }): string | null;
28
+ /**
29
+ * The creating slash entries once the host fills the picker (ADR 0035 §5):
30
+ * ask the host for a new database, then insert a view of its first source
31
+ * after `after`. Nothing is written until the host answers; `null`, or a
32
+ * database with no source, writes nothing.
33
+ */
34
+ export declare function createHostedDatabaseView(std: BlockStdScope, picker: DataSourcePickerService, options: {
35
+ after: BlockModel;
36
+ viewType: string;
37
+ removeEmptyLine?: boolean;
38
+ }): Promise<string | null>;