@formicoidea/labre-core 1.0.0 → 2.0.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 (207) hide show
  1. package/architecture/code.c4 +48 -44
  2. package/architecture/likec4.config.json +3 -3
  3. package/dist/_pkgs/affine-block-root/configs/toolbar.d.ts +1 -1
  4. package/dist/_pkgs/affine-block-root/configs/toolbar.js +4 -2
  5. package/dist/_pkgs/affine-block-surface/extensions/reading-toolbar.js +12 -12
  6. package/dist/_pkgs/affine-components/context-menu/menu-all.d.ts +1 -0
  7. package/dist/_pkgs/affine-components/context-menu/menu-renderer.d.ts +3 -1
  8. package/dist/_pkgs/affine-components/context-menu/menu-renderer.js +9 -1
  9. package/dist/_pkgs/affine-components/context-menu/menu.d.ts +7 -0
  10. package/dist/_pkgs/affine-components/context-menu/menu.js +5 -0
  11. package/dist/_pkgs/affine-components/context-menu/sub-menu.d.ts +19 -1
  12. package/dist/_pkgs/affine-components/context-menu/sub-menu.js +46 -7
  13. package/dist/_pkgs/affine-components/highlight-dropdown-menu/highlight-duotone-icon.js +8 -8
  14. package/dist/_pkgs/affine-components/highlight-dropdown-menu/text-duotone-icon.js +11 -11
  15. package/dist/_pkgs/affine-database-block/configs/slash-menu.d.ts +24 -0
  16. package/dist/_pkgs/affine-database-block/configs/slash-menu.js +52 -37
  17. package/dist/_pkgs/affine-database-block/creation-menu.d.ts +6 -0
  18. package/dist/_pkgs/affine-database-block/data-source.d.ts +6 -0
  19. package/dist/_pkgs/affine-database-block/data-source.js +16 -0
  20. package/dist/_pkgs/affine-database-block/database-block-styles.js +4 -3
  21. package/dist/_pkgs/affine-database-block/database-block.d.ts +23 -0
  22. package/dist/_pkgs/affine-database-block/database-block.js +129 -19
  23. package/dist/_pkgs/affine-database-block/database-dnd-preview-block.js +5 -1
  24. package/dist/_pkgs/affine-database-block/detail-panel/block-renderer.js +5 -2
  25. package/dist/_pkgs/affine-database-block/detail-panel/note-renderer.js +3 -2
  26. package/dist/_pkgs/affine-database-block/external-data-source.d.ts +17 -0
  27. package/dist/_pkgs/affine-database-block/external-data-source.js +54 -4
  28. package/dist/_pkgs/affine-database-block/index.d.ts +3 -0
  29. package/dist/_pkgs/affine-database-block/index.js +5 -0
  30. package/dist/_pkgs/affine-database-block/linked-view.d.ts +59 -0
  31. package/dist/_pkgs/affine-database-block/linked-view.js +131 -1
  32. package/dist/_pkgs/affine-database-block/properties/created-time/define.js +3 -1
  33. package/dist/_pkgs/affine-database-block/properties/link/cell-renderer.js +3 -2
  34. package/dist/_pkgs/affine-database-block/properties/link/define.js +3 -1
  35. package/dist/_pkgs/affine-database-block/properties/rich-text/define.js +3 -1
  36. package/dist/_pkgs/affine-database-block/properties/text/hosted.js +1 -0
  37. package/dist/_pkgs/affine-database-block/properties/title/define.js +3 -1
  38. package/dist/_pkgs/affine-database-block/properties/title/hosted.js +1 -0
  39. package/dist/_pkgs/affine-database-block/service/new-row-menu.d.ts +1 -1
  40. package/dist/_pkgs/affine-database-block/service/new-row-menu.js +1 -1
  41. package/dist/_pkgs/affine-database-block/translations.d.ts +29 -0
  42. package/dist/_pkgs/affine-database-block/translations.js +104 -0
  43. package/dist/_pkgs/affine-database-block/turn-into-source.d.ts +38 -0
  44. package/dist/_pkgs/affine-database-block/turn-into-source.js +187 -0
  45. package/dist/_pkgs/affine-database-block/view-deletion.d.ts +15 -0
  46. package/dist/_pkgs/affine-database-block/view-deletion.js +113 -0
  47. package/dist/_pkgs/affine-database-block/views/index.d.ts +7 -9
  48. package/dist/_pkgs/affine-database-block/views/index.js +7 -10
  49. package/dist/_pkgs/affine-database-engine/core/common/properties.js +7 -7
  50. package/dist/_pkgs/affine-database-engine/core/common/property-menu.d.ts +18 -2
  51. package/dist/_pkgs/affine-database-engine/core/common/property-menu.js +78 -27
  52. package/dist/_pkgs/affine-database-engine/core/data-source/base.d.ts +11 -0
  53. package/dist/_pkgs/affine-database-engine/core/data-source/base.js +3 -0
  54. package/dist/_pkgs/affine-database-engine/core/detail/detail.js +8 -5
  55. package/dist/_pkgs/affine-database-engine/core/detail/field.js +14 -7
  56. package/dist/_pkgs/affine-database-engine/core/filter/add-filter.js +4 -2
  57. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/boolean.js +7 -4
  58. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/create.d.ts +9 -1
  59. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/create.js +2 -0
  60. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/date.js +7 -4
  61. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/multi-tag.js +17 -8
  62. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/number.js +6 -6
  63. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/string.js +19 -12
  64. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/tag.js +9 -4
  65. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/unknown.js +7 -4
  66. package/dist/_pkgs/affine-database-engine/core/filter/literal/define.js +6 -4
  67. package/dist/_pkgs/affine-database-engine/core/filter/literal/matcher.d.ts +2 -1
  68. package/dist/_pkgs/affine-database-engine/core/filter/literal/matcher.js +3 -2
  69. package/dist/_pkgs/affine-database-engine/core/filter/literal/types.d.ts +4 -1
  70. package/dist/_pkgs/affine-database-engine/core/filter/literal/types.js +1 -1
  71. package/dist/_pkgs/affine-database-engine/core/group-by/define.js +11 -9
  72. package/dist/_pkgs/affine-database-engine/core/group-by/group-title.js +16 -6
  73. package/dist/_pkgs/affine-database-engine/core/group-by/locate-row.d.ts +16 -0
  74. package/dist/_pkgs/affine-database-engine/core/group-by/locate-row.js +32 -0
  75. package/dist/_pkgs/affine-database-engine/core/group-by/renderer/date-group.js +10 -3
  76. package/dist/_pkgs/affine-database-engine/core/group-by/setting.d.ts +2 -0
  77. package/dist/_pkgs/affine-database-engine/core/group-by/setting.js +40 -28
  78. package/dist/_pkgs/affine-database-engine/core/group-by/trait.d.ts +3 -0
  79. package/dist/_pkgs/affine-database-engine/core/group-by/trait.js +8 -0
  80. package/dist/_pkgs/affine-database-engine/core/group-by/types.d.ts +3 -1
  81. package/dist/_pkgs/affine-database-engine/core/group-by/types.js +1 -1
  82. package/dist/_pkgs/affine-database-engine/core/property/types.d.ts +7 -0
  83. package/dist/_pkgs/affine-database-engine/core/property/types.js +1 -1
  84. package/dist/_pkgs/affine-database-engine/core/sort/add-sort.js +3 -1
  85. package/dist/_pkgs/affine-database-engine/core/statistics/any.js +43 -21
  86. package/dist/_pkgs/affine-database-engine/core/statistics/checkbox.js +29 -14
  87. package/dist/_pkgs/affine-database-engine/core/statistics/number.js +54 -31
  88. package/dist/_pkgs/affine-database-engine/core/statistics/types.d.ts +8 -0
  89. package/dist/_pkgs/affine-database-engine/core/statistics/types.js +2 -1
  90. package/dist/_pkgs/affine-database-engine/core/utils/wording.d.ts +20 -1
  91. package/dist/_pkgs/affine-database-engine/core/utils/wording.js +24 -0
  92. package/dist/_pkgs/affine-database-engine/core/view-manager/property.d.ts +7 -0
  93. package/dist/_pkgs/affine-database-engine/core/view-manager/property.js +29 -5
  94. package/dist/_pkgs/affine-database-engine/core/view-manager/single-view.d.ts +14 -0
  95. package/dist/_pkgs/affine-database-engine/core/view-manager/single-view.js +11 -0
  96. package/dist/_pkgs/affine-database-engine/property-presets/checkbox/define.js +3 -1
  97. package/dist/_pkgs/affine-database-engine/property-presets/date/define.js +3 -1
  98. package/dist/_pkgs/affine-database-engine/property-presets/multi-select/define.js +3 -1
  99. package/dist/_pkgs/affine-database-engine/property-presets/number/define.js +3 -1
  100. package/dist/_pkgs/affine-database-engine/property-presets/number/utils/formats.d.ts +3 -0
  101. package/dist/_pkgs/affine-database-engine/property-presets/number/utils/formats.js +56 -9
  102. package/dist/_pkgs/affine-database-engine/property-presets/progress/define.js +3 -1
  103. package/dist/_pkgs/affine-database-engine/property-presets/select/define.js +3 -1
  104. package/dist/_pkgs/affine-database-engine/property-presets/text/define.js +3 -1
  105. package/dist/_pkgs/affine-database-engine/translations.d.ts +133 -5
  106. package/dist/_pkgs/affine-database-engine/translations.js +625 -9
  107. package/dist/_pkgs/affine-database-engine/view-presets/convert.js +0 -28
  108. package/dist/_pkgs/affine-database-engine/view-presets/effect.js +0 -2
  109. package/dist/_pkgs/affine-database-engine/view-presets/flat/flat-converts.js +2 -4
  110. package/dist/_pkgs/affine-database-engine/view-presets/flat/flat-view-ui.d.ts +57 -0
  111. package/dist/_pkgs/affine-database-engine/view-presets/flat/flat-view-ui.js +113 -4
  112. package/dist/_pkgs/affine-database-engine/view-presets/gallery/gallery-view.js +2 -1
  113. package/dist/_pkgs/affine-database-engine/view-presets/index.d.ts +0 -2
  114. package/dist/_pkgs/affine-database-engine/view-presets/index.js +0 -3
  115. package/dist/_pkgs/affine-database-engine/view-presets/kanban/kanban-view-manager.js +2 -0
  116. package/dist/_pkgs/affine-database-engine/view-presets/kanban/mobile/group.js +7 -5
  117. package/dist/_pkgs/affine-database-engine/view-presets/kanban/mobile/kanban-view-ui-logic.d.ts +5 -0
  118. package/dist/_pkgs/affine-database-engine/view-presets/kanban/mobile/kanban-view-ui-logic.js +25 -3
  119. package/dist/_pkgs/affine-database-engine/view-presets/kanban/mobile/menu.js +12 -6
  120. package/dist/_pkgs/affine-database-engine/view-presets/kanban/pc/controller/selection.d.ts +8 -0
  121. package/dist/_pkgs/affine-database-engine/view-presets/kanban/pc/controller/selection.js +35 -12
  122. package/dist/_pkgs/affine-database-engine/view-presets/kanban/pc/group.js +7 -5
  123. package/dist/_pkgs/affine-database-engine/view-presets/kanban/pc/header.js +5 -1
  124. package/dist/_pkgs/affine-database-engine/view-presets/kanban/pc/kanban-view-ui-logic.d.ts +5 -0
  125. package/dist/_pkgs/affine-database-engine/view-presets/kanban/pc/kanban-view-ui-logic.js +8 -4
  126. package/dist/_pkgs/affine-database-engine/view-presets/kanban/pc/menu.js +12 -6
  127. package/dist/_pkgs/affine-database-engine/view-presets/list/list-view.js +2 -1
  128. package/dist/_pkgs/affine-database-engine/view-presets/table/mobile/column-header.js +6 -4
  129. package/dist/_pkgs/affine-database-engine/view-presets/table/mobile/group.js +6 -5
  130. package/dist/_pkgs/affine-database-engine/view-presets/table/mobile/header.js +2 -2
  131. package/dist/_pkgs/affine-database-engine/view-presets/table/mobile/table-view-ui-logic.d.ts +4 -3
  132. package/dist/_pkgs/affine-database-engine/view-presets/table/mobile/table-view-ui-logic.js +29 -5
  133. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/controller/clipboard.js +6 -2
  134. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/controller/selection.js +2 -0
  135. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/group.js +6 -5
  136. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/header/column-header.js +11 -7
  137. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/header/database-header-column.js +16 -12
  138. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/header/number-format-bar.js +4 -2
  139. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/menu.js +9 -6
  140. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/table-view-ui-logic.d.ts +8 -1
  141. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/table-view-ui-logic.js +29 -7
  142. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/controller/clipboard.js +6 -2
  143. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/controller/selection.js +2 -0
  144. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/bottom/group-footer.js +5 -2
  145. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/bottom/stats/column-stats-column.d.ts +1 -1
  146. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/bottom/stats/column-stats-column.js +14 -6
  147. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/top/group-header.js +5 -2
  148. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/top/group-title.js +5 -3
  149. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/top/header/column-header.js +17 -10
  150. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/top/header/number-format-bar.js +4 -2
  151. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/top/header/single-column-header.js +20 -14
  152. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/row/menu.js +9 -6
  153. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/table-view-ui-logic.d.ts +6 -1
  154. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/table-view-ui-logic.js +30 -3
  155. package/dist/_pkgs/affine-database-engine/view-presets/table/stats/column-stats-column.d.ts +1 -1
  156. package/dist/_pkgs/affine-database-engine/view-presets/table/stats/column-stats-column.js +14 -6
  157. package/dist/_pkgs/affine-database-engine/view-presets/table/table-view-manager.js +2 -0
  158. package/dist/_pkgs/affine-database-engine/widget-presets/quick-setting-bar/filter/condition-view.d.ts +2 -0
  159. package/dist/_pkgs/affine-database-engine/widget-presets/quick-setting-bar/filter/condition-view.js +13 -6
  160. package/dist/_pkgs/affine-database-engine/widget-presets/quick-setting-bar/filter/group-panel-view.js +20 -13
  161. package/dist/_pkgs/affine-database-engine/widget-presets/quick-setting-bar/filter/root-panel-view.js +10 -5
  162. package/dist/_pkgs/affine-database-engine/widget-presets/quick-setting-bar/sort/root-panel.js +8 -5
  163. package/dist/_pkgs/affine-database-engine/widget-presets/tools/presets/search/search.js +2 -2
  164. package/dist/_pkgs/affine-database-engine/widget-presets/tools/presets/table-add-row/add-row.d.ts +6 -0
  165. package/dist/_pkgs/affine-database-engine/widget-presets/tools/presets/table-add-row/add-row.js +49 -4
  166. package/dist/_pkgs/affine-database-engine/widget-presets/tools/presets/view-options/view-settings.d.ts +3 -3
  167. package/dist/_pkgs/affine-database-engine/widget-presets/tools/presets/view-options/view-settings.js +3 -3
  168. package/dist/_pkgs/affine-database-engine/widget-presets/views-bar/views-view.js +5 -0
  169. package/dist/_pkgs/affine-database-view-block/configs/slash-menu.js +6 -3
  170. package/dist/_pkgs/affine-database-view-block/data-view-block.js +5 -4
  171. package/dist/_pkgs/affine-fragment-doc-title/doc-title.d.ts +3 -2
  172. package/dist/_pkgs/affine-fragment-doc-title/doc-title.js +3 -2
  173. package/dist/_pkgs/affine-shared/services/data-source-picker-service.d.ts +130 -1
  174. package/dist/_pkgs/affine-widget-edgeless-zoom-toolbar/index.js +26 -26
  175. package/dist/_pkgs/affine-widget-keyboard-toolbar/config.js +10 -21
  176. package/dist/_pkgs/affine-widget-keyboard-toolbar/icons.js +98 -98
  177. package/dist/_pkgs/affine-widget-page-dragging-area/index.js +10 -10
  178. package/dist/_pkgs/affine-widget-viewport-overlay/index.js +13 -13
  179. package/package.json +1 -1
  180. package/dist/_pkgs/affine-database-engine/view-presets/calendar/calendar-view-manager.d.ts +0 -70
  181. package/dist/_pkgs/affine-database-engine/view-presets/calendar/calendar-view-manager.js +0 -449
  182. package/dist/_pkgs/affine-database-engine/view-presets/calendar/define.d.ts +0 -10
  183. package/dist/_pkgs/affine-database-engine/view-presets/calendar/define.js +0 -29
  184. package/dist/_pkgs/affine-database-engine/view-presets/calendar/effect.d.ts +0 -1
  185. package/dist/_pkgs/affine-database-engine/view-presets/calendar/effect.js +0 -4
  186. package/dist/_pkgs/affine-database-engine/view-presets/calendar/index.d.ts +0 -6
  187. package/dist/_pkgs/affine-database-engine/view-presets/calendar/index.js +0 -6
  188. package/dist/_pkgs/affine-database-engine/view-presets/calendar/layout.d.ts +0 -37
  189. package/dist/_pkgs/affine-database-engine/view-presets/calendar/layout.js +0 -138
  190. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/actions.d.ts +0 -7
  191. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/actions.js +0 -64
  192. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/dnd.d.ts +0 -32
  193. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/dnd.js +0 -159
  194. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/effect.d.ts +0 -1
  195. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/effect.js +0 -7
  196. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/hit-test.d.ts +0 -1
  197. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/hit-test.js +0 -28
  198. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/styles.d.ts +0 -1
  199. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/styles.js +0 -707
  200. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/view.d.ts +0 -89
  201. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/view.js +0 -849
  202. package/dist/_pkgs/affine-database-engine/view-presets/calendar/renderer.d.ts +0 -2
  203. package/dist/_pkgs/affine-database-engine/view-presets/calendar/renderer.js +0 -8
  204. package/dist/_pkgs/affine-database-engine/view-presets/calendar/source.d.ts +0 -8
  205. package/dist/_pkgs/affine-database-engine/view-presets/calendar/source.js +0 -3
  206. package/dist/_pkgs/affine-database-engine/view-presets/calendar/types.d.ts +0 -79
  207. package/dist/_pkgs/affine-database-engine/view-presets/calendar/types.js +0 -1
