@formicoidea/labre-core 1.1.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 (190) hide show
  1. package/architecture/code.c4 +37 -34
  2. package/architecture/likec4.config.json +3 -3
  3. package/dist/_pkgs/affine-block-surface/extensions/reading-toolbar.js +12 -12
  4. package/dist/_pkgs/affine-components/context-menu/menu-renderer.d.ts +3 -1
  5. package/dist/_pkgs/affine-components/context-menu/menu-renderer.js +9 -1
  6. package/dist/_pkgs/affine-components/context-menu/menu.d.ts +7 -0
  7. package/dist/_pkgs/affine-components/context-menu/menu.js +5 -0
  8. package/dist/_pkgs/affine-components/context-menu/sub-menu.d.ts +16 -1
  9. package/dist/_pkgs/affine-components/context-menu/sub-menu.js +32 -5
  10. package/dist/_pkgs/affine-components/highlight-dropdown-menu/highlight-duotone-icon.js +8 -8
  11. package/dist/_pkgs/affine-components/highlight-dropdown-menu/text-duotone-icon.js +11 -11
  12. package/dist/_pkgs/affine-database-block/configs/slash-menu.js +14 -6
  13. package/dist/_pkgs/affine-database-block/database-block-styles.js +4 -3
  14. package/dist/_pkgs/affine-database-block/database-block.js +6 -18
  15. package/dist/_pkgs/affine-database-block/database-dnd-preview-block.js +5 -1
  16. package/dist/_pkgs/affine-database-block/detail-panel/block-renderer.js +5 -2
  17. package/dist/_pkgs/affine-database-block/detail-panel/note-renderer.js +3 -2
  18. package/dist/_pkgs/affine-database-block/external-data-source.d.ts +10 -0
  19. package/dist/_pkgs/affine-database-block/external-data-source.js +24 -0
  20. package/dist/_pkgs/affine-database-block/properties/created-time/define.js +3 -1
  21. package/dist/_pkgs/affine-database-block/properties/link/cell-renderer.js +3 -2
  22. package/dist/_pkgs/affine-database-block/properties/link/define.js +3 -1
  23. package/dist/_pkgs/affine-database-block/properties/rich-text/define.js +3 -1
  24. package/dist/_pkgs/affine-database-block/properties/text/hosted.js +1 -0
  25. package/dist/_pkgs/affine-database-block/properties/title/define.js +3 -1
  26. package/dist/_pkgs/affine-database-block/properties/title/hosted.js +1 -0
  27. package/dist/_pkgs/affine-database-block/service/new-row-menu.d.ts +1 -1
  28. package/dist/_pkgs/affine-database-block/service/new-row-menu.js +1 -1
  29. package/dist/_pkgs/affine-database-block/translations.d.ts +11 -0
  30. package/dist/_pkgs/affine-database-block/translations.js +57 -0
  31. package/dist/_pkgs/affine-database-block/views/index.d.ts +7 -9
  32. package/dist/_pkgs/affine-database-block/views/index.js +7 -10
  33. package/dist/_pkgs/affine-database-engine/core/common/properties.js +7 -7
  34. package/dist/_pkgs/affine-database-engine/core/common/property-menu.d.ts +18 -2
  35. package/dist/_pkgs/affine-database-engine/core/common/property-menu.js +78 -27
  36. package/dist/_pkgs/affine-database-engine/core/data-source/base.d.ts +11 -0
  37. package/dist/_pkgs/affine-database-engine/core/data-source/base.js +3 -0
  38. package/dist/_pkgs/affine-database-engine/core/detail/detail.js +8 -5
  39. package/dist/_pkgs/affine-database-engine/core/detail/field.js +14 -7
  40. package/dist/_pkgs/affine-database-engine/core/filter/add-filter.js +4 -2
  41. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/boolean.js +7 -4
  42. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/create.d.ts +9 -1
  43. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/create.js +2 -0
  44. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/date.js +7 -4
  45. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/multi-tag.js +17 -8
  46. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/number.js +6 -6
  47. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/string.js +19 -12
  48. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/tag.js +9 -4
  49. package/dist/_pkgs/affine-database-engine/core/filter/filter-fn/unknown.js +7 -4
  50. package/dist/_pkgs/affine-database-engine/core/filter/literal/define.js +6 -4
  51. package/dist/_pkgs/affine-database-engine/core/filter/literal/matcher.d.ts +2 -1
  52. package/dist/_pkgs/affine-database-engine/core/filter/literal/matcher.js +3 -2
  53. package/dist/_pkgs/affine-database-engine/core/filter/literal/types.d.ts +4 -1
  54. package/dist/_pkgs/affine-database-engine/core/filter/literal/types.js +1 -1
  55. package/dist/_pkgs/affine-database-engine/core/group-by/define.js +11 -9
  56. package/dist/_pkgs/affine-database-engine/core/group-by/group-title.js +16 -6
  57. package/dist/_pkgs/affine-database-engine/core/group-by/locate-row.d.ts +16 -0
  58. package/dist/_pkgs/affine-database-engine/core/group-by/locate-row.js +32 -0
  59. package/dist/_pkgs/affine-database-engine/core/group-by/renderer/date-group.js +10 -3
  60. package/dist/_pkgs/affine-database-engine/core/group-by/setting.d.ts +2 -0
  61. package/dist/_pkgs/affine-database-engine/core/group-by/setting.js +40 -28
  62. package/dist/_pkgs/affine-database-engine/core/group-by/trait.d.ts +3 -0
  63. package/dist/_pkgs/affine-database-engine/core/group-by/trait.js +8 -0
  64. package/dist/_pkgs/affine-database-engine/core/group-by/types.d.ts +3 -1
  65. package/dist/_pkgs/affine-database-engine/core/group-by/types.js +1 -1
  66. package/dist/_pkgs/affine-database-engine/core/property/types.d.ts +7 -0
  67. package/dist/_pkgs/affine-database-engine/core/property/types.js +1 -1
  68. package/dist/_pkgs/affine-database-engine/core/sort/add-sort.js +3 -1
  69. package/dist/_pkgs/affine-database-engine/core/statistics/any.js +43 -21
  70. package/dist/_pkgs/affine-database-engine/core/statistics/checkbox.js +29 -14
  71. package/dist/_pkgs/affine-database-engine/core/statistics/number.js +54 -31
  72. package/dist/_pkgs/affine-database-engine/core/statistics/types.d.ts +8 -0
  73. package/dist/_pkgs/affine-database-engine/core/statistics/types.js +2 -1
  74. package/dist/_pkgs/affine-database-engine/core/utils/wording.d.ts +20 -1
  75. package/dist/_pkgs/affine-database-engine/core/utils/wording.js +24 -0
  76. package/dist/_pkgs/affine-database-engine/core/view-manager/property.d.ts +7 -0
  77. package/dist/_pkgs/affine-database-engine/core/view-manager/property.js +29 -5
  78. package/dist/_pkgs/affine-database-engine/core/view-manager/single-view.d.ts +14 -0
  79. package/dist/_pkgs/affine-database-engine/core/view-manager/single-view.js +11 -0
  80. package/dist/_pkgs/affine-database-engine/property-presets/checkbox/define.js +3 -1
  81. package/dist/_pkgs/affine-database-engine/property-presets/date/define.js +3 -1
  82. package/dist/_pkgs/affine-database-engine/property-presets/multi-select/define.js +3 -1
  83. package/dist/_pkgs/affine-database-engine/property-presets/number/define.js +3 -1
  84. package/dist/_pkgs/affine-database-engine/property-presets/number/utils/formats.d.ts +3 -0
  85. package/dist/_pkgs/affine-database-engine/property-presets/number/utils/formats.js +56 -9
  86. package/dist/_pkgs/affine-database-engine/property-presets/progress/define.js +3 -1
  87. package/dist/_pkgs/affine-database-engine/property-presets/select/define.js +3 -1
  88. package/dist/_pkgs/affine-database-engine/property-presets/text/define.js +3 -1
  89. package/dist/_pkgs/affine-database-engine/translations.d.ts +133 -5
  90. package/dist/_pkgs/affine-database-engine/translations.js +625 -9
  91. package/dist/_pkgs/affine-database-engine/view-presets/convert.js +0 -28
  92. package/dist/_pkgs/affine-database-engine/view-presets/effect.js +0 -2
  93. package/dist/_pkgs/affine-database-engine/view-presets/flat/flat-converts.js +2 -4
  94. package/dist/_pkgs/affine-database-engine/view-presets/flat/flat-view-ui.d.ts +57 -0
  95. package/dist/_pkgs/affine-database-engine/view-presets/flat/flat-view-ui.js +113 -4
  96. package/dist/_pkgs/affine-database-engine/view-presets/gallery/gallery-view.js +2 -1
  97. package/dist/_pkgs/affine-database-engine/view-presets/index.d.ts +0 -2
  98. package/dist/_pkgs/affine-database-engine/view-presets/index.js +0 -3
  99. package/dist/_pkgs/affine-database-engine/view-presets/kanban/kanban-view-manager.js +2 -0
  100. package/dist/_pkgs/affine-database-engine/view-presets/kanban/mobile/group.js +7 -5
  101. package/dist/_pkgs/affine-database-engine/view-presets/kanban/mobile/kanban-view-ui-logic.d.ts +5 -0
  102. package/dist/_pkgs/affine-database-engine/view-presets/kanban/mobile/kanban-view-ui-logic.js +25 -3
  103. package/dist/_pkgs/affine-database-engine/view-presets/kanban/mobile/menu.js +12 -6
  104. package/dist/_pkgs/affine-database-engine/view-presets/kanban/pc/controller/selection.d.ts +8 -0
  105. package/dist/_pkgs/affine-database-engine/view-presets/kanban/pc/controller/selection.js +35 -12
  106. package/dist/_pkgs/affine-database-engine/view-presets/kanban/pc/group.js +7 -5
  107. package/dist/_pkgs/affine-database-engine/view-presets/kanban/pc/header.js +5 -1
  108. package/dist/_pkgs/affine-database-engine/view-presets/kanban/pc/kanban-view-ui-logic.d.ts +5 -0
  109. package/dist/_pkgs/affine-database-engine/view-presets/kanban/pc/kanban-view-ui-logic.js +8 -4
  110. package/dist/_pkgs/affine-database-engine/view-presets/kanban/pc/menu.js +12 -6
  111. package/dist/_pkgs/affine-database-engine/view-presets/list/list-view.js +2 -1
  112. package/dist/_pkgs/affine-database-engine/view-presets/table/mobile/column-header.js +6 -4
  113. package/dist/_pkgs/affine-database-engine/view-presets/table/mobile/group.js +6 -5
  114. package/dist/_pkgs/affine-database-engine/view-presets/table/mobile/header.js +2 -2
  115. package/dist/_pkgs/affine-database-engine/view-presets/table/mobile/table-view-ui-logic.d.ts +4 -3
  116. package/dist/_pkgs/affine-database-engine/view-presets/table/mobile/table-view-ui-logic.js +29 -5
  117. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/controller/clipboard.js +6 -2
  118. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/controller/selection.js +2 -0
  119. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/group.js +6 -5
  120. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/header/column-header.js +11 -7
  121. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/header/database-header-column.js +16 -12
  122. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/header/number-format-bar.js +4 -2
  123. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/menu.js +9 -6
  124. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/table-view-ui-logic.d.ts +8 -1
  125. package/dist/_pkgs/affine-database-engine/view-presets/table/pc/table-view-ui-logic.js +29 -7
  126. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/controller/clipboard.js +6 -2
  127. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/controller/selection.js +2 -0
  128. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/bottom/group-footer.js +5 -2
  129. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/bottom/stats/column-stats-column.d.ts +1 -1
  130. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/bottom/stats/column-stats-column.js +14 -6
  131. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/top/group-header.js +5 -2
  132. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/top/group-title.js +5 -3
  133. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/top/header/column-header.js +17 -10
  134. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/top/header/number-format-bar.js +4 -2
  135. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/group/top/header/single-column-header.js +20 -14
  136. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/row/menu.js +9 -6
  137. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/table-view-ui-logic.d.ts +6 -1
  138. package/dist/_pkgs/affine-database-engine/view-presets/table/pc-virtual/table-view-ui-logic.js +30 -3
  139. package/dist/_pkgs/affine-database-engine/view-presets/table/stats/column-stats-column.d.ts +1 -1
  140. package/dist/_pkgs/affine-database-engine/view-presets/table/stats/column-stats-column.js +14 -6
  141. package/dist/_pkgs/affine-database-engine/view-presets/table/table-view-manager.js +2 -0
  142. package/dist/_pkgs/affine-database-engine/widget-presets/quick-setting-bar/filter/condition-view.d.ts +2 -0
  143. package/dist/_pkgs/affine-database-engine/widget-presets/quick-setting-bar/filter/condition-view.js +13 -6
  144. package/dist/_pkgs/affine-database-engine/widget-presets/quick-setting-bar/filter/group-panel-view.js +20 -13
  145. package/dist/_pkgs/affine-database-engine/widget-presets/quick-setting-bar/filter/root-panel-view.js +10 -5
  146. package/dist/_pkgs/affine-database-engine/widget-presets/quick-setting-bar/sort/root-panel.js +8 -5
  147. package/dist/_pkgs/affine-database-engine/widget-presets/tools/presets/search/search.js +2 -2
  148. package/dist/_pkgs/affine-database-engine/widget-presets/tools/presets/table-add-row/add-row.d.ts +6 -0
  149. package/dist/_pkgs/affine-database-engine/widget-presets/tools/presets/table-add-row/add-row.js +49 -4
  150. package/dist/_pkgs/affine-database-engine/widget-presets/tools/presets/view-options/view-settings.d.ts +3 -3
  151. package/dist/_pkgs/affine-database-engine/widget-presets/tools/presets/view-options/view-settings.js +3 -3
  152. package/dist/_pkgs/affine-database-engine/widget-presets/views-bar/views-view.js +5 -0
  153. package/dist/_pkgs/affine-database-view-block/configs/slash-menu.js +6 -3
  154. package/dist/_pkgs/affine-database-view-block/data-view-block.js +5 -4
  155. package/dist/_pkgs/affine-fragment-doc-title/doc-title.d.ts +3 -2
  156. package/dist/_pkgs/affine-fragment-doc-title/doc-title.js +3 -2
  157. package/dist/_pkgs/affine-shared/services/data-source-picker-service.d.ts +31 -0
  158. package/dist/_pkgs/affine-widget-edgeless-zoom-toolbar/index.js +26 -26
  159. package/dist/_pkgs/affine-widget-keyboard-toolbar/icons.js +98 -98
  160. package/dist/_pkgs/affine-widget-page-dragging-area/index.js +10 -10
  161. package/dist/_pkgs/affine-widget-viewport-overlay/index.js +13 -13
  162. package/package.json +1 -1
  163. package/dist/_pkgs/affine-database-engine/view-presets/calendar/calendar-view-manager.d.ts +0 -70
  164. package/dist/_pkgs/affine-database-engine/view-presets/calendar/calendar-view-manager.js +0 -449
  165. package/dist/_pkgs/affine-database-engine/view-presets/calendar/define.d.ts +0 -10
  166. package/dist/_pkgs/affine-database-engine/view-presets/calendar/define.js +0 -29
  167. package/dist/_pkgs/affine-database-engine/view-presets/calendar/effect.d.ts +0 -1
  168. package/dist/_pkgs/affine-database-engine/view-presets/calendar/effect.js +0 -4
  169. package/dist/_pkgs/affine-database-engine/view-presets/calendar/index.d.ts +0 -6
  170. package/dist/_pkgs/affine-database-engine/view-presets/calendar/index.js +0 -6
  171. package/dist/_pkgs/affine-database-engine/view-presets/calendar/layout.d.ts +0 -37
  172. package/dist/_pkgs/affine-database-engine/view-presets/calendar/layout.js +0 -138
  173. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/actions.d.ts +0 -7
  174. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/actions.js +0 -64
  175. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/dnd.d.ts +0 -32
  176. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/dnd.js +0 -159
  177. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/effect.d.ts +0 -1
  178. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/effect.js +0 -7
  179. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/hit-test.d.ts +0 -1
  180. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/hit-test.js +0 -28
  181. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/styles.d.ts +0 -1
  182. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/styles.js +0 -707
  183. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/view.d.ts +0 -89
  184. package/dist/_pkgs/affine-database-engine/view-presets/calendar/pc/view.js +0 -849
  185. package/dist/_pkgs/affine-database-engine/view-presets/calendar/renderer.d.ts +0 -2
  186. package/dist/_pkgs/affine-database-engine/view-presets/calendar/renderer.js +0 -8
  187. package/dist/_pkgs/affine-database-engine/view-presets/calendar/source.d.ts +0 -8
  188. package/dist/_pkgs/affine-database-engine/view-presets/calendar/source.js +0 -3
  189. package/dist/_pkgs/affine-database-engine/view-presets/calendar/types.d.ts +0 -79
  190. package/dist/_pkgs/affine-database-engine/view-presets/calendar/types.js +0 -1
