@formicoidea/labre-core 0.47.1 → 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 (239) 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 +48 -4
  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-block-embed-doc/embed-linked-doc-block/configs/new-doc.d.ts +25 -0
  46. package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/new-doc.js +71 -0
  47. package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/slash-menu.js +3 -11
  48. package/dist/_pkgs/affine-components/date-picker/date-picker.d.ts +20 -0
  49. package/dist/_pkgs/affine-components/date-picker/date-picker.js +60 -26
  50. package/dist/_pkgs/affine-components/date-picker/style.js +1 -0
  51. package/dist/_pkgs/affine-components/translations.d.ts +4 -0
  52. package/dist/_pkgs/affine-components/translations.js +26 -0
  53. package/dist/_pkgs/affine-fragment-doc-title/doc-title.d.ts +18 -0
  54. package/dist/_pkgs/affine-fragment-doc-title/doc-title.js +41 -2
  55. package/dist/_pkgs/affine-fragment-doc-title/index.d.ts +1 -1
  56. package/dist/_pkgs/affine-fragment-doc-title/index.js +1 -1
  57. package/dist/_pkgs/affine-fragment-doc-title/title-band/band-cell.d.ts +30 -0
  58. package/dist/_pkgs/affine-fragment-doc-title/title-band/band-cell.js +137 -0
  59. package/dist/_pkgs/affine-fragment-doc-title/title-band/format.d.ts +7 -19
  60. package/dist/_pkgs/affine-fragment-doc-title/title-band/format.js +0 -38
  61. package/dist/_pkgs/affine-fragment-doc-title/title-band/show-here.d.ts +19 -0
  62. package/dist/_pkgs/affine-fragment-doc-title/title-band/show-here.js +61 -0
  63. package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.d.ts +33 -18
  64. package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.js +263 -205
  65. package/dist/_pkgs/affine-fragment-doc-title/translations.d.ts +7 -4
  66. package/dist/_pkgs/affine-fragment-doc-title/translations.js +12 -9
  67. package/dist/_pkgs/affine-model/blocks/database/types.d.ts +16 -0
  68. package/dist/_pkgs/affine-model/blocks/database/types.js +5 -1
  69. package/dist/_pkgs/affine-shared/services/data-source-picker-service.d.ts +139 -0
  70. package/dist/_pkgs/affine-shared/services/data-source-picker-service.js +22 -0
  71. package/dist/_pkgs/affine-shared/services/index.d.ts +1 -0
  72. package/dist/_pkgs/affine-shared/services/index.js +1 -0
  73. package/dist/_pkgs/affine-shared/services/linked-doc-creation-service.d.ts +15 -6
  74. package/dist/_pkgs/affine-shared/services/telemetry-service/database.d.ts +59 -0
  75. package/dist/_pkgs/affine-shared/services/title-band-service.d.ts +34 -7
  76. package/dist/_pkgs/affine-shared/utils/model/doc.d.ts +10 -2
  77. package/dist/_pkgs/affine-shared/utils/model/doc.js +17 -7
  78. package/dist/_pkgs/data-view/core/component/cell-status/cell-status-css.d.ts +2 -0
  79. package/dist/_pkgs/data-view/core/component/cell-status/cell-status-css.js +16 -0
  80. package/dist/_pkgs/data-view/core/component/cell-status/cell-status.d.ts +10 -0
  81. package/dist/_pkgs/data-view/core/component/cell-status/cell-status.js +23 -0
  82. package/dist/_pkgs/data-view/core/component/index.d.ts +1 -0
  83. package/dist/_pkgs/data-view/core/component/index.js +1 -0
  84. package/dist/_pkgs/data-view/core/component/overflow/fit.d.ts +26 -0
  85. package/dist/_pkgs/data-view/core/component/overflow/fit.js +48 -0
  86. package/dist/_pkgs/data-view/core/component/overflow/overflow.d.ts +26 -3
  87. package/dist/_pkgs/data-view/core/component/overflow/overflow.js +84 -31
  88. package/dist/_pkgs/data-view/core/component/tags/colors.d.ts +7 -0
  89. package/dist/_pkgs/data-view/core/component/tags/colors.js +22 -10
  90. package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.d.ts +25 -2
  91. package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.js +81 -32
  92. package/dist/_pkgs/data-view/core/data-source/base.d.ts +5 -1
  93. package/dist/_pkgs/data-view/core/data-source/base.js +7 -1
  94. package/dist/_pkgs/data-view/core/data-source/hydration.d.ts +44 -0
  95. package/dist/_pkgs/data-view/core/data-source/hydration.js +31 -0
  96. package/dist/_pkgs/data-view/core/data-source/index.d.ts +1 -0
  97. package/dist/_pkgs/data-view/core/data-source/index.js +1 -0
  98. package/dist/_pkgs/data-view/core/data-view.d.ts +22 -2
  99. package/dist/_pkgs/data-view/core/data-view.js +14 -0
  100. package/dist/_pkgs/data-view/core/effect.js +4 -0
  101. package/dist/_pkgs/data-view/core/group-by/collapsed-state.d.ts +3 -0
  102. package/dist/_pkgs/data-view/core/group-by/collapsed-state.js +59 -0
  103. package/dist/_pkgs/data-view/core/group-by/group-properties.d.ts +21 -0
  104. package/dist/_pkgs/data-view/core/group-by/group-properties.js +38 -0
  105. package/dist/_pkgs/data-view/core/group-by/group-title.js +4 -0
  106. package/dist/_pkgs/data-view/core/group-by/group-visibility.d.ts +40 -0
  107. package/dist/_pkgs/data-view/core/group-by/group-visibility.js +291 -0
  108. package/dist/_pkgs/data-view/core/group-by/setting.d.ts +11 -3
  109. package/dist/_pkgs/data-view/core/group-by/setting.js +81 -8
  110. package/dist/_pkgs/data-view/core/group-by/trait.d.ts +22 -0
  111. package/dist/_pkgs/data-view/core/group-by/trait.js +62 -1
  112. package/dist/_pkgs/data-view/core/index.d.ts +3 -0
  113. package/dist/_pkgs/data-view/core/index.js +3 -0
  114. package/dist/_pkgs/data-view/core/property/base-cell.d.ts +15 -1
  115. package/dist/_pkgs/data-view/core/property/base-cell.js +28 -3
  116. package/dist/_pkgs/data-view/core/property/index.d.ts +1 -0
  117. package/dist/_pkgs/data-view/core/property/index.js +1 -0
  118. package/dist/_pkgs/data-view/core/property/standalone-cell.d.ts +109 -0
  119. package/dist/_pkgs/data-view/core/property/standalone-cell.js +324 -0
  120. package/dist/_pkgs/data-view/core/telemetry.d.ts +16 -0
  121. package/dist/_pkgs/data-view/core/telemetry.js +22 -0
  122. package/dist/_pkgs/data-view/core/utils/new-tab-click.d.ts +2 -0
  123. package/dist/_pkgs/data-view/core/utils/new-tab-click.js +4 -0
  124. package/dist/_pkgs/data-view/core/utils/wording.d.ts +11 -0
  125. package/dist/_pkgs/data-view/core/utils/wording.js +9 -0
  126. package/dist/_pkgs/data-view/core/view/data-view.d.ts +7 -0
  127. package/dist/_pkgs/data-view/core/view/default-name.d.ts +10 -0
  128. package/dist/_pkgs/data-view/core/view/default-name.js +14 -0
  129. package/dist/_pkgs/data-view/core/view/index.d.ts +2 -0
  130. package/dist/_pkgs/data-view/core/view/index.js +2 -0
  131. package/dist/_pkgs/data-view/core/view/open-in.d.ts +27 -0
  132. package/dist/_pkgs/data-view/core/view/open-in.js +39 -0
  133. package/dist/_pkgs/data-view/core/view-manager/cell.d.ts +5 -0
  134. package/dist/_pkgs/data-view/core/view-manager/cell.js +11 -0
  135. package/dist/_pkgs/data-view/core/view-manager/index.d.ts +3 -0
  136. package/dist/_pkgs/data-view/core/view-manager/index.js +3 -0
  137. package/dist/_pkgs/data-view/core/view-manager/new-row-menu-opener.d.ts +18 -0
  138. package/dist/_pkgs/data-view/core/view-manager/new-row-menu-opener.js +2 -0
  139. package/dist/_pkgs/data-view/core/view-manager/properties-panel-opener.d.ts +8 -0
  140. package/dist/_pkgs/data-view/core/view-manager/properties-panel-opener.js +9 -0
  141. package/dist/_pkgs/data-view/core/view-manager/property.d.ts +14 -0
  142. package/dist/_pkgs/data-view/core/view-manager/single-view.d.ts +28 -1
  143. package/dist/_pkgs/data-view/core/view-manager/single-view.js +45 -1
  144. package/dist/_pkgs/data-view/core/view-manager/view-creation.d.ts +49 -0
  145. package/dist/_pkgs/data-view/core/view-manager/view-creation.js +40 -0
  146. package/dist/_pkgs/data-view/core/view-manager/view-manager.d.ts +6 -2
  147. package/dist/_pkgs/data-view/core/view-manager/view-manager.js +2 -2
  148. package/dist/_pkgs/data-view/property-presets/date/cell-renderer.d.ts +2 -0
  149. package/dist/_pkgs/data-view/property-presets/date/cell-renderer.js +11 -2
  150. package/dist/_pkgs/data-view/property-presets/multi-select/cell-renderer.js +3 -1
  151. package/dist/_pkgs/data-view/property-presets/select/cell-renderer.js +3 -1
  152. package/dist/_pkgs/data-view/property-presets/text/cell-renderer.js +3 -1
  153. package/dist/_pkgs/data-view/translations.d.ts +55 -0
  154. package/dist/_pkgs/data-view/translations.js +181 -0
  155. package/dist/_pkgs/data-view/view-presets/calendar/define.js +3 -1
  156. package/dist/_pkgs/data-view/view-presets/convert.js +2 -0
  157. package/dist/_pkgs/data-view/view-presets/effect.js +4 -0
  158. package/dist/_pkgs/data-view/view-presets/flat/flat-converts.d.ts +2 -0
  159. package/dist/_pkgs/data-view/view-presets/flat/flat-converts.js +35 -0
  160. package/dist/_pkgs/data-view/view-presets/flat/flat-view-manager.d.ts +79 -0
  161. package/dist/_pkgs/data-view/view-presets/flat/flat-view-manager.js +194 -0
  162. package/dist/_pkgs/data-view/view-presets/flat/flat-view-ui.d.ts +56 -0
  163. package/dist/_pkgs/data-view/view-presets/flat/flat-view-ui.js +266 -0
  164. package/dist/_pkgs/data-view/view-presets/gallery/define.d.ts +14 -0
  165. package/dist/_pkgs/data-view/view-presets/gallery/define.js +15 -0
  166. package/dist/_pkgs/data-view/view-presets/gallery/effect.d.ts +1 -0
  167. package/dist/_pkgs/data-view/view-presets/gallery/effect.js +4 -0
  168. package/dist/_pkgs/data-view/view-presets/gallery/gallery-view.d.ts +27 -0
  169. package/dist/_pkgs/data-view/view-presets/gallery/gallery-view.js +179 -0
  170. package/dist/_pkgs/data-view/view-presets/gallery/index.d.ts +2 -0
  171. package/dist/_pkgs/data-view/view-presets/gallery/index.js +2 -0
  172. package/dist/_pkgs/data-view/view-presets/gallery/renderer.d.ts +1 -0
  173. package/dist/_pkgs/data-view/view-presets/gallery/renderer.js +11 -0
  174. package/dist/_pkgs/data-view/view-presets/index.d.ts +5 -0
  175. package/dist/_pkgs/data-view/view-presets/index.js +7 -0
  176. package/dist/_pkgs/data-view/view-presets/kanban/define.js +3 -1
  177. package/dist/_pkgs/data-view/view-presets/kanban/kanban-view-manager.js +5 -53
  178. package/dist/_pkgs/data-view/view-presets/kanban/mobile/card.js +8 -1
  179. package/dist/_pkgs/data-view/view-presets/kanban/mobile/cell.js +6 -1
  180. package/dist/_pkgs/data-view/view-presets/kanban/mobile/group.d.ts +4 -2
  181. package/dist/_pkgs/data-view/view-presets/kanban/mobile/group.js +52 -6
  182. package/dist/_pkgs/data-view/view-presets/kanban/mobile/kanban-view-ui-logic.js +5 -1
  183. package/dist/_pkgs/data-view/view-presets/kanban/pc/card.js +2 -0
  184. package/dist/_pkgs/data-view/view-presets/kanban/pc/cell.js +4 -0
  185. package/dist/_pkgs/data-view/view-presets/kanban/pc/group.d.ts +4 -2
  186. package/dist/_pkgs/data-view/view-presets/kanban/pc/group.js +51 -6
  187. package/dist/_pkgs/data-view/view-presets/kanban/pc/kanban-view-ui-logic.js +5 -1
  188. package/dist/_pkgs/data-view/view-presets/list/define.d.ts +14 -0
  189. package/dist/_pkgs/data-view/view-presets/list/define.js +15 -0
  190. package/dist/_pkgs/data-view/view-presets/list/effect.d.ts +1 -0
  191. package/dist/_pkgs/data-view/view-presets/list/effect.js +4 -0
  192. package/dist/_pkgs/data-view/view-presets/list/index.d.ts +2 -0
  193. package/dist/_pkgs/data-view/view-presets/list/index.js +2 -0
  194. package/dist/_pkgs/data-view/view-presets/list/list-view.d.ts +24 -0
  195. package/dist/_pkgs/data-view/view-presets/list/list-view.js +194 -0
  196. package/dist/_pkgs/data-view/view-presets/list/renderer.d.ts +1 -0
  197. package/dist/_pkgs/data-view/view-presets/list/renderer.js +11 -0
  198. package/dist/_pkgs/data-view/view-presets/table/collapsed-state.d.ts +3 -14
  199. package/dist/_pkgs/data-view/view-presets/table/collapsed-state.js +6 -30
  200. package/dist/_pkgs/data-view/view-presets/table/consts.d.ts +2 -0
  201. package/dist/_pkgs/data-view/view-presets/table/consts.js +2 -0
  202. package/dist/_pkgs/data-view/view-presets/table/define.js +3 -1
  203. package/dist/_pkgs/data-view/view-presets/table/mobile/cell.js +4 -1
  204. package/dist/_pkgs/data-view/view-presets/table/mobile/column-header.js +2 -2
  205. package/dist/_pkgs/data-view/view-presets/table/mobile/group.d.ts +3 -1
  206. package/dist/_pkgs/data-view/view-presets/table/mobile/group.js +20 -5
  207. package/dist/_pkgs/data-view/view-presets/table/mobile/row.js +10 -2
  208. package/dist/_pkgs/data-view/view-presets/table/mobile/table-view-ui-logic.js +4 -1
  209. package/dist/_pkgs/data-view/view-presets/table/pc/cell.js +4 -1
  210. package/dist/_pkgs/data-view/view-presets/table/pc/controller/hotkeys.js +1 -1
  211. package/dist/_pkgs/data-view/view-presets/table/pc/group.d.ts +3 -1
  212. package/dist/_pkgs/data-view/view-presets/table/pc/group.js +20 -5
  213. package/dist/_pkgs/data-view/view-presets/table/pc/menu.d.ts +1 -1
  214. package/dist/_pkgs/data-view/view-presets/table/pc/menu.js +2 -1
  215. package/dist/_pkgs/data-view/view-presets/table/pc/row/row.js +3 -2
  216. package/dist/_pkgs/data-view/view-presets/table/pc/table-view-ui-logic.js +4 -1
  217. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/controller/hotkeys.js +1 -1
  218. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/bottom/stats/column-stats-column.js +5 -1
  219. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/top/group-title.js +22 -19
  220. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/row/cell.js +4 -1
  221. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/table-view-ui-logic.js +7 -2
  222. package/dist/_pkgs/data-view/view-presets/table/stats/column-stats-column.js +5 -1
  223. package/dist/_pkgs/data-view/view-presets/table/table-view-manager.js +5 -53
  224. package/dist/_pkgs/data-view/widget-presets/tools/presets/table-add-row/add-row.d.ts +1 -0
  225. package/dist/_pkgs/data-view/widget-presets/tools/presets/table-add-row/add-row.js +60 -2
  226. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-options.d.ts +18 -1
  227. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-options.js +121 -124
  228. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-settings.d.ts +43 -0
  229. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-settings.js +187 -0
  230. package/dist/_pkgs/data-view/widget-presets/views-bar/views-view.d.ts +36 -3
  231. package/dist/_pkgs/data-view/widget-presets/views-bar/views-view.js +187 -59
  232. package/dist/extensions/view.d.ts +2 -2
  233. package/dist/extensions/view.js +10 -3
  234. package/dist/flags.d.ts +8 -4
  235. package/dist/flags.js +8 -4
  236. package/dist/frameworks.d.ts +27 -0
  237. package/dist/frameworks.js +28 -0
  238. package/dist/translations.js +13 -1
  239. package/package.json +5 -1