@@ -1,8 +1,9 @@
1
- import { FeatureFlagService } from '../affine-shared/services/index.js';
1
+ import { DataSourcePickerProvider, FeatureFlagService, } from '../affine-shared/services/index.js';
2
2
  import { DataSourceBase, ViewManagerBase, } from '../affine-database-engine/index.js';
3
3
  import { DisposableGroup } from '../global/disposable/index.js';
4
4
  import { computed, signal } from '@preact/signals-core';
5
5
  import { deleteView, duplicateView, moveViewTo, updateView, } from './utils/block-utils.js';
6
+ import { deleteViewThroughHost } from './view-deletion.js';
6
7
  import { databaseBlockViewConverts, databaseBlockViewMetaGet, databaseBlockViews, } from './views/index.js';
7
8
  /**
8
9
  * Intermediate base for `affine:database` data sources whose **view config**
@@ -87,10 +88,41 @@ export class HostedDataSourceBase extends DataSourceBase {
87
88
  enable_table_virtual_scroll: featureFlagService.getFlag('enable_table_virtual_scroll') ?? false,
88
89
  };
89
90
  });
91
+ /**
92
+ * Refuses every edit on a writable store: a database with no source, under
93
+ * a host that requires one, shows its native rows read-only (ADR 0035
94
+ * amendment of 2026-10-29). Every write path of the view layer reads
95
+ * `readonly$` (cells, paste, drag, "New", view and property menus).
96
+ */
97
+ this.locked$ = signal(false);
98
+ /**
99
+ * The host's lock on the current view's source (`sourcePolicy` of the
100
+ * picker, ADR 0035 amendment of 2026-10-29), asked again only when the
101
+ * block's database or the view's source changes; the host's signal then
102
+ * carries every flip to the open views. `null`: nothing locked (a native
103
+ * database, no picker, no `sourcePolicy`, or a host that threw).
104
+ */
105
+ this.hostPolicy$ = computed(() => {
106
+ const databaseId = this._model.props.externalSourceId$.value;
107
+ if (!databaseId)
108
+ return null;
109
+ const picker = this.serviceGet(DataSourcePickerProvider);
110
+ if (!picker?.sourcePolicy)
111
+ return null;
112
+ try {
113
+ return picker.sourcePolicy(databaseId, this.currentSourceId$.value);
114
+ }
115
+ catch (error) {
116
+ console.error(error);
117
+ return null;
118
+ }
119
+ });
120
+ this.propertiesLocked$ = computed(() => this.hostPolicy$.value?.value.propertiesLocked === true);
121
+ this.rowsLocked$ = computed(() => this.hostPolicy$.value?.value.rowsLocked === true);
90
122
  // Mobile edits too (ADR 0035 §1, B5): the table and kanban presets ship
