@formicoidea/labre-core 0.48.0 → 0.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +44 -5
- 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-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/title-band/band-cell.d.ts +8 -0
- package/dist/_pkgs/affine-fragment-doc-title/title-band/band-cell.js +12 -0
- package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.d.ts +5 -0
- package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.js +44 -4
- 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/telemetry-service/database.d.ts +59 -0
- package/dist/_pkgs/affine-shared/services/title-band-service.d.ts +24 -0
- 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 +18 -0
- package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.js +63 -21
- 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 +2 -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/standalone-cell.d.ts +15 -1
- package/dist/_pkgs/data-view/core/property/standalone-cell.js +19 -1
- 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 +8 -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 +2 -0
- package/dist/_pkgs/data-view/property-presets/select/cell-renderer.js +2 -0
- 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
|
@@ -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';
|
|
@@ -27,6 +28,7 @@ export function coreEffects() {
|
|
|
27
28
|
customElements.define('data-view-group-title-number-view', NumberGroupView);
|
|
28
29
|
customElements.define('affine-lit-icon', AffineLitIcon);
|
|
29
30
|
customElements.define('data-view-group-setting', GroupSetting);
|
|
31
|
+
customElements.define('dv-hidden-groups', DataViewHiddenGroups);
|
|
30
32
|
customElements.define('affine-multi-tag-select', MultiTagSelect);
|
|
31
33
|
customElements.define('data-view-group-title-boolean-view', BooleanGroupView);
|
|
32
34
|
customElements.define('data-view-group-title-date-view', DateGroupView);
|
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { sortByManually } from './trait.js';
|
|
2
|
+
/**
|
|
3
|
+
* The group ops every grouped preset hands its `GroupTrait`, over the view's
|
|
4
|
+
* stored `groupProperties` (the shape table and kanban have always stored:
|
|
5
|
+
* `{ key, hide, manuallyCardSort }`). One copy for table, kanban, gallery and
|
|
6
|
+
* list (ADR 0035 §8, B8), so a hidden group and a manual order read and write
|
|
7
|
+
* the same way in every view.
|
|
8
|
+
*
|
|
9
|
+
* Every write lists the entry of every group key it is given, so a hidden
|
|
10
|
+
* group keeps its `hide` and its card order through a reorder; nothing is
|
|
11
|
+
* written when the value would not change.
|
|
12
|
+
*/
|
|
13
|
+
export const groupPropertiesOps = (read, write) => {
|
|
14
|
+
const entries = () => new Map(read().map(v => [v.key, v]));
|
|
15
|
+
const entry = (map, key) => map.get(key) ?? { key, hide: false, manuallyCardSort: [] };
|
|
16
|
+
const groupHidden = (key) => read().find(v => v.key === key)?.hide === true;
|
|
17
|
+
return {
|
|
18
|
+
sortGroup: (keys) => sortByManually(keys, v => v, read().map(v => v.key)),
|
|
19
|
+
sortRow: (key, rows) => sortByManually(rows, v => v.rowId, read().find(v => v.key === key)?.manuallyCardSort ?? []),
|
|
20
|
+
changeGroupSort: (keys) => {
|
|
21
|
+
const map = entries();
|
|
22
|
+
write(keys.map(key => entry(map, key)));
|
|
23
|
+
},
|
|
24
|
+
changeRowSort: (groupKeys, groupKey, keys) => {
|
|
25
|
+
const map = entries();
|
|
26
|
+
write(groupKeys.map(key => key === groupKey
|
|
27
|
+
? { ...entry(map, key), manuallyCardSort: keys }
|
|
28
|
+
: entry(map, key)));
|
|
29
|
+
},
|
|
30
|
+
groupHidden,
|
|
31
|
+
groupHideSet: (groupKeys, groupKey, hide) => {
|
|
32
|
+
if (groupHidden(groupKey) === hide)
|
|
33
|
+
return;
|
|
34
|
+
const map = entries();
|
|
35
|
+
write(groupKeys.map(key => key === groupKey ? { ...entry(map, key), hide } : entry(map, key)));
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
};
|
|
@@ -3,8 +3,12 @@ import { IS_MOBILE } from '../../../global/env/index.js';
|
|
|
3
3
|
import { MoreHorizontalIcon, PlusIcon } from '@blocksuite/icons/lit';
|
|
4
4
|
import { nothing } from 'lit';
|
|
5
5
|
import { html } from 'lit/static-html.js';
|
|
6
|
+
import { VALUES_PENDING_MARK, valuesReady } from '../data-source/hydration.js';
|
|
6
7
|
import { renderUniLit } from '../utils/uni-component/uni-component.js';
|
|
7
8
|
function GroupHeaderCount(group) {
|
|
9
|
+
if (!valuesReady(group.property.view.manager.dataSource)) {
|
|
10
|
+
return html ` <div class="group-header-count">${VALUES_PENDING_MARK}</div>`;
|
|
11
|
+
}
|
|
8
12
|
const cards = group.rows;
|
|
9
13
|
if (!cards.length) {
|
|
10
14
|
return;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type MenuConfig } from '../../../affine-components/context-menu/index.js';
|
|
2
|
+
import { type BlockStdScope, ShadowlessElement } from '../../../std/index.js';
|
|
3
|
+
import { nothing } from 'lit';
|
|
4
|
+
import { type Wording } from '../utils/wording.js';
|
|
5
|
+
import type { Group, GroupTrait } from './trait.js';
|
|
6
|
+
/**
|
|
7
|
+
* The group chrome every grouped preset shares (ADR 0035 §8, B8, PRD
|
|
8
|
+
* REQ-DB-16): "Hide group" in a group's menu, the fold toggle of a group
|
|
9
|
+
* header, and the list of hidden groups drawn at the end of the view. Hiding
|
|
10
|
+
* is a view setting, shared by everyone; folding is personal
|
|
11
|
+
* (`collapsed-state.ts`).
|
|
12
|
+
*/
|
|
13
|
+
/** "Hide group", for a group's own menu. Absent where the view hides none. */
|
|
14
|
+
export declare const hideGroupAction: (group: Group, wording: Wording) => MenuConfig;
|
|
15
|
+
/**
|
|
16
|
+
* A group header's fold button. Folding is never a write, so a read-only
|
|
17
|
+
* view folds too.
|
|
18
|
+
*/
|
|
19
|
+
export declare const renderGroupToggle: (group: Group, wording: Wording) => import("lit-html").TemplateResult<1>;
|
|
20
|
+
export declare const groupToggleStyles: import("lit").CSSResult;
|
|
21
|
+
declare const DataViewHiddenGroups_base: typeof ShadowlessElement & import("../../../global/utils/types.js").Constructor<import("../../../global/lit/with-disposable.js").DisposableClass>;
|
|
22
|
+
/**
|
|
23
|
+
* The hidden groups of a view, at its end, each with a button that shows it
|
|
24
|
+
* again (PRD REQ-DB-16). Nothing when the view hides no group. A read-only
|
|
25
|
+
* view lists them without the button.
|
|
26
|
+
*/
|
|
27
|
+
export declare class DataViewHiddenGroups extends DataViewHiddenGroups_base {
|
|
28
|
+
static styles: import("lit").CSSResult;
|
|
29
|
+
/** Absent outside an editor (a unit test): the wordings read English. */
|
|
30
|
+
accessor std: BlockStdScope;
|
|
31
|
+
accessor groupTrait: GroupTrait | undefined;
|
|
32
|
+
connectedCallback(): void;
|
|
33
|
+
render(): import("lit-html").TemplateResult<1> | typeof nothing;
|
|
34
|
+
}
|
|
35
|
+
declare global {
|
|
36
|
+
interface HTMLElementTagNameMap {
|
|
37
|
+
'dv-hidden-groups': DataViewHiddenGroups;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
import { menu } from '../../../affine-components/context-menu/index.js';
|
|
36
|
+
import { SignalWatcher, WithDisposable } from '../../../global/lit/index.js';
|
|
37
|
+
import { InvisibleIcon, ToggleDownIcon, ToggleRightIcon, ViewIcon, } from '@blocksuite/icons/lit';
|
|
38
|
+
import { ShadowlessElement, stdContext } from '../../../std/index.js';
|
|
39
|
+
import { consume } from '@lit/context';
|
|
40
|
+
import { cssVarV2 } from '@toeverything/theme/v2';
|
|
41
|
+
import { css, html, nothing, unsafeCSS } from 'lit';
|
|
42
|
+
import { property } from 'lit/decorators.js';
|
|
43
|
+
import { repeat } from 'lit/directives/repeat.js';
|
|
44
|
+
import { DATA_VIEW_GROUP_COLLAPSE, DATA_VIEW_GROUP_EXPAND, DATA_VIEW_GROUP_HIDE, DATA_VIEW_GROUP_SHOW, DATA_VIEW_HIDDEN_GROUPS, } from '../../translations.js';
|
|
45
|
+
import { VALUES_PENDING_MARK, valuesReady } from '../data-source/hydration.js';
|
|
46
|
+
import { renderUniLit } from '../utils/uni-component/uni-component.js';
|
|
47
|
+
import { wordingOf } from '../utils/wording.js';
|
|
48
|
+
/**
|
|
49
|
+
* The group chrome every grouped preset shares (ADR 0035 §8, B8, PRD
|
|
50
|
+
* REQ-DB-16): "Hide group" in a group's menu, the fold toggle of a group
|
|
51
|
+
* header, and the list of hidden groups drawn at the end of the view. Hiding
|
|
52
|
+
* is a view setting, shared by everyone; folding is personal
|
|
53
|
+
* (`collapsed-state.ts`).
|
|
54
|
+
*/
|
|
55
|
+
/** "Hide group", for a group's own menu. Absent where the view hides none. */
|
|
56
|
+
export const hideGroupAction = (group, wording) => menu.action({
|
|
57
|
+
name: wording(DATA_VIEW_GROUP_HIDE),
|
|
58
|
+
prefix: InvisibleIcon(),
|
|
59
|
+
hide: () => !group.manager.groupsCanHide,
|
|
60
|
+
select: () => {
|
|
61
|
+
group.manager.groupHideSet(group.key, true);
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
const groupCount = (group) => valuesReady(group.property.view.manager.dataSource)
|
|
65
|
+
? group.rows.length
|
|
66
|
+
: VALUES_PENDING_MARK;
|
|
67
|
+
/**
|
|
68
|
+
* A group header's fold button. Folding is never a write, so a read-only
|
|
69
|
+
* view folds too.
|
|
70
|
+
*/
|
|
71
|
+
export const renderGroupToggle = (group, wording) => {
|
|
72
|
+
const collapsed = group.manager.collapsed$(group.key).value;
|
|
73
|
+
const label = wording(collapsed ? DATA_VIEW_GROUP_EXPAND : DATA_VIEW_GROUP_COLLAPSE);
|
|
74
|
+
return html `<button
|
|
75
|
+
class="dv-group-toggle"
|
|
76
|
+
data-testid="dv-group-toggle"
|
|
77
|
+
aria-expanded="${collapsed ? 'false' : 'true'}"
|
|
78
|
+
aria-label="${label}"
|
|
79
|
+
title="${label}"
|
|
80
|
+
@click="${(event) => {
|
|
81
|
+
event.stopPropagation();
|
|
82
|
+
group.manager.collapsedSet(group.key, !collapsed);
|
|
83
|
+
}}"
|
|
84
|
+
>
|
|
85
|
+
${collapsed ? ToggleRightIcon() : ToggleDownIcon()}
|
|
86
|
+
</button>`;
|
|
87
|
+
};
|
|
88
|
+
export const groupToggleStyles = css `
|
|
89
|
+
.dv-group-toggle {
|
|
90
|
+
display: flex;
|
|
91
|
+
flex-shrink: 0;
|
|
92
|
+
align-items: center;
|
|
93
|
+
justify-content: center;
|
|
94
|
+
width: 24px;
|
|
95
|
+
height: 24px;
|
|
96
|
+
padding: 0;
|
|
97
|
+
border: none;
|
|
98
|
+
border-radius: 4px;
|
|
99
|
+
background: transparent;
|
|
100
|
+
color: var(--affine-icon-color);
|
|
101
|
+
cursor: pointer;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.dv-group-toggle svg {
|
|
105
|
+
width: 16px;
|
|
106
|
+
height: 16px;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.dv-group-toggle:focus-visible {
|
|
110
|
+
outline: 2px solid var(--affine-primary-color);
|
|
111
|
+
outline-offset: 1px;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@media (hover: hover) {
|
|
115
|
+
.dv-group-toggle:hover {
|
|
116
|
+
background-color: var(--affine-hover-color);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@media (pointer: coarse) {
|
|
121
|
+
.dv-group-toggle {
|
|
122
|
+
width: 44px;
|
|
123
|
+
height: 44px;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
`;
|
|
127
|
+
/**
|
|
128
|
+
* The hidden groups of a view, at its end, each with a button that shows it
|
|
129
|
+
* again (PRD REQ-DB-16). Nothing when the view hides no group. A read-only
|
|
130
|
+
* view lists them without the button.
|
|
131
|
+
*/
|
|
132
|
+
let DataViewHiddenGroups = (() => {
|
|
133
|
+
let _classSuper = SignalWatcher(WithDisposable(ShadowlessElement));
|
|
134
|
+
let _std_decorators;
|
|
135
|
+
let _std_initializers = [];
|
|
136
|
+
let _std_extraInitializers = [];
|
|
137
|
+
let _groupTrait_decorators;
|
|
138
|
+
let _groupTrait_initializers = [];
|
|
139
|
+
let _groupTrait_extraInitializers = [];
|
|
140
|
+
return class DataViewHiddenGroups extends _classSuper {
|
|
141
|
+
static {
|
|
142
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
143
|
+
_std_decorators = [consume({ context: stdContext })];
|
|
144
|
+
_groupTrait_decorators = [property({ attribute: false })];
|
|
145
|
+
__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);
|
|
146
|
+
__esDecorate(this, null, _groupTrait_decorators, { kind: "accessor", name: "groupTrait", static: false, private: false, access: { has: obj => "groupTrait" in obj, get: obj => obj.groupTrait, set: (obj, value) => { obj.groupTrait = value; } }, metadata: _metadata }, _groupTrait_initializers, _groupTrait_extraInitializers);
|
|
147
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
148
|
+
}
|
|
149
|
+
static { this.styles = css `
|
|
150
|
+
dv-hidden-groups {
|
|
151
|
+
display: block;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.dv-hidden-groups {
|
|
155
|
+
display: flex;
|
|
156
|
+
flex-direction: column;
|
|
157
|
+
gap: 2px;
|
|
158
|
+
padding: 8px 0;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.dv-hidden-groups-title {
|
|
162
|
+
display: flex;
|
|
163
|
+
align-items: center;
|
|
164
|
+
gap: 8px;
|
|
165
|
+
padding: 0 4px 4px;
|
|
166
|
+
font-size: 12px;
|
|
167
|
+
line-height: 20px;
|
|
168
|
+
color: var(--affine-text-secondary-color);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.dv-hidden-group {
|
|
172
|
+
display: flex;
|
|
173
|
+
align-items: center;
|
|
174
|
+
gap: 8px;
|
|
175
|
+
min-height: 32px;
|
|
176
|
+
padding: 0 4px;
|
|
177
|
+
border-radius: 4px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.dv-hidden-group-title {
|
|
181
|
+
flex: 1 1 auto;
|
|
182
|
+
min-width: 0;
|
|
183
|
+
overflow: hidden;
|
|
184
|
+
opacity: 0.7;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.dv-hidden-group-count {
|
|
188
|
+
flex-shrink: 0;
|
|
189
|
+
font-size: 12px;
|
|
190
|
+
color: var(--affine-text-secondary-color);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.dv-hidden-group-show {
|
|
194
|
+
display: flex;
|
|
195
|
+
flex-shrink: 0;
|
|
196
|
+
align-items: center;
|
|
197
|
+
justify-content: center;
|
|
198
|
+
width: 28px;
|
|
199
|
+
height: 28px;
|
|
200
|
+
padding: 0;
|
|
201
|
+
border: 1px solid ${unsafeCSS(cssVarV2.layer.insideBorder.border)};
|
|
202
|
+
border-radius: 4px;
|
|
203
|
+
background: transparent;
|
|
204
|
+
color: var(--affine-icon-color);
|
|
205
|
+
cursor: pointer;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.dv-hidden-group-show svg {
|
|
209
|
+
width: 16px;
|
|
210
|
+
height: 16px;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.dv-hidden-group-show:focus-visible {
|
|
214
|
+
outline: 2px solid var(--affine-primary-color);
|
|
215
|
+
outline-offset: 1px;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
@media (hover: hover) {
|
|
219
|
+
.dv-hidden-group-show:hover {
|
|
220
|
+
background-color: var(--affine-hover-color);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
@media (pointer: coarse) {
|
|
225
|
+
.dv-hidden-group {
|
|
226
|
+
min-height: 44px;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.dv-hidden-group-show {
|
|
230
|
+
width: 44px;
|
|
231
|
+
height: 44px;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
`; }
|
|
235
|
+
#std_accessor_storage = __runInitializers(this, _std_initializers, void 0);
|
|
236
|
+
/** Absent outside an editor (a unit test): the wordings read English. */
|
|
237
|
+
get std() { return this.#std_accessor_storage; }
|
|
238
|
+
set std(value) { this.#std_accessor_storage = value; }
|
|
239
|
+
#groupTrait_accessor_storage = (__runInitializers(this, _std_extraInitializers), __runInitializers(this, _groupTrait_initializers, undefined));
|
|
240
|
+
get groupTrait() { return this.#groupTrait_accessor_storage; }
|
|
241
|
+
set groupTrait(value) { this.#groupTrait_accessor_storage = value; }
|
|
242
|
+
connectedCallback() {
|
|
243
|
+
super.connectedCallback();
|
|
244
|
+
this.dataset.testid = 'dv-hidden-groups';
|
|
245
|
+
}
|
|
246
|
+
render() {
|
|
247
|
+
const trait = this.groupTrait;
|
|
248
|
+
const groups = trait?.hiddenGroups$.value ?? [];
|
|
249
|
+
if (!trait || !groups.length)
|
|
250
|
+
return nothing;
|
|
251
|
+
const wording = wordingOf(this.std);
|
|
252
|
+
const readonly = trait.view.readonly$.value;
|
|
253
|
+
const show = wording(DATA_VIEW_GROUP_SHOW);
|
|
254
|
+
return html `<div class="dv-hidden-groups">
|
|
255
|
+
<div class="dv-hidden-groups-title">
|
|
256
|
+
<span>${wording(DATA_VIEW_HIDDEN_GROUPS)}</span>
|
|
257
|
+
<span>${groups.length}</span>
|
|
258
|
+
</div>
|
|
259
|
+
${repeat(groups, group => group.key, group => {
|
|
260
|
+
const props = { group, readonly: true };
|
|
261
|
+
return html `<div
|
|
262
|
+
class="dv-hidden-group"
|
|
263
|
+
data-testid="dv-hidden-group"
|
|
264
|
+
data-group-key="${group.key}"
|
|
265
|
+
>
|
|
266
|
+
<div class="dv-hidden-group-title">
|
|
267
|
+
${renderUniLit(group.view, props)}
|
|
268
|
+
</div>
|
|
269
|
+
<span class="dv-hidden-group-count">${groupCount(group)}</span>
|
|
270
|
+
${readonly
|
|
271
|
+
? nothing
|
|
272
|
+
: html `<button
|
|
273
|
+
class="dv-hidden-group-show"
|
|
274
|
+
data-testid="dv-group-show"
|
|
275
|
+
aria-label="${show}"
|
|
276
|
+
title="${show}"
|
|
277
|
+
@click="${() => trait.groupHideSet(group.key, false)}"
|
|
278
|
+
>
|
|
279
|
+
${ViewIcon()}
|
|
280
|
+
</button>`}
|
|
281
|
+
</div>`;
|
|
282
|
+
})}
|
|
283
|
+
</div>`;
|
|
284
|
+
}
|
|
285
|
+
constructor() {
|
|
286
|
+
super(...arguments);
|
|
287
|
+
__runInitializers(this, _groupTrait_extraInitializers);
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
})();
|
|
291
|
+
export { DataViewHiddenGroups };
|