@@ -33,6 +33,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
33
33
  return useValue ? value : void 0;
34
34
  };
35
35
  import { createPopup, menu, popMenu, popupTargetFromElement, } from '../../../../affine-components/context-menu/index.js';
36
+ import { TOOLBAR_DELETE, } from '../../../../affine-shared/services/index.js';
36
37
  import { unsafeCSSVarV2 } from '../../../../affine-shared/theme/index.js';
37
38
  import { rangeWrap } from '../../../../affine-shared/utils/index.js';
38
39
  import { IS_MOBILE } from '../../../../global/env/index.js';
@@ -50,6 +51,7 @@ import { createRef, ref } from 'lit/directives/ref.js';
50
51
  import { repeat } from 'lit/directives/repeat.js';
51
52
  import { styleMap } from 'lit/directives/style-map.js';
52
53
  import { html } from 'lit/static-html.js';
54
+ import { TAG_SELECT_CREATE, TAG_SELECT_PLACEHOLDER, TAG_SELECT_TIP, } from '../../../translations.js';
53
55
  import { stopPropagation } from '../../utils/event.js';
54
56
  import { dragHandler } from '../../utils/wc-dnd/dnd-context.js';
55
57
  import { defaultActivators } from '../../utils/wc-dnd/sensors/index.js';