91
123
  // their own touch renderers, chosen by `DataViewRootUILogic`.
92
124
  this.readonly$ = computed(() => {
93
- return this._model.store.readonly;
125
+ return this._model.store.readonly || this.locked$.value;
94
126
  });
95
127
  this.viewConverts = databaseBlockViewConverts;
96
128
  this.viewMetas = databaseBlockViews;
@@ -185,8 +217,26 @@ export class HostedDataSourceBase extends DataSourceBase {
185
217
  return viewData.id;
186
218
  }
187
219
  viewDataDelete(viewId) {
188
- this._model.store.captureSync();
189
- deleteView(this._model, viewId);
220
+ deleteViewThroughHost({
221
+ model: this._model,
222
+ viewId,
223
+ picker: this.serviceGet(DataSourcePickerProvider),
224
+ removeNow: () => {
225
+ this._model.store.captureSync();
226
+ deleteView(this._model, viewId);
227
+ },
228
+ // The view manager moved on when the gesture was made; a removal the
229
+ // host made later must not leave a vanished view current.
230
+ afterRemove: () => {
231
+ const manager = this.viewManager;
232
+ const views = manager.views$.peek();
233
+ const current = manager.currentViewId$.peek();
234
+ const next = views[0];
235
+ if (current !== undefined && !views.includes(current) && next) {
236
+ manager.setCurrentView(next);
237
+ }
238
+ },
239
+ });
190
240
  }
