@chelone/core 0.6.0 → 0.9.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/assistant/assistant-session.d.ts +6 -0
- package/dist/assistant/assistant-session.js +204 -181
- package/dist/assistant/echo-transport.js +26 -29
- package/dist/assistant/http-transport.d.ts +10 -0
- package/dist/assistant/http-transport.js +98 -0
- package/dist/assistant/types.d.ts +1 -7
- package/dist/auth/access-control.d.ts +13 -5
- package/dist/auth/access-control.js +25 -21
- package/dist/auth/auth-options.d.ts +23 -17
- package/dist/auth/auth-options.js +82 -48
- package/dist/auth/permission-matrix.d.ts +12 -0
- package/dist/auth/permission-matrix.js +67 -0
- package/dist/auth/types.d.ts +14 -4
- package/dist/block-editor/block-document.d.ts +64 -0
- package/dist/block-editor/block-document.js +147 -0
- package/dist/block-editor/data-blocks.d.ts +63 -0
- package/dist/block-editor/data-blocks.js +117 -0
- package/dist/chart/chart-data.js +46 -44
- package/dist/command-menu/hotkey.js +58 -47
- package/dist/command-menu/recents.d.ts +4 -0
- package/dist/command-menu/recents.js +12 -11
- package/dist/command-menu/registry.d.ts +9 -5
- package/dist/command-menu/registry.js +36 -46
- package/dist/controller/calendar-dates.d.ts +12 -0
- package/dist/controller/calendar-dates.js +94 -113
- package/dist/controller/calendar-events.js +93 -88
- package/dist/controller/client-list-controller.d.ts +2 -2
- package/dist/controller/client-list-controller.js +251 -254
- package/dist/controller/data-table-columns.d.ts +2 -0
- package/dist/controller/data-table-columns.js +50 -56
- package/dist/controller/deep-equal.d.ts +1 -0
- package/dist/controller/deep-equal.js +14 -0
- package/dist/controller/filter-toggle.js +36 -44
- package/dist/controller/in-place-editor.d.ts +43 -0
- package/dist/controller/in-place-editor.js +43 -0
- package/dist/controller/infinite-list-controller.js +219 -189
- package/dist/controller/inspector.d.ts +55 -0
- package/dist/controller/inspector.js +70 -0
- package/dist/controller/job-monitor.d.ts +10 -4
- package/dist/controller/job-monitor.js +46 -47
- package/dist/controller/kanban-board.js +45 -24
- package/dist/controller/list-controller.d.ts +8 -5
- package/dist/controller/list-controller.js +447 -400
- package/dist/controller/list-params.js +96 -87
- package/dist/controller/pivot-grid.d.ts +4 -4
- package/dist/controller/pivot-grid.js +89 -95
- package/dist/controller/prev-next.d.ts +2 -2
- package/dist/controller/prev-next.js +74 -54
- package/dist/controller/record-controllers.d.ts +14 -6
- package/dist/controller/record-controllers.js +288 -257
- package/dist/controller/record-diff.d.ts +21 -0
- package/dist/controller/record-diff.js +50 -0
- package/dist/controller/record-timeline.d.ts +5 -5
- package/dist/controller/record-timeline.js +42 -30
- package/dist/controller/record-tree.js +57 -47
- package/dist/controller/record-workflow.d.ts +38 -16
- package/dist/controller/record-workflow.js +85 -64
- package/dist/controller/reference-many-controller.d.ts +2 -0
- package/dist/controller/reference-many-controller.js +199 -192
- package/dist/controller/reference-one-controller.d.ts +1 -1
- package/dist/controller/reference-one-controller.js +63 -56
- package/dist/controller/saved-queries.js +104 -91
- package/dist/controller/translate-fallback.js +10 -6
- package/dist/csv/export.d.ts +4 -3
- package/dist/csv/export.js +43 -40
- package/dist/csv/import-controller.d.ts +4 -0
- package/dist/csv/import-controller.js +189 -169
- package/dist/csv/match-headers.js +29 -22
- package/dist/csv/parse-with.js +60 -54
- package/dist/csv/run-import.js +69 -72
- package/dist/csv/validate-rows.d.ts +1 -1
- package/dist/csv/validate-rows.js +65 -52
- package/dist/data/cache-ops.d.ts +5 -4
- package/dist/data/cache-ops.js +208 -188
- package/dist/data/combine-data-providers.js +25 -23
- package/dist/data/data-provider-log.d.ts +45 -0
- package/dist/data/data-provider-log.js +93 -0
- package/dist/data/errors.js +14 -10
- package/dist/data/fake-provider.d.ts +6 -3
- package/dist/data/fake-provider.js +135 -114
- package/dist/data/fetch-utils.js +61 -44
- package/dist/data/filter-branch.d.ts +5 -0
- package/dist/data/filter-branch.js +10 -0
- package/dist/data/get-many-aggregate.js +84 -76
- package/dist/data/http-error.js +17 -12
- package/dist/data/keys.js +50 -36
- package/dist/data/mutation-options.d.ts +14 -9
- package/dist/data/mutation-options.js +93 -109
- package/dist/data/query-options.js +73 -68
- package/dist/data/remove-empty.d.ts +3 -0
- package/dist/data/remove-empty.js +11 -0
- package/dist/data/undoable.d.ts +2 -2
- package/dist/data/undoable.js +190 -174
- package/dist/data/with-lifecycle-callbacks.d.ts +45 -17
- package/dist/data/with-lifecycle-callbacks.js +66 -52
- package/dist/environment/application-update-store.js +58 -55
- package/dist/environment/offline-store.js +21 -21
- package/dist/form/array-binding.d.ts +30 -11
- package/dist/form/array-binding.js +184 -166
- package/dist/form/choice-ids.d.ts +7 -0
- package/dist/form/choice-ids.js +11 -0
- package/dist/form/choices-controller.d.ts +22 -2
- package/dist/form/choices-controller.js +315 -275
- package/dist/form/date-format.d.ts +38 -0
- package/dist/form/date-format.js +89 -0
- package/dist/form/dirty-values.d.ts +2 -2
- package/dist/form/dirty-values.js +22 -11
- package/dist/form/duration.d.ts +22 -0
- package/dist/form/duration.js +49 -0
- package/dist/form/edit-create-form.d.ts +12 -5
- package/dist/form/edit-create-form.js +243 -188
- package/dist/form/event-value.d.ts +6 -0
- package/dist/form/event-value.js +17 -0
- package/dist/form/field-error.d.ts +14 -0
- package/dist/form/field-error.js +28 -0
- package/dist/form/field-name.d.ts +20 -0
- package/dist/form/field-name.js +6 -0
- package/dist/form/filter-form-values.js +63 -49
- package/dist/form/form-controller.d.ts +9 -1
- package/dist/form/form-controller.js +165 -160
- package/dist/form/form-groups.d.ts +4 -3
- package/dist/form/form-groups.js +79 -79
- package/dist/form/form-handle.d.ts +175 -0
- package/dist/form/form-handle.js +68 -0
- package/dist/form/input-binding.d.ts +56 -31
- package/dist/form/input-binding.js +171 -118
- package/dist/form/input-values.d.ts +140 -0
- package/dist/form/input-values.js +206 -0
- package/dist/form/json-text.d.ts +11 -0
- package/dist/form/json-text.js +62 -37
- package/dist/form/save-pipeline.d.ts +6 -8
- package/dist/form/save-pipeline.js +91 -82
- package/dist/form/set-form-values.d.ts +6 -0
- package/dist/form/set-form-values.js +10 -0
- package/dist/form/source.js +97 -65
- package/dist/form/text-of.d.ts +2 -0
- package/dist/form/text-of.js +7 -0
- package/dist/form/validators.d.ts +58 -19
- package/dist/form/validators.js +97 -71
- package/dist/geo/bbox.d.ts +5 -4
- package/dist/geo/bbox.js +69 -48
- package/dist/geo/bounds.d.ts +14 -3
- package/dist/geo/bounds.js +98 -68
- package/dist/geo/constraints.js +88 -93
- package/dist/geo/coordinates.d.ts +10 -0
- package/dist/geo/coordinates.js +44 -23
- package/dist/geo/editor.d.ts +13 -13
- package/dist/geo/editor.js +176 -153
- package/dist/geo/geocoding.d.ts +4 -4
- package/dist/geo/geocoding.js +38 -41
- package/dist/geo/geojson.d.ts +12 -74
- package/dist/geo/geojson.js +52 -40
- package/dist/geo/geometry-math.d.ts +4 -4
- package/dist/geo/geometry-math.js +100 -93
- package/dist/geo/index.d.ts +9 -8
- package/dist/geo/map-layers.d.ts +42 -7
- package/dist/geo/map-layers.js +88 -62
- package/dist/geo/map-style.d.ts +12 -0
- package/dist/geo/map-style.js +43 -32
- package/dist/geo/messages.js +48 -45
- package/dist/geo/nominatim.js +88 -80
- package/dist/geo/osm-presets.d.ts +4 -3
- package/dist/geo/osm-presets.js +108 -86
- package/dist/geo/osm-tags.js +14 -12
- package/dist/geo/overpass.d.ts +14 -2
- package/dist/geo/overpass.js +83 -90
- package/dist/geo/shape-value.d.ts +9 -5
- package/dist/geo/shape-value.js +169 -146
- package/dist/geo/snap-to-roads.d.ts +3 -3
- package/dist/geo/snap-to-roads.js +55 -50
- package/dist/geo/throttle.js +36 -39
- package/dist/guards.d.ts +44 -0
- package/dist/guards.js +77 -0
- package/dist/i18n/default-messages.js +34 -29
- package/dist/i18n/english-messages.d.ts +172 -0
- package/dist/i18n/english-messages.js +359 -189
- package/dist/i18n/i18n.d.ts +2 -2
- package/dist/i18n/i18n.js +47 -60
- package/dist/i18n/inflection.d.ts +34 -0
- package/dist/i18n/inflection.js +82 -0
- package/dist/i18n/messages.d.ts +10 -2
- package/dist/i18n/messages.js +17 -4
- package/dist/i18n/missing-keys.d.ts +4 -0
- package/dist/i18n/missing-keys.js +70 -62
- package/dist/i18n/translatable.d.ts +16 -1
- package/dist/i18n/translatable.js +40 -47
- package/dist/index.d.ts +87 -39
- package/dist/index.js +54 -301
- package/dist/json/deep-equal.d.ts +8 -0
- package/dist/json/deep-equal.js +24 -0
- package/dist/json/strip-json-comments.js +38 -42
- package/dist/noop.d.ts +2 -0
- package/dist/noop.js +4 -0
- package/dist/notification/error-message.d.ts +2 -0
- package/dist/notification/error-message.js +10 -0
- package/dist/notification/notification-store.d.ts +3 -2
- package/dist/notification/notification-store.js +41 -45
- package/dist/onboarding-tour/placement.d.ts +2 -0
- package/dist/onboarding-tour/placement.js +65 -78
- package/dist/onboarding-tour/tour-controller.js +46 -54
- package/dist/realtime/add-events-for-mutations.js +75 -81
- package/dist/realtime/announce-lock.js +16 -13
- package/dist/realtime/broadcast-channel-transport.js +65 -59
- package/dist/realtime/copy-members.js +22 -14
- package/dist/realtime/in-memory-lock-provider.js +40 -48
- package/dist/realtime/live.js +95 -101
- package/dist/realtime/lock-options.js +16 -16
- package/dist/realtime/lock-session.js +91 -78
- package/dist/realtime/memory-transport.js +25 -25
- package/dist/realtime/presence.js +120 -122
- package/dist/realtime/realtime-data-provider.d.ts +10 -0
- package/dist/realtime/realtime-data-provider.js +45 -42
- package/dist/realtime/reconnect-backoff.js +17 -0
- package/dist/realtime/sse-transport.d.ts +31 -0
- package/dist/realtime/sse-transport.js +235 -0
- package/dist/realtime/status-store.js +23 -28
- package/dist/realtime/topic-hub.js +62 -71
- package/dist/realtime/topics.js +10 -12
- package/dist/realtime/types.js +10 -12
- package/dist/realtime/unread-count.js +21 -21
- package/dist/realtime/websocket-transport.d.ts +32 -0
- package/dist/realtime/websocket-transport.js +306 -0
- package/dist/resource/describe-resource.d.ts +2 -0
- package/dist/resource/describe-resource.js +247 -219
- package/dist/resource/get-at-path.js +29 -14
- package/dist/resource/identifier.d.ts +18 -0
- package/dist/resource/identifier.js +27 -0
- package/dist/resource/record.d.ts +4 -0
- package/dist/resource/record.js +10 -0
- package/dist/resource/register.d.ts +7 -0
- package/dist/resource/registry-store.d.ts +45 -15
- package/dist/resource/registry-store.js +67 -60
- package/dist/resource/registry.d.ts +10 -0
- package/dist/resource/registry.js +8 -4
- package/dist/resource/source-path.d.ts +23 -2
- package/dist/rich-text/rich-text-extras.d.ts +134 -0
- package/dist/rich-text/rich-text-extras.js +181 -0
- package/dist/rich-text/rich-text-image.d.ts +124 -0
- package/dist/rich-text/rich-text-image.js +163 -0
- package/dist/rich-text/rich-text.d.ts +6 -0
- package/dist/rich-text/rich-text.js +125 -88
- package/dist/router/location.d.ts +24 -4
- package/dist/router/location.js +43 -18
- package/dist/router/match.js +47 -39
- package/dist/router/paths.js +40 -34
- package/dist/router/record-from-location.d.ts +1 -1
- package/dist/router/record-from-location.js +25 -17
- package/dist/store/adapters.js +51 -55
- package/dist/store/micro-store.js +57 -59
- package/dist/store/shallow-equal.d.ts +12 -0
- package/dist/store/shallow-equal.js +20 -0
- package/dist/store/store.js +54 -57
- package/dist/ui-defaults.d.ts +15 -0
- package/dist/ui-defaults.js +17 -0
- package/package.json +13 -11
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type MicroStore } from "../store/micro-store.js";
|
|
2
|
+
import { type DataTableColumnInfo } from "./data-table-columns.js";
|
|
3
|
+
/**
|
|
4
|
+
* What the panel edits. `editor` is generic so each adapter stores its own
|
|
5
|
+
* editor type (a React node, a Vue component).
|
|
6
|
+
*/
|
|
7
|
+
export interface InspectorSelection<TEditor> {
|
|
8
|
+
key: string;
|
|
9
|
+
title?: string;
|
|
10
|
+
editor: TEditor;
|
|
11
|
+
}
|
|
12
|
+
export interface InspectorState<TEditor> {
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
selected: InspectorSelection<TEditor> | null;
|
|
15
|
+
}
|
|
16
|
+
export interface Inspector<TEditor> {
|
|
17
|
+
store: MicroStore<InspectorState<TEditor>>;
|
|
18
|
+
enable(): void;
|
|
19
|
+
/** Also clears the selection. */
|
|
20
|
+
disable(): void;
|
|
21
|
+
toggle(): void;
|
|
22
|
+
/** Replaces the selection while enabled and does nothing while disabled. */
|
|
23
|
+
select(selection: InspectorSelection<TEditor>): void;
|
|
24
|
+
/** Clears the selection only when its key is `key`, so a stale unmount cannot clear a newer one. */
|
|
25
|
+
release(key: string): void;
|
|
26
|
+
}
|
|
27
|
+
export declare function createInspector<TEditor = unknown>(): Inspector<TEditor>;
|
|
28
|
+
export declare const inspectorPositionKey = "chelone.inspector.position";
|
|
29
|
+
/** The panel's width in pixels. */
|
|
30
|
+
export declare const PANEL_WIDTH = 320;
|
|
31
|
+
/** How far one arrow key moves the panel, in pixels. */
|
|
32
|
+
export declare const INSPECTOR_KEY_STEP = 16;
|
|
33
|
+
/** The message key a `<Configurable>`'s open button falls back to. */
|
|
34
|
+
export declare const INSPECTOR_OPEN_LABEL = "chelone.inspector.customize";
|
|
35
|
+
export interface InspectorPosition {
|
|
36
|
+
x: number;
|
|
37
|
+
y: number;
|
|
38
|
+
}
|
|
39
|
+
export interface InspectorViewport {
|
|
40
|
+
viewportWidth: number;
|
|
41
|
+
viewportHeight: number;
|
|
42
|
+
panelWidth: number;
|
|
43
|
+
margin?: number;
|
|
44
|
+
handleHeight?: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Keeps the panel's drag handle on screen. A missing or non-finite position
|
|
48
|
+
* gives the top right corner.
|
|
49
|
+
*/
|
|
50
|
+
export declare function clampInspectorPosition(position: InspectorPosition | null | undefined, { viewportWidth, viewportHeight, panelWidth, margin, handleHeight, }: InspectorViewport): InspectorPosition;
|
|
51
|
+
export declare function defaultConfigurableInputsStoreKey(resource: string): string;
|
|
52
|
+
export declare function configurableInputColumns(inputs: readonly {
|
|
53
|
+
source?: unknown;
|
|
54
|
+
label?: unknown;
|
|
55
|
+
}[]): DataTableColumnInfo[];
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { createMicroStore } from "../store/micro-store.js";
|
|
2
|
+
import { getDataTableColumnId } from "./data-table-columns.js";
|
|
3
|
+
// src/controller/inspector.ts
|
|
4
|
+
function createInspector() {
|
|
5
|
+
const store = createMicroStore({
|
|
6
|
+
enabled: false,
|
|
7
|
+
selected: null
|
|
8
|
+
});
|
|
9
|
+
const enable = () => store.setState({ enabled: true });
|
|
10
|
+
const disable = () => store.setState({
|
|
11
|
+
enabled: false,
|
|
12
|
+
selected: null
|
|
13
|
+
});
|
|
14
|
+
return {
|
|
15
|
+
store,
|
|
16
|
+
enable,
|
|
17
|
+
disable,
|
|
18
|
+
toggle() {
|
|
19
|
+
if (store.getSnapshot().enabled) disable();
|
|
20
|
+
else enable();
|
|
21
|
+
},
|
|
22
|
+
select(selection) {
|
|
23
|
+
if (!store.getSnapshot().enabled) return;
|
|
24
|
+
store.setState({ selected: selection });
|
|
25
|
+
},
|
|
26
|
+
release(key) {
|
|
27
|
+
if (store.getSnapshot().selected?.key !== key) return;
|
|
28
|
+
store.setState({ selected: null });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
var inspectorPositionKey = "chelone.inspector.position";
|
|
33
|
+
/** The panel's width in pixels. */
|
|
34
|
+
var PANEL_WIDTH = 320;
|
|
35
|
+
/** How far one arrow key moves the panel, in pixels. */
|
|
36
|
+
var INSPECTOR_KEY_STEP = 16;
|
|
37
|
+
/** The message key a `<Configurable>`'s open button falls back to. */
|
|
38
|
+
var INSPECTOR_OPEN_LABEL = "chelone.inspector.customize";
|
|
39
|
+
var clamp = (value, min, max) => Math.min(Math.max(value, min), Math.max(min, max));
|
|
40
|
+
/**
|
|
41
|
+
* Keeps the panel's drag handle on screen. A missing or non-finite position
|
|
42
|
+
* gives the top right corner.
|
|
43
|
+
*/
|
|
44
|
+
function clampInspectorPosition(position, { viewportWidth, viewportHeight, panelWidth, margin = 8, handleHeight = 48 }) {
|
|
45
|
+
const maxX = viewportWidth - panelWidth - margin;
|
|
46
|
+
const maxY = viewportHeight - handleHeight;
|
|
47
|
+
if (!position || !Number.isFinite(position.x) || !Number.isFinite(position.y)) return {
|
|
48
|
+
x: clamp(maxX, margin, maxX),
|
|
49
|
+
y: margin
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
x: clamp(position.x, margin, maxX),
|
|
53
|
+
y: clamp(position.y, margin, maxY)
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function defaultConfigurableInputsStoreKey(resource) {
|
|
57
|
+
return `${resource}.inputs`;
|
|
58
|
+
}
|
|
59
|
+
function configurableInputColumns(inputs) {
|
|
60
|
+
return inputs.map(({ source, label }, index) => {
|
|
61
|
+
const column = { id: getDataTableColumnId({
|
|
62
|
+
source,
|
|
63
|
+
label
|
|
64
|
+
}) ?? `input-${index}` };
|
|
65
|
+
if (typeof source === "string") column.source = source;
|
|
66
|
+
if (typeof label === "string") column.label = label;
|
|
67
|
+
return column;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
export { INSPECTOR_KEY_STEP, INSPECTOR_OPEN_LABEL, PANEL_WIDTH, clampInspectorPosition, configurableInputColumns, createInspector, defaultConfigurableInputsStoreKey, inspectorPositionKey };
|
|
@@ -11,9 +11,9 @@ import type { ResourceRecord } from "../resource/record.js";
|
|
|
11
11
|
import type { SourceKey } from "../resource/source-path.js";
|
|
12
12
|
/** The monitor's tabs, in order. One `buildKanbanBuckets` column per status. */
|
|
13
13
|
export declare const DEFAULT_JOB_TABS: readonly ["running", "queued", "failed", "done"];
|
|
14
|
-
export interface JobActionOptions<TRecord
|
|
14
|
+
export interface JobActionOptions<TRecord extends object> {
|
|
15
15
|
/** Record field holding the job status, a top-level key. Default `"status"`. */
|
|
16
|
-
statusSource?:
|
|
16
|
+
statusSource?: keyof TRecord & string;
|
|
17
17
|
/** Statuses a job can be retried from. Default `["failed"]`. */
|
|
18
18
|
retryFrom?: readonly string[];
|
|
19
19
|
/** Statuses a job can be cancelled from. Default `["running", "queued"]`. */
|
|
@@ -32,10 +32,16 @@ export interface JobActions {
|
|
|
32
32
|
/** The arguments of one `update` call, ready to hand to a data provider. */
|
|
33
33
|
export interface JobPlan<TRecord> {
|
|
34
34
|
id: Identifier;
|
|
35
|
-
data:
|
|
35
|
+
data: Partial<TRecord>;
|
|
36
36
|
previousData: TRecord;
|
|
37
37
|
}
|
|
38
|
-
|
|
38
|
+
/**
|
|
39
|
+
* The status key a monitor reads: `source`, or `"status"`. `SourceKey` is
|
|
40
|
+
* `keyof TRecord & string` for a typed record and `string` for a loose one,
|
|
41
|
+
* whose keys are every string, so it is always a key of `TRecord`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function jobStatusSource<TRecord extends object>(source?: SourceKey<TRecord>): keyof TRecord & string;
|
|
44
|
+
export declare function getJobActions<TRecord extends object>(record: TRecord & object, options?: JobActionOptions<TRecord>): JobActions;
|
|
39
45
|
/** The `update` that retries the job, or `null` when it cannot be retried. */
|
|
40
46
|
export declare function planJobRetry<TRecord extends ResourceRecord = ResourceRecord>(record: TRecord, options?: JobActionOptions<TRecord>): JobPlan<TRecord> | null;
|
|
41
47
|
/** The `update` that cancels the job, or `null` when it cannot be cancelled. */
|
|
@@ -1,59 +1,58 @@
|
|
|
1
1
|
import { getAllowedTransitions } from "./record-workflow.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
// src/controller/job-monitor.ts
|
|
3
|
+
/** The monitor's tabs, in order. One `buildKanbanBuckets` column per status. */
|
|
4
|
+
var DEFAULT_JOB_TABS = [
|
|
5
|
+
"running",
|
|
6
|
+
"queued",
|
|
7
|
+
"failed",
|
|
8
|
+
"done"
|
|
7
9
|
];
|
|
8
10
|
function canMove(record, source, from, to) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
const transitions = Object.fromEntries(from.map((status) => [status, [to]]));
|
|
12
|
+
const { current, allowed } = getAllowedTransitions(record, {
|
|
13
|
+
source,
|
|
14
|
+
transitions
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
status: current,
|
|
18
|
+
allowed: allowed.includes(to)
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The status key a monitor reads: `source`, or `"status"`. `SourceKey` is
|
|
23
|
+
* `keyof TRecord & string` for a typed record and `string` for a loose one,
|
|
24
|
+
* whose keys are every string, so it is always a key of `TRecord`.
|
|
25
|
+
*/
|
|
26
|
+
function jobStatusSource(source) {
|
|
27
|
+
return source ?? "status";
|
|
15
28
|
}
|
|
16
29
|
function getJobActions(record, options = {}) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const cancel = canMove(record, statusSource, cancelFrom, cancelValue);
|
|
26
|
-
return {
|
|
27
|
-
status: retry.status,
|
|
28
|
-
canRetry: retry.allowed,
|
|
29
|
-
canCancel: cancel.allowed
|
|
30
|
-
};
|
|
30
|
+
const { statusSource = "status", retryFrom = ["failed"], cancelFrom = ["running", "queued"], retryValue = "queued", cancelValue = "cancelled" } = options;
|
|
31
|
+
const retry = canMove(record, statusSource, retryFrom, retryValue);
|
|
32
|
+
const cancel = canMove(record, statusSource, cancelFrom, cancelValue);
|
|
33
|
+
return {
|
|
34
|
+
status: retry.status,
|
|
35
|
+
canRetry: retry.allowed,
|
|
36
|
+
canCancel: cancel.allowed
|
|
37
|
+
};
|
|
31
38
|
}
|
|
32
39
|
function plan(record, source, value, allowed) {
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
if (!allowed) return null;
|
|
41
|
+
const data = { [source]: value };
|
|
42
|
+
return {
|
|
43
|
+
id: record.id,
|
|
44
|
+
data,
|
|
45
|
+
previousData: record
|
|
46
|
+
};
|
|
35
47
|
}
|
|
48
|
+
/** The `update` that retries the job, or `null` when it cannot be retried. */
|
|
36
49
|
function planJobRetry(record, options = {}) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
record,
|
|
40
|
-
statusSource,
|
|
41
|
-
retryValue,
|
|
42
|
-
getJobActions(record, options).canRetry
|
|
43
|
-
);
|
|
50
|
+
const { statusSource = "status", retryValue = "queued" } = options;
|
|
51
|
+
return plan(record, statusSource, retryValue, getJobActions(record, options).canRetry);
|
|
44
52
|
}
|
|
53
|
+
/** The `update` that cancels the job, or `null` when it cannot be cancelled. */
|
|
45
54
|
function planJobCancel(record, options = {}) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
record,
|
|
49
|
-
statusSource,
|
|
50
|
-
cancelValue,
|
|
51
|
-
getJobActions(record, options).canCancel
|
|
52
|
-
);
|
|
55
|
+
const { statusSource = "status", cancelValue = "cancelled" } = options;
|
|
56
|
+
return plan(record, statusSource, cancelValue, getJobActions(record, options).canCancel);
|
|
53
57
|
}
|
|
54
|
-
export {
|
|
55
|
-
DEFAULT_JOB_TABS,
|
|
56
|
-
getJobActions,
|
|
57
|
-
planJobCancel,
|
|
58
|
-
planJobRetry
|
|
59
|
-
};
|
|
58
|
+
export { DEFAULT_JOB_TABS, getJobActions, jobStatusSource, planJobCancel, planJobRetry };
|
|
@@ -1,30 +1,51 @@
|
|
|
1
|
+
// src/controller/kanban-board.ts
|
|
2
|
+
/**
|
|
3
|
+
* The column key a record sits under: its group value as a string, with a
|
|
4
|
+
* missing or null value reading as `""`. A top-level key, because a move can
|
|
5
|
+
* only write `{ [source]: value }` — as in {@link getAllowedTransitions}.
|
|
6
|
+
* Read through `Reflect.get`: `SourceKey<R>` of a generic record is a
|
|
7
|
+
* deferred type, so `record[groupSource]` would not typecheck.
|
|
8
|
+
*/
|
|
1
9
|
function bucketKey(record, groupSource) {
|
|
2
|
-
|
|
3
|
-
return String(value ?? "");
|
|
10
|
+
return String(Reflect.get(record, groupSource) ?? "");
|
|
4
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* One bucket per column, in column order, empty columns included. A record
|
|
14
|
+
* lands in the column whose id is its group key; a record that names no column
|
|
15
|
+
* is in no bucket, and records keep list order inside a bucket. A repeated
|
|
16
|
+
* column id keeps the first column's records and leaves the later one empty.
|
|
17
|
+
*/
|
|
5
18
|
function buildKanbanBuckets(records, groupSource, columns) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
const buckets = columns.map((column) => ({
|
|
20
|
+
column,
|
|
21
|
+
records: []
|
|
22
|
+
}));
|
|
23
|
+
const bucketOf = /* @__PURE__ */ new Map();
|
|
24
|
+
columns.forEach((column, index) => {
|
|
25
|
+
if (!bucketOf.has(column.id)) bucketOf.set(column.id, index);
|
|
26
|
+
});
|
|
27
|
+
for (const record of records) {
|
|
28
|
+
const index = bucketOf.get(bucketKey(record, groupSource));
|
|
29
|
+
if (index === void 0) continue;
|
|
30
|
+
const bucket = buckets[index];
|
|
31
|
+
if (bucket) bucket.records.push(record);
|
|
32
|
+
}
|
|
33
|
+
return buckets;
|
|
20
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* The update a drop into `targetColumnId` asks for, or `null` when there is
|
|
37
|
+
* nothing to write: the target is not a column, or the record already sits in
|
|
38
|
+
* it. A drop that writes nothing still fires a data-provider `update` on every
|
|
39
|
+
* board that re-renders on a dropped drag, so the adapters ask here first.
|
|
40
|
+
*/
|
|
21
41
|
function planKanbanMove(record, groupSource, columns, targetColumnId) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
42
|
+
if (!columns.some((column) => column.id === targetColumnId)) return null;
|
|
43
|
+
if (bucketKey(record, groupSource) === targetColumnId) return null;
|
|
44
|
+
const data = { [groupSource]: targetColumnId };
|
|
45
|
+
return {
|
|
46
|
+
id: record.id,
|
|
47
|
+
data,
|
|
48
|
+
previousData: record
|
|
49
|
+
};
|
|
26
50
|
}
|
|
27
|
-
export {
|
|
28
|
-
buildKanbanBuckets,
|
|
29
|
-
planKanbanMove
|
|
30
|
-
};
|
|
51
|
+
export { buildKanbanBuckets, planKanbanMove };
|
|
@@ -19,7 +19,7 @@ export interface ListControllerState<TRecord> {
|
|
|
19
19
|
pageInfo: PageInfo | undefined;
|
|
20
20
|
isPending: boolean;
|
|
21
21
|
isFetching: boolean;
|
|
22
|
-
error:
|
|
22
|
+
error: Error | null;
|
|
23
23
|
hasNextPage: boolean | undefined;
|
|
24
24
|
hasPreviousPage: boolean | undefined;
|
|
25
25
|
}
|
|
@@ -76,6 +76,9 @@ export interface ListControllerOptions {
|
|
|
76
76
|
storeKey?: string | false;
|
|
77
77
|
enabled?: boolean;
|
|
78
78
|
}
|
|
79
|
+
/** The `perPage` a list starts at when nothing is persisted or in the URL. The single definition: `prev-next` and both adapters read this. */
|
|
80
|
+
export declare const DEFAULT_PER_PAGE = 10;
|
|
81
|
+
/** Debounce delay for `setFilters(..., debounced=true)` when no `debounceMs` option is given. Shared with the reference-many and choices controllers. */
|
|
79
82
|
export declare const DEFAULT_DEBOUNCE_MS = 500;
|
|
80
83
|
export declare const DEFAULT_SELECT_ALL_LIMIT = 250;
|
|
81
84
|
/**
|
|
@@ -108,17 +111,17 @@ export declare function runSelectAll(notifications: NotificationStore | undefine
|
|
|
108
111
|
* again after a success can say so.
|
|
109
112
|
*/
|
|
110
113
|
export declare function createErrorAnnouncer(notifications: NotificationStore | undefined): {
|
|
111
|
-
announce(error:
|
|
114
|
+
announce(error: Error | null): void;
|
|
112
115
|
rearm(): void;
|
|
113
116
|
};
|
|
114
117
|
/** `hasNextPage`/`hasPreviousPage` from the provider's `pageInfo` or, failing that, the total. */
|
|
115
|
-
export declare function pageFlags(page: number, perPage: number, total: number | undefined, pageInfo: PageInfo | undefined): Pick<ListControllerState<
|
|
118
|
+
export declare function pageFlags(page: number, perPage: number, total: number | undefined, pageInfo: PageInfo | undefined): Pick<ListControllerState<ResourceRecord>, "hasNextPage" | "hasPreviousPage">;
|
|
116
119
|
/**
|
|
117
120
|
* The page an out-of-range state should move to, or undefined when it is in
|
|
118
121
|
* range. Only a SETTLED result may move past page 1, so a reset-induced
|
|
119
122
|
* refetch can never trigger another reset.
|
|
120
123
|
*/
|
|
121
|
-
export declare function resetPageTarget(s: Pick<ListControllerState<
|
|
124
|
+
export declare function resetPageTarget(s: Pick<ListControllerState<ResourceRecord>, "page" | "perPage" | "total" | "data" | "isPending" | "isFetching">): number | undefined;
|
|
122
125
|
/**
|
|
123
126
|
* Vanilla list controller: one QueryObserver mapped into a micro-store.
|
|
124
127
|
*
|
|
@@ -142,7 +145,7 @@ export declare function resetPageTarget(s: Pick<ListControllerState<unknown>, "p
|
|
|
142
145
|
* The actions of a list controller, for an adapter to spread next to its own
|
|
143
146
|
* reactive state. They are the same functions across state changes.
|
|
144
147
|
*/
|
|
145
|
-
export declare function listControllerActions(controller: Omit<ListController<
|
|
148
|
+
export declare function listControllerActions(controller: Omit<ListController<ResourceRecord>, keyof MicroStore<ListControllerState<ResourceRecord>> | "defaultPerPage">): {
|
|
146
149
|
setPage: (page: number) => void;
|
|
147
150
|
setPerPage: (perPage: number) => void;
|
|
148
151
|
setSort: (sort: SortPayload | SortPayload[]) => void;
|