@@ -1,10 +1,8 @@
1
- import { calendarEffects } from './calendar/effect.js';
2
1
  import { galleryEffects } from './gallery/effect.js';
3
2
  import { kanbanEffects } from './kanban/effect.js';
4
3
  import { listEffects } from './list/effect.js';
5
4
  import { tableEffects } from './table/effect.js';
6
5
  export function viewPresetsEffects() {
7
- calendarEffects();
8
6
  galleryEffects();
9
7
  kanbanEffects();
10
8
  listEffects();
@@ -1,4 +1,3 @@
1
- import { calendarViewModel } from '../calendar/define.js';
2
1
  import { galleryViewModel } from '../gallery/define.js';
3
2
  import { kanbanViewModel } from '../kanban/define.js';
4
3
  import { listViewModel } from '../list/define.js';
@@ -8,8 +7,7 @@ import { tableViewModel } from '../table/define.js';
8
7
  * sort and the grouping (B8: every layout groups, as table and kanban already
9
8
  * kept `groupBy` between them); the properties shown are the target layout's
10
9
  * own default, as when Notion switches a view's layout. A source with no
11
- * grouping leaves the target's default: a kanban still gets its own. Calendar
12
- * is a source only: nothing converts into it (ADR 0035 §6).
10
+ * grouping leaves the target's default: a kanban still gets its own.
13
11
  */
14
12
  const keepFilterSortAndGroup = (data) => {
15
13
  const { filter, sort, groupBy } = data;
@@ -27,7 +25,7 @@ const convert = (from, to) => ({
27
25
  convert: keepFilterSortAndGroup,
28
26
  });
29
27
  export const flatViewConverts = [
30
- ...[tableViewModel, kanbanViewModel, calendarViewModel, ...flatModels]
28
+ ...[tableViewModel, kanbanViewModel, ...flatModels]
31
29
  .flatMap(from => flatModels.map(to => [from.type, to.type]))
32
30
  .filter(([from, to]) => from !== to)
33
31
  .map(([from, to]) => convert(from, to)),
@@ -16,19 +16,76 @@ import type { FlatSingleView } from './flat-view-manager.js';
16
16
  * the table's and the kanban's open buttons take. Grouped (B8), each group
17
17
  * draws under the table's group header; drag and drop of rows between groups
18
18
  * is not offered: a row changes group by editing its value.
19
+ *
20
+ * The title is drawn read-only, so a click on it opens the row; the one row
21
+ * named by `editingTitleimport {
22
+ popFilterableSimpleMenu,
23
+ popupTargetFromElement,
24
+ } from '../../../affine-components/context-menu/index.js';
25
+ import { translateKey } from '../../../affine-shared/services/index.js';
26
+ import { OPEN_LABEL } from '../../../affine-components/translations.js';
27
+ import type { ChromeWording } from '../../../affine-shared/services/index.js';
28
+ import type { UniComponent } from '../../../affine-shared/types/index.js';
29
+ import type { InsertToPosition } from '../../../affine-shared/utils/index.js';
30
+ import { IS_MOBILE } from '../../../global/env/index.js';
31
+ import { CenterPeekIcon } from '@blocksuite/icons/lit';
32
+ import type { BlockStdScope } from '../../../std/index.js';
33
+ import { stdContext } from '../../../std/index.js';
34
+ import { consume } from '@lit/context';
35
+ import { signal } from '@preact/signals-core';
36
+ import { cssVarV2 } from '@toeverything/theme/v2';
37
+ import { css, html, nothing, unsafeCSS } from 'lit';
38
+ import { repeat } from 'lit/directives/repeat.js';
39
+
40
+ import { renderCellStatus } from '../../core/component/cell-status/cell-status.js';
41
+ import { GroupTitle } from '../../core/group-by/group-title.js';
42
+ import { firstDrawnRow } from '../../core/group-by/locate-row.js';
43
+ import {
44
+ hideGroupAction,
45
+ renderGroupToggle,
46
+ } from '../../core/group-by/group-visibility.js';
47
+ import type { Group } from '../../core/group-by/trait.js';
48
+ import { isNewTabClick } from '../../core/utils/new-tab-click.js';
49
+ import { renderUniLit } from '../../core/utils/uni-component/uni-component.js';
50
+ import {
51
+ DataViewUIBase,
52
+ DataViewUILogicBase,
53
+ } from '../../core/view/data-view-base.js';
54
+ import type { Property } from '../../core/view-manager/property.js';
55
+ import type { Row } from '../../core/view-manager/row.js';
56
+ import type { FlatSingleView } from './flat-view-manager.js';
57
+
58
+ draws it editable, which is how "New" and the
59
+ * page title's Enter put a title in editing (`editTitle`).
19
60
  */
20
61
  export declare abstract class FlatViewUILogic<View extends FlatSingleView = FlatSingleView> extends DataViewUILogicBase<View> {
62
+ ui$: import("@preact/signals-core").Signal<FlatViewUI<FlatViewUILogic<FlatSingleView<import("./flat-view-manager.js").FlatViewDataType<string>>>> | undefined>;
63
+ /** The row whose title is drawn editable, while it edits. */
64
+ readonly editingTitle$: import("@preact/signals-core").Signal<string | undefined>;
21
65
  clearSelection: () => void;
66
+ /**
67
+ * The page title's Enter (ADR 0035 B13): the first card's or row's title
68
+ * in editing, top of the first unfolded group. Writes nothing.
69
+ */
22
70
  focusFirstCell: () => void;
23
71
  showIndicator: (_evt: MouseEvent) => boolean;
24
72
  hideIndicator: () => void;
25
73
  moveTo: (_id: string, _evt: MouseEvent) => void;
74
+ /**
75
+ * "New" adds the row and puts its title in editing, as a table's "New
76
+ * record" does: it no longer opens the row (product owner, recette
77
+ * P3-15). On a phone, where a card's values are edited in the row page
78
+ * (P7), it still opens it.
79
+ */
26
80
  addRow: (position: InsertToPosition, groupKey?: string) => string | undefined;
81
+ /** Draws the title of `rowId` editable and opens its editor. */
82
+ editTitle(rowId: string): void;
27
83
  abstract renderer: UniComponent<unknown>;
28
84
  /** A Ctrl/Cmd click asks the host for a new tab (ADR 0035 §9a). */
29
85
  openRow: (rowId: string, newTab?: boolean) => void;
30
86
  }
31
87
  export declare abstract class FlatViewUI<Logic extends FlatViewUILogic = FlatViewUILogic> extends DataViewUIBase<Logic> {
88
+ connectedCallback(): void;
32
89
  /** Absent outside an editor (a unit test): the wordings read English. */
33
90
  accessor std: BlockStdScope;
34
91
  protected wording([key, fallback]: ChromeWording): string;
@@ -39,11 +39,13 @@ import { IS_MOBILE } from '../../../global/env/index.js';
39
39
  import { CenterPeekIcon } from '@blocksuite/icons/lit';
40
40
  import { stdContext } from '../../../std/index.js';
41
41
  import { consume } from '@lit/context';
42
+ import { signal } from '@preact/signals-core';
42
43
  import { cssVarV2 } from '@toeverything/theme/v2';
43
44
  import { css, html, nothing, unsafeCSS } from 'lit';
44
45
  import { repeat } from 'lit/directives/repeat.js';
45
46
  import { renderCellStatus } from '../../core/component/cell-status/cell-status.js';
46
47
  import { GroupTitle } from '../../core/group-by/group-title.js';
48
+ import { firstDrawnRow } from '../../core/group-by/locate-row.js';
47
49
  import { hideGroupAction, renderGroupToggle, } from '../../core/group-by/group-visibility.js';
48
50
  import { isNewTabClick } from '../../core/utils/new-tab-click.js';
49
51
  import { renderUniLit } from '../../core/utils/uni-component/uni-component.js';
@@ -56,21 +58,84 @@ import { DataViewUIBase, DataViewUILogicBase, } from '../../core/view/data-view-
56
58
  * the table's and the kanban's open buttons take. Grouped (B8), each group
57
59
  * draws under the table's group header; drag and drop of rows between groups
58
60
  * is not offered: a row changes group by editing its value.
61
+ *
62
+ * The title is drawn read-only, so a click on it opens the row; the one row
63
+ * named by `editingTitleimport {
64
+ popFilterableSimpleMenu,
65
+ popupTargetFromElement,
66
+ } from '../../../affine-components/context-menu/index.js';
67
+ import { translateKey } from '../../../affine-shared/services/index.js';
68
+ import { OPEN_LABEL } from '../../../affine-components/translations.js';
69
+ import type { ChromeWording } from '../../../affine-shared/services/index.js';
70
+ import type { UniComponent } from '../../../affine-shared/types/index.js';
71
+ import type { InsertToPosition } from '../../../affine-shared/utils/index.js';
72
+ import { IS_MOBILE } from '../../../global/env/index.js';
73
+ import { CenterPeekIcon } from '@blocksuite/icons/lit';
74
+ import type { BlockStdScope } from '../../../std/index.js';
75
+ import { stdContext } from '../../../std/index.js';
76
+ import { consume } from '@lit/context';
77
+ import { signal } from '@preact/signals-core';
78
+ import { cssVarV2 } from '@toeverything/theme/v2';
79
+ import { css, html, nothing, unsafeCSS } from 'lit';
80
+ import { repeat } from 'lit/directives/repeat.js';
81
+
82
+ import { renderCellStatus } from '../../core/component/cell-status/cell-status.js';
83
+ import { GroupTitle } from '../../core/group-by/group-title.js';
84
+ import { firstDrawnRow } from '../../core/group-by/locate-row.js';
85
+ import {
86
+ hideGroupAction,
87
+ renderGroupToggle,
88
+ } from '../../core/group-by/group-visibility.js';
89
+ import type { Group } from '../../core/group-by/trait.js';
90
+ import { isNewTabClick } from '../../core/utils/new-tab-click.js';
91
+ import { renderUniLit } from '../../core/utils/uni-component/uni-component.js';
92
+ import {
93
+ DataViewUIBase,
94
+ DataViewUILogicBase,
95
+ } from '../../core/view/data-view-base.js';
96
+ import type { Property } from '../../core/view-manager/property.js';
97
+ import type { Row } from '../../core/view-manager/row.js';
98
+ import type { FlatSingleView } from './flat-view-manager.js';
99
+
100
+ draws it editable, which is how "New" and the
101
+ * page title's Enter put a title in editing (`editTitle`).
59
102
  */
60
103
  export class FlatViewUILogic extends DataViewUILogicBase {
61
104
  constructor() {
62
105
  super(...arguments);
106
+ this.ui$ = signal(undefined);
107
+ /** The row whose title is drawn editable, while it edits. */
108
+ this.editingTitle$ = signal(undefined);
63
109
  this.clearSelection = () => { };
64
- this.focusFirstCell = () => { };
110
+ /**
111
+ * The page title's Enter (ADR 0035 B13): the first card's or row's title
112
+ * in editing, top of the first unfolded group. Writes nothing.
113
+ */
114
+ this.focusFirstCell = () => {
115
+ const view = this.view;
116
+ const first = firstDrawnRow(view.groupTrait, view.rows$.peek());
117
+ if (first)
118
+ this.editTitle(first.rowId);
119
+ };
65
120
  this.showIndicator = (_evt) => false;
66
121
  this.hideIndicator = () => { };
67
122
  this.moveTo = (_id, _evt) => { };
123
+ /**
124
+ * "New" adds the row and puts its title in editing, as a table's "New
125
+ * record" does: it no longer opens the row (product owner, recette
126
+ * P3-15). On a phone, where a card's values are edited in the row page
127
+ * (P7), it still opens it.
128
+ */
68
129
  this.addRow = (position, groupKey) => {
69
130
  if (this.view.readonly$.value)
70
131
  return;
71
132
  const rowId = this.view.rowAdd(position, groupKey);
72
- if (rowId)
133
+ if (!rowId)
134
+ return rowId;
135
+ if (IS_MOBILE)
73
136
  this.openRow(rowId);
137
+ else
138
+ this.editTitle(rowId);
74
139
  return rowId;
75
140
  };
76
141
  /** A Ctrl/Cmd click asks the host for a new tab (ADR 0035 §9a). */
@@ -78,6 +143,33 @@ export class FlatViewUILogic extends DataViewUILogicBase {
78
143
  this.root.openDetailPanel({ view: this.view, rowId, newTab });
79
144
  };
80
145
  }
146
+ /** Draws the title of `rowId` editable and opens its editor. */
147
+ editTitle(rowId) {
148
+ if (IS_MOBILE || this.view.readonly$.peek())
149
+ return;
150
+ const titleId = this.view.titleProperty$.peek()?.id;
151
+ if (!titleId)
152
+ return;
153
+ this.editingTitle$.value = rowId;
154
+ // Once the row is drawn and its title re-rendered editable.
155
+ requestAnimationFrame(() => {
156
+ const ui = this.ui$.peek();
157
+ ui?.updateComplete
158
+ .then(() => {
159
+ const row = [
160
+ ...ui.querySelectorAll('[data-row-id]'),
161
+ ].find(element => element.dataset.rowId === rowId);
162
+ const cell = [
163
+ ...(row?.querySelectorAll('dv-standalone-cell') ?? []),
164
+ ].find(element => element.dataset.propertyId === titleId);
165
+ if (cell)
166
+ cell.edit();
167
+ else
168
+ this.editingTitle$.value = undefined;
169
+ })
170
+ .catch(console.error);
171
+ });
172
+ }
81
173
  }
82
174
  let FlatViewUI = (() => {
83
175
  let _classSuper = DataViewUIBase;
@@ -100,6 +192,14 @@ let FlatViewUI = (() => {
100
192
  __esDecorate(this, null, _std_decorators, { kind: "accessor", name: "std", static: false, private: false, access: { has: obj => "std" in obj, get: obj => obj.std, set: (obj, value) => { obj.std = value; } }, metadata: _metadata }, _std_initializers, _std_extraInitializers);
101
193
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
102
194
  }
195
+ connectedCallback() {
196
+ super.connectedCallback();
197
+ this.logic.ui$.value = this;
198
+ this.disposables.add(() => {
199
+ if (this.logic.ui$.peek() === this)
200
+ this.logic.ui$.value = undefined;
201
+ });
202
+ }
103
203
  #std_accessor_storage;
104
204
  /** Absent outside an editor (a unit test): the wordings read English. */
105
205
  get std() { return this.#std_accessor_storage; }
@@ -119,6 +219,10 @@ let FlatViewUI = (() => {
119
219
  */
120
220
  renderCell(property, rowId, readonly = false) {
121
221
  const view = this.view;
222
+ const logic = this.logic;
223
+ const titleEditing = readonly &&
224
+ logic.editingTitle$.value === rowId &&
225
+ view.titleProperty$.value?.id === property.id;
122
226
  const cell = property.cellGetOrCreate(rowId);
123
227
  // As a table cell: a value not yet hydrated mounts no renderer, so nothing
124
228
  // can be edited over it (ADR 0035 §9e).
@@ -129,11 +233,16 @@ let FlatViewUI = (() => {
129
233
  return html `<dv-standalone-cell
130
234
  data-property-id="${property.id}"
131
235
  .cell="${cell}"
132
- .readonly="${readonly ||
236
+ .readonly="${(readonly && !titleEditing) ||
133
237
  IS_MOBILE ||
134
238
  view.readonly$.value ||
135
239
  property.readonly$.value}"
136
- .onEditingChange="${(editing) => view.lockRows(editing)}"
240
+ .onEditingChange="${(editing) => {
241
+ view.lockRows(editing);
242
+ if (!editing && logic.editingTitle$.peek() === rowId) {
243
+ logic.editingTitle$.value = undefined;
244
+ }
245
+ }}"
137
246
  ></dv-standalone-cell>`;
138
247
  }
139
248
  renderOpenButton(rowId) {
@@ -165,8 +165,9 @@ export class GalleryViewUI extends FlatViewUI {
165
165
  </div>`;
166
166
  }
167
167
  renderNewCard(groupKey) {
168
- if (this.view.readonly$.value)
168
+ if (this.view.readonly$.value || this.view.rowsLocked$.value) {
169
169
  return nothing;
170
+ }
170
171
  return html `<button
171
172
  class="dv-gallery-new"
172
173
  data-testid="dv-flat-new"
@@ -1,4 +1,3 @@
1
- export * from './calendar/index.js';
2
1
  export * from './convert.js';
3
2
  export * from './flat/flat-view-manager.js';
4
3
  export * from './gallery/index.js';
@@ -8,7 +7,6 @@ export * from './table/index.js';
8
7
  export declare const viewPresets: {
9
8
  tableViewMeta: import("../index.js").ViewMeta<"table", import("./index.js").TableViewData>;
10
9
  kanbanViewMeta: import("../index.js").ViewMeta<"kanban", import("./index.js").KanbanViewData>;
11
- calendarViewMeta: import("../index.js").ViewMeta<"calendar", import("./index.js").CalendarViewData>;
12
10
  galleryViewMeta: import("../index.js").ViewMeta<"gallery", import("./index.js").GalleryViewData>;
13
11
  listViewMeta: import("../index.js").ViewMeta<"list", import("./index.js").ListViewData>;
14
12
  };
@@ -1,9 +1,7 @@
1
- import { calendarViewMeta } from './calendar/index.js';
2
1
  import { galleryViewMeta } from './gallery/index.js';
3
2
  import { kanbanViewMeta } from './kanban/index.js';
4
3
  import { listViewMeta } from './list/index.js';
5
4
  import { tableViewMeta } from './table/index.js';
6
- export * from './calendar/index.js';
7
5
  export * from './convert.js';
8
6
  export * from './flat/flat-view-manager.js';
9
7
  export * from './gallery/index.js';
@@ -13,7 +11,6 @@ export * from './table/index.js';
13
11
  export const viewPresets = {
14
12
  tableViewMeta: tableViewMeta,
15
13
  kanbanViewMeta: kanbanViewMeta,
16
- calendarViewMeta: calendarViewMeta,
17
14
  galleryViewMeta: galleryViewMeta,
18
15
  listViewMeta: listViewMeta,
19
16
  };
@@ -84,6 +84,8 @@ export class KanbanSingleView extends SingleViewBase {
84
84
  }
85
85
  addCard(position, group) {
86
86
  const id = this.rowAdd(position);
87
+ if (!id)
88
+ return id;
87
89
  this.groupTrait.addToGroup(id, group);
88
90
  const filter = this.filter$.value;
89
91
  if (filter.conditions.length > 0) {
@@ -44,7 +44,9 @@ import { html } from 'lit/static-html.js';
44
44
  import { GroupTitle } from '../../../core/group-by/group-title.js';
45
45
  import { groupToggleStyles, hideGroupAction, renderGroupToggle, } from '../../../core/group-by/group-visibility.js';
46
46
  import { dragHandler } from '../../../core/utils/wc-dnd/dnd-context.js';
47
- import { wordingOf } from '../../../core/utils/wording.js';
47
+ import { wordingOf, wordingFrom } from '../../../core/utils/wording.js';
48
+ import { DATA_VIEW_GROUP_DELETE_CARDS, DATA_VIEW_GROUP_ADD, } from '../../../translations.js';
49
+ import { TOOLBAR_UNGROUP } from '../../../../affine-shared/services/index.js';
48
50
  const styles = css `
49
51
  mobile-kanban-group {
50
52
  width: 260px;
@@ -162,7 +164,7 @@ let MobileKanbanGroup = (() => {
162
164
  ></mobile-kanban-card>
163
165
  `;
164
166
  })}
165
- ${this.view.readonly$.value
167
+ ${this.view.readonly$.value || this.view.rowsLocked$.value
166
168
  ? nothing
167
169
  : html ` <div class="mobile-add-card" @click="${this.clickAddCard}">
168
170
  <div
@@ -170,7 +172,7 @@ let MobileKanbanGroup = (() => {
170
172
  >
171
173
  ${AddCursorIcon()}
172
174
  </div>
173
- Add
175
+ ${wordingFrom(this)(DATA_VIEW_GROUP_ADD)}
174
176
  </div>`}
175
177
  </div>
176
178
  `;
@@ -201,7 +203,7 @@ let MobileKanbanGroup = (() => {
201
203
  menu.group({
202
204
  items: [
203
205
  menu.action({
204
- name: 'Ungroup',
206
+ name: wordingFrom(this)(TOOLBAR_UNGROUP),
205
207
  hide: () => this.group.value == null,
206
208
  select: () => {
207
209
  this.group.rows.forEach(row => {
@@ -212,7 +214,7 @@ let MobileKanbanGroup = (() => {
212
214
  }),
213
215
  hideGroupAction(this.group, wordingOf(this.std)),
214
216
  menu.action({
215
- name: 'Delete Cards',
217
+ name: wordingFrom(this)(DATA_VIEW_GROUP_DELETE_CARDS),
216
218
  select: () => {
217
219
  this.view.rowsDelete(this.group.rows.map(row => row.rowId));
218
220
  this.requestUpdate();
@@ -7,6 +7,11 @@ export declare class MobileKanbanViewUILogic extends DataViewUILogicBase<KanbanS
7
7
  ui$: import("@preact/signals-core").Signal<MobileKanbanViewUI | undefined>;
8
8
  private get readonly();
9
9
  clearSelection: () => void;
10
+ /**
11
+ * The toolbar's "+" adds the card and puts its title in editing, as on
12
+ * the desktop board: it no longer opens the card (product owner, recette
13
+ * P3-15). Nothing is written but the row.
14
+ */
10
15
  addRow: (position: InsertToPosition) => string | undefined;
11
16
  focusFirstCell: () => void;
12
17
  showIndicator: (_evt: MouseEvent) => boolean;
@@ -7,6 +7,7 @@ import { repeat } from 'lit/directives/repeat.js';
7
7
  import { styleMap } from 'lit/directives/style-map.js';
8
8
  import { html } from 'lit/static-html.js';
9
9
  import { createUniComponentFromWebComponent, renderUniLit, } from '../../../core/index.js';
10
+ import { locateRow } from '../../../core/group-by/locate-row.js';
10
11
  import { sortable } from '../../../core/utils/wc-dnd/sort/sort-context.js';
11
12
  import { DataViewUIBase, DataViewUILogicBase, } from '../../../core/view/data-view-base.js';
12
13
  const mobileKanbanViewWrapper = css({
@@ -38,14 +39,35 @@ export class MobileKanbanViewUILogic extends DataViewUILogicBase {
38
39
  super(...arguments);
39
40
  this.ui$ = signal(undefined);
40
41
  this.clearSelection = () => { };
42
+ /**
43
+ * The toolbar's "+" adds the card and puts its title in editing, as on
44
+ * the desktop board: it no longer opens the card (product owner, recette
45
+ * P3-15). Nothing is written but the row.
46
+ */
41
47
  this.addRow = (position) => {
42
48
  if (this.readonly)
43
49
  return;
44
50
  const id = this.view.rowAdd(position);
45
51
  this.ui$.value?.requestUpdate();
46
- // The toolbar's "+" opens the new card, as on the desktop board (P7).
47
- if (id)
48
- this.root.openDetailPanel({ view: this.view, rowId: id });
52
+ if (!id)
53
+ return;
54
+ requestAnimationFrame(() => {
55
+ const view = this.view;
56
+ const at = locateRow(view.groupTrait, view.rows$.peek(), id);
57
+ const columnId = view.mainProperties$.peek().titleColumn || view.propertyIds$.peek()[0];
58
+ if (!at || at.groupKey === undefined || !columnId)
59
+ return;
60
+ // The phone cells follow the logic's selection (`mobile/cell.ts`).
61
+ this.setSelection({
62
+ viewId: view.id,
63
+ type: 'kanban',
64
+ selectionType: 'cell',
65
+ groupKey: at.groupKey,
66
+ cardId: id,
67
+ columnId,
68
+ isEditing: true,
69
+ });
70
+ });
49
71
  return id;
50
72
  };
51
73
  this.focusFirstCell = () => { };
@@ -2,6 +2,8 @@ import { menu, popFilterableSimpleMenu, } from '../../../../affine-components/co
2
2
  import { ArrowRightBigIcon, DeleteIcon, ExpandFullIcon, MoveLeftIcon, MoveRightIcon, } from '@blocksuite/icons/lit';
3
3
  import { html } from 'lit';
4
4
  import { groupTraitKey } from '../../../core/group-by/trait.js';
5
+ import { DATA_VIEW_CARD_EXPAND, DATA_VIEW_CARD_MOVE_TO, DATA_VIEW_ROW_INSERT_BEFORE, DATA_VIEW_ROW_INSERT_AFTER, DATA_VIEW_CARD_DELETE, DATA_VIEW_UNGROUPED, } from '../../../translations.js';
6
+ import { wordingFrom } from '../../../core/utils/wording.js';
5
7
  export const popCardMenu = (ele, groupKey, cardId, kanbanViewLogic) => {
6
8
  const groupTrait = kanbanViewLogic.view.traitGet(groupTraitKey);
7
9
  if (!groupTrait) {
@@ -11,7 +13,7 @@ export const popCardMenu = (ele, groupKey, cardId, kanbanViewLogic) => {
11
13
  menu.group({
12
14
  items: [
13
15
  menu.action({
14
- name: 'Expand Card',
16
+ name: wordingFrom(ele.element)(DATA_VIEW_CARD_EXPAND),
15
17
  prefix: ExpandFullIcon(),
16
18
  select: () => {
17
19
  kanbanViewLogic.root.openDetailPanel({
@@ -25,7 +27,7 @@ export const popCardMenu = (ele, groupKey, cardId, kanbanViewLogic) => {
25
27
  menu.group({
26
28
  items: [
27
29
  menu.subMenu({
28
- name: 'Move To',
30
+ name: wordingFrom(ele.element)(DATA_VIEW_CARD_MOVE_TO),
29
31
  prefix: ArrowRightBigIcon(),
30
32
  options: {
31
33
  items: groupTrait.groupsDataList$.value
@@ -34,7 +36,9 @@ export const popCardMenu = (ele, groupKey, cardId, kanbanViewLogic) => {
34
36
  })
35
37
  .map(group => {
36
38
  return menu.action({
37
- name: group.value != null ? group.name$.value : 'Ungroup',
39
+ name: group.value != null
40
+ ? group.name$.value
41
+ : wordingFrom(ele.element)(DATA_VIEW_UNGROUPED),
38
42
  select: () => {
39
43
  groupTrait.moveCardTo(cardId, groupKey, group.key, 'start');
40
44
  },
@@ -48,7 +52,8 @@ export const popCardMenu = (ele, groupKey, cardId, kanbanViewLogic) => {
48
52
  name: '',
49
53
  items: [
50
54
  menu.action({
51
- name: 'Insert Before',
55
+ name: wordingFrom(ele.element)(DATA_VIEW_ROW_INSERT_BEFORE),
56
+ hide: () => kanbanViewLogic.view.rowsLocked$.value,
52
57
  prefix: html ` <div
53
58
  style="transform: rotate(90deg);display:flex;align-items:center;"
54
59
  >
@@ -60,7 +65,8 @@ export const popCardMenu = (ele, groupKey, cardId, kanbanViewLogic) => {
60
65
  },
61
66
  }),
62
67
  menu.action({
63
- name: 'Insert After',
68
+ name: wordingFrom(ele.element)(DATA_VIEW_ROW_INSERT_AFTER),
69
+ hide: () => kanbanViewLogic.view.rowsLocked$.value,
64
70
  prefix: html ` <div
65
71
  style="transform: rotate(90deg);display:flex;align-items:center;"
66
72
  >
@@ -76,7 +82,7 @@ export const popCardMenu = (ele, groupKey, cardId, kanbanViewLogic) => {
76
82
  menu.group({
77
83
  items: [
78
84
  menu.action({
79
- name: 'Delete Card',
85
+ name: wordingFrom(ele.element)(DATA_VIEW_CARD_DELETE),
80
86
  class: {
81
87
  'delete-item': true,
82
88
  },
@@ -16,7 +16,15 @@ export declare class KanbanSelectionController implements ReactiveController {
16
16
  clear(): void;
17
17
  deleteCard(): void;
18
18
  focus(selection: KanbanViewSelection): void;
19
+ /**
20
+ * The first card's title in editing (the page title's Enter, ADR 0035
21
+ * B13): the first card of the first unfolded group that has one, not of
22
+ * the first group, which is often an empty "Ungrouped".
23
+ */
19
24
  focusFirstCell(): void;
25
+ /** Selects the title cell of the card `rowId` in editing. */
26
+ editCardTitle(rowId: string): void;
27
+ private editTitle;
20
28
  focusIn(): void;
21
29
  focusNext(position: 'up' | 'down' | 'left' | 'right'): void;
22
30
  focusOut(): void;
@@ -1,4 +1,5 @@
1
1
  import { BlockSuiteError, ErrorCode } from '../../../../../global/exceptions/index.js';
2
+ import { firstDrawnRow, locateRow, } from '../../../../core/group-by/locate-row.js';
2
3
  import { KanbanCard } from '../card.js';
3
4
  import { KanbanCell } from '../cell.js';
4
5
  export class KanbanSelectionController {
@@ -143,19 +144,37 @@ export class KanbanSelectionController {
143
144
  container.focus();
144
145
  }
145
146
  }
147
+ /**
148
+ * The first card's title in editing (the page title's Enter, ADR 0035
149
+ * B13): the first card of the first unfolded group that has one, not of
150
+ * the first group, which is often an empty "Ungrouped".
151
+ */
146
152
  focusFirstCell() {
147
- const group = this.logic.groups$.value?.[0];
148
- const card = group?.rows[0];
149
- const columnId = card && this.view.getHeaderTitle(card.rowId)?.id;
150
- if (group && card && columnId) {
151
- this.selection = {
152
- selectionType: 'cell',
153
- groupKey: group.key,
154
- cardId: card.rowId,
155
- columnId,
156
- isEditing: false,
157
- };
158
- }
153
+ const view = this.view;
154
+ const first = firstDrawnRow(view.groupTrait, view.rows$.peek());
155
+ if (first)
156
+ this.editTitle(first);
157
+ }
158
+ /** Selects the title cell of the card `rowId` in editing. */
159
+ editCardTitle(rowId) {
160
+ const view = this.view;
161
+ const at = locateRow(view.groupTrait, view.rows$.peek(), rowId);
162
+ if (at)
163
+ this.editTitle(at);
164
+ }
165
+ editTitle(at) {
166
+ // The column a group's own "New" edits (`pc/group.ts`).
167
+ const columnId = this.view.mainProperties$.peek().titleColumn ||
168
+ this.view.propertyIds$.peek()[0];
169
+ if (at.groupKey === undefined || !columnId)
170
+ return;
171
+ this.selection = {
172
+ selectionType: 'cell',
173
+ groupKey: at.groupKey,
174
+ cardId: at.rowId,
175
+ columnId,
176
+ isEditing: true,
177
+ };
159
178
  }
160
179
  focusIn() {
161
180
  const host = this.host;
@@ -398,6 +417,8 @@ export class KanbanSelectionController {
398
417
  }
399
418
  const { cardId, groupKey } = selection.cards[0];
400
419
  const id = this.view.addCard({ before: false, id: cardId }, groupKey);
420
+ if (!id)
421
+ return;
401
422
  requestAnimationFrame(() => {
402
423
  const columnId = this.view.mainProperties$.value.titleColumn;
403
424
  if (columnId) {
@@ -429,6 +450,8 @@ export class KanbanSelectionController {
429
450
  }
430
451
  const { cardId, groupKey } = selection.cards[0];
431
452
  const id = this.view.addCard({ before: true, id: cardId }, groupKey);
453
+ if (!id)
454
+ return;
432
455
  requestAnimationFrame(() => {
433
456
  const columnId = this.view.mainProperties$.value.titleColumn;
434
457
  if (columnId) {