191
241
  viewDataDuplicate(id) {
192
242
  return duplicateView(this._model, id);
@@ -1,5 +1,6 @@
1
1
  export * from './adapters/index.js';
2
2
  export * from './commands.js';
3
+ export { canCreateDatabase, createDatabaseByGesture, } from './configs/slash-menu.js';
3
4
  export * from './config.js';
4
5
  export * from './context/index.js';
5
6
  export * from './creation-menu.js';
@@ -17,3 +18,5 @@ export * from './view-creation.js';
17
18
  export * from './views/index.js';
18
19
  export * from '../affine-database-engine/index.js';
19
20
  export * from './linked-view.js';
21
+ export * from './turn-into-source.js';
22
+ export { DATABASE_CREATION_TITLE } from './translations.js';
@@ -1,5 +1,6 @@
1
1
  export * from './adapters/index.js';
2
2
  export * from './commands.js';
3
+ export { canCreateDatabase, createDatabaseByGesture, } from './configs/slash-menu.js';
3
4
  export * from './config.js';
4
5
  export * from './context/index.js';
5
6
  export * from './creation-menu.js';
@@ -17,3 +18,7 @@ export * from './view-creation.js';
17
18
  export * from './views/index.js';
18
19
  export * from '../affine-database-engine/index.js';
19
20
  export * from './linked-view.js';
21
+ export * from './turn-into-source.js';
22
+ // The creation popover (`@labre/affine-database-editor`) titles itself with
23
+ // the wording core declares for its "Connect a source" button.
24
+ export { DATABASE_CREATION_TITLE } from './translations.js';
@@ -47,6 +47,65 @@ export declare function connectDatabaseToSource(std: BlockStdScope, model: Datab
47
47
  database: Pick<DataSourcePickerDatabase, 'id' | 'title'>;
48
48
  sourceId: string;
49
49
  }): boolean;
