alinea 2.0.0-preview.13 → 2.0.0-preview.14
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/.init/content/pages/welcome.json +1 -1
- package/dist/.mcp/later/dev.json +1 -1
- package/dist/.mcp/online/dev.json +1 -1
- package/dist/adapter/next/cms.js +6 -2
- package/dist/adapter/next/context.js +1 -4
- package/dist/adapter/next/handler.js +12 -1
- package/dist/backend/CommitEntries.d.ts +17 -0
- package/dist/backend/CommitEntries.js +39 -0
- package/dist/backend/Handler.d.ts +9 -0
- package/dist/backend/Handler.js +80 -20
- package/dist/backend/api/BasicAuth.js +5 -1
- package/dist/backend/api/CreateBackend.js +2 -2
- package/dist/backend/api/DatabaseApi.js +18 -5
- package/dist/backend/api/GithubApi.d.ts +13 -0
- package/dist/backend/api/GithubApi.js +170 -30
- package/dist/backend/api/database.js +2 -2
- package/dist/backend/util/Syncable.d.ts +6 -0
- package/dist/backend/util/Syncable.js +3 -1
- package/dist/bundled.d.ts +911 -151
- package/dist/chunks/{chunk-5H4D5JQL.js → chunk-2PP7WJUJ.js} +1 -11
- package/dist/chunks/{chunk-QHHMKJUO.js → chunk-7DDPSWRY.js} +465 -2
- package/dist/chunks/{chunk-HOETF6HN.js → chunk-PMGIIYDD.js} +1 -0
- package/dist/chunks/{chunk-3QFSGTGF.js → chunk-SCV3TEXM.js} +1 -1
- package/dist/chunks/{chunk-UPY2RUZF.js → chunk-TWBREZWC.js} +30 -0
- package/dist/cli/Generate.js +20 -7
- package/dist/cli/Mcp.js +1 -1
- package/dist/cli/Serve.js +1 -1
- package/dist/cli/bin.js +1 -1
- package/dist/cli/build/BuildEmitter.d.ts +5 -1
- package/dist/cli/build/BuildEmitter.js +8 -3
- package/dist/cli/generate/CompileConfig.js +10 -6
- package/dist/cli/generate/DevDB.d.ts +4 -1
- package/dist/cli/generate/DevDB.js +15 -7
- package/dist/cli/generate/GenerateDashboard.js +1 -0
- package/dist/cli/generate/MediaLocations.d.ts +18 -0
- package/dist/cli/generate/MediaLocations.js +69 -0
- package/dist/cli/serve/CreateLocalServer.js +1 -0
- package/dist/cli/serve/mcp/DevMcp.js +1 -1
- package/dist/cloud/CloudRemote.js +21 -7
- package/dist/cms.d.ts +4 -2
- package/dist/components/Alert.js +2 -2
- package/dist/components/AppShell.js +2 -2
- package/dist/components/AsyncList.d.ts +52 -0
- package/dist/components/AsyncList.js +69 -0
- package/dist/components/Breadcrumbs.js +6 -6
- package/dist/components/Button.js +4 -4
- package/dist/components/Calendar.js +18 -18
- package/dist/components/Checkbox.js +10 -10
- package/dist/components/CheckboxGroup.js +2 -2
- package/dist/components/Collapsible.js +5 -5
- package/dist/components/ColorSwatch.js +2 -2
- package/dist/components/ColorSwatchPicker.js +4 -4
- package/dist/components/ComboBox.d.ts +27 -9
- package/dist/components/ComboBox.js +40 -9
- package/dist/components/Command.js +13 -13
- package/dist/components/ContentCard.js +28 -28
- package/dist/components/ContentGrid.js +11 -11
- package/dist/components/DataList.js +1 -1
- package/dist/components/DateField.d.ts +4 -0
- package/dist/components/DateField.js +2 -2
- package/dist/components/DatePicker.js +2 -2
- package/dist/components/DateRangePicker.js +2 -2
- package/dist/components/Dialog.d.ts +14 -3
- package/dist/components/Dialog.js +38 -11
- package/dist/components/DropZone.js +6 -6
- package/dist/components/DropdownMenu.js +8 -8
- package/dist/components/Empty.js +4 -4
- package/dist/components/Field.d.ts +1 -1
- package/dist/components/Field.js +18 -12
- package/dist/components/Form.d.ts +23 -0
- package/dist/components/Form.js +64 -0
- package/dist/components/Link.d.ts +8 -1
- package/dist/components/List.js +27 -27
- package/dist/components/MediaPreview.js +5 -5
- package/dist/components/MultipleSelect.d.ts +13 -8
- package/dist/components/MultipleSelect.js +25 -25
- package/dist/components/NavRail.js +7 -7
- package/dist/components/NumberField.d.ts +5 -1
- package/dist/components/NumberField.js +6 -4
- package/dist/components/Page.js +6 -6
- package/dist/components/Popover.js +2 -2
- package/dist/components/PreviewFrame.js +8 -8
- package/dist/components/RadioGroup.js +10 -10
- package/dist/components/Resizable.js +1 -1
- package/dist/components/SearchField.js +8 -8
- package/dist/components/Select.d.ts +13 -10
- package/dist/components/Select.js +18 -32
- package/dist/components/Sheet.js +6 -6
- package/dist/components/Sidebar.js +5 -5
- package/dist/components/SortableList.js +12 -12
- package/dist/components/Spinner.js +4 -4
- package/dist/components/Stack.d.ts +20 -0
- package/dist/components/Stack.js +45 -0
- package/dist/components/Surface.js +1 -1
- package/dist/components/Switch.js +5 -5
- package/dist/components/Table.d.ts +11 -1
- package/dist/components/Table.js +81 -53
- package/dist/components/Tabs.js +6 -6
- package/dist/components/TagGroup.js +10 -10
- package/dist/components/TextField.d.ts +7 -1
- package/dist/components/TextField.js +20 -11
- package/dist/components/TimeField.d.ts +6 -1
- package/dist/components/TimeField.js +51 -26
- package/dist/components/Timestamp.js +1 -1
- package/dist/components/ToggleGroup.js +2 -2
- package/dist/components/Toolbar.js +3 -3
- package/dist/components/Tooltip.js +5 -4
- package/dist/components/Tree.js +27 -27
- package/dist/components/internal/DateControl.js +11 -11
- package/dist/components/internal/FormScope.d.ts +2 -0
- package/dist/components/internal/FormScope.js +8 -0
- package/dist/components/internal/ListBoxGroup.d.ts +12 -0
- package/dist/components/internal/ListBoxGroup.js +46 -0
- package/dist/components/internal/ListBoxOption.d.ts +2 -2
- package/dist/components/internal/ListBoxOption.js +5 -5
- package/dist/components/internal/Locale.js +2 -2
- package/dist/components/internal/PopoverSurface.js +5 -4
- package/dist/components/internal/SelectionCheckbox.js +5 -5
- package/dist/components/internal/Slot.js +1 -1
- package/dist/components/internal/ToggleButton.js +4 -4
- package/dist/components/internal/Trigger.js +2 -2
- package/dist/components/internal/useDragDrop.js +2 -2
- package/dist/components/types.d.ts +4 -0
- package/dist/components.d.ts +3 -0
- package/dist/components.js +3 -0
- package/dist/core/Client.js +12 -1
- package/dist/core/Config.d.ts +6 -0
- package/dist/core/Config.js +12 -0
- package/dist/core/DashboardEntry.d.ts +19 -0
- package/dist/core/DashboardEntry.js +0 -0
- package/dist/core/Document.d.ts +2 -2
- package/dist/core/Document.js +10 -3
- package/dist/core/EntryFields.d.ts +8 -2
- package/dist/core/Field.d.ts +5 -0
- package/dist/core/Filter.d.ts +19 -2
- package/dist/core/Filter.js +5 -0
- package/dist/core/Graph.d.ts +10 -2
- package/dist/core/Overview.d.ts +74 -5
- package/dist/core/Overview.js +1 -0
- package/dist/core/Root.js +1 -1
- package/dist/core/Scope.d.ts +5 -0
- package/dist/core/Scope.js +22 -5
- package/dist/core/Type.d.ts +25 -6
- package/dist/core/Type.js +25 -7
- package/dist/core/db/LocalStore.d.ts +7 -0
- package/dist/core/field/CreateField.d.ts +1 -2
- package/dist/core/source/Source.d.ts +2 -0
- package/dist/core/source/Source.js +11 -0
- package/dist/core/util/Async.d.ts +2 -0
- package/dist/core/util/Async.js +12 -1
- package/dist/core/util/Checks.js +1 -1
- package/dist/core/util/Slugs.js +4 -3
- package/dist/dashboard/App.css +13 -11
- package/dist/dashboard/App.d.ts +1 -0
- package/dist/dashboard/App.js +22 -6
- package/dist/dashboard/Href.d.ts +37 -0
- package/dist/dashboard/Href.js +46 -0
- package/dist/dashboard/app/ActivityStatus.js +34 -12
- package/dist/dashboard/app/AuthView.js +2 -2
- package/dist/dashboard/app/BlockSettings.d.ts +9 -0
- package/dist/dashboard/app/BlockSettings.js +16 -0
- package/dist/dashboard/app/BlockSheet.js +3 -3
- package/dist/dashboard/app/BlockSheetStoryFrame.js +2 -2
- package/dist/dashboard/app/CompactField.js +15 -15
- package/dist/dashboard/app/CroppedImage.js +2 -2
- package/dist/dashboard/app/DashboardLayout.d.ts +1 -1
- package/dist/dashboard/app/DashboardLayout.js +12 -0
- package/dist/dashboard/app/EntryActions.d.ts +11 -0
- package/dist/dashboard/app/EntryActions.js +30 -0
- package/dist/dashboard/app/EntryFields.d.ts +15 -2
- package/dist/dashboard/app/EntryFields.js +26 -5
- package/dist/dashboard/app/EntryHeader.js +17 -7
- package/dist/dashboard/app/EntryReferences.js +2 -2
- package/dist/dashboard/app/EntrySidebar.js +25 -23
- package/dist/dashboard/app/EntrySidebarPreview.js +2 -2
- package/dist/dashboard/app/EntryValidationModal.js +3 -3
- package/dist/dashboard/app/Explorer.js +84 -45
- package/dist/dashboard/app/ExplorerBatchActions.js +4 -4
- package/dist/dashboard/app/ExplorerControls.js +5 -5
- package/dist/dashboard/app/ExplorerList.js +2 -2
- package/dist/dashboard/app/ExplorerModal.js +3 -3
- package/dist/dashboard/app/ExplorerOverviewHeader.d.ts +6 -0
- package/dist/dashboard/app/ExplorerOverviewHeader.js +28 -0
- package/dist/dashboard/app/ExplorerTable.js +7 -7
- package/dist/dashboard/app/ExplorerTabs.d.ts +12 -0
- package/dist/dashboard/app/ExplorerTabs.js +42 -0
- package/dist/dashboard/app/ImageEditor.js +31 -31
- package/dist/dashboard/app/LinkPicker.js +3 -3
- package/dist/dashboard/app/LocaleMenu.js +9 -9
- package/dist/dashboard/app/MediaPreviewCell.js +5 -5
- package/dist/dashboard/app/OverviewCell.js +12 -10
- package/dist/dashboard/app/RemoveDialog.js +5 -0
- package/dist/dashboard/app/SearchBar.js +4 -4
- package/dist/dashboard/app/SettingsTab.d.ts +6 -0
- package/dist/dashboard/app/SettingsTab.js +27 -0
- package/dist/dashboard/app/SidebarTree.js +19 -19
- package/dist/dashboard/app/WorkspaceMenu.js +6 -6
- package/dist/dashboard/app/WorkspaceRoots.js +102 -98
- package/dist/dashboard/app/editor/FileEditor.js +18 -18
- package/dist/dashboard/app/pages/EntryPage.js +42 -39
- package/dist/dashboard/app/pages/RootPage.js +3 -3
- package/dist/dashboard/app/pages/SplashPage.js +94 -79
- package/dist/dashboard/app/pages/UsersPage.js +9 -9
- package/dist/dashboard/app/ui/DashboardModal.js +14 -14
- package/dist/dashboard/atoms/activity.d.ts +1 -0
- package/dist/dashboard/atoms/activity.js +8 -5
- package/dist/dashboard/atoms/config.d.ts +2 -0
- package/dist/dashboard/atoms/dashboard.d.ts +11 -0
- package/dist/dashboard/atoms/dashboard.js +8 -0
- package/dist/dashboard/atoms/editor.d.ts +7 -1
- package/dist/dashboard/atoms/editor.js +14 -2
- package/dist/dashboard/atoms/explorer.d.ts +15 -0
- package/dist/dashboard/atoms/explorer.js +43 -14
- package/dist/dashboard/atoms/graph.d.ts +5 -0
- package/dist/dashboard/atoms/graph.js +26 -1
- package/dist/dashboard/atoms/nav.d.ts +16 -10
- package/dist/dashboard/atoms/nav.js +96 -36
- package/dist/dashboard/atoms/overview.d.ts +26 -4
- package/dist/dashboard/atoms/overview.js +41 -12
- package/dist/dashboard/atoms/root.js +7 -1
- package/dist/dashboard/boot/ActivityEvent.d.ts +1 -1
- package/dist/dashboard/boot/Boot.js +6 -0
- package/dist/dashboard/boot/DashboardWorker.d.ts +6 -0
- package/dist/dashboard/boot/DashboardWorker.js +89 -8
- package/dist/dashboard/boot/LoadWorker.js +3 -0
- package/dist/dashboard/boot/SyncEvent.d.ts +7 -0
- package/dist/dashboard/boot/SyncEvent.js +14 -0
- package/dist/dashboard/boot/WorkerDB.d.ts +1 -0
- package/dist/dashboard/boot/WorkerDB.js +3 -0
- package/dist/dashboard/cms/EntryTable.d.ts +4 -3
- package/dist/dashboard/cms/EntryTable.js +2 -2
- package/dist/dashboard/cms/ViewProps.d.ts +3 -2
- package/dist/dashboard/cms/hooks.d.ts +34 -18
- package/dist/dashboard/cms/hooks.js +43 -18
- package/dist/dashboard/contexts.d.ts +3 -2
- package/dist/dashboard/contexts.js +3 -2
- package/dist/dashboard/hook/UseEntryEditor.d.ts +1 -1
- package/dist/dashboard/hook/UseEntryEditor.js +7 -3
- package/dist/dashboard/icons.d.ts +1 -0
- package/dist/dashboard/icons.js +15 -0
- package/dist/database/BrowserEntryStore.js +35 -13
- package/dist/database/DatabaseTables.js +1 -1
- package/dist/database/EntryDatabase.d.ts +10 -1
- package/dist/database/EntryDatabase.js +31 -10
- package/dist/database/EntryStore.js +1 -11
- package/dist/database/entry/EntryTable.d.ts +5 -3
- package/dist/database/entry/EntryTable.js +25 -8
- package/dist/database/query/Condition.d.ts +4 -1
- package/dist/database/query/Condition.js +16 -5
- package/dist/database/query/EntryQuery.js +59 -7
- package/dist/database/query/Relation.d.ts +13 -1
- package/dist/database/query/Relation.js +19 -1
- package/dist/database/query/Search.d.ts +7 -1
- package/dist/database/query/Search.js +54 -9
- package/dist/database/sync/EntrySyncer.d.ts +2 -0
- package/dist/database/sync/EntrySyncer.js +4 -2
- package/dist/database/sync/Ingest.d.ts +2 -1
- package/dist/database/sync/Ingest.js +20 -6
- package/dist/field/code/CodeField.view.js +12 -12
- package/dist/field/link/EntryLink.d.ts +4 -5
- package/dist/field/link/FileLink.d.ts +2 -2
- package/dist/field/link/ImageLink.d.ts +2 -5
- package/dist/field/link/ImageLink.js +0 -1
- package/dist/field/link/LinkField.view.js +18 -15
- package/dist/field/list/ListField.view.js +50 -35
- package/dist/field/metadata/MetadataField.view.js +14 -14
- package/dist/field/richtext/RichTextBlock.js +39 -35
- package/dist/field/richtext/RichTextExtensions.js +23 -23
- package/dist/field/richtext/RichTextField.view.js +6 -6
- package/dist/field/richtext/RichTextInsertMenu.js +5 -5
- package/dist/field/richtext/RichTextToolbar.js +26 -1
- package/dist/field/richtext/Toolbar.d.ts +9 -1
- package/dist/field/richtext/Toolbar.js +12 -2
- package/dist/field/select/SelectField.view.js +1 -0
- package/dist/index.css +174 -23
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/next.d.ts +2 -0
- package/dist/next.edge.d.ts +2 -0
- package/dist/picker/entry/EntryPicker.d.ts +3 -1
- package/dist/picker/entry/EntryPicker.js +15 -1
- package/dist/preview/react.js +3 -0
- package/dist/query.d.ts +26 -14
- package/dist/query.js +4 -0
- package/dist/types.d.ts +8 -5
- package/dist/ui/Stack.d.ts +4 -2
- package/docs/ai-setup.md +3 -3
- package/docs/cli.md +4 -2
- package/docs/components/combo-box.md +105 -16
- package/docs/components/date-field.md +1 -1
- package/docs/components/dialog.md +51 -0
- package/docs/components/form.md +67 -0
- package/docs/components/link.md +10 -0
- package/docs/components/multiple-select.md +9 -17
- package/docs/components/number-field.md +5 -1
- package/docs/components/select.md +9 -20
- package/docs/components/stack.md +42 -0
- package/docs/components/table.md +83 -0
- package/docs/components/text-field.md +9 -1
- package/docs/components/time-field.md +5 -1
- package/docs/components.md +39 -1
- package/docs/configuration.md +3 -1
- package/docs/custom-fields.md +135 -7
- package/docs/deploy/self-host.md +2 -0
- package/docs/deploy.md +7 -4
- package/docs/fields/image.md +0 -1
- package/docs/fields/list.md +19 -0
- package/docs/fields/object.md +5 -3
- package/docs/fields/rich-text.md +31 -0
- package/docs/index.md +8 -6
- package/docs/instant-publishing.md +23 -2
- package/docs/overviews.md +128 -4
- package/docs/query/filtering.md +2 -0
- package/docs/query/related.md +58 -9
- package/docs/query.md +52 -1
- package/docs/quickstart.md +5 -5
- package/docs/schema/document.md +2 -0
- package/docs/schema/type.md +3 -1
- package/docs/upgrading.md +100 -19
- package/llms-full.txt +1022 -125
- package/package.json +1 -1
- package/readme.md +2 -2
- package/dist/chunks/{chunk-4ZA6KZHS.js → chunk-6FQ5IMNA.js} +3 -3
|
@@ -2,6 +2,7 @@ import type { DragTypes, DropTarget, Key } from 'alinea/components';
|
|
|
2
2
|
import type { Config } from 'alinea/core/Config';
|
|
3
3
|
import { type EntryStatus } from 'alinea/core/Entry';
|
|
4
4
|
import type { EntryFields } from 'alinea/core/EntryFields';
|
|
5
|
+
import { type OpenFilter } from 'alinea/core/Filter';
|
|
5
6
|
import type { Filter } from 'alinea/core/Filter';
|
|
6
7
|
import type { GraphQuery } from 'alinea/core/Graph';
|
|
7
8
|
import type { OverviewSort } from 'alinea/core/Overview';
|
|
@@ -74,6 +75,11 @@ export interface ExplorerOptions {
|
|
|
74
75
|
* explorer. The explorers of a root share them.
|
|
75
76
|
*/
|
|
76
77
|
filterState?: PrimitiveAtom<OverviewFilterSelection>;
|
|
78
|
+
/**
|
|
79
|
+
* The key of the tab the editor picked, defaults to state kept by the
|
|
80
|
+
* explorer. Page explorers keep it in the url.
|
|
81
|
+
*/
|
|
82
|
+
tabState?: WritableAtom<string | undefined, [string | undefined], void>;
|
|
77
83
|
showSelectionControls?: boolean;
|
|
78
84
|
initialSelection?: Array<string>;
|
|
79
85
|
/**
|
|
@@ -112,6 +118,11 @@ export interface ExplorerSortState {
|
|
|
112
118
|
}
|
|
113
119
|
export interface ExplorerReadyPage {
|
|
114
120
|
canUpload: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* The condition of the selected tab and the picked filters, undefined when
|
|
123
|
+
* none applies
|
|
124
|
+
*/
|
|
125
|
+
filter: OpenFilter<EntryFields> | undefined;
|
|
115
126
|
/** The filter options the listed entries match, by filter key */
|
|
116
127
|
filters: OverviewFilterSelection;
|
|
117
128
|
isMedia: boolean;
|
|
@@ -129,6 +140,8 @@ export interface ExplorerReadyPage {
|
|
|
129
140
|
searchScope: 'workspace' | 'everything';
|
|
130
141
|
searchesEverything: boolean;
|
|
131
142
|
sort: ExplorerSortState;
|
|
143
|
+
/** The key of the tab shown, undefined when the overview has no tabs */
|
|
144
|
+
tab: string | undefined;
|
|
132
145
|
view: ExplorerView;
|
|
133
146
|
}
|
|
134
147
|
export declare function explorerPageIsPending(page: ExplorerReadyPage, location: ExplorerLocation, locale: string | null): boolean;
|
|
@@ -316,6 +329,8 @@ export declare class ExplorerAtoms {
|
|
|
316
329
|
* key. The page lists the ones that apply to its overview.
|
|
317
330
|
*/
|
|
318
331
|
requestedFilters: PrimitiveAtom<OverviewFilterSelection>;
|
|
332
|
+
/** The key of the tab the editor picked, undefined for the first tab */
|
|
333
|
+
requestedTab: WritableAtom<string | undefined, [string | undefined], void>;
|
|
319
334
|
selectedLocale: WritableAtom<string | null, [
|
|
320
335
|
SetStateAction<string | null>
|
|
321
336
|
], void>;
|
|
@@ -24,11 +24,14 @@ import { MissingEntryError, treeEntryAtoms } from "./entry.js";
|
|
|
24
24
|
import {
|
|
25
25
|
columnLinkIds,
|
|
26
26
|
loadColumnValues,
|
|
27
|
+
hasFilterLoaders,
|
|
28
|
+
loadFilterOptions,
|
|
27
29
|
loadOverviewParent,
|
|
28
30
|
overviewFilter,
|
|
29
31
|
overviewOrder,
|
|
30
32
|
pickedFilters,
|
|
31
33
|
pickedSort,
|
|
34
|
+
pickedTab,
|
|
32
35
|
resolveOverview,
|
|
33
36
|
sortedColumn,
|
|
34
37
|
summarizeRows,
|
|
@@ -73,7 +76,8 @@ function explorerScrollKey(page) {
|
|
|
73
76
|
page.resultMode,
|
|
74
77
|
page.searchScope,
|
|
75
78
|
page.search.trim(),
|
|
76
|
-
page.filters
|
|
79
|
+
page.filters,
|
|
80
|
+
page.tab ?? null
|
|
77
81
|
]);
|
|
78
82
|
}
|
|
79
83
|
function explorerLocations(config, policy, options) {
|
|
@@ -284,6 +288,7 @@ var ExplorerAtoms = class {
|
|
|
284
288
|
this.scrollOffset = options.scrollOffset ?? dispense((_key) => atom(0));
|
|
285
289
|
this.requestedSort = options.sortState ?? atom(void 0);
|
|
286
290
|
this.requestedFilters = options.filterState ?? atom({});
|
|
291
|
+
this.requestedTab = options.tabState ?? atom(void 0);
|
|
287
292
|
this.mode = options.mode ?? "browse";
|
|
288
293
|
this.hasRowAction = options.onAction !== void 0 || options.enableNavigation === true && options.onConfirm === void 0;
|
|
289
294
|
this.rootScope = this.mode === "search" ? "workspace" : "current";
|
|
@@ -399,21 +404,28 @@ var ExplorerAtoms = class {
|
|
|
399
404
|
uploadResource(location2, parent)
|
|
400
405
|
);
|
|
401
406
|
const items = await itemsPromise;
|
|
402
|
-
const shown =
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
407
|
+
const shown = {
|
|
408
|
+
...resolveOverview(
|
|
409
|
+
get(configAtom),
|
|
410
|
+
await get(get(this.#overviewParent)),
|
|
411
|
+
{
|
|
412
|
+
children: summarizeRows(
|
|
413
|
+
items.map((item) => get(get(item.data).data.item))
|
|
414
|
+
)
|
|
415
|
+
}
|
|
416
|
+
),
|
|
417
|
+
// The filters do not follow the rows, their options are loaded
|
|
418
|
+
filters: overview.filters
|
|
419
|
+
};
|
|
411
420
|
const requested = get(this.requestedSort);
|
|
412
421
|
const sorted = search.trim() ? void 0 : pickedSort(shown, requested);
|
|
413
422
|
const filters = pickedFilters(shown, requestedFilters);
|
|
414
|
-
const
|
|
423
|
+
const requestedTab = get(this.requestedTab);
|
|
424
|
+
const tab = pickedTab(shown, requestedTab);
|
|
425
|
+
const filtered = Object.keys(filters).length > 0 || Boolean(tab?.filter);
|
|
415
426
|
return {
|
|
416
427
|
canUpload,
|
|
428
|
+
filter: overviewFilter(shown, filters, requestedTab),
|
|
417
429
|
filters,
|
|
418
430
|
isMedia,
|
|
419
431
|
items,
|
|
@@ -437,6 +449,7 @@ var ExplorerAtoms = class {
|
|
|
437
449
|
// Entries can not be reordered between hidden ones
|
|
438
450
|
manual: !search.trim() && !sorted && !shown.sort && !filtered
|
|
439
451
|
},
|
|
452
|
+
tab: tab?.key,
|
|
440
453
|
view
|
|
441
454
|
};
|
|
442
455
|
});
|
|
@@ -479,6 +492,8 @@ var ExplorerAtoms = class {
|
|
|
479
492
|
* key. The page lists the ones that apply to its overview.
|
|
480
493
|
*/
|
|
481
494
|
requestedFilters;
|
|
495
|
+
/** The key of the tab the editor picked, undefined for the first tab */
|
|
496
|
+
requestedTab;
|
|
482
497
|
selectedLocale;
|
|
483
498
|
root;
|
|
484
499
|
itemsReady;
|
|
@@ -556,9 +571,15 @@ var ExplorerAtoms = class {
|
|
|
556
571
|
*/
|
|
557
572
|
overview = atom(async (get) => {
|
|
558
573
|
const parent = await get(get(this.#overviewParent));
|
|
559
|
-
|
|
574
|
+
const overview = resolveOverview(get(configAtom), parent, {
|
|
560
575
|
mixed: !get(this.#listedParent)
|
|
561
576
|
});
|
|
577
|
+
if (!hasFilterLoaders(overview)) return overview;
|
|
578
|
+
get(shaAtom);
|
|
579
|
+
return loadFilterOptions(overview, {
|
|
580
|
+
graph: get(graphAtom),
|
|
581
|
+
locale: get(this.selectedLocale)
|
|
582
|
+
});
|
|
562
583
|
});
|
|
563
584
|
#parentAt = dispense(
|
|
564
585
|
(workspace, root, parentId) => atom(
|
|
@@ -795,7 +816,11 @@ var ExplorerAtoms = class {
|
|
|
795
816
|
root: entry.root,
|
|
796
817
|
parentId: entry.id,
|
|
797
818
|
locale,
|
|
798
|
-
filter: overviewFilter(
|
|
819
|
+
filter: overviewFilter(
|
|
820
|
+
overview,
|
|
821
|
+
requestedFilters,
|
|
822
|
+
get(this.requestedTab)
|
|
823
|
+
),
|
|
799
824
|
status: "preferDraft",
|
|
800
825
|
groupBy: Entry.id,
|
|
801
826
|
orderBy: overviewOrder(overview, get(this.requestedSort)),
|
|
@@ -850,7 +875,11 @@ var ExplorerAtoms = class {
|
|
|
850
875
|
const overview = await get(this.overview);
|
|
851
876
|
const flatList = resultMode === "matches";
|
|
852
877
|
const condition = flatList ? this.#options.condition : void 0;
|
|
853
|
-
const picked = overviewFilter(
|
|
878
|
+
const picked = overviewFilter(
|
|
879
|
+
overview,
|
|
880
|
+
requestedFilters,
|
|
881
|
+
get(this.requestedTab)
|
|
882
|
+
);
|
|
854
883
|
const locations = searchesMultipleRoots ? get(this.locations) : void 0;
|
|
855
884
|
if (locations?.length === 0) return void 0;
|
|
856
885
|
const allowed = locations && {
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import type { SyncProgress } from 'alinea/core/db/LocalStore';
|
|
2
|
+
/** The files fetched by a running sync from the remote. */
|
|
3
|
+
export declare const syncProgressAtom: import("jotai").WritableAtom<SyncProgress | undefined, [], () => void> & {
|
|
4
|
+
onMount: (init: () => () => void) => () => void;
|
|
5
|
+
};
|
|
1
6
|
export declare const shaAtom: import("jotai").Atom<Promise<string | undefined>>;
|
|
2
7
|
export declare const entryRevisionAtom: (id: string) => import("jotai").Atom<string | undefined>;
|
|
3
8
|
export declare const syncAtom: import("jotai").WritableAtom<null, [], Promise<string | undefined>> & {
|
|
@@ -8,6 +8,7 @@ import "../../chunks/chunk-CQ52GEHY.js";
|
|
|
8
8
|
|
|
9
9
|
// src/dashboard/atoms/graph.ts
|
|
10
10
|
import { IndexEvent } from "alinea/core/db/IndexEvent";
|
|
11
|
+
import { SyncEvent } from "../boot/SyncEvent.js";
|
|
11
12
|
import { eventsAtom, graphAtom } from "./core.js";
|
|
12
13
|
import { dispense } from "./utils.js";
|
|
13
14
|
var indexStateValueAtom = atom({ entryRevisions: /* @__PURE__ */ new Map() });
|
|
@@ -34,6 +35,25 @@ var indexStateAtom = Object.assign(
|
|
|
34
35
|
),
|
|
35
36
|
{ onMount: (init) => init() }
|
|
36
37
|
);
|
|
38
|
+
var syncProgressValueAtom = atom(void 0);
|
|
39
|
+
var syncProgressAtom = Object.assign(
|
|
40
|
+
atom(
|
|
41
|
+
(get) => get(syncProgressValueAtom),
|
|
42
|
+
(get, set) => {
|
|
43
|
+
const events = get(eventsAtom);
|
|
44
|
+
const listen = (event) => {
|
|
45
|
+
if (event instanceof SyncEvent)
|
|
46
|
+
set(syncProgressValueAtom, event.progress);
|
|
47
|
+
};
|
|
48
|
+
events.addEventListener(SyncEvent.type, listen);
|
|
49
|
+
return () => {
|
|
50
|
+
events.removeEventListener(SyncEvent.type, listen);
|
|
51
|
+
set(syncProgressValueAtom, void 0);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
),
|
|
55
|
+
{ onMount: (init) => init() }
|
|
56
|
+
);
|
|
37
57
|
var shaAtom = atom(async (get) => {
|
|
38
58
|
const current = get(indexStateAtom).sha;
|
|
39
59
|
if (current) return current;
|
|
@@ -51,6 +71,7 @@ var syncAtom = atom(null, async (get, set) => {
|
|
|
51
71
|
});
|
|
52
72
|
var graphReadyAtom = atom(async (get) => {
|
|
53
73
|
const graph = get(graphAtom);
|
|
74
|
+
if (isReadyGraph(graph)) return graph.ready();
|
|
54
75
|
if (isSyncableGraph(graph)) await graph.sync();
|
|
55
76
|
});
|
|
56
77
|
function readGraphSha(graph) {
|
|
@@ -59,9 +80,13 @@ function readGraphSha(graph) {
|
|
|
59
80
|
function isSyncableGraph(graph) {
|
|
60
81
|
return typeof graph.sync === "function";
|
|
61
82
|
}
|
|
83
|
+
function isReadyGraph(graph) {
|
|
84
|
+
return typeof graph.ready === "function";
|
|
85
|
+
}
|
|
62
86
|
export {
|
|
63
87
|
entryRevisionAtom,
|
|
64
88
|
graphReadyAtom,
|
|
65
89
|
shaAtom,
|
|
66
|
-
syncAtom
|
|
90
|
+
syncAtom,
|
|
91
|
+
syncProgressAtom
|
|
67
92
|
};
|
|
@@ -2,6 +2,8 @@ import { Atom, type Getter } from 'jotai';
|
|
|
2
2
|
import type { OverviewSort } from 'alinea/core/Overview';
|
|
3
3
|
import type { EntryDefaultView } from 'alinea/core/Type';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
|
+
import { nav } from '../Href.js';
|
|
6
|
+
export { nav };
|
|
5
7
|
export interface RouteBlock {
|
|
6
8
|
confirm: () => void | Promise<void>;
|
|
7
9
|
}
|
|
@@ -12,7 +14,10 @@ export declare const routeBlockAtom: import("jotai").PrimitiveAtom<RouteBlock |
|
|
|
12
14
|
init: RouteBlock | null;
|
|
13
15
|
};
|
|
14
16
|
export interface DashboardRoute {
|
|
15
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* An edit link names an entry by its url, or by its id without workspace
|
|
19
|
+
* and root, until it is looked up
|
|
20
|
+
*/
|
|
16
21
|
page?: 'splash' | 'entry' | 'users' | 'edit';
|
|
17
22
|
url?: string;
|
|
18
23
|
workspace?: string;
|
|
@@ -22,22 +27,19 @@ export interface DashboardRoute {
|
|
|
22
27
|
view?: EntryDefaultView;
|
|
23
28
|
/** The column an overview is sorted by, eg. `price` or `-price` */
|
|
24
29
|
sort?: string;
|
|
30
|
+
/** The tab an overview shows, eg. `active` */
|
|
31
|
+
tab?: string;
|
|
25
32
|
/** Replace the current history entry instead of adding one */
|
|
26
33
|
replace?: boolean;
|
|
27
34
|
}
|
|
28
|
-
interface ResolvedDashboardRoute extends DashboardRoute {
|
|
35
|
+
export interface ResolvedDashboardRoute extends DashboardRoute {
|
|
29
36
|
page: 'splash' | 'entry' | 'users' | 'edit';
|
|
30
37
|
}
|
|
31
|
-
export declare const nav: {
|
|
32
|
-
splash(): string;
|
|
33
|
-
users(): string;
|
|
34
|
-
/** The editor of the entry at `url`, as linked from a page of the site */
|
|
35
|
-
edit(url: string, workspace?: string, root?: string): string;
|
|
36
|
-
entry(workspace?: string, root?: string, entryId?: string, locale?: string | null, view?: EntryDefaultView, sort?: string): string;
|
|
37
|
-
};
|
|
38
38
|
/** The url parameter of an overview sort: the column, prefixed with - when descending */
|
|
39
39
|
export declare function formatOverviewSort(sort?: OverviewSort): string | undefined;
|
|
40
40
|
export declare function parseOverviewSort(value: string | undefined): OverviewSort | undefined;
|
|
41
|
+
/** @internal */
|
|
42
|
+
export declare function hashFromRoute(route: ResolvedDashboardRoute): string;
|
|
41
43
|
interface NavigationRequest {
|
|
42
44
|
browser?: boolean;
|
|
43
45
|
replace?: boolean;
|
|
@@ -62,5 +64,9 @@ export declare const pageAtom: Atom<Page>;
|
|
|
62
64
|
* when `entry` is null. The overview of the current page keeps it in the url.
|
|
63
65
|
*/
|
|
64
66
|
export declare const overviewSortAtom: (workspace: string, root: string, entry: string | null) => import("jotai").WritableAtom<OverviewSort | undefined, [sort: OverviewSort | undefined], void>;
|
|
67
|
+
/**
|
|
68
|
+
* The tab of the overview listing the children of an entry, or of a root
|
|
69
|
+
* when `entry` is null. The overview of the current page keeps it in the url.
|
|
70
|
+
*/
|
|
71
|
+
export declare const overviewTabAtom: (workspace: string, root: string, entry: string | null) => import("jotai").WritableAtom<string | undefined, [tab: string | undefined], void>;
|
|
65
72
|
export declare function page(render: (page: Page, get: Getter) => ReactNode | Promise<ReactNode>): (page: Page, get: Getter) => ReactNode | Promise<ReactNode>;
|
|
66
|
-
export {};
|
|
@@ -64,32 +64,9 @@ import { workspaceAtom, workspacesAtom } from "./config.js";
|
|
|
64
64
|
import { configAtom, graphAtom } from "./core.js";
|
|
65
65
|
import { policyAtom } from "./user.js";
|
|
66
66
|
import { dispense } from "./utils.js";
|
|
67
|
+
import { nav } from "../Href.js";
|
|
67
68
|
var routeGuardAtom = atom(null);
|
|
68
69
|
var routeBlockAtom = atom(null);
|
|
69
|
-
var nav = {
|
|
70
|
-
splash() {
|
|
71
|
-
return "/";
|
|
72
|
-
},
|
|
73
|
-
users() {
|
|
74
|
-
return "/users";
|
|
75
|
-
},
|
|
76
|
-
/** The editor of the entry at `url`, as linked from a page of the site */
|
|
77
|
-
edit(url, workspace, root) {
|
|
78
|
-
const params = new URLSearchParams({ url });
|
|
79
|
-
if (workspace) params.set("workspace", workspace);
|
|
80
|
-
if (root) params.set("root", root);
|
|
81
|
-
return `/edit?${params}`;
|
|
82
|
-
},
|
|
83
|
-
entry(workspace, root, entryId, locale, view, sort) {
|
|
84
|
-
const rootPart = root ? `${root}${locale ? `:${locale}` : ""}` : "";
|
|
85
|
-
const path = `/entry/${[workspace, rootPart, entryId].filter(Boolean).join("/")}`;
|
|
86
|
-
const params = new URLSearchParams();
|
|
87
|
-
if (view) params.set("view", view);
|
|
88
|
-
if (sort) params.set("sort", sort);
|
|
89
|
-
const search = params.toString();
|
|
90
|
-
return search ? `${path}?${search}` : path;
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
70
|
function formatOverviewSort(sort) {
|
|
94
71
|
if (!sort) return void 0;
|
|
95
72
|
return sort.direction === "desc" ? `-${sort.column}` : sort.column;
|
|
@@ -105,11 +82,21 @@ function listKey(workspace, root, entry) {
|
|
|
105
82
|
return `${workspace ?? ""}/${root ?? ""}/${entry ?? ""}`;
|
|
106
83
|
}
|
|
107
84
|
var overviewSortMemoryAtom = atom(/* @__PURE__ */ new Map());
|
|
85
|
+
var overviewTabMemoryAtom = atom(/* @__PURE__ */ new Map());
|
|
108
86
|
function routeFromHash(hash) {
|
|
109
87
|
const [path, search = ""] = hash.slice(1).split("?");
|
|
110
88
|
const [action, workspace, rootPart = "", entry] = path.split("/").slice(1);
|
|
111
89
|
const params = new URLSearchParams(search);
|
|
112
90
|
const url = params.get("url");
|
|
91
|
+
const id = params.get("id");
|
|
92
|
+
const view = params.get("view");
|
|
93
|
+
if (action === "edit" && id)
|
|
94
|
+
return {
|
|
95
|
+
page: "edit",
|
|
96
|
+
entry: id,
|
|
97
|
+
locale: params.get("locale") ?? void 0,
|
|
98
|
+
view: view === "edit" || view === "overview" ? view : void 0
|
|
99
|
+
};
|
|
113
100
|
if (action === "edit" && url)
|
|
114
101
|
return {
|
|
115
102
|
page: "edit",
|
|
@@ -119,8 +106,8 @@ function routeFromHash(hash) {
|
|
|
119
106
|
};
|
|
120
107
|
const page2 = action === "users" ? "users" : action === "entry" ? "entry" : "splash";
|
|
121
108
|
const [root, locale] = rootPart.split(":");
|
|
122
|
-
const view = params.get("view");
|
|
123
109
|
const sort = params.get("sort");
|
|
110
|
+
const tab = params.get("tab");
|
|
124
111
|
return {
|
|
125
112
|
page: page2,
|
|
126
113
|
workspace: page2 === "entry" ? workspace : void 0,
|
|
@@ -128,12 +115,20 @@ function routeFromHash(hash) {
|
|
|
128
115
|
entry: page2 === "entry" ? entry : void 0,
|
|
129
116
|
locale: page2 === "entry" ? locale : void 0,
|
|
130
117
|
view: page2 === "entry" && (view === "edit" || view === "overview") ? view : void 0,
|
|
131
|
-
sort: page2 === "entry" && sort ? sort : void 0
|
|
118
|
+
sort: page2 === "entry" && sort ? sort : void 0,
|
|
119
|
+
tab: page2 === "entry" && tab ? tab : void 0
|
|
132
120
|
};
|
|
133
121
|
}
|
|
134
122
|
function routeFromUpdate(update) {
|
|
135
123
|
if (update.page === "users") return { page: "users" };
|
|
136
124
|
if (update.page === "splash") return { page: "splash" };
|
|
125
|
+
if (update.page === "edit" && update.entry)
|
|
126
|
+
return {
|
|
127
|
+
page: "edit",
|
|
128
|
+
entry: update.entry,
|
|
129
|
+
locale: update.locale,
|
|
130
|
+
view: update.view
|
|
131
|
+
};
|
|
137
132
|
if (update.page === "edit")
|
|
138
133
|
return update.url ? {
|
|
139
134
|
page: "edit",
|
|
@@ -148,10 +143,13 @@ function routeFromUpdate(update) {
|
|
|
148
143
|
entry: update.entry,
|
|
149
144
|
locale: update.locale,
|
|
150
145
|
view: update.view,
|
|
151
|
-
sort: update.sort
|
|
146
|
+
sort: update.sort,
|
|
147
|
+
tab: update.tab
|
|
152
148
|
};
|
|
153
149
|
}
|
|
154
150
|
function hashFromRoute(route) {
|
|
151
|
+
if (route.page === "edit" && route.entry)
|
|
152
|
+
return `#${nav.link(route.entry, route.locale, route.view)}`;
|
|
155
153
|
if (route.page === "edit")
|
|
156
154
|
return `#${nav.edit(route.url ?? "/", route.workspace, route.root)}`;
|
|
157
155
|
return route.page === "splash" ? `#${nav.splash()}` : route.page === "users" ? `#${nav.users()}` : `#${nav.entry(
|
|
@@ -160,7 +158,8 @@ function hashFromRoute(route) {
|
|
|
160
158
|
route.entry,
|
|
161
159
|
route.locale,
|
|
162
160
|
route.view,
|
|
163
|
-
route.sort
|
|
161
|
+
route.sort,
|
|
162
|
+
route.tab
|
|
164
163
|
)}`;
|
|
165
164
|
}
|
|
166
165
|
var locationAtom = atomWithLocation({
|
|
@@ -190,7 +189,10 @@ var routeAtom = Object.assign(
|
|
|
190
189
|
replace: update.replace
|
|
191
190
|
};
|
|
192
191
|
if (request.route.page !== "edit")
|
|
193
|
-
return navigate(get, set, request,
|
|
192
|
+
return navigate(get, set, request, {
|
|
193
|
+
sort: "sort" in update,
|
|
194
|
+
tab: "tab" in update
|
|
195
|
+
});
|
|
194
196
|
const current = get(currentRouteAtom);
|
|
195
197
|
const lookup = ++linkLookups;
|
|
196
198
|
set(
|
|
@@ -201,7 +203,7 @@ var routeAtom = Object.assign(
|
|
|
201
203
|
return linkedRoute(get, request.route).catch(() => ({ page: "splash" })).then((route) => {
|
|
202
204
|
if (lookup !== linkLookups || get(currentRouteAtom) !== current)
|
|
203
205
|
return;
|
|
204
|
-
navigate(get, set, { route, replace: true }, true);
|
|
206
|
+
navigate(get, set, { route, replace: true }, { sort: true, tab: true });
|
|
205
207
|
});
|
|
206
208
|
}
|
|
207
209
|
),
|
|
@@ -225,19 +227,23 @@ var routeAtom = Object.assign(
|
|
|
225
227
|
}
|
|
226
228
|
}
|
|
227
229
|
);
|
|
228
|
-
function navigate(get, set, request,
|
|
230
|
+
function navigate(get, set, request, given) {
|
|
229
231
|
let { route } = request;
|
|
230
232
|
const key = sortKey(get, request);
|
|
231
|
-
|
|
232
|
-
if (key && !explicit) {
|
|
233
|
+
if (key && !request.browser) {
|
|
233
234
|
const sort = get(overviewSortMemoryAtom).get(key);
|
|
234
|
-
if (sort
|
|
235
|
+
if (sort && route.sort === void 0 && !given.sort)
|
|
236
|
+
route = { ...route, sort: formatOverviewSort(sort) };
|
|
237
|
+
const tab = get(overviewTabMemoryAtom).get(key);
|
|
238
|
+
if (tab && route.tab === void 0 && !given.tab) route = { ...route, tab };
|
|
235
239
|
}
|
|
236
240
|
const previous = get(currentRouteAtom);
|
|
237
241
|
const commit = (replace = request.replace ?? false, syncLocation = !request.browser) => {
|
|
238
242
|
set(currentRouteAtom, route);
|
|
239
|
-
if (key)
|
|
243
|
+
if (key) {
|
|
240
244
|
set(overviewSortMemoryAtom, (memory) => remember(memory, key, route.sort));
|
|
245
|
+
set(overviewTabMemoryAtom, (memory) => rememberTab(memory, key, route.tab));
|
|
246
|
+
}
|
|
241
247
|
if (!syncLocation) return;
|
|
242
248
|
set(locationAtom, (location) => ({ ...location, hash: hashFromRoute(route) }), {
|
|
243
249
|
replace
|
|
@@ -263,8 +269,29 @@ function navigate(get, set, request, sortGiven) {
|
|
|
263
269
|
}
|
|
264
270
|
commit();
|
|
265
271
|
}
|
|
266
|
-
async function linkedRoute(get,
|
|
272
|
+
async function linkedRoute(get, route) {
|
|
273
|
+
const { url = "/", workspace, root } = route;
|
|
267
274
|
const graph = get(graphAtom);
|
|
275
|
+
if (route.entry) {
|
|
276
|
+
const found2 = await graph.first({
|
|
277
|
+
id: route.entry,
|
|
278
|
+
status: "preferDraft",
|
|
279
|
+
select: {
|
|
280
|
+
workspace: Entry.workspace,
|
|
281
|
+
root: Entry.root,
|
|
282
|
+
locale: Entry.locale
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
if (!found2) return { page: "splash" };
|
|
286
|
+
return {
|
|
287
|
+
page: "entry",
|
|
288
|
+
workspace: found2.workspace,
|
|
289
|
+
root: found2.root,
|
|
290
|
+
entry: route.entry,
|
|
291
|
+
locale: route.locale ?? found2.locale ?? void 0,
|
|
292
|
+
view: route.view
|
|
293
|
+
};
|
|
294
|
+
}
|
|
268
295
|
const query = {
|
|
269
296
|
workspace,
|
|
270
297
|
root,
|
|
@@ -308,6 +335,13 @@ function remember(memory, key, value) {
|
|
|
308
335
|
else next.delete(key);
|
|
309
336
|
return next;
|
|
310
337
|
}
|
|
338
|
+
function rememberTab(memory, key, value) {
|
|
339
|
+
if (memory.get(key) === value) return memory;
|
|
340
|
+
const next = new Map(memory);
|
|
341
|
+
if (value) next.set(key, value);
|
|
342
|
+
else next.delete(key);
|
|
343
|
+
return next;
|
|
344
|
+
}
|
|
311
345
|
var pageAtom = atom((get) => resolvePage(get, get(routeAtom)));
|
|
312
346
|
function resolvePage(get, route) {
|
|
313
347
|
if (route.page === "edit")
|
|
@@ -368,13 +402,39 @@ var overviewSortAtom = dispense(
|
|
|
368
402
|
);
|
|
369
403
|
}
|
|
370
404
|
);
|
|
405
|
+
var overviewTabAtom = dispense(
|
|
406
|
+
(workspace, root, entry) => {
|
|
407
|
+
const key = listKey(workspace, root, entry ?? void 0);
|
|
408
|
+
return atom(
|
|
409
|
+
(get) => get(overviewTabMemoryAtom).get(key),
|
|
410
|
+
(get, set, tab) => {
|
|
411
|
+
const page2 = get(pageAtom);
|
|
412
|
+
if (page2.type !== "entry" || listKey(page2.workspace, page2.root, page2.entry) !== key) {
|
|
413
|
+
set(overviewTabMemoryAtom, (memory) => rememberTab(memory, key, tab));
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
set(routeAtom, {
|
|
417
|
+
workspace,
|
|
418
|
+
root,
|
|
419
|
+
entry: page2.entry,
|
|
420
|
+
locale: page2.locale ?? void 0,
|
|
421
|
+
view: page2.view,
|
|
422
|
+
tab,
|
|
423
|
+
replace: true
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
);
|
|
371
429
|
function page(render) {
|
|
372
430
|
return render;
|
|
373
431
|
}
|
|
374
432
|
export {
|
|
375
433
|
formatOverviewSort,
|
|
434
|
+
hashFromRoute,
|
|
376
435
|
nav,
|
|
377
436
|
overviewSortAtom,
|
|
437
|
+
overviewTabAtom,
|
|
378
438
|
page,
|
|
379
439
|
pageAtom,
|
|
380
440
|
parseOverviewSort,
|
|
@@ -6,7 +6,7 @@ import type { Graph, Order, Projection } from 'alinea/core/Graph';
|
|
|
6
6
|
import type { OrderBy } from 'alinea/core/OrderBy';
|
|
7
7
|
import type { EntryFields } from 'alinea/core/EntryFields';
|
|
8
8
|
import type { OpenFilter } from 'alinea/core/Filter';
|
|
9
|
-
import { type OverviewActionProps, type OverviewCellProps, type OverviewColumnAlign, type OverviewColumnWidth, type OverviewEntry, type OverviewFormatContext, type OverviewOptions, type OverviewSort, type OverviewSortDirection } from 'alinea/core/Overview';
|
|
9
|
+
import { type OverviewActionProps, type OverviewCellProps, type OverviewColumnAlign, type OverviewColumnWidth, type OverviewEntry, type OverviewFilterContext, type OverviewFilterOptions, type OverviewFormatContext, type OverviewHeaderProps, type OverviewOptions, type OverviewSort, type OverviewSortDirection } from 'alinea/core/Overview';
|
|
10
10
|
import { type RootData } from 'alinea/core/Root';
|
|
11
11
|
import { Type } from 'alinea/core/Type';
|
|
12
12
|
import type { View } from 'alinea/core/View';
|
|
@@ -65,7 +65,16 @@ export interface OverviewFilterState {
|
|
|
65
65
|
key: string;
|
|
66
66
|
label: string;
|
|
67
67
|
multiple: boolean;
|
|
68
|
+
/** The options, empty until `loadFilterOptions` loaded those of `load` */
|
|
68
69
|
options: Array<OverviewFilterOptionState>;
|
|
70
|
+
/** Loads the options of filters that build them from the content */
|
|
71
|
+
load?: (context: OverviewFilterContext) => OverviewFilterOptions | Promise<OverviewFilterOptions>;
|
|
72
|
+
}
|
|
73
|
+
/** A tab of an overview */
|
|
74
|
+
export interface OverviewTabState {
|
|
75
|
+
key: string;
|
|
76
|
+
label: string;
|
|
77
|
+
filter?: OpenFilter<EntryFields>;
|
|
69
78
|
}
|
|
70
79
|
/** The keys of the options editors picked, by the key of their filter */
|
|
71
80
|
export interface OverviewFilterSelection {
|
|
@@ -82,11 +91,14 @@ export interface OverviewState {
|
|
|
82
91
|
sorts: Array<OverviewSortState>;
|
|
83
92
|
/** The filters editors can apply */
|
|
84
93
|
filters: Array<OverviewFilterState>;
|
|
94
|
+
/** The tabs above the list, the first one is selected by default */
|
|
95
|
+
tabs: Array<OverviewTabState>;
|
|
85
96
|
/** The order children are listed in when the editor did not sort */
|
|
86
97
|
sort?: OrderBy | Array<OrderBy>;
|
|
87
98
|
layout?: 'table' | 'cards';
|
|
88
99
|
thumbnail?: OverviewSelection;
|
|
89
100
|
actions: Array<View<OverviewActionProps>>;
|
|
101
|
+
header?: View<OverviewHeaderProps>;
|
|
90
102
|
/** The names of the types the parent contains */
|
|
91
103
|
types: Array<string>;
|
|
92
104
|
}
|
|
@@ -119,6 +131,10 @@ export interface OverviewResolveOptions {
|
|
|
119
131
|
export declare function resolveOverview(config: Config, parent: OverviewParent, options?: OverviewResolveOptions): OverviewState;
|
|
120
132
|
/** Resolves an overview for a list of entries of the given types */
|
|
121
133
|
export declare function resolveOverviewOptions(config: Config, overview: OverviewOptions | undefined, types: Array<string>, sort: OrderBy | Array<OrderBy> | undefined, options?: OverviewResolveOptions): OverviewState;
|
|
134
|
+
/** Whether an overview has filters whose options load from the content */
|
|
135
|
+
export declare function hasFilterLoaders(overview: OverviewState): boolean;
|
|
136
|
+
/** Loads the options of the filters that build them from the content */
|
|
137
|
+
export declare function loadFilterOptions(overview: OverviewState, context: OverviewFilterContext): Promise<OverviewState>;
|
|
122
138
|
/** The projection a column selects for entries of a type */
|
|
123
139
|
export declare function columnProjection(select: OverviewSelection | undefined, typeName: string): Projection | undefined;
|
|
124
140
|
/**
|
|
@@ -146,10 +162,16 @@ export declare function sortedColumn(overview: OverviewState, sort: OverviewSort
|
|
|
146
162
|
*/
|
|
147
163
|
export declare function pickedFilters(overview: OverviewState, selection: OverviewFilterSelection): OverviewFilterSelection;
|
|
148
164
|
/**
|
|
149
|
-
* The
|
|
150
|
-
*
|
|
165
|
+
* The tab the editor picked, or the first tab when it is unknown. Undefined
|
|
166
|
+
* when the overview has no tabs.
|
|
167
|
+
*/
|
|
168
|
+
export declare function pickedTab(overview: OverviewState, tab: string | undefined): OverviewTabState | undefined;
|
|
169
|
+
/**
|
|
170
|
+
* The condition of the selected tab and the picked filters: entries match
|
|
171
|
+
* the tab, every filter, and any of the options picked of a filter.
|
|
172
|
+
* Undefined when nothing applies.
|
|
151
173
|
*/
|
|
152
|
-
export declare function overviewFilter(overview: OverviewState, selection: OverviewFilterSelection): OpenFilter<EntryFields> | undefined;
|
|
174
|
+
export declare function overviewFilter(overview: OverviewState, selection: OverviewFilterSelection, tab?: string): OpenFilter<EntryFields> | undefined;
|
|
153
175
|
/** The rows an overview renders, as loaded by the explorer or an EntryTable */
|
|
154
176
|
export interface OverviewRow {
|
|
155
177
|
id: string;
|