@@ -58,6 +60,7 @@ import { verticalListSortingStrategy } from '../../utils/wc-dnd/sort/strategies/
58
60
  import { arrayMove } from '../../utils/wc-dnd/utils/array-move.js';
59
61
  import { getTagColor, selectOptionColors } from './colors.js';
60
62
  import { selectedStyle, selectOptionContentStyle, selectOptionDragHandlerStyle, selectOptionIconStyle, selectOptionNewIconStyle, selectOptionsContainerStyle, selectOptionsTipsStyle, selectOptionStyle, tagContainerStyle, tagDeleteIconStyle, tagSelectContainerStyle, tagSelectInputContainerStyle, tagSelectInputStyle, tagTextStyle, } from './styles-css.js';
63
+ const englishWording = (wording) => wording[1];
61
64
  // Parent elements that can hand over a tag draft typed in the table.
62
65
  const TABLE_CELL_HOST_SELECTOR = 'dv-table-view-cell-container, affine-database-virtual-cell-container';
63
66
  export function consumeTagDraftFromTableCellHost(fromElement) {
@@ -77,7 +80,7 @@ class TagManager {
77
80
  constructor(ops) {
78
81
  this.ops = ops;
79
82
  this.changeTag = (option) => {
80
- this.ops.onOptionsChange(this.ops.options.value.map(item => {
83
+ this.ops.onOptionsChange?.(this.ops.options.value.map(item => {
81
84
  if (item.id === option.id) {
82
85
  return {
83
86
  ...item,
@@ -90,7 +93,7 @@ class TagManager {
90
93
  this.color$ = signal(getTagColor());
91
94
  this.createOption = () => {
92
95
  const value = this.text$.value.trim();
93
- if (value === '')
96
+ if (value === '' || !this.ops.onOptionsChange)
94
97
  return;
95
98
  const id = nanoid();
96
99
  this.ops.onOptionsChange([
@@ -109,7 +112,7 @@ class TagManager {
109
112
  }
110
113
  };
111
114
  this.deleteOption = (id) => {
112
- this.ops.onOptionsChange(this.ops.options.value.filter(item => item.id !== id));
115
+ this.ops.onOptionsChange?.(this.ops.options.value.filter(item => item.id !== id));
113
116
  };
114
117
  this.filteredOptions$ = computed(() => {
115
118
  let matched = false;
@@ -129,7 +132,7 @@ class TagManager {
129
132
  matched = true;
130
133
  }
131
134
  }
132
- if (this.text$.value && !matched) {
135
+ if (this.text$.value && !matched && this.ops.onOptionsChange) {
133
136
  options.push({
134
137
  id: 'create',
135
138
  color: this.color$.value,
@@ -179,6 +182,9 @@ let MultiTagSelect = (() => {
179
182
  let _onOptionsChange_decorators;
180
183
  let _onOptionsChange_initializers = [];
181
184
  let _onOptionsChange_extraInitializers = [];
185
+ let _optionEdits_decorators;
186
+ let _optionEdits_initializers = [];
187
+ let _optionEdits_extraInitializers = [];
182
188
  let _options_decorators;
183
189
  let _options_initializers = [];
184
190
  let _options_extraInitializers = [];
@@ -188,6 +194,9 @@ let MultiTagSelect = (() => {
188
194
  let _initialDraftText_decorators;
189
195
  let _initialDraftText_initializers = [];
190
196
  let _initialDraftText_extraInitializers = [];
197
+ let _wording_decorators;
198
+ let _wording_initializers = [];
199
+ let _wording_extraInitializers = [];
191
200
  return class MultiTagSelect extends _classSuper {
192
201
  static {
193
202
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
@@ -195,16 +204,20 @@ let MultiTagSelect = (() => {
195
204
  _onChange_decorators = [property({ attribute: false })];
196
205
  _onComplete_decorators = [property({ attribute: false })];
197
206
  _onOptionsChange_decorators = [property({ attribute: false })];
207
+ _optionEdits_decorators = [property({ attribute: false })];
198
208
  _options_decorators = [property({ attribute: false })];
199
209
  _value_decorators = [property({ attribute: false })];
200
210
  _initialDraftText_decorators = [property({ attribute: false })];
211
+ _wording_decorators = [property({ attribute: false })];
201
212
  __esDecorate(this, null, _mode_decorators, { kind: "accessor", name: "mode", static: false, private: false, access: { has: obj => "mode" in obj, get: obj => obj.mode, set: (obj, value) => { obj.mode = value; } }, metadata: _metadata }, _mode_initializers, _mode_extraInitializers);
202
213
  __esDecorate(this, null, _onChange_decorators, { kind: "accessor", name: "onChange", static: false, private: false, access: { has: obj => "onChange" in obj, get: obj => obj.onChange, set: (obj, value) => { obj.onChange = value; } }, metadata: _metadata }, _onChange_initializers, _onChange_extraInitializers);
203
214
  __esDecorate(this, null, _onComplete_decorators, { kind: "accessor", name: "onComplete", static: false, private: false, access: { has: obj => "onComplete" in obj, get: obj => obj.onComplete, set: (obj, value) => { obj.onComplete = value; } }, metadata: _metadata }, _onComplete_initializers, _onComplete_extraInitializers);
204
215
  __esDecorate(this, null, _onOptionsChange_decorators, { kind: "accessor", name: "onOptionsChange", static: false, private: false, access: { has: obj => "onOptionsChange" in obj, get: obj => obj.onOptionsChange, set: (obj, value) => { obj.onOptionsChange = value; } }, metadata: _metadata }, _onOptionsChange_initializers, _onOptionsChange_extraInitializers);
216
+ __esDecorate(this, null, _optionEdits_decorators, { kind: "accessor", name: "optionEdits", static: false, private: false, access: { has: obj => "optionEdits" in obj, get: obj => obj.optionEdits, set: (obj, value) => { obj.optionEdits = value; } }, metadata: _metadata }, _optionEdits_initializers, _optionEdits_extraInitializers);
205
217
  __esDecorate(this, null, _options_decorators, { kind: "accessor", name: "options", static: false, private: false, access: { has: obj => "options" in obj, get: obj => obj.options, set: (obj, value) => { obj.options = value; } }, metadata: _metadata }, _options_initializers, _options_extraInitializers);
206
218
  __esDecorate(this, null, _value_decorators, { kind: "accessor", name: "value", static: false, private: false, access: { has: obj => "value" in obj, get: obj => obj.value, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, _value_initializers, _value_extraInitializers);
207
219
  __esDecorate(this, null, _initialDraftText_decorators, { kind: "accessor", name: "initialDraftText", static: false, private: false, access: { has: obj => "initialDraftText" in obj, get: obj => obj.initialDraftText, set: (obj, value) => { obj.initialDraftText = value; } }, metadata: _metadata }, _initialDraftText_initializers, _initialDraftText_extraInitializers);
220
+ __esDecorate(this, null, _wording_decorators, { kind: "accessor", name: "wording", static: false, private: false, access: { has: obj => "wording" in obj, get: obj => obj.wording, set: (obj, value) => { obj.wording = value; } }, metadata: _metadata }, _wording_initializers, _wording_extraInitializers);
208
221
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
209
222
  }
210
223
  get text() {
@@ -223,7 +236,7 @@ let MultiTagSelect = (() => {
223
236
  <input
224
237
  class="${tagSelectInputStyle}"
225
238
  ${ref(this._selectInput)}
226
- placeholder="Type here..."
239
+ placeholder="${this.say(TAG_SELECT_PLACEHOLDER)}"
227
240
  .value="${this.text.value}"
228
241
  @input="${this._onInput}"
229
242
  @keydown="${this._onInputKeydown}"
@@ -246,11 +259,17 @@ let MultiTagSelect = (() => {
246
259
  </div>`;
247
260
  }
248
261
  renderTags() {
262
+ const editable = !!this.onOptionsChange;
263
+ const reorderable = editable && this.optionEdits === 'all';
249
264
  return html `
250
265
  <div
251
266
  style="height: 0.5px;background-color: ${cssVarV2('layer/insideBorder/border')};margin: 4px 0;"
252
267
  ></div>
253
- <div class="${selectOptionsTipsStyle}">Select tag or create one</div>
268
+ ${editable
269
+ ? html `<div class="${selectOptionsTipsStyle}">
270
+ ${this.say(TAG_SELECT_TIP)}
271
+ </div>`
272
+ : nothing}
254
273
  <div data-testid="tag-option-list" class="${selectOptionsContainerStyle}">
255
274
  ${repeat(this.tagManager.filteredOptions$.value, select => select.id, (select, index) => {
256
275
  const isSelected = index === this.selectedIndex$.value;
@@ -267,7 +286,9 @@ let MultiTagSelect = (() => {
267
286
  };
268
287
  return html `
269
288
  <div
270
- ${!select.isCreate ? sortable(select.id) : nothing}
289
+ ${reorderable && !select.isCreate
290
+ ? sortable(select.id)
291
+ : nothing}
271
292
  class="${classes}"
272
293
  @mouseenter="${mouseenter}"
273
294
  @click="${select.select}"
@@ -275,17 +296,19 @@ let MultiTagSelect = (() => {
275
296
  <div class="${selectOptionContentStyle}">
276
297
  ${select.isCreate
277
298
  ? html ` <div class="${selectOptionNewIconStyle}">
278
- Create
299
+ ${this.say(TAG_SELECT_CREATE)}
279
300
  </div>`
280
- : html `
281
- <div
282
- ${dragHandler(select.id)}
283
- class="${selectOptionDragHandlerStyle}"
284
- ></div>
285
- `}
301
+ : reorderable
302
+ ? html `
303
+ <div
304
+ ${dragHandler(select.id)}
305
+ class="${selectOptionDragHandlerStyle}"
306
+ ></div>
307
+ `
308
+ : nothing}
286
309
  ${this.renderTag(select.value, select.color)}
287
310
  </div>
288
- ${!select.isCreate
311
+ ${editable && !select.isCreate
289
312
  ? html ` <div
290
313
  class="${selectOptionIconStyle}"
291
314
  @click="${clickOption}"
@@ -343,6 +366,9 @@ let MultiTagSelect = (() => {
343
366
  #onOptionsChange_accessor_storage;
344
367
  get onOptionsChange() { return this.#onOptionsChange_accessor_storage; }
345
368
  set onOptionsChange(value) { this.#onOptionsChange_accessor_storage = value; }
369
+ #optionEdits_accessor_storage;
370
+ get optionEdits() { return this.#optionEdits_accessor_storage; }
371
+ set optionEdits(value) { this.#optionEdits_accessor_storage = value; }
346
372
  #options_accessor_storage;
347
373
  get options() { return this.#options_accessor_storage; }
348
374
  set options(value) { this.#options_accessor_storage = value; }
@@ -352,6 +378,12 @@ let MultiTagSelect = (() => {
352
378
  #initialDraftText_accessor_storage;
353
379
  get initialDraftText() { return this.#initialDraftText_accessor_storage; }
354
380
  set initialDraftText(value) { this.#initialDraftText_accessor_storage = value; }
381
+ #wording_accessor_storage;
382
+ get wording() { return this.#wording_accessor_storage; }
383
+ set wording(value) { this.#wording_accessor_storage = value; }
384
+ say(wording) {
385
+ return (this.wording ?? englishWording)(wording);
386
+ }
355
387
  constructor() {
356
388
  super(...arguments);
357
389
  this._clickItemOption = (e, id) => {
@@ -360,20 +392,27 @@ let MultiTagSelect = (() => {
360
392
  if (!option) {
361
393
  return;
362
394
  }
395
+ const rename = menu.input({
396
+ initialValue: option.value,
397
+ onChange: text => {
398
+ this.tagManager.changeTag({
399
+ id: option.id,
400
+ value: text,
401
+ });
402
+ },
403
+ });
404
+ if (this.optionEdits === 'create-rename') {
405
+ popMenu(popupTargetFromElement(e.currentTarget), {
406
+ options: { items: [rename] },
407
+ });
408
+ return;
409
+ }
363
410
  popMenu(popupTargetFromElement(e.currentTarget), {
364
411
  options: {
365
412
  items: [
366
- menu.input({
367
- initialValue: option.value,
368
- onChange: text => {
369
- this.tagManager.changeTag({
370
- id: option.id,
371
- value: text,
372
- });
373
- },
374
- }),
413
+ rename,
375
414
  menu.action({
376
- name: 'Delete',
415
+ name: this.say(TOOLBAR_DELETE),
377
416
  prefix: DeleteIcon(),
378
417
  class: {
379
418
  'delete-item': true,
@@ -392,7 +431,7 @@ let MultiTagSelect = (() => {
392
431
  height: '20px',
393
432
  });
394
433
  return menu.action({
395
- name: item.name,
434
+ name: item.wording ? this.say(item.wording) : item.name,
396
435
  prefix: html ` <div style=${styles}></div>`,
397
436
  isSelected: option.color === item.color,
398
437
  select: () => {
@@ -445,7 +484,10 @@ let MultiTagSelect = (() => {
445
484
  onDragEnd: evt => {
446
485
  const over = evt.over;
447
486
  const activeId = evt.active.id;
448
- if (over && over.id !== activeId) {
487
+ if (over &&
488
+ over.id !== activeId &&
489
+ this.onOptionsChange &&
490
+ this.optionEdits === 'all') {
449
491
  this.onOptionsChange(arrayMove(this.options.value, this.options.value.findIndex(v => v.id === activeId), this.options.value.findIndex(v => v.id === over.id)));
450
492
  this.requestUpdate();
451
493
  // const properties = this.filteredOptions$.value.map(v=>v.id);
@@ -470,18 +512,21 @@ let MultiTagSelect = (() => {
470
512
  this.#mode_accessor_storage = __runInitializers(this, _mode_initializers, 'multi');
471
513
  this.#onChange_accessor_storage = (__runInitializers(this, _mode_extraInitializers), __runInitializers(this, _onChange_initializers, void 0));
472
514
  this.#onComplete_accessor_storage = (__runInitializers(this, _onChange_extraInitializers), __runInitializers(this, _onComplete_initializers, void 0));
473
- this.#onOptionsChange_accessor_storage = (__runInitializers(this, _onComplete_extraInitializers), __runInitializers(this, _onOptionsChange_initializers, void 0));
474
- this.#options_accessor_storage = (__runInitializers(this, _onOptionsChange_extraInitializers), __runInitializers(this, _options_initializers, void 0));
515
+ this.#onOptionsChange_accessor_storage = (__runInitializers(this, _onComplete_extraInitializers), __runInitializers(this, _onOptionsChange_initializers, undefined));
516
+ this.#optionEdits_accessor_storage = (__runInitializers(this, _onOptionsChange_extraInitializers), __runInitializers(this, _optionEdits_initializers, 'all'));
517
+ this.#options_accessor_storage = (__runInitializers(this, _optionEdits_extraInitializers), __runInitializers(this, _options_initializers, void 0));
475
518
  this.selectedIndex$ = (__runInitializers(this, _options_extraInitializers), signal(0));
476
519
  this.#value_accessor_storage = __runInitializers(this, _value_initializers, void 0);
477
520
  this.#initialDraftText_accessor_storage = (__runInitializers(this, _value_extraInitializers), __runInitializers(this, _initialDraftText_initializers, void 0));
478
- __runInitializers(this, _initialDraftText_extraInitializers);
521
+ this.#wording_accessor_storage = (__runInitializers(this, _initialDraftText_extraInitializers), __runInitializers(this, _wording_initializers, undefined));
522
+ __runInitializers(this, _wording_extraInitializers);
479
523
  }
480
524
  };
481
525
  })();
482
526
  export { MultiTagSelect };
483
527
  const popMobileTagSelect = (target, ops) => {
484
528
  const tagManager = new TagManager(ops);
529
+ const say = ops.wording ?? englishWording;
485
530
  if (ops.initialDraftText) {
486
531
  tagManager.text$.value = ops.initialDraftText;
487
532
  }
@@ -518,7 +563,7 @@ const popMobileTagSelect = (target, ops) => {
518
563
  <input
519
564
  .value="${tagManager.text$.value}"
520
565
  @input="${onInput}"
521
- placeholder="Type here..."
566
+ placeholder="${say(TAG_SELECT_PLACEHOLDER)}"
522
567
  type="text"
523
568
  style="outline: none;border: none;flex:1;min-width: 10px"
524
569
  />
@@ -539,7 +584,9 @@ const popMobileTagSelect = (target, ops) => {
539
584
  return html `
540
585
  <div style="display: flex; align-items:center;">
541
586
  ${option.isCreate
542
- ? html ` <div style="margin-right: 8px;">Create</div>`
587
+ ? html ` <div style="margin-right: 8px;">
588
+ ${say(TAG_SELECT_CREATE)}
589
+ </div>`
543
590
  : ''}
544
591
  <div class="${tagContainerStyle}" style=${style}>
545
592
  <div class="${tagTextStyle}">${option.value}</div>
@@ -576,7 +623,9 @@ export const popTagSelect = (target, ops) => {
576
623
  component.onChange = ops.onChange;
577
624
  component.options = ops.options;
578
625
  component.onOptionsChange = ops.onOptionsChange;
626
+ component.optionEdits = ops.optionEdits ?? 'all';
579
627
  component.initialDraftText = ops.initialDraftText;
628
+ component.wording = ops.wording;
580
629
  component.onComplete = () => {
581
630
  ops.onComplete?.();
582
631
  remove();
@@ -8,7 +8,8 @@ import type { DatabaseFlags } from '../types.js';
8
8
  import type { ViewConvertConfig } from '../view/convert.js';
9
9
  import type { DataViewDataType, ViewMeta } from '../view/data-view.js';
10
10
  import type { ViewManager } from '../view-manager/view-manager.js';
11
- export interface DataSource {
11
+ import { type CellStatus, type DataSourceHydration, type ValuesState } from './hydration.js';
12
+ export interface DataSource extends DataSourceHydration {
12
13
  readonly$: ReadonlySignal<boolean>;
13
14
  properties$: ReadonlySignal<string[]>;
14
15
  featureFlags$: ReadonlySignal<DatabaseFlags>;
@@ -65,6 +66,9 @@ export interface DataSource {
65
66
  }
66
67
  export declare const DataSourceScope: import("../../../global/di/types.js").ServiceScope;
67
68
  export declare abstract class DataSourceBase implements DataSource {
69
+ /** Every cell is `ready` unless a source says otherwise (ADR 0035 §9e). */
70
+ cellStatus(_rowId: string, _propertyId: string): CellStatus;
71
+ valuesState$: ReadonlySignal<ValuesState>;
68
72
  propertyTypeCanSet(propertyId: string): boolean;
69
73
  propertyCanDuplicate(propertyId: string): boolean;
70
74
  propertyCanDelete(propertyId: string): boolean;
@@ -1,8 +1,10 @@
1
1
  import { Container, createScope, } from '../../../global/di/index.js';
2
- import { computed } from '@preact/signals-core';
2
+ import { computed, signal } from '@preact/signals-core';
3
+ import { VALUES_READY, } from './hydration.js';
3
4
  export const DataSourceScope = createScope('data-source');
4
5
  export class DataSourceBase {
5
6
  constructor() {
7
+ this.valuesState$ = signal(VALUES_READY);
6
8
  this.container = new Container();
7
9
  this.fixedProperties$ = computed(() => {
8
10
  return this.allPropertyMetas$.value
@@ -13,6 +15,10 @@ export class DataSourceBase {
13
15
  return new Set(this.fixedProperties$.value);
14
16
  });
15
17
  }
18
+ /** Every cell is `ready` unless a source says otherwise (ADR 0035 §9e). */
19
+ cellStatus(_rowId, _propertyId) {
20
+ return 'ready';
21
+ }
16
22
  propertyTypeCanSet(propertyId) {
17
23
  return !this.isFixedProperty(propertyId);
18
24
  }
@@ -0,0 +1,44 @@
1
+ import type { ReadonlySignal } from '@preact/signals-core';
2
+ /**
3
+ * Cell hydration (ADR 0035 §9e, issue B2): a widening of the data-source
4
+ * contract, not a seam.
5
+ *
6
+ * A host source whose values arrive after its rows (Labre keeps them in SQL,
7
+ * labre ADR-0047) says, per cell, whether the value it answers is the real one
8
+ * yet, and, for the whole source, whether values are still loading or failed.
9
+ * Every member is optional: a source that says nothing is `ready` at once,
10
+ * which is the inline source and every 0.48 host source, unchanged.
11
+ *
12
+ * Nothing is written in any state. A cell that is not `ready` mounts no
13
+ * renderer and refuses `valueSet`, so neither the user nor a paste, a fill or
14
+ * a kanban drop can write over a value the source has not delivered.
15
+ */
16
+ export type CellStatus = 'ready' | 'pending' | 'error';
17
+ export type ValuesStatus = 'loading' | 'ready' | 'error';
18
+ export interface ValuesState {
19
+ readonly status: ValuesStatus;
20
+ /** `Date.now()` when the source entered `status`. */
21
+ readonly since: number;
22
+ }
23
+ export interface DataSourceHydration {
24
+ cellStatus?(rowId: string, propertyId: string): CellStatus;
25
+ valuesState$?: ReadonlySignal<ValuesState>;
26
+ /** Present when the source can try again after an `error`. */
27
+ retryValues?(): void;
28
+ }
29
+ export declare const VALUES_READY: ValuesState;
30
+ /** How long values may load before a banner says so (REQ-DB-12). */
31
+ export declare const VALUES_SLOW_AFTER_MS = 3000;
32
+ export declare function cellStatusOf(source: DataSourceHydration, rowId: string, propertyId: string): CellStatus;
33
+ export declare function valuesStateOf(source: DataSourceHydration): ValuesState;
34
+ /** What a count shows while values are not ready. */
35
+ export declare const VALUES_PENDING_MARK = "\u2026";
36
+ /** Counts (group headers, column statistics) show an ellipsis until `true`. */
37
+ export declare function valuesReady(source: DataSourceHydration): boolean;
38
+ export type ValuesBanner = 'none' | 'slow' | 'error';
39
+ /**
40
+ * Which banner a view shows: none while values load for less than
41
+ * {@link VALUES_SLOW_AFTER_MS}, `slow` after, `error` as soon as loading
42
+ * failed. Pure, so the 3 s rule is tested without a timer.
43
+ */
44
+ export declare function valuesBannerOf(state: ValuesState, now: number): ValuesBanner;
@@ -0,0 +1,31 @@
1
+ export const VALUES_READY = Object.freeze({
2
+ status: 'ready',
3
+ since: 0,
4
+ });
5
+ /** How long values may load before a banner says so (REQ-DB-12). */
6
+ export const VALUES_SLOW_AFTER_MS = 3000;
7
+ export function cellStatusOf(source, rowId, propertyId) {
8
+ return source.cellStatus?.(rowId, propertyId) ?? 'ready';
9
+ }
10
+ export function valuesStateOf(source) {
11
+ return source.valuesState$?.value ?? VALUES_READY;
12
+ }
13
+ /** What a count shows while values are not ready. */
14
+ export const VALUES_PENDING_MARK = '…';
15
+ /** Counts (group headers, column statistics) show an ellipsis until `true`. */
16
+ export function valuesReady(source) {
17
+ return valuesStateOf(source).status === 'ready';
18
+ }
19
+ /**
20
+ * Which banner a view shows: none while values load for less than
21
+ * {@link VALUES_SLOW_AFTER_MS}, `slow` after, `error` as soon as loading
22
+ * failed. Pure, so the 3 s rule is tested without a timer.
23
+ */
24
+ export function valuesBannerOf(state, now) {
25
+ if (state.status === 'error')
26
+ return 'error';
27
+ if (state.status === 'loading' && now - state.since >= VALUES_SLOW_AFTER_MS) {
28
+ return 'slow';
29
+ }
30
+ return 'none';
31
+ }
@@ -1 +1,2 @@
1
1
  export * from './base.js';
2
+ export * from './hydration.js';
@@ -1 +1,2 @@
1
1
  export * from './base.js';
2
+ export * from './hydration.js';
@@ -2,6 +2,7 @@ import type { DatabaseAllEvents, EventTraceFn } from '../../affine-shared/servic
2
2
  import type { DisposableMember } from '../../global/disposable/index.js';
3
3
  import { type Clipboard, type DndController, type EventName, ShadowlessElement, type UIEventHandler } from '../../std/index.js';
4
4
  import { type ReadonlySignal } from '@preact/signals-core';
5
+ import { type TemplateResult } from 'lit';
5
6
  import type { DataSource } from './data-source/index.js';
6
7
  import type { DataViewSelection } from './types.js';
7
8
  import type { DataViewUILogicBase } from './view/data-view-base.js';
@@ -22,10 +23,22 @@ export type DataViewRendererConfig = {
22
23
  selection$: ReadonlySignal<DataViewSelection | undefined>;
23
24
  setSelection: (selection: DataViewSelection | undefined) => void;
24
25
  eventTrace: EventTraceFn<DatabaseAllEvents>;
26
+ /**
27
+ * Drawn instead of the current view, header widget included, when it
28
+ * returns something (a source the view names that the host cannot resolve,
29
+ * ADR 0035 §7): the caller draws what of its header still makes sense.
30
+ * Absent: every view draws as in 0.48.
31
+ */
32
+ viewPlaceholder?: (logic: DataViewUILogicBase) => TemplateResult | undefined;
25
33
  detailPanelConfig: {
26
34
  openDetailPanel: (target: HTMLElement, data: {
27
35
  view: SingleView;
28
36
  rowId: string;
37
+ /**
38
+ * A Ctrl/Cmd click: the host may open the row in a new tab (ADR 0035
39
+ * §9a). Absent for a gesture with no such modifier.
40
+ */
41
+ newTab?: boolean;
29
42
  }) => Promise<void>;
30
43
  };
31
44
  };
@@ -45,13 +58,19 @@ export declare class DataViewRootUILogic {
45
58
  readonly currentViewId$: ReadonlySignal<string | undefined>;
46
59
  readonly currentView$: ReadonlySignal<DataViewUILogicBase<SingleView, DataViewSelection> | undefined>;
47
60
  focusFirstCell: () => void;
61
+ /**
62
+ * The one way a view opens a row, whatever its preset (the database block
63
+ * routes it to the host's opener or to its own detail panel, ADR 0035 §9a).
64
+ * `newTab` says the gesture asked for a new tab (`isNewTabClick`).
65
+ */
48
66
  openDetailPanel: (ops: {
49
67
  view: SingleView;
50
68
  rowId: string;
69
+ newTab?: boolean;
51
70
  onClose?: () => void;
52
71
  }) => void;
53
72
  setupViewChangeListener(): () => void;
54
- render(): import("lit-html").TemplateResult;
73
+ render(): TemplateResult;
55
74
  }
56
75
  declare const DataViewRootUI_base: typeof ShadowlessElement & import("../../global/utils/types.js").Constructor<import("../../global/lit/with-disposable.js").DisposableClass>;
57
76
  export declare class DataViewRootUI extends DataViewRootUI_base {
@@ -62,10 +81,11 @@ export declare class DataViewRootUI extends DataViewRootUI_base {
62
81
  openDetailPanel: (ops: {
63
82
  view: SingleView;
64
83
  rowId: string;
84
+ newTab?: boolean;
65
85
  onClose?: () => void;
66
86
  }) => void;
67
87
  connectedCallback(): void;
68
- render(): import("lit-html").TemplateResult | undefined;
88
+ render(): TemplateResult | undefined;
69
89
  }
70
90
  declare global {
71
91
  interface HTMLElementTagNameMap {
@@ -110,6 +110,11 @@ export class DataViewRootUILogic {
110
110
  this.focusFirstCell = () => {
111
111
  this.currentView$.value?.focusFirstCell();
112
112
  };
113
+ /**
114
+ * The one way a view opens a row, whatever its preset (the database block
115
+ * routes it to the host's opener or to its own detail panel, ADR 0035 §9a).
116
+ * `newTab` says the gesture asked for a new tab (`isNewTabClick`).
117
+ */
113
118
  this.openDetailPanel = (ops) => {
114
119
  const openDetailPanel = this.config.detailPanelConfig.openDetailPanel;
115
120
  const target = this.dataViewRenderer;
@@ -117,6 +122,7 @@ export class DataViewRootUILogic {
117
122
  openDetailPanel(target, {
118
123
  view: ops.view,
119
124
  rowId: ops.rowId,
125
+ ...(ops.newTab ? { newTab: true } : {}),
120
126
  })
121
127
  .catch(console.error)
122
128
  .finally(ops.onClose);
@@ -197,6 +203,14 @@ let DataViewRootUI = (() => {
197
203
  if (!currentView) {
198
204
  return;
199
205
  }
206
+ const placeholder = this.logic.config.viewPlaceholder?.(currentView);
207
+ if (placeholder) {
208
+ return html `
209
+ <div style="display: contents" class="${containerClass}">
210
+ ${placeholder}
211
+ </div>
212
+ `;
213
+ }
200
214
  return html `
201
215
  <div style="display: contents" class="${containerClass}">
202
216
  ${renderUniLit(currentView.renderer, {
@@ -6,6 +6,7 @@ import { DataViewRootUI } from './data-view.js';
6
6
  import { RecordDetail } from './detail/detail.js';
7
7
  import { RecordField } from './detail/field.js';
8
8
  import { VariableRefView } from './expression/ref/ref-view.js';
9
+ import { DataViewHiddenGroups } from './group-by/group-visibility.js';
9
10
  import { BooleanGroupView } from './group-by/renderer/boolean-group.js';
10
11
  import { DateGroupView } from './group-by/renderer/date-group.js';
11
12
  import { NumberGroupView } from './group-by/renderer/number-group.js';
@@ -13,6 +14,7 @@ import { SelectGroupView } from './group-by/renderer/select-group.js';
13
14
  import { StringGroupView } from './group-by/renderer/string-group.js';
14
15
  import { GroupSetting } from './group-by/setting.js';
15
16
  import { AffineLitIcon, UniAnyRender, UniLit } from './index.js';
17
+ import { StandaloneCellHost } from './property/standalone-cell.js';
16
18
  import { AnyRender } from './utils/uni-component/render-template.js';
17
19
  export function coreEffects() {
18
20
  customElements.define('affine-data-view-renderer', DataViewRootUI);
@@ -26,6 +28,7 @@ export function coreEffects() {
26
28
  customElements.define('data-view-group-title-number-view', NumberGroupView);
27
29
  customElements.define('affine-lit-icon', AffineLitIcon);
28
30
  customElements.define('data-view-group-setting', GroupSetting);
31
+ customElements.define('dv-hidden-groups', DataViewHiddenGroups);
29
32
  customElements.define('affine-multi-tag-select', MultiTagSelect);
30
33
  customElements.define('data-view-group-title-boolean-view', BooleanGroupView);
31
34
  customElements.define('data-view-group-title-date-view', DateGroupView);
@@ -34,4 +37,5 @@ export function coreEffects() {
34
37
  customElements.define('uni-any-render', UniAnyRender);
35
38
  customElements.define('variable-ref-view', VariableRefView);
36
39
  customElements.define('affine-data-view-record-detail', RecordDetail);
40
+ customElements.define('dv-standalone-cell', StandaloneCellHost);
37
41
  }
@@ -0,0 +1,3 @@
1
+ import { type ReadonlySignal } from '@preact/signals-core';
2
+ export declare function groupCollapsed$(viewId: string, groupKey: string): ReadonlySignal<boolean>;
3
+ export declare function groupCollapsedSet(viewId: string, groupKey: string, collapsed: boolean): void;
@@ -0,0 +1,59 @@
1
+ import { signal } from '@preact/signals-core';
2
+ /**
3
+ * Whether a group of a view is folded, for every preset (ADR 0035 §8, B8,
4
+ * PRD REQ-DB-16). Personal and per device: kept in `localStorage`, never in
5
+ * the document, like the local hide of ADR 0031. A host seam was not chosen:
6
+ * it would be a row in the seams table forever for a device ergonomic, and a
7
+ * fold that follows the user across devices is not asked for.
8
+ *
9
+ * Only a folded group has an entry (`'1'`); unfolding removes it. Any other
10
+ * value, a storage that throws (private mode, blocked site data) or no
11
+ * storage at all reads as unfolded. One signal per key, shared by every
12
+ * element drawing that group, so a fold is seen everywhere at once.
13
+ *
14
+ * Until 0.49 the table kept this in `sessionStorage` under
15
+ * `affine:table-group:*`; those entries were per tab and are not read back.
16
+ */
17
+ const PREFIX = 'labre:data-view:group-collapsed:';
18
+ const storageKey = (viewId, groupKey) => `${PREFIX}${viewId}:${groupKey}`;
19
+ const states = new Map();
20
+ function readStored(key) {
21
+ try {
22
+ return globalThis.localStorage?.getItem(key) === '1';
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ function writeStored(key, collapsed) {
29
+ try {
30
+ if (collapsed) {
31
+ globalThis.localStorage?.setItem(key, '1');
32
+ }
33
+ else {
34
+ globalThis.localStorage?.removeItem(key);
35
+ }
36
+ }
37
+ catch {
38
+ // A storage that refuses keeps the fold for this session only.
39
+ }
40
+ }
41
+ function stateOf(viewId, groupKey) {
42
+ const key = storageKey(viewId, groupKey);
43
+ let state = states.get(key);
44
+ if (!state) {
45
+ state = signal(readStored(key));
46
+ states.set(key, state);
47
+ }
48
+ return state;
49
+ }
50
+ export function groupCollapsed$(viewId, groupKey) {
51
+ return stateOf(viewId, groupKey);
52
+ }
53
+ export function groupCollapsedSet(viewId, groupKey, collapsed) {
54
+ const state = stateOf(viewId, groupKey);
55
+ if (state.peek() === collapsed)
56
+ return;
57
+ state.value = collapsed;
58
+ writeStored(storageKey(viewId, groupKey), collapsed);
59
+ }
@@ -0,0 +1,21 @@
1
+ import type { GroupProperty } from '../common/types.js';
2
+ import type { Row } from '../view-manager/row.js';
3
+ /**
4
+ * The group ops every grouped preset hands its `GroupTrait`, over the view's
5
+ * stored `groupProperties` (the shape table and kanban have always stored:
6
+ * `{ key, hide, manuallyCardSort }`). One copy for table, kanban, gallery and
7
+ * list (ADR 0035 §8, B8), so a hidden group and a manual order read and write
8
+ * the same way in every view.
9
+ *
10
+ * Every write lists the entry of every group key it is given, so a hidden
11
+ * group keeps its `hide` and its card order through a reorder; nothing is
12
+ * written when the value would not change.
13
+ */
14
+ export declare const groupPropertiesOps: (read: () => GroupProperty[], write: (groupProperties: GroupProperty[]) => void) => {
15
+ sortGroup: (keys: string[]) => string[];
16
+ sortRow: (key: string, rows: Row[]) => Row[];
17
+ changeGroupSort: (keys: string[]) => void;
18
+ changeRowSort: (groupKeys: string[], groupKey: string, keys: string[]) => void;
19
+ groupHidden: (key: string) => boolean;
20
+ groupHideSet: (groupKeys: string[], groupKey: string, hide: boolean) => void;
21
+ };