50
+ /**
51
+ * What a database shows under a host that requires a source
52
+ * (`requireSource`, ADR 0035 amendment of 2026-10-29, product owner's
53
+ * decision of the same day). The SOURCE decides, never the row count:
54
+ *
55
+ * - `'none'`: the host does not require one, or the block reads a source it
56
+ * resolves. A hosted database with no row is an ordinary empty table.
57
+ * - `'connect'`: no source and no row (the creation gesture left
58
+ * unfinished), or a hosted source the host no longer resolves (the source
59
+ * or its base deleted). An empty view offering "Connect a source".
60
+ * - `'read-only'`: no source but native rows (a database written before
61
+ * 1.0, by a host without a picker, or pasted from one). The rows render,
62
+ * since documents render forever, and nothing native can be edited.
63
+ *
64
+ * Nothing is stored: a native database and the gesture left unfinished are
65
+ * the same bytes, so neither may be edited natively.
66
+ */
67
+ export type SourceRequirement = 'none' | 'connect' | 'read-only';
68
+ export declare function sourceRequirement(std: BlockStdScope, model: DatabaseBlockModel, sourceMissing?: boolean): SourceRequirement;
69
+ /**
70
+ * Re-points one view of a hosted database whose source the host no longer
71
+ * resolves (ADR 0035 amendment of 2026-10-29): the block takes the picked
72
+ * database's `externalSourceId` when it differs, and the view reads
73
+ * `sourceId` with its data re-derived over it (`defaultViewData`: its id
74
+ * and name kept, its layout too where the preset can build over the new
75
+ * source). The other views are left as they are. One undo step. Returns
76
+ * `false` and writes nothing on a read-only document, on a block with no
77
+ * source (`connectDatabaseToSource` connects those), without a host data
78
+ * source or without that view.
79
+ */
80
+ export declare function reconnectDatabaseView(std: BlockStdScope, model: DatabaseBlockModel, choice: {
81
+ database: Pick<DataSourcePickerDatabase, 'id'>;
82
+ sourceId: string;
83
+ viewId: string;
84
+ }): boolean;
85
+ /**
86
+ * Whether "Create Table" (`convertToDatabase`) may run. Where no source is
87
+ * required, it moves the blocks into a native database, as in 1.0. Where
88
+ * one is, it turns them into a source of the host's (`createDatabaseFrom`,
89
+ * ADR 0035 amendment of 2026-10-29), and is hidden without that method: a
90
+ * native database would be shown read-only at once.
91
+ */
92
+ export declare function canConvertToDatabase(std: BlockStdScope): boolean;
93
+ /**
94
+ * Moves a database with native rows into the host source just created from
95
+ * them (`createDatabaseFrom`, ADR 0035 amendment of 2026-10-29): the block
96
+ * takes the database's `externalSourceId`, its title when it has none, an
97
+ * empty schema of its own; EVERY view is kept by id, name and layout and
98
+ * reads `sourceId`, its data re-derived over the source (its filters, sorts
99
+ * and columns named native property ids, which the host's are not); the
100
+ * native rows are deleted. One undo step, which gives the native database
101
+ * back; the host's database stays. Returns `false` and writes nothing on a
102
+ * read-only document, on a block already connected, or without a host data
103
+ * source.
104
+ */
105
+ export declare function moveDatabaseIntoSource(std: BlockStdScope, model: DatabaseBlockModel, choice: {
106
+ database: Pick<DataSourcePickerDatabase, 'id' | 'title'>;
107
+ sourceId: string;
108
+ }): boolean;
50
109
  /**
51
110
  * The creating slash entries once the host fills the picker (ADR 0035 §5):
52
111
  * ask the host for a new database, then insert a view of its first source
@@ -1,4 +1,4 @@
1
- import { TelemetryProvider, } from '../affine-shared/services/index.js';
1
+ import { DataSourcePickerProvider, TelemetryProvider, } from '../affine-shared/services/index.js';
2
2
  import { nanoid, Text } from '../store/index.js';
3
3
  import { DatabaseDataSourceProvider } from './service/index.js';
4
4
  /**
@@ -131,6 +131,136 @@ export function connectDatabaseToSource(std, model, choice) {
131
131
  });
132
132
  return true;
133
133
  }
134
+ export function sourceRequirement(std, model, sourceMissing = false) {
135
+ if (std.getOptional(DataSourcePickerProvider)?.requireSource !== true) {
136
+ return 'none';
137
+ }
138
+ if (model.props.externalSourceId === undefined) {
139
+ return model.children.length === 0 ? 'connect' : 'read-only';
140
+ }
141
+ return sourceMissing ? 'connect' : 'none';
142
+ }
143
+ /**
144
+ * Re-points one view of a hosted database whose source the host no longer
145
+ * resolves (ADR 0035 amendment of 2026-10-29): the block takes the picked
146
+ * database's `externalSourceId` when it differs, and the view reads
147
+ * `sourceId` with its data re-derived over it (`defaultViewData`: its id
148
+ * and name kept, its layout too where the preset can build over the new
149
+ * source). The other views are left as they are. One undo step. Returns
150
+ * `false` and writes nothing on a read-only document, on a block with no
151
+ * source (`connectDatabaseToSource` connects those), without a host data
152
+ * source or without that view.
153
+ */
154
+ export function reconnectDatabaseView(std, model, choice) {
155
+ const { store } = std;
156
+ if (store.readonly)
157
+ return false;
158
+ if (model.props.externalSourceId === undefined)
159
+ return false;
160
+ const provider = std.getOptional(DatabaseDataSourceProvider);
161
+ if (!provider)
162
+ return false;
163
+ const { database, sourceId, viewId } = choice;
164
+ const index = model.props.views.findIndex(view => view.id === viewId);
165
+ const current = model.props.views[index];
166
+ if (!current)
167
+ return false;
168
+ const view = { id: current.id, name: current.name, mode: current.mode };
169
+ const withView = (data) => model.props.views.map((old, i) => (i === index ? data : old));
170
+ store.captureSync();
171
+ store.transact(() => {
172
+ if (model.props.externalSourceId !== database.id) {
173
+ store.updateBlock(model, { externalSourceId: database.id });
174
+ }
175
+ store.updateBlock(model, { views: withView({ ...view, sourceId }) });
176
+ const dataSource = provider.createDataSource(model);
177
+ try {
178
+ dataSource.viewManager.setCurrentView(view.id);
179
+ store.updateBlock(model, {
180
+ views: withView({
181
+ ...defaultViewData(dataSource, view.mode),
182
+ id: view.id,
183
+ name: view.name,
184
+ sourceId,
185
+ }),
186
+ });
187
+ }
188
+ finally {
189
+ dataSource.dispose();
190
+ }
191
+ });
192
+ return true;
193
+ }
194
+ /**
195
+ * Whether "Create Table" (`convertToDatabase`) may run. Where no source is
196
+ * required, it moves the blocks into a native database, as in 1.0. Where
197
+ * one is, it turns them into a source of the host's (`createDatabaseFrom`,
198
+ * ADR 0035 amendment of 2026-10-29), and is hidden without that method: a
199
+ * native database would be shown read-only at once.
200
+ */
201
+ export function canConvertToDatabase(std) {
202
+ const picker = std.getOptional(DataSourcePickerProvider);
203
+ return picker?.requireSource !== true || !!picker.createDatabaseFrom;
204
+ }
205
+ /**
206
+ * Moves a database with native rows into the host source just created from
207
+ * them (`createDatabaseFrom`, ADR 0035 amendment of 2026-10-29): the block
208
+ * takes the database's `externalSourceId`, its title when it has none, an
209
+ * empty schema of its own; EVERY view is kept by id, name and layout and
210
+ * reads `sourceId`, its data re-derived over the source (its filters, sorts
211
+ * and columns named native property ids, which the host's are not); the
212
+ * native rows are deleted. One undo step, which gives the native database
213
+ * back; the host's database stays. Returns `false` and writes nothing on a
214
+ * read-only document, on a block already connected, or without a host data
215
+ * source.
216
+ */
217
+ export function moveDatabaseIntoSource(std, model, choice) {
218
+ const { store } = std;
219
+ if (store.readonly)
220
+ return false;
221
+ if (model.props.externalSourceId !== undefined)
222
+ return false;
223
+ const provider = std.getOptional(DatabaseDataSourceProvider);
224
+ if (!provider)
225
+ return false;
226
+ const { database, sourceId } = choice;
227
+ const views = model.props.views.map(view => ({
228
+ id: view.id,
229
+ name: view.name,
230
+ mode: view.mode,
231
+ }));
232
+ store.captureSync();
233
+ store.transact(() => {
234
+ const title = model.props.title;
235
+ if (title.length === 0 && database.title)
236
+ title.insert(database.title, 0);
237
+ store.updateBlock(model, {
238
+ externalSourceId: database.id,
239
+ columns: [],
240
+ views: views.map(view => ({ ...view, sourceId })),
241
+ });
242
+ const dataSource = provider.createDataSource(model);
243
+ try {
244
+ store.updateBlock(model, {
245
+ views: views.map(view => {
246
+ dataSource.viewManager.setCurrentView(view.id);
247
+ return {
248
+ ...defaultViewData(dataSource, view.mode),
249
+ id: view.id,
250
+ name: view.name,
251
+ sourceId,
252
+ };
253
+ }),
254
+ });
255
+ }
256
+ finally {
257
+ dataSource.dispose();
258
+ }
259
+ for (const row of [...model.children])
260
+ store.deleteBlock(row);
261
+ });
262
+ return true;
263
+ }
134
264
  /**
135
265
  * A preset's default view data over `dataSource`, named and typed. A preset
136
266
  * that cannot build one over this source (a board with no property to group
@@ -1,9 +1,11 @@
1
1
  import { propertyType, t } from '../../../affine-database-engine/index.js';
2
2
  import { format } from 'date-fns/format';
3
3
  import zod from 'zod';
4
+ import { DATABASE_TYPE_CREATED_TIME } from '../../translations.js';
4
5
  export const createdTimeColumnType = propertyType('created-time');
5
6
  export const createdTimePropertyModelConfig = createdTimeColumnType.modelConfig({
6
- name: 'Created Time',
7
+ name: DATABASE_TYPE_CREATED_TIME[1],
8
+ nameWording: DATABASE_TYPE_CREATED_TIME,
7
9
  propertyData: {
8
10
  schema: zod.object({}),
9
11
  default: () => ({}),
@@ -1,5 +1,5 @@
1
1
  import { RefNodeSlotsProvider } from '../../../affine-inline-reference/index.js';
2
- import { ParseDocUrlProvider } from '../../../affine-shared/services/index.js';
2
+ import { ParseDocUrlProvider, DOC_UNTITLED, translateKey, } from '../../../affine-shared/services/index.js';
3
3
  import { isSafeLinkUrl, isValidUrl, normalizeUrl, stopPropagation, } from '../../../affine-shared/utils/index.js';
4
4
  import { BaseCellRenderer, createFromBaseCellRenderer, createIcon, } from '../../../affine-database-engine/index.js';
5
5
  import { EditIcon } from '@blocksuite/icons/lit';
@@ -68,7 +68,8 @@ export class LinkCell extends BaseCellRenderer {
68
68
  if (title == null) {
69
69
  return;
70
70
  }
71
- return title || 'Untitled';
71
+ return (title ||
72
+ (this.std ? translateKey(this.std, ...DOC_UNTITLED) : DOC_UNTITLED[1]));
72
73
  });
73
74
  }
74
75
  firstUpdated(_changedProperties) {
@@ -1,8 +1,10 @@
1
1
  import { propertyType, t } from '../../../affine-database-engine/index.js';
2
2
  import zod from 'zod';
3
+ import { DATABASE_TYPE_LINK } from '../../translations.js';
3
4
  export const linkColumnType = propertyType('link');
4
5
  export const linkPropertyModelConfig = linkColumnType.modelConfig({
5
- name: 'Link',
6
+ name: DATABASE_TYPE_LINK[1],
7
+ nameWording: DATABASE_TYPE_LINK,
6
8
  propertyData: {
7
9
  schema: zod.object({}),
8
10
  default: () => ({}),
@@ -4,6 +4,7 @@ import * as Y from 'yjs';
4
4
  import zod from 'zod';
5
5
  import { EditorHostKey } from '../../context/host-context.js';
6
6
  import { isLinkedDoc } from '../../utils/title-doc.js';
7
+ import { DATABASE_TYPE_TEXT } from '../../translations.js';
7
8
  export const richTextColumnType = propertyType('rich-text');
8
9
  export const toYText = (text) => {
9
10
  if (text instanceof Text) {
@@ -12,7 +13,8 @@ export const toYText = (text) => {
12
13
  return text;
13
14
  };
14
15
  export const richTextPropertyModelConfig = richTextColumnType.modelConfig({
15
- name: 'Text',
16
+ name: DATABASE_TYPE_TEXT[1],
17
+ nameWording: DATABASE_TYPE_TEXT,
16
18
  propertyData: {
17
19
  schema: zod.object({}),
18
20
  default: () => ({}),
@@ -19,6 +19,7 @@ export const hostedTextColumnConfig = {
19
19
  config: {
20
20
  ...textPropertyConfig.config,
21
21
  name: richTextPropertyModelConfig.config.name,
22
+ nameWording: richTextPropertyModelConfig.config.nameWording,
22
23
  hide: false,
23
24
  },
24
25
  };
@@ -4,9 +4,11 @@ import { Doc } from 'yjs';
4
4
  import zod from 'zod';
5
5
  import { EditorHostKey } from '../../context/host-context.js';
6
6
  import { isLinkedDoc } from '../../utils/title-doc.js';
7
+ import { DATABASE_TYPE_TITLE } from '../../translations.js';
7
8
  export const titleColumnType = propertyType('title');
8
9
  export const titlePropertyModelConfig = titleColumnType.modelConfig({
9
- name: 'Title',
10
+ name: DATABASE_TYPE_TITLE[1],
11
+ nameWording: DATABASE_TYPE_TITLE,
10
12
  propertyData: {
11
13
  schema: zod.object({}),
12
14
  default: () => ({}),
@@ -18,6 +18,7 @@ import { titleColumnType, titlePropertyModelConfig } from './define.js';
18
18
  export const hostedTitlePropertyModelConfig = titleColumnType.modelConfig({
19
19
  // One wording and one data shape with the inline title column.
20
20
  name: titlePropertyModelConfig.config.name,
21
+ nameWording: titlePropertyModelConfig.config.nameWording,
21
22
  propertyData: titlePropertyModelConfig.config.propertyData,
22
23
  jsonValue: {
23
24
  schema: zod.string(),
@@ -41,7 +41,7 @@ export declare const DatabaseNewRowMenuProvider: import("../../global/di/types.j
41
41
  * say it does not.
42
42
  *
43
43
  * Absent or `null`, "New" is the single button of 0.48 in every view (table,
44
- * kanban, gallery, list, calendar) and on the full page: no chevron.
44
+ * kanban, gallery, list) and on the full page: no chevron.
45
45
  *
46
46
  * `di.override`, so a later registration wins and registering twice never
47
47
  * throws at boot.
@@ -5,7 +5,7 @@ export const DatabaseNewRowMenuProvider = createIdentifier('LabreDatabaseNewRowM
5
5
  * say it does not.
6
6
  *
7
7
  * Absent or `null`, "New" is the single button of 0.48 in every view (table,
8
- * kanban, gallery, list, calendar) and on the full page: no chevron.
8
+ * kanban, gallery, list) and on the full page: no chevron.
9
9
  *
10
10
  * `di.override`, so a later registration wins and registering twice never
11
11
  * throws at boot.
@@ -2,9 +2,38 @@ import type { ChromeWording } from '../affine-shared/services/index.js';
2
2
  /** Drawn in place of a view whose `sourceId` the host cannot resolve. */
