@chelone/core 0.6.0 → 0.7.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 +21 -17
- package/dist/auth/auth-options.js +80 -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 +60 -0
- package/dist/block-editor/block-document.js +143 -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.js +8 -11
- package/dist/command-menu/registry.d.ts +9 -5
- package/dist/command-menu/registry.js +36 -46
- package/dist/controller/calendar-dates.js +82 -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 +42 -0
- package/dist/controller/in-place-editor.js +42 -0
- package/dist/controller/infinite-list-controller.js +219 -189
- package/dist/controller/inspector.d.ts +49 -0
- package/dist/controller/inspector.js +64 -0
- package/dist/controller/job-monitor.d.ts +3 -4
- package/dist/controller/job-monitor.js +37 -47
- package/dist/controller/kanban-board.d.ts +2 -3
- package/dist/controller/kanban-board.js +43 -24
- package/dist/controller/list-controller.d.ts +5 -5
- package/dist/controller/list-controller.js +444 -400
- package/dist/controller/list-params.js +96 -87
- 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.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.js +198 -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 +2 -1
- package/dist/csv/export.js +43 -40
- package/dist/csv/import-controller.js +185 -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 +129 -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 +3 -2
- package/dist/form/choices-controller.js +302 -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 +169 -118
- package/dist/form/input-values.d.ts +130 -0
- package/dist/form/input-values.js +177 -0
- package/dist/form/json-text.js +51 -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.js +31 -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 +7 -6
- package/dist/geo/map-layers.d.ts +42 -7
- package/dist/geo/map-layers.js +88 -62
- package/dist/geo/map-style.js +31 -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 +37 -0
- package/dist/guards.js +62 -0
- package/dist/i18n/default-messages.js +34 -29
- package/dist/i18n/english-messages.js +187 -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.js +66 -62
- package/dist/i18n/translatable.d.ts +16 -1
- package/dist/i18n/translatable.js +40 -47
- package/dist/index.d.ts +71 -24
- package/dist/index.js +40 -288
- 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.js +63 -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 +232 -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 +16 -1
- package/dist/rich-text/rich-text-extras.d.ts +132 -0
- package/dist/rich-text/rich-text-extras.js +179 -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 +22 -4
- package/dist/router/location.js +41 -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/package.json +13 -11
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
var clamp = (value, min, max) => Math.min(Math.max(value, min), Math.max(min, max));
|
|
34
|
+
/**
|
|
35
|
+
* Keeps the panel's drag handle on screen. A missing or non-finite position
|
|
36
|
+
* gives the top right corner.
|
|
37
|
+
*/
|
|
38
|
+
function clampInspectorPosition(position, { viewportWidth, viewportHeight, panelWidth, margin = 8, handleHeight = 48 }) {
|
|
39
|
+
const maxX = viewportWidth - panelWidth - margin;
|
|
40
|
+
const maxY = viewportHeight - handleHeight;
|
|
41
|
+
if (!position || !Number.isFinite(position.x) || !Number.isFinite(position.y)) return {
|
|
42
|
+
x: clamp(maxX, margin, maxX),
|
|
43
|
+
y: margin
|
|
44
|
+
};
|
|
45
|
+
return {
|
|
46
|
+
x: clamp(position.x, margin, maxX),
|
|
47
|
+
y: clamp(position.y, margin, maxY)
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function defaultConfigurableInputsStoreKey(resource) {
|
|
51
|
+
return `${resource}.inputs`;
|
|
52
|
+
}
|
|
53
|
+
function configurableInputColumns(inputs) {
|
|
54
|
+
return inputs.map(({ source, label }, index) => {
|
|
55
|
+
const column = { id: getDataTableColumnId({
|
|
56
|
+
source,
|
|
57
|
+
label
|
|
58
|
+
}) ?? `input-${index}` };
|
|
59
|
+
if (typeof source === "string") column.source = source;
|
|
60
|
+
if (typeof label === "string") column.label = label;
|
|
61
|
+
return column;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
export { clampInspectorPosition, configurableInputColumns, createInspector, defaultConfigurableInputsStoreKey, inspectorPositionKey };
|
|
@@ -8,12 +8,11 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { Identifier } from "../resource/identifier.js";
|
|
10
10
|
import type { ResourceRecord } from "../resource/record.js";
|
|
11
|
-
import type { SourceKey } from "../resource/source-path.js";
|
|
12
11
|
/** The monitor's tabs, in order. One `buildKanbanBuckets` column per status. */
|
|
13
12
|
export declare const DEFAULT_JOB_TABS: readonly ["running", "queued", "failed", "done"];
|
|
14
|
-
export interface JobActionOptions<TRecord
|
|
13
|
+
export interface JobActionOptions<TRecord extends object> {
|
|
15
14
|
/** Record field holding the job status, a top-level key. Default `"status"`. */
|
|
16
|
-
statusSource?:
|
|
15
|
+
statusSource?: keyof TRecord & string;
|
|
17
16
|
/** Statuses a job can be retried from. Default `["failed"]`. */
|
|
18
17
|
retryFrom?: readonly string[];
|
|
19
18
|
/** Statuses a job can be cancelled from. Default `["running", "queued"]`. */
|
|
@@ -35,7 +34,7 @@ export interface JobPlan<TRecord> {
|
|
|
35
34
|
data: Record<string, string>;
|
|
36
35
|
previousData: TRecord;
|
|
37
36
|
}
|
|
38
|
-
export declare function getJobActions<TRecord
|
|
37
|
+
export declare function getJobActions<TRecord extends object>(record: TRecord & object, options?: JobActionOptions<TRecord>): JobActions;
|
|
39
38
|
/** The `update` that retries the job, or `null` when it cannot be retried. */
|
|
40
39
|
export declare function planJobRetry<TRecord extends ResourceRecord = ResourceRecord>(record: TRecord, options?: JobActionOptions<TRecord>): JobPlan<TRecord> | null;
|
|
41
40
|
/** The `update` that cancels the job, or `null` when it cannot be cancelled. */
|
|
@@ -1,59 +1,49 @@
|
|
|
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
|
+
};
|
|
15
20
|
}
|
|
16
21
|
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
|
-
};
|
|
22
|
+
const { statusSource = "status", retryFrom = ["failed"], cancelFrom = ["running", "queued"], retryValue = "queued", cancelValue = "cancelled" } = options;
|
|
23
|
+
const retry = canMove(record, statusSource, retryFrom, retryValue);
|
|
24
|
+
const cancel = canMove(record, statusSource, cancelFrom, cancelValue);
|
|
25
|
+
return {
|
|
26
|
+
status: retry.status,
|
|
27
|
+
canRetry: retry.allowed,
|
|
28
|
+
canCancel: cancel.allowed
|
|
29
|
+
};
|
|
31
30
|
}
|
|
32
31
|
function plan(record, source, value, allowed) {
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
if (!allowed) return null;
|
|
33
|
+
return {
|
|
34
|
+
id: record.id,
|
|
35
|
+
data: { [source]: value },
|
|
36
|
+
previousData: record
|
|
37
|
+
};
|
|
35
38
|
}
|
|
39
|
+
/** The `update` that retries the job, or `null` when it cannot be retried. */
|
|
36
40
|
function planJobRetry(record, options = {}) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
record,
|
|
40
|
-
statusSource,
|
|
41
|
-
retryValue,
|
|
42
|
-
getJobActions(record, options).canRetry
|
|
43
|
-
);
|
|
41
|
+
const { statusSource = "status", retryValue = "queued" } = options;
|
|
42
|
+
return plan(record, statusSource, retryValue, getJobActions(record, options).canRetry);
|
|
44
43
|
}
|
|
44
|
+
/** The `update` that cancels the job, or `null` when it cannot be cancelled. */
|
|
45
45
|
function planJobCancel(record, options = {}) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
record,
|
|
49
|
-
statusSource,
|
|
50
|
-
cancelValue,
|
|
51
|
-
getJobActions(record, options).canCancel
|
|
52
|
-
);
|
|
46
|
+
const { statusSource = "status", cancelValue = "cancelled" } = options;
|
|
47
|
+
return plan(record, statusSource, cancelValue, getJobActions(record, options).canCancel);
|
|
53
48
|
}
|
|
54
|
-
export {
|
|
55
|
-
DEFAULT_JOB_TABS,
|
|
56
|
-
getJobActions,
|
|
57
|
-
planJobCancel,
|
|
58
|
-
planJobRetry
|
|
59
|
-
};
|
|
49
|
+
export { DEFAULT_JOB_TABS, getJobActions, planJobCancel, planJobRetry };
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { Identifier } from "../resource/identifier.js";
|
|
11
11
|
import type { ResourceRecord } from "../resource/record.js";
|
|
12
|
-
import type { SourceKey } from "../resource/source-path.js";
|
|
13
12
|
export interface KanbanColumnDef {
|
|
14
13
|
/** Value written to `groupSource` by a drop into this column. */
|
|
15
14
|
id: string;
|
|
@@ -36,11 +35,11 @@ export interface KanbanMove<R> {
|
|
|
36
35
|
* is in no bucket, and records keep list order inside a bucket. A repeated
|
|
37
36
|
* column id keeps the first column's records and leaves the later one empty.
|
|
38
37
|
*/
|
|
39
|
-
export declare function buildKanbanBuckets<R extends ResourceRecord>(records: readonly R[], groupSource:
|
|
38
|
+
export declare function buildKanbanBuckets<R extends ResourceRecord>(records: readonly R[], groupSource: keyof R & string, columns: readonly KanbanColumnDef[]): KanbanBucket<R>[];
|
|
40
39
|
/**
|
|
41
40
|
* The update a drop into `targetColumnId` asks for, or `null` when there is
|
|
42
41
|
* nothing to write: the target is not a column, or the record already sits in
|
|
43
42
|
* it. A drop that writes nothing still fires a data-provider `update` on every
|
|
44
43
|
* board that re-renders on a dropped drag, so the adapters ask here first.
|
|
45
44
|
*/
|
|
46
|
-
export declare function planKanbanMove<R extends ResourceRecord>(record: R, groupSource:
|
|
45
|
+
export declare function planKanbanMove<R extends ResourceRecord>(record: R, groupSource: keyof R & string, columns: readonly KanbanColumnDef[], targetColumnId: string): KanbanMove<R> | null;
|
|
@@ -1,30 +1,49 @@
|
|
|
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
|
+
*/
|
|
1
7
|
function bucketKey(record, groupSource) {
|
|
2
|
-
|
|
3
|
-
return String(value ?? "");
|
|
8
|
+
return String(record[groupSource] ?? "");
|
|
4
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* One bucket per column, in column order, empty columns included. A record
|
|
12
|
+
* lands in the column whose id is its group key; a record that names no column
|
|
13
|
+
* is in no bucket, and records keep list order inside a bucket. A repeated
|
|
14
|
+
* column id keeps the first column's records and leaves the later one empty.
|
|
15
|
+
*/
|
|
5
16
|
function buildKanbanBuckets(records, groupSource, columns) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
const buckets = columns.map((column) => ({
|
|
18
|
+
column,
|
|
19
|
+
records: []
|
|
20
|
+
}));
|
|
21
|
+
const bucketOf = /* @__PURE__ */ new Map();
|
|
22
|
+
columns.forEach((column, index) => {
|
|
23
|
+
if (!bucketOf.has(column.id)) bucketOf.set(column.id, index);
|
|
24
|
+
});
|
|
25
|
+
for (const record of records) {
|
|
26
|
+
const index = bucketOf.get(bucketKey(record, groupSource));
|
|
27
|
+
if (index === void 0) continue;
|
|
28
|
+
const bucket = buckets[index];
|
|
29
|
+
if (bucket) bucket.records.push(record);
|
|
30
|
+
}
|
|
31
|
+
return buckets;
|
|
20
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* The update a drop into `targetColumnId` asks for, or `null` when there is
|
|
35
|
+
* nothing to write: the target is not a column, or the record already sits in
|
|
36
|
+
* it. A drop that writes nothing still fires a data-provider `update` on every
|
|
37
|
+
* board that re-renders on a dropped drag, so the adapters ask here first.
|
|
38
|
+
*/
|
|
21
39
|
function planKanbanMove(record, groupSource, columns, targetColumnId) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
40
|
+
if (!columns.some((column) => column.id === targetColumnId)) return null;
|
|
41
|
+
if (bucketKey(record, groupSource) === targetColumnId) return null;
|
|
42
|
+
const data = { [groupSource]: targetColumnId };
|
|
43
|
+
return {
|
|
44
|
+
id: record.id,
|
|
45
|
+
data,
|
|
46
|
+
previousData: record
|
|
47
|
+
};
|
|
26
48
|
}
|
|
27
|
-
export {
|
|
28
|
-
buildKanbanBuckets,
|
|
29
|
-
planKanbanMove
|
|
30
|
-
};
|
|
49
|
+
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
|
}
|
|
@@ -108,17 +108,17 @@ export declare function runSelectAll(notifications: NotificationStore | undefine
|
|
|
108
108
|
* again after a success can say so.
|
|
109
109
|
*/
|
|
110
110
|
export declare function createErrorAnnouncer(notifications: NotificationStore | undefined): {
|
|
111
|
-
announce(error:
|
|
111
|
+
announce(error: Error | null): void;
|
|
112
112
|
rearm(): void;
|
|
113
113
|
};
|
|
114
114
|
/** `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<
|
|
115
|
+
export declare function pageFlags(page: number, perPage: number, total: number | undefined, pageInfo: PageInfo | undefined): Pick<ListControllerState<ResourceRecord>, "hasNextPage" | "hasPreviousPage">;
|
|
116
116
|
/**
|
|
117
117
|
* The page an out-of-range state should move to, or undefined when it is in
|
|
118
118
|
* range. Only a SETTLED result may move past page 1, so a reset-induced
|
|
119
119
|
* refetch can never trigger another reset.
|
|
120
120
|
*/
|
|
121
|
-
export declare function resetPageTarget(s: Pick<ListControllerState<
|
|
121
|
+
export declare function resetPageTarget(s: Pick<ListControllerState<ResourceRecord>, "page" | "perPage" | "total" | "data" | "isPending" | "isFetching">): number | undefined;
|
|
122
122
|
/**
|
|
123
123
|
* Vanilla list controller: one QueryObserver mapped into a micro-store.
|
|
124
124
|
*
|
|
@@ -142,7 +142,7 @@ export declare function resetPageTarget(s: Pick<ListControllerState<unknown>, "p
|
|
|
142
142
|
* The actions of a list controller, for an adapter to spread next to its own
|
|
143
143
|
* reactive state. They are the same functions across state changes.
|
|
144
144
|
*/
|
|
145
|
-
export declare function listControllerActions(controller: Omit<ListController<
|
|
145
|
+
export declare function listControllerActions(controller: Omit<ListController<ResourceRecord>, keyof MicroStore<ListControllerState<ResourceRecord>> | "defaultPerPage">): {
|
|
146
146
|
setPage: (page: number) => void;
|
|
147
147
|
setPerPage: (perPage: number) => void;
|
|
148
148
|
setSort: (sort: SortPayload | SortPayload[]) => void;
|