@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.
- package/dist/_pkgs/affine-block-data-view/configs/slash-menu.js +3 -1
- package/dist/_pkgs/affine-block-data-view/view.d.ts +17 -1
- package/dist/_pkgs/affine-block-data-view/view.js +21 -2
- package/dist/_pkgs/affine-block-database/commands.d.ts +2 -2
- package/dist/_pkgs/affine-block-database/commands.js +3 -3
- package/dist/_pkgs/affine-block-database/components/values-banner.d.ts +28 -0
- package/dist/_pkgs/affine-block-database/components/values-banner.js +199 -0
- package/dist/_pkgs/affine-block-database/configs/slash-menu.d.ts +6 -1
- package/dist/_pkgs/affine-block-database/configs/slash-menu.js +57 -70
- package/dist/_pkgs/affine-block-database/data-source.d.ts +9 -5
- package/dist/_pkgs/affine-block-database/data-source.js +11 -7
- package/dist/_pkgs/affine-block-database/database-block-styles.d.ts +2 -0
- package/dist/_pkgs/affine-block-database/database-block-styles.js +15 -0
- package/dist/_pkgs/affine-block-database/database-block.d.ts +23 -0
- package/dist/_pkgs/affine-block-database/database-block.js +141 -19
- package/dist/_pkgs/affine-block-database/effects.js +2 -0
- package/dist/_pkgs/affine-block-database/external-data-source.d.ts +69 -2
- package/dist/_pkgs/affine-block-database/external-data-source.js +88 -16
- package/dist/_pkgs/affine-block-database/index.d.ts +2 -0
- package/dist/_pkgs/affine-block-database/index.js +2 -0
- package/dist/_pkgs/affine-block-database/linked-view.d.ts +38 -0
- package/dist/_pkgs/affine-block-database/linked-view.js +109 -0
- package/dist/_pkgs/affine-block-database/properties/index.d.ts +2 -0
- package/dist/_pkgs/affine-block-database/properties/index.js +2 -0
- package/dist/_pkgs/affine-block-database/properties/text/hosted.d.ts +15 -0
- package/dist/_pkgs/affine-block-database/properties/text/hosted.js +24 -0
- package/dist/_pkgs/affine-block-database/properties/title/hosted.d.ts +16 -0
- package/dist/_pkgs/affine-block-database/properties/title/hosted.js +42 -0
- package/dist/_pkgs/affine-block-database/service/index.d.ts +3 -0
- package/dist/_pkgs/affine-block-database/service/index.js +3 -0
- package/dist/_pkgs/affine-block-database/service/new-row-menu.d.ts +49 -0
- package/dist/_pkgs/affine-block-database/service/new-row-menu.js +21 -0
- package/dist/_pkgs/affine-block-database/service/open-row.d.ts +77 -0
- package/dist/_pkgs/affine-block-database/service/open-row.js +62 -0
- package/dist/_pkgs/affine-block-database/service/properties-panel.d.ts +23 -0
- package/dist/_pkgs/affine-block-database/service/properties-panel.js +33 -0
- package/dist/_pkgs/affine-block-database/translations.d.ts +10 -0
- package/dist/_pkgs/affine-block-database/translations.js +35 -0
- package/dist/_pkgs/affine-block-database/view-creation.d.ts +10 -0
- package/dist/_pkgs/affine-block-database/view-creation.js +14 -0
- package/dist/_pkgs/affine-block-database/view.d.ts +31 -1
- package/dist/_pkgs/affine-block-database/view.js +48 -4
- package/dist/_pkgs/affine-block-database/views/index.d.ts +30 -3
- package/dist/_pkgs/affine-block-database/views/index.js +44 -3
- package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/new-doc.d.ts +25 -0
- package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/new-doc.js +71 -0
- package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/slash-menu.js +3 -11
- package/dist/_pkgs/affine-components/date-picker/date-picker.d.ts +20 -0
- package/dist/_pkgs/affine-components/date-picker/date-picker.js +60 -26
- package/dist/_pkgs/affine-components/date-picker/style.js +1 -0
- package/dist/_pkgs/affine-components/translations.d.ts +4 -0
- package/dist/_pkgs/affine-components/translations.js +26 -0
- package/dist/_pkgs/affine-fragment-doc-title/doc-title.d.ts +18 -0
- package/dist/_pkgs/affine-fragment-doc-title/doc-title.js +41 -2
- package/dist/_pkgs/affine-fragment-doc-title/index.d.ts +1 -1
- package/dist/_pkgs/affine-fragment-doc-title/index.js +1 -1
- package/dist/_pkgs/affine-fragment-doc-title/title-band/band-cell.d.ts +30 -0
- package/dist/_pkgs/affine-fragment-doc-title/title-band/band-cell.js +137 -0
- package/dist/_pkgs/affine-fragment-doc-title/title-band/format.d.ts +7 -19
- package/dist/_pkgs/affine-fragment-doc-title/title-band/format.js +0 -38
- package/dist/_pkgs/affine-fragment-doc-title/title-band/show-here.d.ts +19 -0
- package/dist/_pkgs/affine-fragment-doc-title/title-band/show-here.js +61 -0
- package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.d.ts +33 -18
- package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.js +263 -205
- package/dist/_pkgs/affine-fragment-doc-title/translations.d.ts +7 -4
- package/dist/_pkgs/affine-fragment-doc-title/translations.js +12 -9
- package/dist/_pkgs/affine-model/blocks/database/types.d.ts +16 -0
- package/dist/_pkgs/affine-model/blocks/database/types.js +5 -1
- package/dist/_pkgs/affine-shared/services/data-source-picker-service.d.ts +139 -0
- package/dist/_pkgs/affine-shared/services/data-source-picker-service.js +22 -0
- package/dist/_pkgs/affine-shared/services/index.d.ts +1 -0
- package/dist/_pkgs/affine-shared/services/index.js +1 -0
- package/dist/_pkgs/affine-shared/services/linked-doc-creation-service.d.ts +15 -6
- package/dist/_pkgs/affine-shared/services/telemetry-service/database.d.ts +59 -0
- package/dist/_pkgs/affine-shared/services/title-band-service.d.ts +34 -7
- package/dist/_pkgs/affine-shared/utils/model/doc.d.ts +10 -2
- package/dist/_pkgs/affine-shared/utils/model/doc.js +17 -7
- package/dist/_pkgs/data-view/core/component/cell-status/cell-status-css.d.ts +2 -0
- package/dist/_pkgs/data-view/core/component/cell-status/cell-status-css.js +16 -0
- package/dist/_pkgs/data-view/core/component/cell-status/cell-status.d.ts +10 -0
- package/dist/_pkgs/data-view/core/component/cell-status/cell-status.js +23 -0
- package/dist/_pkgs/data-view/core/component/index.d.ts +1 -0
- package/dist/_pkgs/data-view/core/component/index.js +1 -0
- package/dist/_pkgs/data-view/core/component/overflow/fit.d.ts +26 -0
- package/dist/_pkgs/data-view/core/component/overflow/fit.js +48 -0
- package/dist/_pkgs/data-view/core/component/overflow/overflow.d.ts +26 -3
- package/dist/_pkgs/data-view/core/component/overflow/overflow.js +84 -31
- package/dist/_pkgs/data-view/core/component/tags/colors.d.ts +7 -0
- package/dist/_pkgs/data-view/core/component/tags/colors.js +22 -10
- package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.d.ts +25 -2
- package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.js +81 -32
- package/dist/_pkgs/data-view/core/data-source/base.d.ts +5 -1
- package/dist/_pkgs/data-view/core/data-source/base.js +7 -1
- package/dist/_pkgs/data-view/core/data-source/hydration.d.ts +44 -0
- package/dist/_pkgs/data-view/core/data-source/hydration.js +31 -0
- package/dist/_pkgs/data-view/core/data-source/index.d.ts +1 -0
- package/dist/_pkgs/data-view/core/data-source/index.js +1 -0
- package/dist/_pkgs/data-view/core/data-view.d.ts +22 -2
- package/dist/_pkgs/data-view/core/data-view.js +14 -0
- package/dist/_pkgs/data-view/core/effect.js +4 -0
- package/dist/_pkgs/data-view/core/group-by/collapsed-state.d.ts +3 -0
- package/dist/_pkgs/data-view/core/group-by/collapsed-state.js +59 -0
- package/dist/_pkgs/data-view/core/group-by/group-properties.d.ts +21 -0
- package/dist/_pkgs/data-view/core/group-by/group-properties.js +38 -0
- package/dist/_pkgs/data-view/core/group-by/group-title.js +4 -0
- package/dist/_pkgs/data-view/core/group-by/group-visibility.d.ts +40 -0
- package/dist/_pkgs/data-view/core/group-by/group-visibility.js +291 -0
- package/dist/_pkgs/data-view/core/group-by/setting.d.ts +11 -3
- package/dist/_pkgs/data-view/core/group-by/setting.js +81 -8
- package/dist/_pkgs/data-view/core/group-by/trait.d.ts +22 -0
- package/dist/_pkgs/data-view/core/group-by/trait.js +62 -1
- package/dist/_pkgs/data-view/core/index.d.ts +3 -0
- package/dist/_pkgs/data-view/core/index.js +3 -0
- package/dist/_pkgs/data-view/core/property/base-cell.d.ts +15 -1
- package/dist/_pkgs/data-view/core/property/base-cell.js +28 -3
- package/dist/_pkgs/data-view/core/property/index.d.ts +1 -0
- package/dist/_pkgs/data-view/core/property/index.js +1 -0
- package/dist/_pkgs/data-view/core/property/standalone-cell.d.ts +109 -0
- package/dist/_pkgs/data-view/core/property/standalone-cell.js +324 -0
- package/dist/_pkgs/data-view/core/telemetry.d.ts +16 -0
- package/dist/_pkgs/data-view/core/telemetry.js +22 -0
- package/dist/_pkgs/data-view/core/utils/new-tab-click.d.ts +2 -0
- package/dist/_pkgs/data-view/core/utils/new-tab-click.js +4 -0
- package/dist/_pkgs/data-view/core/utils/wording.d.ts +11 -0
- package/dist/_pkgs/data-view/core/utils/wording.js +9 -0
- package/dist/_pkgs/data-view/core/view/data-view.d.ts +7 -0
- package/dist/_pkgs/data-view/core/view/default-name.d.ts +10 -0
- package/dist/_pkgs/data-view/core/view/default-name.js +14 -0
- package/dist/_pkgs/data-view/core/view/index.d.ts +2 -0
- package/dist/_pkgs/data-view/core/view/index.js +2 -0
- package/dist/_pkgs/data-view/core/view/open-in.d.ts +27 -0
- package/dist/_pkgs/data-view/core/view/open-in.js +39 -0
- package/dist/_pkgs/data-view/core/view-manager/cell.d.ts +5 -0
- package/dist/_pkgs/data-view/core/view-manager/cell.js +11 -0
- package/dist/_pkgs/data-view/core/view-manager/index.d.ts +3 -0
- package/dist/_pkgs/data-view/core/view-manager/index.js +3 -0
- package/dist/_pkgs/data-view/core/view-manager/new-row-menu-opener.d.ts +18 -0
- package/dist/_pkgs/data-view/core/view-manager/new-row-menu-opener.js +2 -0
- package/dist/_pkgs/data-view/core/view-manager/properties-panel-opener.d.ts +8 -0
- package/dist/_pkgs/data-view/core/view-manager/properties-panel-opener.js +9 -0
- package/dist/_pkgs/data-view/core/view-manager/property.d.ts +14 -0
- package/dist/_pkgs/data-view/core/view-manager/single-view.d.ts +28 -1
- package/dist/_pkgs/data-view/core/view-manager/single-view.js +45 -1
- package/dist/_pkgs/data-view/core/view-manager/view-creation.d.ts +49 -0
- package/dist/_pkgs/data-view/core/view-manager/view-creation.js +40 -0
- package/dist/_pkgs/data-view/core/view-manager/view-manager.d.ts +6 -2
- package/dist/_pkgs/data-view/core/view-manager/view-manager.js +2 -2
- package/dist/_pkgs/data-view/property-presets/date/cell-renderer.d.ts +2 -0
- package/dist/_pkgs/data-view/property-presets/date/cell-renderer.js +11 -2
- package/dist/_pkgs/data-view/property-presets/multi-select/cell-renderer.js +3 -1
- package/dist/_pkgs/data-view/property-presets/select/cell-renderer.js +3 -1
- package/dist/_pkgs/data-view/property-presets/text/cell-renderer.js +3 -1
- package/dist/_pkgs/data-view/translations.d.ts +55 -0
- package/dist/_pkgs/data-view/translations.js +181 -0
- package/dist/_pkgs/data-view/view-presets/calendar/define.js +3 -1
- package/dist/_pkgs/data-view/view-presets/convert.js +2 -0
- package/dist/_pkgs/data-view/view-presets/effect.js +4 -0
- package/dist/_pkgs/data-view/view-presets/flat/flat-converts.d.ts +2 -0
- package/dist/_pkgs/data-view/view-presets/flat/flat-converts.js +35 -0
- package/dist/_pkgs/data-view/view-presets/flat/flat-view-manager.d.ts +79 -0
- package/dist/_pkgs/data-view/view-presets/flat/flat-view-manager.js +194 -0
- package/dist/_pkgs/data-view/view-presets/flat/flat-view-ui.d.ts +56 -0
- package/dist/_pkgs/data-view/view-presets/flat/flat-view-ui.js +266 -0
- package/dist/_pkgs/data-view/view-presets/gallery/define.d.ts +14 -0
- package/dist/_pkgs/data-view/view-presets/gallery/define.js +15 -0
- package/dist/_pkgs/data-view/view-presets/gallery/effect.d.ts +1 -0
- package/dist/_pkgs/data-view/view-presets/gallery/effect.js +4 -0
- package/dist/_pkgs/data-view/view-presets/gallery/gallery-view.d.ts +27 -0
- package/dist/_pkgs/data-view/view-presets/gallery/gallery-view.js +179 -0
- package/dist/_pkgs/data-view/view-presets/gallery/index.d.ts +2 -0
- package/dist/_pkgs/data-view/view-presets/gallery/index.js +2 -0
- package/dist/_pkgs/data-view/view-presets/gallery/renderer.d.ts +1 -0
- package/dist/_pkgs/data-view/view-presets/gallery/renderer.js +11 -0
- package/dist/_pkgs/data-view/view-presets/index.d.ts +5 -0
- package/dist/_pkgs/data-view/view-presets/index.js +7 -0
- package/dist/_pkgs/data-view/view-presets/kanban/define.js +3 -1
- package/dist/_pkgs/data-view/view-presets/kanban/kanban-view-manager.js +5 -53
- package/dist/_pkgs/data-view/view-presets/kanban/mobile/card.js +8 -1
- package/dist/_pkgs/data-view/view-presets/kanban/mobile/cell.js +6 -1
- package/dist/_pkgs/data-view/view-presets/kanban/mobile/group.d.ts +4 -2
- package/dist/_pkgs/data-view/view-presets/kanban/mobile/group.js +52 -6
- package/dist/_pkgs/data-view/view-presets/kanban/mobile/kanban-view-ui-logic.js +5 -1
- package/dist/_pkgs/data-view/view-presets/kanban/pc/card.js +2 -0
- package/dist/_pkgs/data-view/view-presets/kanban/pc/cell.js +4 -0
- package/dist/_pkgs/data-view/view-presets/kanban/pc/group.d.ts +4 -2
- package/dist/_pkgs/data-view/view-presets/kanban/pc/group.js +51 -6
- package/dist/_pkgs/data-view/view-presets/kanban/pc/kanban-view-ui-logic.js +5 -1
- package/dist/_pkgs/data-view/view-presets/list/define.d.ts +14 -0
- package/dist/_pkgs/data-view/view-presets/list/define.js +15 -0
- package/dist/_pkgs/data-view/view-presets/list/effect.d.ts +1 -0
- package/dist/_pkgs/data-view/view-presets/list/effect.js +4 -0
- package/dist/_pkgs/data-view/view-presets/list/index.d.ts +2 -0
- package/dist/_pkgs/data-view/view-presets/list/index.js +2 -0
- package/dist/_pkgs/data-view/view-presets/list/list-view.d.ts +24 -0
- package/dist/_pkgs/data-view/view-presets/list/list-view.js +194 -0
- package/dist/_pkgs/data-view/view-presets/list/renderer.d.ts +1 -0
- package/dist/_pkgs/data-view/view-presets/list/renderer.js +11 -0
- package/dist/_pkgs/data-view/view-presets/table/collapsed-state.d.ts +3 -14
- package/dist/_pkgs/data-view/view-presets/table/collapsed-state.js +6 -30
- package/dist/_pkgs/data-view/view-presets/table/consts.d.ts +2 -0
- package/dist/_pkgs/data-view/view-presets/table/consts.js +2 -0
- package/dist/_pkgs/data-view/view-presets/table/define.js +3 -1
- package/dist/_pkgs/data-view/view-presets/table/mobile/cell.js +4 -1
- package/dist/_pkgs/data-view/view-presets/table/mobile/column-header.js +2 -2
- package/dist/_pkgs/data-view/view-presets/table/mobile/group.d.ts +3 -1
- package/dist/_pkgs/data-view/view-presets/table/mobile/group.js +20 -5
- package/dist/_pkgs/data-view/view-presets/table/mobile/row.js +10 -2
- package/dist/_pkgs/data-view/view-presets/table/mobile/table-view-ui-logic.js +4 -1
- package/dist/_pkgs/data-view/view-presets/table/pc/cell.js +4 -1
- package/dist/_pkgs/data-view/view-presets/table/pc/controller/hotkeys.js +1 -1
- package/dist/_pkgs/data-view/view-presets/table/pc/group.d.ts +3 -1
- package/dist/_pkgs/data-view/view-presets/table/pc/group.js +20 -5
- package/dist/_pkgs/data-view/view-presets/table/pc/menu.d.ts +1 -1
- package/dist/_pkgs/data-view/view-presets/table/pc/menu.js +2 -1
- package/dist/_pkgs/data-view/view-presets/table/pc/row/row.js +3 -2
- package/dist/_pkgs/data-view/view-presets/table/pc/table-view-ui-logic.js +4 -1
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/controller/hotkeys.js +1 -1
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/bottom/stats/column-stats-column.js +5 -1
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/top/group-title.js +22 -19
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/row/cell.js +4 -1
- package/dist/_pkgs/data-view/view-presets/table/pc-virtual/table-view-ui-logic.js +7 -2
- package/dist/_pkgs/data-view/view-presets/table/stats/column-stats-column.js +5 -1
- package/dist/_pkgs/data-view/view-presets/table/table-view-manager.js +5 -53
- package/dist/_pkgs/data-view/widget-presets/tools/presets/table-add-row/add-row.d.ts +1 -0
- package/dist/_pkgs/data-view/widget-presets/tools/presets/table-add-row/add-row.js +60 -2
- package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-options.d.ts +18 -1
- package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-options.js +121 -124
- package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-settings.d.ts +43 -0
- package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-settings.js +187 -0
- package/dist/_pkgs/data-view/widget-presets/views-bar/views-view.d.ts +36 -3
- package/dist/_pkgs/data-view/widget-presets/views-bar/views-view.js +187 -59
- package/dist/extensions/view.d.ts +2 -2
- package/dist/extensions/view.js +10 -3
- package/dist/flags.d.ts +8 -4
- package/dist/flags.js +8 -4
- package/dist/frameworks.d.ts +27 -0
- package/dist/frameworks.js +28 -0
- package/dist/translations.js +13 -1
- 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="
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
299
|
+
${this.say(TAG_SELECT_CREATE)}
|
|
279
300
|
</div>`
|
|
280
|
-
:
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
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
|
-
|
|
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:
|
|
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 &&
|
|
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,
|
|
474
|
-
this.#
|
|
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="
|
|
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;">
|
|
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
|
-
|
|
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
|
+
}
|
|
@@ -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():
|
|
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():
|
|
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,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
|
+
};
|