3
3
  export declare const DATABASE_SOURCE_MISSING: ChromeWording;
4
4
  export declare const DATABASE_SOURCE_MISSING_HINT: ChromeWording;
5
+ /**
6
+ * Drawn in place of a database that waits for its source, when the host
7
+ * requires one (`requireSource`, ADR 0035 amendment of 2026-10-29).
8
+ */
9
+ export declare const DATABASE_SOURCE_REQUIRED: ChromeWording;
10
+ export declare const DATABASE_SOURCE_REQUIRED_HINT: ChromeWording;
11
+ /** Over native rows shown read-only, under the same host. */
12
+ export declare const DATABASE_SOURCE_REQUIRED_READ_ONLY: ChromeWording;
13
+ /**
14
+ * The creation popover's title (`@labre/affine-database-editor`) and the
15
+ * button of a database waiting for its source: one chrome word, one key,
16
+ * declared in core, the lowest reader.
17
+ */
18
+ export declare const DATABASE_CREATION_TITLE: ChromeWording;
19
+ /** Over native rows shown read-only: moves them into a new host database. */
20
+ export declare const DATABASE_MOVE_INTO_SOURCE: ChromeWording;
21
+ export declare const DATABASE_TURN_INTO_FAILED: ChromeWording;
22
+ export declare const DATABASE_TURN_INTO_NESTED: ChromeWording;
5
23
  /** After 3 s of loading (`VALUES_SLOW_AFTER_MS`). */
