@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
|
@@ -1,425 +1,472 @@
|
|
|
1
|
-
import { QueryObserver } from "@tanstack/query-core";
|
|
2
1
|
import { getListOptions } from "../data/query-options.js";
|
|
2
|
+
import { removeEmpty } from "../data/remove-empty.js";
|
|
3
|
+
import { isRecord } from "../guards.js";
|
|
3
4
|
import { createMicroStore } from "../store/micro-store.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import { QueryObserver } from "@tanstack/query-core";
|
|
6
|
+
// src/controller/list-controller.ts
|
|
7
|
+
/** The `perPage` a list starts at when nothing is persisted or in the URL. The single definition: `prev-next` and both adapters read this. */
|
|
8
|
+
var DEFAULT_PER_PAGE = 10;
|
|
9
|
+
/** Debounce delay for `setFilters(..., debounced=true)` when no `debounceMs` option is given. Shared with the reference-many and choices controllers. */
|
|
10
|
+
var DEFAULT_DEBOUNCE_MS = 500;
|
|
11
|
+
var DEFAULT_SORT = [{
|
|
12
|
+
field: "id",
|
|
13
|
+
order: "ASC"
|
|
14
|
+
}];
|
|
8
15
|
function normalizeSort(sort, fallback) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return entries.map((entry) => ({ ...entry }));
|
|
12
|
-
}
|
|
13
|
-
function removeEmpty(filter) {
|
|
14
|
-
const result = {};
|
|
15
|
-
for (const [key, value] of Object.entries(filter)) {
|
|
16
|
-
if (value === "" || value === null || value === void 0) continue;
|
|
17
|
-
result[key] = value;
|
|
18
|
-
}
|
|
19
|
-
return result;
|
|
16
|
+
if (!sort) return fallback.map((entry) => ({ ...entry }));
|
|
17
|
+
return (Array.isArray(sort) ? sort : [sort]).map((entry) => ({ ...entry }));
|
|
20
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Returns `filter` without the value at `path`: the flat key of that name and,
|
|
21
|
+
* for a dotted path, the nested value, pruning parents it leaves empty. Never
|
|
22
|
+
* mutates `filter`. Shared with the client controller.
|
|
23
|
+
*/
|
|
21
24
|
function removeFilterPath(filter, path) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
25
|
+
const { [path]: _flat, ...rest } = filter;
|
|
26
|
+
const keys = path.split(".");
|
|
27
|
+
if (keys.length === 1) return rest;
|
|
28
|
+
const prune = (node, depth) => {
|
|
29
|
+
const key = keys[depth];
|
|
30
|
+
if (key === void 0) return node;
|
|
31
|
+
const child = node[key];
|
|
32
|
+
if (depth === keys.length - 1) {
|
|
33
|
+
const { [key]: _removed, ...others } = node;
|
|
34
|
+
return others;
|
|
35
|
+
}
|
|
36
|
+
if (!isRecord(child)) return node;
|
|
37
|
+
const pruned = prune(child, depth + 1);
|
|
38
|
+
if (pruned === child) return node;
|
|
39
|
+
if (Object.keys(pruned).length === 0) {
|
|
40
|
+
const { [key]: _emptied, ...others } = node;
|
|
41
|
+
return others;
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
...node,
|
|
45
|
+
[key]: pruned
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
return prune(rest, 0);
|
|
44
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Turns a {@link ListParamsPatch} into the state slice it changes. Shared with
|
|
52
|
+
* the client controller so the page-reset rule lives in one place.
|
|
53
|
+
*/
|
|
45
54
|
function listParamsFromPatch(patch) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
next.page = patch.page;
|
|
55
|
-
} else if (patch.filter !== void 0 || patch.sort !== void 0 || patch.perPage !== void 0) {
|
|
56
|
-
next.page = 1;
|
|
57
|
-
}
|
|
58
|
-
return next;
|
|
55
|
+
const next = {};
|
|
56
|
+
if (patch.filter !== void 0) next.filter = removeEmpty(patch.filter);
|
|
57
|
+
if (patch.displayedFilters !== void 0) next.displayedFilters = { ...patch.displayedFilters };
|
|
58
|
+
if (patch.sort !== void 0) next.sort = normalizeSort(patch.sort, []);
|
|
59
|
+
if (patch.perPage !== void 0) next.perPage = patch.perPage;
|
|
60
|
+
if (patch.page !== void 0) next.page = patch.page;
|
|
61
|
+
else if (patch.filter !== void 0 || patch.sort !== void 0 || patch.perPage !== void 0) next.page = 1;
|
|
62
|
+
return next;
|
|
59
63
|
}
|
|
64
|
+
/** The notification key for a failed fetch: the error's own message, else `chelone.notification.http_error`. */
|
|
60
65
|
function errorMessageKey(error) {
|
|
61
|
-
|
|
62
|
-
return message || "chelone.notification.http_error";
|
|
66
|
+
return (error instanceof Error ? error.message : "") || "chelone.notification.http_error";
|
|
63
67
|
}
|
|
68
|
+
/** Notifies a failed fetch under its message, falling back to the generic http error. */
|
|
64
69
|
function notifyFetchError(notifications, error) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
notifications?.notify(errorMessageKey(error), {
|
|
71
|
+
type: "error",
|
|
72
|
+
messageArgs: { _: String(error) }
|
|
73
|
+
});
|
|
69
74
|
}
|
|
75
|
+
/** Warns that `selectAll` stopped at `limit` rows. A shorter result is complete and stays quiet. */
|
|
70
76
|
function notifySelectAllLimit(notifications, count, limit) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
if (count < limit) return;
|
|
78
|
+
notifications?.notify("chelone.message.select_all_limit_reached", {
|
|
79
|
+
type: "warning",
|
|
80
|
+
messageArgs: { max: limit }
|
|
81
|
+
});
|
|
76
82
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Fetches one page with `limit` (default 250), applies its ids, then warns at
|
|
85
|
+
* the limit. Fetch, apply and warning failures use `notifyFetchError`.
|
|
86
|
+
* Destruction skips the fetch or suppresses its result and failure notification.
|
|
87
|
+
*/
|
|
88
|
+
async function runSelectAll(notifications, fetchPage, apply, isDestroyed, limit = 250) {
|
|
89
|
+
if (isDestroyed()) return;
|
|
90
|
+
try {
|
|
91
|
+
const rows = await fetchPage(limit);
|
|
92
|
+
if (isDestroyed()) return;
|
|
93
|
+
apply(rows.map((record) => record.id));
|
|
94
|
+
notifySelectAllLimit(notifications, rows.length, limit);
|
|
95
|
+
} catch (error) {
|
|
96
|
+
if (isDestroyed()) return;
|
|
97
|
+
notifyFetchError(notifications, error);
|
|
98
|
+
}
|
|
88
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Notifies a distinct error OBJECT once however many results carry it (a new
|
|
102
|
+
* Error with the same message is a new failure and is announced). `rearm`
|
|
103
|
+
* forgets the last one, so a controller that wants the same error announced
|
|
104
|
+
* again after a success can say so.
|
|
105
|
+
*/
|
|
89
106
|
function createErrorAnnouncer(notifications) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
107
|
+
let last = null;
|
|
108
|
+
return {
|
|
109
|
+
announce(error) {
|
|
110
|
+
if (!error || error === last) return;
|
|
111
|
+
last = error;
|
|
112
|
+
notifyFetchError(notifications, error);
|
|
113
|
+
},
|
|
114
|
+
rearm() {
|
|
115
|
+
last = null;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
101
118
|
}
|
|
119
|
+
/** `hasNextPage`/`hasPreviousPage` from the provider's `pageInfo` or, failing that, the total. */
|
|
102
120
|
function pageFlags(page, perPage, total, pageInfo) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
121
|
+
if (pageInfo) return {
|
|
122
|
+
hasNextPage: pageInfo.hasNextPage,
|
|
123
|
+
hasPreviousPage: pageInfo.hasPreviousPage
|
|
124
|
+
};
|
|
125
|
+
if (total !== void 0) return {
|
|
126
|
+
hasNextPage: page * perPage < total,
|
|
127
|
+
hasPreviousPage: page > 1
|
|
128
|
+
};
|
|
129
|
+
return {
|
|
130
|
+
hasNextPage: void 0,
|
|
131
|
+
hasPreviousPage: void 0
|
|
132
|
+
};
|
|
113
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* The page an out-of-range state should move to, or undefined when it is in
|
|
136
|
+
* range. Only a SETTLED result may move past page 1, so a reset-induced
|
|
137
|
+
* refetch can never trigger another reset.
|
|
138
|
+
*/
|
|
114
139
|
function resetPageTarget(s) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
return void 0;
|
|
140
|
+
if (s.page <= 0) return 1;
|
|
141
|
+
if (s.isPending || s.isFetching) return void 0;
|
|
142
|
+
if (s.total !== void 0) {
|
|
143
|
+
const lastPage = Math.max(Math.ceil(s.total / s.perPage), 1);
|
|
144
|
+
return s.page > lastPage ? lastPage : void 0;
|
|
145
|
+
}
|
|
146
|
+
if (s.page > 1 && s.data !== void 0 && s.data.length === 0) return 1;
|
|
123
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* Vanilla list controller: one QueryObserver mapped into a micro-store.
|
|
150
|
+
*
|
|
151
|
+
* Lifecycle (Task 4R): construction is INERT — pure state + closures, zero
|
|
152
|
+
* subscriptions, zero fetching. A controller constructed in a discarded
|
|
153
|
+
* React render (Suspense retry, StrictMode double render, hidden
|
|
154
|
+
* <Activity> pre-render) is plain garbage, never a zombie. Acquisition
|
|
155
|
+
* (QueryObserver + KV selection subscription) happens on the micro-store's
|
|
156
|
+
* FIRST subscriber; the LAST unsubscribe releases everything. Attach/detach
|
|
157
|
+
* cycles are re-entrant; re-attach rebuilds query options from CURRENT
|
|
158
|
+
* state, so params changed while detached take effect on the next attach.
|
|
159
|
+
* `destroy()` remains the hard imperative teardown for non-React consumers.
|
|
160
|
+
*
|
|
161
|
+
* Loop-prevention architecture rule: `observer.setOptions` is called ONLY
|
|
162
|
+
* from param-mutating actions — never directly from the observer result
|
|
163
|
+
* subscription. Out-of-range page resets go through the normal `setPage`
|
|
164
|
+
* action path and are guarded to run only on SETTLED results, so they
|
|
165
|
+
* cannot ping-pong.
|
|
166
|
+
*/
|
|
167
|
+
/**
|
|
168
|
+
* The actions of a list controller, for an adapter to spread next to its own
|
|
169
|
+
* reactive state. They are the same functions across state changes.
|
|
170
|
+
*/
|
|
124
171
|
function listControllerActions(controller) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
172
|
+
return {
|
|
173
|
+
setPage: controller.setPage,
|
|
174
|
+
setPerPage: controller.setPerPage,
|
|
175
|
+
setSort: controller.setSort,
|
|
176
|
+
setFilters: controller.setFilters,
|
|
177
|
+
setParams: controller.setParams,
|
|
178
|
+
showFilter: controller.showFilter,
|
|
179
|
+
hideFilter: controller.hideFilter,
|
|
180
|
+
select: controller.select,
|
|
181
|
+
toggleItem: controller.toggleItem,
|
|
182
|
+
unselectAll: controller.unselectAll,
|
|
183
|
+
selectAll: controller.selectAll,
|
|
184
|
+
refetch: controller.refetch
|
|
185
|
+
};
|
|
139
186
|
}
|
|
140
187
|
function createListController(ctx, resource, options = {}) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
188
|
+
const storeKey = options.storeKey === false ? null : options.storeKey ?? resource;
|
|
189
|
+
const paramsKey = storeKey ? `${storeKey}.listParams` : null;
|
|
190
|
+
const selectionKey = storeKey ? `${storeKey}.selectedIds` : null;
|
|
191
|
+
const kv = ctx.store;
|
|
192
|
+
const defaults = {
|
|
193
|
+
page: 1,
|
|
194
|
+
perPage: options.perPage ?? 10,
|
|
195
|
+
sort: normalizeSort(options.sort, DEFAULT_SORT),
|
|
196
|
+
filter: { ...options.filterDefaultValues ?? {} },
|
|
197
|
+
displayedFilters: {}
|
|
198
|
+
};
|
|
199
|
+
const persisted = paramsKey && kv ? kv.getItem(paramsKey) : void 0;
|
|
200
|
+
const initialParams = persisted ? {
|
|
201
|
+
page: persisted.page ?? defaults.page,
|
|
202
|
+
perPage: persisted.perPage ?? defaults.perPage,
|
|
203
|
+
sort: normalizeSort(persisted.sort, defaults.sort),
|
|
204
|
+
filter: { ...persisted.filter ?? defaults.filter },
|
|
205
|
+
displayedFilters: { ...persisted.displayedFilters ?? {} }
|
|
206
|
+
} : defaults;
|
|
207
|
+
const readSelection = () => (selectionKey && kv ? kv.getItem(selectionKey) : void 0) ?? [];
|
|
208
|
+
const store = createMicroStore({
|
|
209
|
+
...initialParams,
|
|
210
|
+
selectedIds: readSelection(),
|
|
211
|
+
data: void 0,
|
|
212
|
+
total: void 0,
|
|
213
|
+
pageInfo: void 0,
|
|
214
|
+
isPending: true,
|
|
215
|
+
isFetching: false,
|
|
216
|
+
error: null,
|
|
217
|
+
hasNextPage: void 0,
|
|
218
|
+
hasPreviousPage: void 0
|
|
219
|
+
}, { onSubscribed: acquire });
|
|
220
|
+
let destroyed = false;
|
|
221
|
+
store.onDestroy(() => {
|
|
222
|
+
destroyed = true;
|
|
223
|
+
});
|
|
224
|
+
/** Non-null exactly while attached — doubles as the attached flag. */
|
|
225
|
+
let observer = null;
|
|
226
|
+
const buildOptions = () => {
|
|
227
|
+
const s = store.getSnapshot();
|
|
228
|
+
return {
|
|
229
|
+
...getListOptions(ctx, resource, {
|
|
230
|
+
pagination: {
|
|
231
|
+
page: s.page,
|
|
232
|
+
perPage: s.perPage
|
|
233
|
+
},
|
|
234
|
+
sort: s.sort.length === 1 ? s.sort[0] : s.sort,
|
|
235
|
+
filter: {
|
|
236
|
+
...s.filter,
|
|
237
|
+
...options.filter ?? {}
|
|
238
|
+
}
|
|
239
|
+
}),
|
|
240
|
+
placeholderData: (prev) => prev,
|
|
241
|
+
retry: false,
|
|
242
|
+
enabled: options.enabled ?? true
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
const persistParams = () => {
|
|
246
|
+
if (!paramsKey || !kv) return;
|
|
247
|
+
const s = store.getSnapshot();
|
|
248
|
+
const params = {
|
|
249
|
+
page: s.page,
|
|
250
|
+
perPage: s.perPage,
|
|
251
|
+
sort: s.sort,
|
|
252
|
+
filter: s.filter,
|
|
253
|
+
displayedFilters: s.displayedFilters
|
|
254
|
+
};
|
|
255
|
+
kv.setItem(paramsKey, params);
|
|
256
|
+
};
|
|
257
|
+
/**
|
|
258
|
+
* The ONLY path that reconfigures the observer — param-mutating actions.
|
|
259
|
+
* Detached, the observer does not exist: state still updates and persists,
|
|
260
|
+
* and the next attach rebuilds options from CURRENT state.
|
|
261
|
+
*/
|
|
262
|
+
const applyParams = (patch) => {
|
|
263
|
+
store.setState(patch);
|
|
264
|
+
persistParams();
|
|
265
|
+
observer?.setOptions(buildOptions());
|
|
266
|
+
};
|
|
267
|
+
const setPage = (page) => {
|
|
268
|
+
if (destroyed) return;
|
|
269
|
+
applyParams({ page });
|
|
270
|
+
};
|
|
271
|
+
const setPerPage = (perPage) => {
|
|
272
|
+
if (destroyed) return;
|
|
273
|
+
applyParams({
|
|
274
|
+
perPage,
|
|
275
|
+
page: 1
|
|
276
|
+
});
|
|
277
|
+
};
|
|
278
|
+
const setSort = (input) => {
|
|
279
|
+
if (destroyed) return;
|
|
280
|
+
const current = store.getSnapshot().sort;
|
|
281
|
+
const single = current.length === 1 ? current[0] : void 0;
|
|
282
|
+
let next;
|
|
283
|
+
if (Array.isArray(input)) next = input.map((entry) => ({ ...entry }));
|
|
284
|
+
else if (single && single.field === input.field) next = [{
|
|
285
|
+
field: input.field,
|
|
286
|
+
order: single.order === "ASC" ? "DESC" : "ASC"
|
|
287
|
+
}];
|
|
288
|
+
else next = [{
|
|
289
|
+
field: input.field,
|
|
290
|
+
order: input.order ?? "ASC"
|
|
291
|
+
}];
|
|
292
|
+
applyParams({
|
|
293
|
+
sort: next,
|
|
294
|
+
page: 1
|
|
295
|
+
});
|
|
296
|
+
};
|
|
297
|
+
const applyFilters = (filter, displayedFilters) => {
|
|
298
|
+
applyParams({
|
|
299
|
+
filter: removeEmpty(filter),
|
|
300
|
+
displayedFilters: displayedFilters === void 0 ? store.getSnapshot().displayedFilters : { ...displayedFilters },
|
|
301
|
+
page: 1
|
|
302
|
+
});
|
|
303
|
+
};
|
|
304
|
+
const setParams = (patch) => {
|
|
305
|
+
if (destroyed) return;
|
|
306
|
+
const next = listParamsFromPatch(patch);
|
|
307
|
+
if (Object.keys(next).length === 0) return;
|
|
308
|
+
if (patch.filter !== void 0) clearDebounce();
|
|
309
|
+
applyParams(next);
|
|
310
|
+
};
|
|
311
|
+
let debounceTimer;
|
|
312
|
+
let pendingFilters;
|
|
313
|
+
const clearDebounce = () => {
|
|
314
|
+
if (debounceTimer !== void 0) {
|
|
315
|
+
clearTimeout(debounceTimer);
|
|
316
|
+
debounceTimer = void 0;
|
|
317
|
+
}
|
|
318
|
+
pendingFilters = void 0;
|
|
319
|
+
};
|
|
320
|
+
store.onDestroy(clearDebounce);
|
|
321
|
+
const setFilters = (filter, displayedFilters, debounced = false) => {
|
|
322
|
+
if (destroyed) return;
|
|
323
|
+
clearDebounce();
|
|
324
|
+
if (!debounced) {
|
|
325
|
+
applyFilters(filter, displayedFilters);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
pendingFilters = {
|
|
329
|
+
filter,
|
|
330
|
+
displayedFilters
|
|
331
|
+
};
|
|
332
|
+
debounceTimer = setTimeout(() => {
|
|
333
|
+
debounceTimer = void 0;
|
|
334
|
+
pendingFilters = void 0;
|
|
335
|
+
if (destroyed) return;
|
|
336
|
+
applyFilters(filter, displayedFilters);
|
|
337
|
+
}, options.debounceMs ?? 500);
|
|
338
|
+
};
|
|
339
|
+
const showFilter = (name, defaultValue) => {
|
|
340
|
+
if (destroyed) return;
|
|
341
|
+
const s = store.getSnapshot();
|
|
342
|
+
applyParams({
|
|
343
|
+
filter: defaultValue === void 0 ? s.filter : removeEmpty({
|
|
344
|
+
...s.filter,
|
|
345
|
+
[name]: defaultValue
|
|
346
|
+
}),
|
|
347
|
+
displayedFilters: {
|
|
348
|
+
...s.displayedFilters,
|
|
349
|
+
[name]: true
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
};
|
|
353
|
+
const hideFilter = (name) => {
|
|
354
|
+
if (destroyed) return;
|
|
355
|
+
const s = store.getSnapshot();
|
|
356
|
+
const pending = pendingFilters;
|
|
357
|
+
clearDebounce();
|
|
358
|
+
const filter = removeFilterPath(pending ? removeEmpty(pending.filter) : s.filter, name);
|
|
359
|
+
const { [name]: _shown, ...displayedFilters } = pending?.displayedFilters ?? s.displayedFilters;
|
|
360
|
+
applyParams({
|
|
361
|
+
filter,
|
|
362
|
+
displayedFilters,
|
|
363
|
+
...pending ? { page: 1 } : {}
|
|
364
|
+
});
|
|
365
|
+
};
|
|
366
|
+
const writeSelection = (ids) => {
|
|
367
|
+
if (selectionKey && kv) {
|
|
368
|
+
kv.setItem(selectionKey, ids);
|
|
369
|
+
if (!observer) store.setState({ selectedIds: ids });
|
|
370
|
+
} else store.setState({ selectedIds: ids });
|
|
371
|
+
};
|
|
372
|
+
const select = (ids) => {
|
|
373
|
+
if (destroyed) return;
|
|
374
|
+
writeSelection([...ids]);
|
|
375
|
+
};
|
|
376
|
+
const toggleItem = (id) => {
|
|
377
|
+
if (destroyed) return;
|
|
378
|
+
const current = store.getSnapshot().selectedIds;
|
|
379
|
+
writeSelection(current.includes(id) ? current.filter((existing) => existing !== id) : [...current, id]);
|
|
380
|
+
};
|
|
381
|
+
const unselectAll = () => {
|
|
382
|
+
if (destroyed) return;
|
|
383
|
+
writeSelection([]);
|
|
384
|
+
};
|
|
385
|
+
const selectAll = (opts) => runSelectAll(ctx.notifications, async (limit) => {
|
|
386
|
+
const s = store.getSnapshot();
|
|
387
|
+
return (await ctx.queryClient.fetchQuery({
|
|
388
|
+
...getListOptions(ctx, resource, {
|
|
389
|
+
pagination: {
|
|
390
|
+
page: 1,
|
|
391
|
+
perPage: limit
|
|
392
|
+
},
|
|
393
|
+
sort: s.sort.length === 1 ? s.sort[0] : s.sort,
|
|
394
|
+
filter: {
|
|
395
|
+
...s.filter,
|
|
396
|
+
...options.filter ?? {}
|
|
397
|
+
}
|
|
398
|
+
}),
|
|
399
|
+
retry: false
|
|
400
|
+
})).data;
|
|
401
|
+
}, writeSelection, () => destroyed, opts?.limit);
|
|
402
|
+
const refetch = () => {
|
|
403
|
+
if (destroyed) return;
|
|
404
|
+
observer?.refetch();
|
|
405
|
+
};
|
|
406
|
+
const maybeResetPage = () => {
|
|
407
|
+
const target = resetPageTarget(store.getSnapshot());
|
|
408
|
+
if (target !== void 0) setPage(target);
|
|
409
|
+
};
|
|
410
|
+
const errors = createErrorAnnouncer(ctx.notifications);
|
|
411
|
+
const onResult = (result) => {
|
|
412
|
+
const list = result.data;
|
|
413
|
+
const { page, perPage } = store.getSnapshot();
|
|
414
|
+
store.setState({
|
|
415
|
+
data: list?.data,
|
|
416
|
+
total: list?.total,
|
|
417
|
+
pageInfo: list?.pageInfo,
|
|
418
|
+
isPending: result.isPending,
|
|
419
|
+
isFetching: result.isFetching,
|
|
420
|
+
error: result.error ?? null,
|
|
421
|
+
...pageFlags(page, perPage, list?.total, list?.pageInfo)
|
|
422
|
+
});
|
|
423
|
+
if (result.error) errors.announce(result.error);
|
|
424
|
+
else errors.rearm();
|
|
425
|
+
maybeResetPage();
|
|
426
|
+
};
|
|
427
|
+
/**
|
|
428
|
+
* Attach: runs on the micro-store's FIRST subscriber (hoisted into the
|
|
429
|
+
* `createMicroStore` options above). Creates and subscribes the observer
|
|
430
|
+
* with options built from CURRENT state, arms the KV selection sync, and
|
|
431
|
+
* returns the teardown that the micro-store runs on last-unsubscribe AND
|
|
432
|
+
* on destroy-while-attached.
|
|
433
|
+
*/
|
|
434
|
+
function acquire() {
|
|
435
|
+
const attached = new QueryObserver(ctx.queryClient, buildOptions());
|
|
436
|
+
observer = attached;
|
|
437
|
+
const unsubscribeObserver = attached.subscribe(onResult);
|
|
438
|
+
onResult(attached.getCurrentResult());
|
|
439
|
+
let unsubscribeSelection;
|
|
440
|
+
if (selectionKey && kv) {
|
|
441
|
+
const syncKey = selectionKey;
|
|
442
|
+
const syncSelection = () => {
|
|
443
|
+
store.setState({ selectedIds: kv.getItem(syncKey) ?? [] });
|
|
444
|
+
};
|
|
445
|
+
unsubscribeSelection = kv.subscribe(syncKey, syncSelection);
|
|
446
|
+
syncSelection();
|
|
447
|
+
}
|
|
448
|
+
return () => {
|
|
449
|
+
unsubscribeObserver();
|
|
450
|
+
unsubscribeSelection?.();
|
|
451
|
+
observer = null;
|
|
452
|
+
clearDebounce();
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
return {
|
|
456
|
+
...store,
|
|
457
|
+
defaultPerPage: defaults.perPage,
|
|
458
|
+
setPage,
|
|
459
|
+
setPerPage,
|
|
460
|
+
setSort,
|
|
461
|
+
setFilters,
|
|
462
|
+
setParams,
|
|
463
|
+
showFilter,
|
|
464
|
+
hideFilter,
|
|
465
|
+
select,
|
|
466
|
+
toggleItem,
|
|
467
|
+
unselectAll,
|
|
468
|
+
selectAll,
|
|
469
|
+
refetch
|
|
470
|
+
};
|
|
410
471
|
}
|
|
411
|
-
export {
|
|
412
|
-
DEFAULT_DEBOUNCE_MS,
|
|
413
|
-
DEFAULT_SELECT_ALL_LIMIT,
|
|
414
|
-
createErrorAnnouncer,
|
|
415
|
-
createListController,
|
|
416
|
-
errorMessageKey,
|
|
417
|
-
listControllerActions,
|
|
418
|
-
listParamsFromPatch,
|
|
419
|
-
notifyFetchError,
|
|
420
|
-
notifySelectAllLimit,
|
|
421
|
-
pageFlags,
|
|
422
|
-
removeFilterPath,
|
|
423
|
-
resetPageTarget,
|
|
424
|
-
runSelectAll
|
|
425
|
-
};
|
|
472
|
+
export { DEFAULT_DEBOUNCE_MS, DEFAULT_PER_PAGE, createErrorAnnouncer, createListController, errorMessageKey, listControllerActions, listParamsFromPatch, notifyFetchError, notifySelectAllLimit, pageFlags, removeFilterPath, resetPageTarget, runSelectAll };
|