6
24
  export declare const DATABASE_VALUES_LOADING: ChromeWording;
7
25
  export declare const DATABASE_VALUES_ERROR: ChromeWording;
8
26
  /** The chevron beside "New", as its label and tooltip. */
9
27
  export declare const DATABASE_NEW_RECORD_MORE: ChromeWording;
28
+ export declare const DATABASE_TYPE_CREATED_TIME: ChromeWording;
29
+ export declare const DATABASE_TYPE_LINK: ChromeWording;
30
+ export declare const DATABASE_TYPE_TEXT: ChromeWording;
31
+ export declare const DATABASE_TYPE_TITLE: ChromeWording;
32
+ export declare const DATABASE_SLASH_TABLE_DESCRIPTION: ChromeWording;
33
+ export declare const DATABASE_SLASH_KANBAN_DESCRIPTION: ChromeWording;
34
+ export declare const DATABASE_TITLE_LABEL: ChromeWording;
35
+ export declare const DATABASE_DELETE: ChromeWording;
36
+ export declare const DATABASE_DRAG_PREVIEW: ChromeWording;
37
+ export declare const DATABASE_DETAIL_EMPTY_HINT: ChromeWording;
38
+ export declare const DATABASE_SLASH_TODO: ChromeWording;
10
39
  export declare const DATABASE_WORDINGS: readonly ChromeWording[];
@@ -8,6 +8,46 @@ export const DATABASE_SOURCE_MISSING_HINT = [
8
8
  'com.labre.database.source-missing.hint',
9
9
  'The source this view reads was deleted or cannot be reached. Pick another view.',
10
10
  ];
11
+ /**
12
+ * Drawn in place of a database that waits for its source, when the host
13
+ * requires one (`requireSource`, ADR 0035 amendment of 2026-10-29).
14
+ */
15
+ export const DATABASE_SOURCE_REQUIRED = [
16
+ 'com.labre.database.source-required',
17
+ 'No source connected',
18
+ ];
19
+ export const DATABASE_SOURCE_REQUIRED_HINT = [
20
+ 'com.labre.database.source-required.hint',
21
+ 'Connect a source to show its rows here.',
22
+ ];
23
+ /** Over native rows shown read-only, under the same host. */
24
+ export const DATABASE_SOURCE_REQUIRED_READ_ONLY = [
25
+ 'com.labre.database.source-required.read-only',
26
+ 'This table has no source: its rows are read-only.',
27
+ ];
28
+ /**
29
+ * The creation popover's title (`@labre/affine-database-editor`) and the
30
+ * button of a database waiting for its source: one chrome word, one key,
31
+ * declared in core, the lowest reader.
32
+ */
33
+ export const DATABASE_CREATION_TITLE = [
34
+ 'com.labre.database.creation.title',
35
+ 'Connect a source',
36
+ ];
37
+ /* ── Turning a table into a source (ADR 0035, amendment of 2026-10-29) ── */
38
+ /** Over native rows shown read-only: moves them into a new host database. */
39
+ export const DATABASE_MOVE_INTO_SOURCE = [
40
+ 'com.labre.database.turn-into.move',
41
+ 'Move into a database',
42
+ ];
43
+ export const DATABASE_TURN_INTO_FAILED = [
44
+ 'com.labre.database.turn-into.failed',
45
+ 'The table could not be created. Nothing was changed.',
46
+ ];
47
+ export const DATABASE_TURN_INTO_NESTED = [
48
+ 'com.labre.database.turn-into.nested',
49
+ 'Rows with nested blocks cannot be moved here. Nothing was changed.',
50
+ ];
11
51
  /* ── Cell hydration (ADR 0035 §9e, issue B2) ───────────────────────────── */
12
52
  /** After 3 s of loading (`VALUES_SLOW_AFTER_MS`). */
13
53
  export const DATABASE_VALUES_LOADING = [
@@ -26,10 +66,74 @@ export const DATABASE_NEW_RECORD_MORE = [
26
66
  'com.labre.database.new-record.more',
27
67
  'Templates and options',
28
68
  ];
69
+ /* ── Database chrome keyed at the recette of 1.1 (#572) ── */
70
+ export const DATABASE_TYPE_CREATED_TIME = [
71
+ 'com.labre.database.property-type.created-time',
72
+ 'Created Time',
73
+ ];
74
+ export const DATABASE_TYPE_LINK = [
75
+ 'com.labre.database.property-type.link',
76
+ 'Link',
77
+ ];
78
+ export const DATABASE_TYPE_TEXT = [
79
+ 'com.labre.database.property-type.text',
80
+ 'Text',
81
+ ];
82
+ export const DATABASE_TYPE_TITLE = [
83
+ 'com.labre.database.property-type.title',
84
+ 'Title',
85
+ ];
86
+ export const DATABASE_SLASH_TABLE_DESCRIPTION = [
87
+ 'com.labre.database.slash.table.description',
88
+ 'Display items in a table format.',
89
+ ];
90
+ export const DATABASE_SLASH_KANBAN_DESCRIPTION = [
91
+ 'com.labre.database.slash.kanban.description',
92
+ 'Visualize data in a dashboard.',
93
+ ];
94
+ export const DATABASE_TITLE_LABEL = [
95
+ 'com.labre.database.title.label',
96
+ 'Database title',
97
+ ];
98
+ export const DATABASE_DELETE = [
99
+ 'com.labre.database.delete',
100
+ 'Delete Database',
101
+ ];
102
+ export const DATABASE_DRAG_PREVIEW = [
103
+ 'com.labre.database.drag-preview',
104
+ 'Database Block',
105
+ ];
106
+ export const DATABASE_DETAIL_EMPTY_HINT = [
107
+ 'com.labre.database.detail.empty-hint',
108
+ 'Click to create a linked doc in center peek.',
109
+ ];
110
+ /* ── The data-view block's slash entry ── */
111
+ export const DATABASE_SLASH_TODO = [
112
+ 'com.labre.database.slash.todo',
113
+ 'Todo',
114
+ ];
29
115
  export const DATABASE_WORDINGS = [
116
+ DATABASE_CREATION_TITLE,
117
+ DATABASE_MOVE_INTO_SOURCE,
30
118
  DATABASE_NEW_RECORD_MORE,
31
119
  DATABASE_SOURCE_MISSING,
32
120
  DATABASE_SOURCE_MISSING_HINT,
121
+ DATABASE_SOURCE_REQUIRED,
122
+ DATABASE_SOURCE_REQUIRED_HINT,
123
+ DATABASE_SOURCE_REQUIRED_READ_ONLY,
124
+ DATABASE_TURN_INTO_FAILED,
125
+ DATABASE_TURN_INTO_NESTED,
33
126
  DATABASE_VALUES_ERROR,
34
127
  DATABASE_VALUES_LOADING,
128
+ DATABASE_TYPE_CREATED_TIME,
129
+ DATABASE_TYPE_LINK,
130
+ DATABASE_TYPE_TEXT,
131
+ DATABASE_TYPE_TITLE,
132
+ DATABASE_SLASH_TABLE_DESCRIPTION,
133
+ DATABASE_SLASH_KANBAN_DESCRIPTION,
134
+ DATABASE_TITLE_LABEL,
135
+ DATABASE_DELETE,
136
+ DATABASE_DRAG_PREVIEW,
137
+ DATABASE_DETAIL_EMPTY_HINT,
138
+ DATABASE_SLASH_TODO,
35
139
  ];
@@ -0,0 +1,38 @@
1
+ import type { DatabaseBlockModel } from '../affine-model/index.js';
2
+ import { type DataSourcePickerContent } from '../affine-shared/services/index.js';
3
+ import type { BlockStdScope } from '../std/index.js';
4
+ import type { BlockModel } from '../store/index.js';
5
+ /**
6
+ * "Turn into a source" (ADR 0035 amendment of 2026-10-29): under a host that
7
+ * requires a source (`requireSource`), "Create Table" on selected paragraphs
8
+ * and "Move into a database" on a database with native rows hand their
9
+ * content to the host's `createDatabaseFrom`, then connect the block to the
10
+ * database it answers, in one undo step. Nothing is written until the host
11
+ * answers; a refusal, a rejection, a read-only document or content changed
12
+ * in the meantime writes nothing and says so with a fixed message.
13
+ */
14
+ /** The id of the title property a conversion of paragraphs sends. */
15
+ export declare const TURN_INTO_TITLE_PROPERTY = "title";
16
+ /** The blocks, less those nested in another of them: they ride in its body. */
17
+ export declare function outermostBlocks(blocks: readonly BlockModel[]): BlockModel[];
18
+ /** One row per block, its title the block's text, its body its children. */
19
+ export declare function blocksContent(std: BlockStdScope, blocks: readonly BlockModel[]): DataSourcePickerContent;
20
+ /**
21
+ * A native database's columns and rows. A value is sent as stored, a rich
22
+ * text as its delta; the title column is the row's own text.
23
+ */
24
+ export declare function databaseContent(std: BlockStdScope, model: DatabaseBlockModel): DataSourcePickerContent;
25
+ /** Whether the host turns content into a source where one is required. */
26
+ export declare function canTurnIntoSource(std: BlockStdScope): boolean;
27
+ /**
28
+ * "Create Table" under a host that requires a source: the selected blocks
29
+ * become the rows of a new host database, and a view of its first source
30
+ * takes their place. Returns whether it was written.
31
+ */
32
+ export declare function turnBlocksIntoSource(std: BlockStdScope, selected: readonly BlockModel[], viewType: string): Promise<boolean>;
33
+ /**
34
+ * "Move into a database" over native rows shown read-only: the database's
35
+ * columns and rows become a new host database, and the block reads its
36
+ * first source (`moveDatabaseIntoSource`). Returns whether it was written.
37
+ */
38
+ export declare function moveDatabaseRowsIntoSource(std: BlockStdScope, model: DatabaseBlockModel): Promise<boolean>;