@chelone/core 0.5.0 → 0.6.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 +22 -0
- package/dist/assistant/assistant-session.js +185 -0
- package/dist/assistant/echo-transport.d.ts +7 -0
- package/dist/assistant/echo-transport.js +31 -0
- package/dist/assistant/types.d.ts +60 -0
- package/dist/chart/chart-data.d.ts +25 -0
- package/dist/chart/chart-data.js +59 -0
- package/dist/controller/infinite-list-controller.js +1 -1
- package/dist/controller/job-monitor.d.ts +42 -0
- package/dist/controller/job-monitor.js +59 -0
- package/dist/controller/pivot-grid.d.ts +36 -0
- package/dist/controller/pivot-grid.js +105 -0
- package/dist/controller/record-timeline.d.ts +35 -0
- package/dist/controller/record-timeline.js +36 -0
- package/dist/data/cache-ops.js +1 -3
- package/dist/form/edit-create-form.js +7 -7
- package/dist/i18n/i18n.d.ts +6 -0
- package/dist/i18n/i18n.js +13 -1
- package/dist/i18n/missing-keys.d.ts +19 -0
- package/dist/i18n/missing-keys.js +64 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +43 -0
- package/dist/onboarding-tour/placement.d.ts +34 -0
- package/dist/onboarding-tour/placement.js +82 -0
- package/dist/onboarding-tour/tour-controller.d.ts +25 -0
- package/dist/onboarding-tour/tour-controller.js +58 -0
- package/dist/realtime/announce-lock.d.ts +7 -0
- package/dist/realtime/announce-lock.js +15 -0
- package/dist/realtime/broadcast-channel-transport.d.ts +14 -0
- package/dist/realtime/broadcast-channel-transport.js +63 -0
- package/dist/realtime/in-memory-lock-provider.js +3 -14
- package/dist/realtime/memory-transport.js +10 -51
- package/dist/realtime/reconnect-backoff.d.ts +15 -0
- package/dist/realtime/topic-hub.d.ts +24 -0
- package/dist/realtime/topic-hub.js +75 -0
- package/dist/rich-text/rich-text.d.ts +56 -0
- package/dist/rich-text/rich-text.js +105 -0
- package/package.json +1 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getAtPath } from "../resource/get-at-path.js";
|
|
2
|
+
import { parseCalendarDate } from "./calendar-dates.js";
|
|
3
|
+
function toTimelineEntries(records, options) {
|
|
4
|
+
const { messageSource, timestampSource, userSource, iconSource } = options;
|
|
5
|
+
return records.map((record) => {
|
|
6
|
+
const message = getAtPath(record, messageSource);
|
|
7
|
+
const user = userSource === void 0 ? void 0 : getAtPath(record, userSource);
|
|
8
|
+
const icon = iconSource === void 0 ? void 0 : getAtPath(record, iconSource);
|
|
9
|
+
return {
|
|
10
|
+
id: record.id,
|
|
11
|
+
record,
|
|
12
|
+
message: message == null ? "" : String(message),
|
|
13
|
+
date: parseCalendarDate(getAtPath(record, timestampSource)),
|
|
14
|
+
user: user == null || user === "" ? void 0 : String(user),
|
|
15
|
+
icon: icon == null || icon === "" ? void 0 : String(icon)
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
const MINUTE = 60;
|
|
20
|
+
const HOUR = 3600;
|
|
21
|
+
const DAY = 86400;
|
|
22
|
+
const MONTH = DAY * 30;
|
|
23
|
+
function formatRelativeTime(date, now, locale) {
|
|
24
|
+
const delta = (date.getTime() - now.getTime()) / 1e3;
|
|
25
|
+
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
|
|
26
|
+
const distance = Math.abs(delta);
|
|
27
|
+
if (distance < MINUTE) return rtf.format(Math.round(delta), "second");
|
|
28
|
+
if (distance < HOUR) return rtf.format(Math.round(delta / MINUTE), "minute");
|
|
29
|
+
if (distance < DAY) return rtf.format(Math.round(delta / HOUR), "hour");
|
|
30
|
+
if (distance < MONTH) return rtf.format(Math.round(delta / DAY), "day");
|
|
31
|
+
return rtf.format(Math.round(delta / MONTH), "month");
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
formatRelativeTime,
|
|
35
|
+
toTimelineEntries
|
|
36
|
+
};
|
package/dist/data/cache-ops.js
CHANGED
|
@@ -6,9 +6,7 @@ function singleResultListKeyPrefixes(resource) {
|
|
|
6
6
|
];
|
|
7
7
|
}
|
|
8
8
|
function withoutIds(page, idSet) {
|
|
9
|
-
const kept = page.data.filter(
|
|
10
|
-
(record) => !idSet.has(String(record.id))
|
|
11
|
-
);
|
|
9
|
+
const kept = page.data.filter((record) => !idSet.has(String(record.id)));
|
|
12
10
|
return kept.length === page.data.length ? void 0 : { ...page, data: kept };
|
|
13
11
|
}
|
|
14
12
|
function withPatchedRows(page, idSet, data) {
|
|
@@ -132,17 +132,17 @@ function createEditFormController(ctx, resource, options) {
|
|
|
132
132
|
return;
|
|
133
133
|
}
|
|
134
134
|
if (action === "partial-apply") {
|
|
135
|
-
const pathAccess = form;
|
|
136
|
-
const fieldMeta = form.state.fieldMeta;
|
|
137
135
|
const dirtyValues = [];
|
|
138
|
-
for (const [path, meta] of Object.entries(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
136
|
+
for (const [path, meta] of Object.entries(
|
|
137
|
+
form.state.fieldMeta
|
|
138
|
+
)) {
|
|
139
|
+
if (!meta?.isDirty) continue;
|
|
140
|
+
const name = path;
|
|
141
|
+
dirtyValues.push([name, form.getFieldValue(name)]);
|
|
142
142
|
}
|
|
143
143
|
form.reset(merged);
|
|
144
144
|
for (const [path, value] of dirtyValues) {
|
|
145
|
-
|
|
145
|
+
form.setFieldValue(path, value, { dontRunListeners: true });
|
|
146
146
|
}
|
|
147
147
|
return;
|
|
148
148
|
}
|
package/dist/i18n/i18n.d.ts
CHANGED
|
@@ -38,5 +38,11 @@ export declare function createI18n<const TCatalog extends MessageCatalog>(option
|
|
|
38
38
|
locale: string;
|
|
39
39
|
messages: Record<string, TCatalog>;
|
|
40
40
|
fallbackLocale?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Called when the current locale's catalog holds no own entry for a key,
|
|
43
|
+
* even when `fallbackLocale` supplies the text. `fallback` is the string `_`
|
|
44
|
+
* param. A throwing callback goes to `console.error`; `translate` is unchanged.
|
|
45
|
+
*/
|
|
46
|
+
onMissingKey?: (key: string, locale: string, fallback: string | undefined) => void;
|
|
41
47
|
}): CheloneI18n<TCatalog>;
|
|
42
48
|
export {};
|
package/dist/i18n/i18n.js
CHANGED
|
@@ -26,7 +26,19 @@ function createI18n(options) {
|
|
|
26
26
|
return {
|
|
27
27
|
translate(key, ...args) {
|
|
28
28
|
const params = args[0];
|
|
29
|
-
const
|
|
29
|
+
const own = lookup(options.messages[locale], key);
|
|
30
|
+
if (own === void 0 && options.onMissingKey) {
|
|
31
|
+
try {
|
|
32
|
+
options.onMissingKey(
|
|
33
|
+
key,
|
|
34
|
+
locale,
|
|
35
|
+
typeof params?._ === "string" ? params._ : void 0
|
|
36
|
+
);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error(error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const value = own ?? (options.fallbackLocale ? lookup(options.messages[options.fallbackLocale], key) : void 0);
|
|
30
42
|
if (value === void 0) {
|
|
31
43
|
if (typeof params?._ === "string") return interpolate(params._, params);
|
|
32
44
|
return key;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface MissingKeyEntry {
|
|
2
|
+
key: string;
|
|
3
|
+
fallback: string | undefined;
|
|
4
|
+
translation: string;
|
|
5
|
+
}
|
|
6
|
+
export interface MissingKeyStore {
|
|
7
|
+
/** Has the `onMissingKey` signature: pass it as `onMissingKey: store.record`. */
|
|
8
|
+
record(key: string, locale: string, fallback: string | undefined): void;
|
|
9
|
+
/** The same array until that locale's entries change. */
|
|
10
|
+
getEntries(locale: string): readonly MissingKeyEntry[];
|
|
11
|
+
/** Ignores a key that was not recorded. */
|
|
12
|
+
setTranslation(locale: string, key: string, text: string): void;
|
|
13
|
+
clear(locale: string): void;
|
|
14
|
+
/** Flat `{ key: text }` JSON, two-space indented, non-blank translations only. */
|
|
15
|
+
toJson(locale: string): string;
|
|
16
|
+
/** Notified once per microtask, however many entries changed. */
|
|
17
|
+
subscribe(callback: () => void): () => void;
|
|
18
|
+
}
|
|
19
|
+
export declare function createMissingKeyStore(): MissingKeyStore;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const NO_ENTRIES = [];
|
|
2
|
+
function createMissingKeyStore() {
|
|
3
|
+
const byLocale = /* @__PURE__ */ new Map();
|
|
4
|
+
const snapshots = /* @__PURE__ */ new Map();
|
|
5
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
6
|
+
let scheduled = false;
|
|
7
|
+
const changed = (locale) => {
|
|
8
|
+
snapshots.delete(locale);
|
|
9
|
+
if (scheduled) return;
|
|
10
|
+
scheduled = true;
|
|
11
|
+
queueMicrotask(() => {
|
|
12
|
+
scheduled = false;
|
|
13
|
+
for (const cb of [...subscribers]) cb();
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
const getEntries = (locale) => {
|
|
17
|
+
const cached = snapshots.get(locale);
|
|
18
|
+
if (cached) return cached;
|
|
19
|
+
const entries = byLocale.get(locale);
|
|
20
|
+
if (!entries?.size) return NO_ENTRIES;
|
|
21
|
+
const snapshot = [...entries.values()];
|
|
22
|
+
snapshots.set(locale, snapshot);
|
|
23
|
+
return snapshot;
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
record(key, locale, fallback) {
|
|
27
|
+
let entries = byLocale.get(locale);
|
|
28
|
+
if (!entries) {
|
|
29
|
+
entries = /* @__PURE__ */ new Map();
|
|
30
|
+
byLocale.set(locale, entries);
|
|
31
|
+
}
|
|
32
|
+
if (entries.has(key)) return;
|
|
33
|
+
entries.set(key, { key, fallback, translation: "" });
|
|
34
|
+
changed(locale);
|
|
35
|
+
},
|
|
36
|
+
getEntries,
|
|
37
|
+
setTranslation(locale, key, text) {
|
|
38
|
+
const entries = byLocale.get(locale);
|
|
39
|
+
const entry = entries?.get(key);
|
|
40
|
+
if (!entries || !entry || entry.translation === text) return;
|
|
41
|
+
entries.set(key, { ...entry, translation: text });
|
|
42
|
+
changed(locale);
|
|
43
|
+
},
|
|
44
|
+
clear(locale) {
|
|
45
|
+
if (!byLocale.get(locale)?.size) return;
|
|
46
|
+
byLocale.delete(locale);
|
|
47
|
+
changed(locale);
|
|
48
|
+
},
|
|
49
|
+
toJson(locale) {
|
|
50
|
+
const out = /* @__PURE__ */ new Map();
|
|
51
|
+
for (const { key, translation } of getEntries(locale)) {
|
|
52
|
+
if (translation.trim() !== "") out.set(key, translation);
|
|
53
|
+
}
|
|
54
|
+
return JSON.stringify(Object.fromEntries(out), null, 2);
|
|
55
|
+
},
|
|
56
|
+
subscribe(callback) {
|
|
57
|
+
subscribers.add(callback);
|
|
58
|
+
return () => void subscribers.delete(callback);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
createMissingKeyStore
|
|
64
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
export { revalidateLogic } from "@tanstack/form-core";
|
|
2
|
+
export type { AssistantSession, AssistantSessionState, CreateAssistantSessionOptions, } from "./assistant/assistant-session.js";
|
|
3
|
+
export { createAssistantSession } from "./assistant/assistant-session.js";
|
|
4
|
+
export type { EchoAssistantTransportOptions } from "./assistant/echo-transport.js";
|
|
5
|
+
export { echoAssistantTransport } from "./assistant/echo-transport.js";
|
|
6
|
+
export type { AssistantChunk, AssistantMessage, AssistantTool, AssistantToolCall, AssistantToolDeclaration, AssistantTransport, JsonObject, JsonValue, } from "./assistant/types.js";
|
|
2
7
|
export type { Permission } from "./auth/access-control.js";
|
|
3
8
|
export { canAccessWithPermissions } from "./auth/access-control.js";
|
|
4
9
|
export type { CheckErrorOutcome } from "./auth/auth-options.js";
|
|
5
10
|
export { authStateQueryOptions, canAccessQueryOptions, checkError, identityQueryOptions, permissionsQueryOptions, } from "./auth/auth-options.js";
|
|
6
11
|
export type { AuthProvider, CanAccessParams, UserIdentity } from "./auth/types.js";
|
|
12
|
+
export type { CartesianRow, DonutSlice, MetricDelta, } from "./chart/chart-data.js";
|
|
13
|
+
export { chartColor, DEFAULT_CHART_COLORS, getMetricDelta, hasChartValues, toCartesianRows, toDonutSlices, } from "./chart/chart-data.js";
|
|
7
14
|
export type { HotkeyEvent, HotkeyTarget } from "./command-menu/hotkey.js";
|
|
8
15
|
export { isTypingTarget, matchesHotkey, shouldHandleHotkey, } from "./command-menu/hotkey.js";
|
|
9
16
|
export type { RecentEntry } from "./command-menu/recents.js";
|
|
@@ -21,16 +28,22 @@ export { arrangeColumns, columnLabelMatches, dataTableColumnKeys, defaultDataTab
|
|
|
21
28
|
export { isFilterSelected, toggleFilterValue, } from "./controller/filter-toggle.js";
|
|
22
29
|
export type { InfiniteListController, InfiniteListControllerState, } from "./controller/infinite-list-controller.js";
|
|
23
30
|
export { createInfiniteListController } from "./controller/infinite-list-controller.js";
|
|
31
|
+
export type { JobActionOptions, JobActions, JobPlan, } from "./controller/job-monitor.js";
|
|
32
|
+
export { DEFAULT_JOB_TABS, getJobActions, planJobCancel, planJobRetry, } from "./controller/job-monitor.js";
|
|
24
33
|
export type { KanbanBucket, KanbanColumnDef, KanbanMove, } from "./controller/kanban-board.js";
|
|
25
34
|
export { buildKanbanBuckets, planKanbanMove, } from "./controller/kanban-board.js";
|
|
26
35
|
export type { ListController, ListControllerContext, ListControllerOptions, ListControllerState, ListParamsPatch, } from "./controller/list-controller.js";
|
|
27
36
|
export { createListController, listControllerActions, } from "./controller/list-controller.js";
|
|
28
37
|
export type { ListParamsQuery, ListUrlState, } from "./controller/list-params.js";
|
|
29
38
|
export { hasCustomParams, listPatchFromSearch, parseListParams, serializeListParams, serializeListState, } from "./controller/list-params.js";
|
|
39
|
+
export type { PivotAggregator, PivotOptions, PivotTable, } from "./controller/pivot-grid.js";
|
|
40
|
+
export { buildPivotTable, formatPivotValue, } from "./controller/pivot-grid.js";
|
|
30
41
|
export type { PrevNextOptions, PrevNextPage, PrevNextParams, PrevNextResolution, PrevNextStoredParams, } from "./controller/prev-next.js";
|
|
31
42
|
export { canUseCachedPage, getPrevNextParams, resolvePrevNext, } from "./controller/prev-next.js";
|
|
32
43
|
export type { CreateController, CreateControllerOptions, CreateControllerState, DeleteController, DeleteControllerOptions, DeleteControllerState, DeleteOneOptions, EditController, EditControllerOptions, EditControllerState, RecordControllerContext, RedirectRequest, RedirectTarget, SaveOptions, SaveTransform, ShowController, ShowControllerOptions, ShowControllerState, } from "./controller/record-controllers.js";
|
|
33
44
|
export { createCreateController, createDeleteController, createEditController, createShowController, } from "./controller/record-controllers.js";
|
|
45
|
+
export type { RecordTimelineEntry, ToTimelineEntriesOptions, } from "./controller/record-timeline.js";
|
|
46
|
+
export { formatRelativeTime, toTimelineEntries, } from "./controller/record-timeline.js";
|
|
34
47
|
export type { RecordTreeNode } from "./controller/record-tree.js";
|
|
35
48
|
export { buildRecordTree } from "./controller/record-tree.js";
|
|
36
49
|
export type { AllowedTransitions, ApprovalOptions, ApprovalState, TransitionOptions, } from "./controller/record-workflow.js";
|
|
@@ -125,13 +138,22 @@ export type { AnyCheloneI18n, CheloneI18n } from "./i18n/i18n.js";
|
|
|
125
138
|
export { createI18n } from "./i18n/i18n.js";
|
|
126
139
|
export type { ExtractParams, MessageCatalog, MessageKey, MessageValue, PluralMessage, TranslateParams, } from "./i18n/messages.js";
|
|
127
140
|
export { defineMessages } from "./i18n/messages.js";
|
|
141
|
+
export type { MissingKeyEntry, MissingKeyStore, } from "./i18n/missing-keys.js";
|
|
142
|
+
export { createMissingKeyStore } from "./i18n/missing-keys.js";
|
|
128
143
|
export type { TranslatableController, TranslatableOptions, TranslatableState, } from "./i18n/translatable.js";
|
|
129
144
|
export { createTranslatableController, getRecordForLocale, } from "./i18n/translatable.js";
|
|
130
145
|
export { stripJsonComments } from "./json/strip-json-comments.js";
|
|
131
146
|
export type { Notification, NotificationStore, NotifyOptions, } from "./notification/notification-store.js";
|
|
132
147
|
export { createNotificationStore } from "./notification/notification-store.js";
|
|
148
|
+
export type { PlaceTourCardOptions, TourCardPosition, TourPlacement, TourRect, } from "./onboarding-tour/placement.js";
|
|
149
|
+
export { placeTourCard, tourSpotlightPath, } from "./onboarding-tour/placement.js";
|
|
150
|
+
export type { TourController, TourControllerOptions, TourEnd, TourState, } from "./onboarding-tour/tour-controller.js";
|
|
151
|
+
export { createTourController, onboardingTourKey, } from "./onboarding-tour/tour-controller.js";
|
|
133
152
|
export type { AddEventsForMutationsOptions } from "./realtime/add-events-for-mutations.js";
|
|
134
153
|
export { addEventsForMutations } from "./realtime/add-events-for-mutations.js";
|
|
154
|
+
export { announceLock } from "./realtime/announce-lock.js";
|
|
155
|
+
export type { BroadcastChannelTransport, BroadcastChannelTransportOptions, } from "./realtime/broadcast-channel-transport.js";
|
|
156
|
+
export { broadcastChannelTransport } from "./realtime/broadcast-channel-transport.js";
|
|
135
157
|
export type { InMemoryLockProviderOptions } from "./realtime/in-memory-lock-provider.js";
|
|
136
158
|
export { inMemoryLockProvider } from "./realtime/in-memory-lock-provider.js";
|
|
137
159
|
export type { LiveOptions, LiveSubscription } from "./realtime/live.js";
|
|
@@ -144,8 +166,11 @@ export { memoryTransport } from "./realtime/memory-transport.js";
|
|
|
144
166
|
export type { PresenceSession, PresenceSessionDataProvider, PresenceSessionOptions, PresenceSessionState, PresenceUser, } from "./realtime/presence.js";
|
|
145
167
|
export { createPresenceSession, getPresenceInitials, toPresenceUser, } from "./realtime/presence.js";
|
|
146
168
|
export { assertRealtimeDataProvider, isRealtimeDataProvider, realtimeDataProvider, } from "./realtime/realtime-data-provider.js";
|
|
169
|
+
export type { RealtimeReconnectConfig } from "./realtime/reconnect-backoff.js";
|
|
147
170
|
export type { RealtimeStatusState } from "./realtime/status-store.js";
|
|
148
171
|
export { createRealtimeStatusStore } from "./realtime/status-store.js";
|
|
172
|
+
export type { TopicHub } from "./realtime/topic-hub.js";
|
|
173
|
+
export { createTopicHub } from "./realtime/topic-hub.js";
|
|
149
174
|
export { lockResourceTopic, lockTopic, presenceTopic, recordTopic, resourceTopic, } from "./realtime/topics.js";
|
|
150
175
|
export type { GetLockParams, GetLocksParams, Lock, LockParams, LockProvider, RealtimeConnectionStatus, RealtimeDataProvider, RealtimeDataProviderOptions, RealtimeEvent, RealtimeEventType, RealtimeTransport, RealtimeTransportError, RealtimeTransportErrorKind, SubscriptionCallback, UnlockParams, } from "./realtime/types.js";
|
|
151
176
|
export { LockConflictError } from "./realtime/types.js";
|
|
@@ -162,6 +187,8 @@ export { defineResources } from "./resource/registry.js";
|
|
|
162
187
|
export type { ComputeDefinitionProps, ResourceDefinition, ResourceDefinitionMap, ResourceRegistry, ResourceRegistryListener, } from "./resource/registry-store.js";
|
|
163
188
|
export { computeDefinition, createResourceRegistry, } from "./resource/registry-store.js";
|
|
164
189
|
export type { AnySourcePath, AnySourcePathOf, FilterSourceKey, RowSourcePath, SourceKey, SourcePath, SourceProp, SourceValue, } from "./resource/source-path.js";
|
|
190
|
+
export type { IsSafeImageSrcOptions, RichTextBlockType, RichTextHeadingLevel, RichTextToolbarGroup, RichTextToolbarItem, RichTextToolbarItemId, } from "./rich-text/rich-text.js";
|
|
191
|
+
export { isSafeImageSrc, isSafeLinkUrl, richTextBlockTypes, richTextSanitizeOptions, richTextStarterKitOptions, richTextToolbarItems, } from "./rich-text/rich-text.js";
|
|
165
192
|
export type { CheloneLocation, NavigateOpts } from "./router/location.js";
|
|
166
193
|
export { parseLocation } from "./router/location.js";
|
|
167
194
|
export type { PathMatch } from "./router/match.js";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { revalidateLogic } from "@tanstack/form-core";
|
|
2
|
+
import { createAssistantSession } from "./assistant/assistant-session.js";
|
|
3
|
+
import { echoAssistantTransport } from "./assistant/echo-transport.js";
|
|
2
4
|
import { canAccessWithPermissions } from "./auth/access-control.js";
|
|
3
5
|
import { authStateQueryOptions, canAccessQueryOptions, checkError, identityQueryOptions, permissionsQueryOptions } from "./auth/auth-options.js";
|
|
6
|
+
import { DEFAULT_CHART_COLORS, chartColor, getMetricDelta, hasChartValues, toCartesianRows, toDonutSlices } from "./chart/chart-data.js";
|
|
4
7
|
import { isTypingTarget, matchesHotkey, shouldHandleHotkey } from "./command-menu/hotkey.js";
|
|
5
8
|
import { recentsKey, rememberRecent } from "./command-menu/recents.js";
|
|
6
9
|
import { createCommandRegistry, getVisibleCommands, groupCommands } from "./command-menu/registry.js";
|
|
@@ -10,11 +13,14 @@ import { createClientListController } from "./controller/client-list-controller.
|
|
|
10
13
|
import { arrangeColumns, columnLabelMatches, dataTableColumnKeys, defaultDataTableStoreKey, getDataTableColumnId, moveColumn, toggleHiddenColumn } from "./controller/data-table-columns.js";
|
|
11
14
|
import { isFilterSelected, toggleFilterValue } from "./controller/filter-toggle.js";
|
|
12
15
|
import { createInfiniteListController } from "./controller/infinite-list-controller.js";
|
|
16
|
+
import { DEFAULT_JOB_TABS, getJobActions, planJobCancel, planJobRetry } from "./controller/job-monitor.js";
|
|
13
17
|
import { buildKanbanBuckets, planKanbanMove } from "./controller/kanban-board.js";
|
|
14
18
|
import { createListController, listControllerActions } from "./controller/list-controller.js";
|
|
15
19
|
import { hasCustomParams, listPatchFromSearch, parseListParams, serializeListParams, serializeListState } from "./controller/list-params.js";
|
|
20
|
+
import { buildPivotTable, formatPivotValue } from "./controller/pivot-grid.js";
|
|
16
21
|
import { canUseCachedPage, getPrevNextParams, resolvePrevNext } from "./controller/prev-next.js";
|
|
17
22
|
import { createCreateController, createDeleteController, createEditController, createShowController } from "./controller/record-controllers.js";
|
|
23
|
+
import { formatRelativeTime, toTimelineEntries } from "./controller/record-timeline.js";
|
|
18
24
|
import { buildRecordTree } from "./controller/record-tree.js";
|
|
19
25
|
import { buildApprovalUpdate, getAllowedTransitions, getApprovalState } from "./controller/record-workflow.js";
|
|
20
26
|
import { createReferenceManyController } from "./controller/reference-many-controller.js";
|
|
@@ -73,10 +79,15 @@ import { defaultMessages } from "./i18n/default-messages.js";
|
|
|
73
79
|
import { englishMessages } from "./i18n/english-messages.js";
|
|
74
80
|
import { createI18n } from "./i18n/i18n.js";
|
|
75
81
|
import { defineMessages } from "./i18n/messages.js";
|
|
82
|
+
import { createMissingKeyStore } from "./i18n/missing-keys.js";
|
|
76
83
|
import { createTranslatableController, getRecordForLocale } from "./i18n/translatable.js";
|
|
77
84
|
import { stripJsonComments } from "./json/strip-json-comments.js";
|
|
78
85
|
import { createNotificationStore } from "./notification/notification-store.js";
|
|
86
|
+
import { placeTourCard, tourSpotlightPath } from "./onboarding-tour/placement.js";
|
|
87
|
+
import { createTourController, onboardingTourKey } from "./onboarding-tour/tour-controller.js";
|
|
79
88
|
import { addEventsForMutations } from "./realtime/add-events-for-mutations.js";
|
|
89
|
+
import { announceLock } from "./realtime/announce-lock.js";
|
|
90
|
+
import { broadcastChannelTransport } from "./realtime/broadcast-channel-transport.js";
|
|
80
91
|
import { inMemoryLockProvider } from "./realtime/in-memory-lock-provider.js";
|
|
81
92
|
import { subscribeLiveLock, subscribeLiveLocks, subscribeLiveRecord, subscribeLiveRecords, subscribeLiveResource } from "./realtime/live.js";
|
|
82
93
|
import { getLockOptions, getLocksOptions } from "./realtime/lock-options.js";
|
|
@@ -85,6 +96,7 @@ import { memoryTransport } from "./realtime/memory-transport.js";
|
|
|
85
96
|
import { createPresenceSession, getPresenceInitials, toPresenceUser } from "./realtime/presence.js";
|
|
86
97
|
import { assertRealtimeDataProvider, isRealtimeDataProvider, realtimeDataProvider } from "./realtime/realtime-data-provider.js";
|
|
87
98
|
import { createRealtimeStatusStore } from "./realtime/status-store.js";
|
|
99
|
+
import { createTopicHub } from "./realtime/topic-hub.js";
|
|
88
100
|
import { lockResourceTopic, lockTopic, presenceTopic, recordTopic, resourceTopic } from "./realtime/topics.js";
|
|
89
101
|
import { LockConflictError } from "./realtime/types.js";
|
|
90
102
|
import { clearUnread, subscribeUnreadCount, unreadKey } from "./realtime/unread-count.js";
|
|
@@ -92,6 +104,7 @@ import { describeResource } from "./resource/describe-resource.js";
|
|
|
92
104
|
import { getAtPath } from "./resource/get-at-path.js";
|
|
93
105
|
import { defineResources } from "./resource/registry.js";
|
|
94
106
|
import { computeDefinition, createResourceRegistry } from "./resource/registry-store.js";
|
|
107
|
+
import { isSafeImageSrc, isSafeLinkUrl, richTextBlockTypes, richTextSanitizeOptions, richTextStarterKitOptions, richTextToolbarItems } from "./rich-text/rich-text.js";
|
|
95
108
|
import { parseLocation } from "./router/location.js";
|
|
96
109
|
import { matchPath } from "./router/match.js";
|
|
97
110
|
import { createPath, joinBasename, removeDoubleSlashes } from "./router/paths.js";
|
|
@@ -100,6 +113,8 @@ import { localStorageAdapter, memoryStoreAdapter } from "./store/adapters.js";
|
|
|
100
113
|
import { createMicroStore } from "./store/micro-store.js";
|
|
101
114
|
import { createStore } from "./store/store.js";
|
|
102
115
|
export {
|
|
116
|
+
DEFAULT_CHART_COLORS,
|
|
117
|
+
DEFAULT_JOB_TABS,
|
|
103
118
|
DEFAULT_SHAPE_STYLE,
|
|
104
119
|
HttpError,
|
|
105
120
|
LockConflictError,
|
|
@@ -109,6 +124,7 @@ export {
|
|
|
109
124
|
OverpassTimeoutError,
|
|
110
125
|
ValidationError,
|
|
111
126
|
addEventsForMutations,
|
|
127
|
+
announceLock,
|
|
112
128
|
applyCsvMapping,
|
|
113
129
|
areaInTypeOf,
|
|
114
130
|
arrangeColumns,
|
|
@@ -117,9 +133,11 @@ export {
|
|
|
117
133
|
assertRealtimeDataProvider,
|
|
118
134
|
authStateQueryOptions,
|
|
119
135
|
bboxToPolygon,
|
|
136
|
+
broadcastChannelTransport,
|
|
120
137
|
buildApprovalUpdate,
|
|
121
138
|
buildKanbanBuckets,
|
|
122
139
|
buildOverpassQuery,
|
|
140
|
+
buildPivotTable,
|
|
123
141
|
buildRecordTree,
|
|
124
142
|
calendarDayKey,
|
|
125
143
|
calendarDays,
|
|
@@ -131,6 +149,7 @@ export {
|
|
|
131
149
|
canAccessQueryOptions,
|
|
132
150
|
canAccessWithPermissions,
|
|
133
151
|
canUseCachedPage,
|
|
152
|
+
chartColor,
|
|
134
153
|
checkError,
|
|
135
154
|
choices,
|
|
136
155
|
clearUnread,
|
|
@@ -144,6 +163,7 @@ export {
|
|
|
144
163
|
createApplicationUpdateStore,
|
|
145
164
|
createArrayBinding,
|
|
146
165
|
createArraySourceScope,
|
|
166
|
+
createAssistantSession,
|
|
147
167
|
createChoicesController,
|
|
148
168
|
createClientListController,
|
|
149
169
|
createCommandRegistry,
|
|
@@ -162,6 +182,7 @@ export {
|
|
|
162
182
|
createLocaleSourceScope,
|
|
163
183
|
createLockSession,
|
|
164
184
|
createMicroStore,
|
|
185
|
+
createMissingKeyStore,
|
|
165
186
|
createMutationOptions,
|
|
166
187
|
createNominatimProvider,
|
|
167
188
|
createNotificationStore,
|
|
@@ -178,6 +199,8 @@ export {
|
|
|
178
199
|
createSavedQueriesController,
|
|
179
200
|
createShowController,
|
|
180
201
|
createStore,
|
|
202
|
+
createTopicHub,
|
|
203
|
+
createTourController,
|
|
181
204
|
createTranslatableController,
|
|
182
205
|
csvErrorRows,
|
|
183
206
|
csvSchemaFields,
|
|
@@ -193,6 +216,7 @@ export {
|
|
|
193
216
|
describeResource,
|
|
194
217
|
detectJsonShape,
|
|
195
218
|
downloadCSV,
|
|
219
|
+
echoAssistantTransport,
|
|
196
220
|
editorStyles,
|
|
197
221
|
email,
|
|
198
222
|
englishMessages,
|
|
@@ -204,6 +228,8 @@ export {
|
|
|
204
228
|
filterFormReflectShape,
|
|
205
229
|
findPresetForTags,
|
|
206
230
|
formatJsonValue,
|
|
231
|
+
formatPivotValue,
|
|
232
|
+
formatRelativeTime,
|
|
207
233
|
fromEditorFeatures,
|
|
208
234
|
fromJsonText,
|
|
209
235
|
geoAreaM2,
|
|
@@ -216,12 +242,14 @@ export {
|
|
|
216
242
|
getDirtyFormValues,
|
|
217
243
|
getFilterFormValues,
|
|
218
244
|
getInfiniteListOptions,
|
|
245
|
+
getJobActions,
|
|
219
246
|
getListOptions,
|
|
220
247
|
getLockOptions,
|
|
221
248
|
getLocksOptions,
|
|
222
249
|
getManyAggregateOptions,
|
|
223
250
|
getManyOptions,
|
|
224
251
|
getManyReferenceOptions,
|
|
252
|
+
getMetricDelta,
|
|
225
253
|
getOneOptions,
|
|
226
254
|
getPresenceInitials,
|
|
227
255
|
getPrevNextParams,
|
|
@@ -230,6 +258,7 @@ export {
|
|
|
230
258
|
getVisibleCommands,
|
|
231
259
|
groupCalendarAgenda,
|
|
232
260
|
groupCommands,
|
|
261
|
+
hasChartValues,
|
|
233
262
|
hasCustomParams,
|
|
234
263
|
hasPendingUndoables,
|
|
235
264
|
hasSelfIntersection,
|
|
@@ -247,6 +276,8 @@ export {
|
|
|
247
276
|
isLngLatBox,
|
|
248
277
|
isRealtimeDataProvider,
|
|
249
278
|
isRequired,
|
|
279
|
+
isSafeImageSrc,
|
|
280
|
+
isSafeLinkUrl,
|
|
250
281
|
isSavedQueryActive,
|
|
251
282
|
isTypingTarget,
|
|
252
283
|
joinBasename,
|
|
@@ -284,6 +315,7 @@ export {
|
|
|
284
315
|
normalizeFormError,
|
|
285
316
|
number,
|
|
286
317
|
omitCalendarRangeFilter,
|
|
318
|
+
onboardingTourKey,
|
|
287
319
|
oneKey,
|
|
288
320
|
overpassQueryOptions,
|
|
289
321
|
parseCalendarDate,
|
|
@@ -292,6 +324,9 @@ export {
|
|
|
292
324
|
parseLocation,
|
|
293
325
|
patchedRecord,
|
|
294
326
|
permissionsQueryOptions,
|
|
327
|
+
placeTourCard,
|
|
328
|
+
planJobCancel,
|
|
329
|
+
planJobRetry,
|
|
295
330
|
planKanbanMove,
|
|
296
331
|
polygonToBBox,
|
|
297
332
|
presenceTopic,
|
|
@@ -313,6 +348,10 @@ export {
|
|
|
313
348
|
resourceTopic,
|
|
314
349
|
revalidateLogic,
|
|
315
350
|
reverseGeocodeQueryOptions,
|
|
351
|
+
richTextBlockTypes,
|
|
352
|
+
richTextSanitizeOptions,
|
|
353
|
+
richTextStarterKitOptions,
|
|
354
|
+
richTextToolbarItems,
|
|
316
355
|
rootSourceScope,
|
|
317
356
|
runCsvImport,
|
|
318
357
|
savedQueriesKey,
|
|
@@ -333,12 +372,16 @@ export {
|
|
|
333
372
|
subscribeUnreadCount,
|
|
334
373
|
tagToFilter,
|
|
335
374
|
toCalendarEvents,
|
|
375
|
+
toCartesianRows,
|
|
336
376
|
toCoordinate,
|
|
377
|
+
toDonutSlices,
|
|
337
378
|
toEditorFeatures,
|
|
338
379
|
toJsonText,
|
|
339
380
|
toPresenceUser,
|
|
381
|
+
toTimelineEntries,
|
|
340
382
|
toggleFilterValue,
|
|
341
383
|
toggleHiddenColumn,
|
|
384
|
+
tourSpotlightPath,
|
|
342
385
|
undoableCallbacks,
|
|
343
386
|
undoableDeleteOptions,
|
|
344
387
|
undoableUpdateOptions,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** A box in viewport pixels. The adapters measure it; core touches no DOM. */
|
|
2
|
+
export interface TourRect {
|
|
3
|
+
top: number;
|
|
4
|
+
left: number;
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
}
|
|
8
|
+
export type TourPlacement = "auto" | "top" | "bottom" | "left" | "right";
|
|
9
|
+
type Side = Exclude<TourPlacement, "auto">;
|
|
10
|
+
export interface PlaceTourCardOptions {
|
|
11
|
+
/** `null` centres the card, for a step that points at nothing. */
|
|
12
|
+
target: TourRect | null;
|
|
13
|
+
card: {
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
};
|
|
17
|
+
viewport: {
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
};
|
|
21
|
+
placement: TourPlacement;
|
|
22
|
+
/** Gap between card and target, and the least distance to a viewport edge. */
|
|
23
|
+
margin?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface TourCardPosition {
|
|
26
|
+
/** The card's top-left corner. */
|
|
27
|
+
top: number;
|
|
28
|
+
left: number;
|
|
29
|
+
side: Side;
|
|
30
|
+
}
|
|
31
|
+
export declare function placeTourCard({ target, card, viewport, placement, margin, }: PlaceTourCardOptions): TourCardPosition;
|
|
32
|
+
/** A CSS `clip-path` that fills the page except the target's rect. */
|
|
33
|
+
export declare function tourSpotlightPath(target: TourRect): string;
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const SIDES = ["bottom", "top", "right", "left"];
|
|
2
|
+
const OPPOSITE = {
|
|
3
|
+
top: "bottom",
|
|
4
|
+
bottom: "top",
|
|
5
|
+
left: "right",
|
|
6
|
+
right: "left"
|
|
7
|
+
};
|
|
8
|
+
function placeTourCard({
|
|
9
|
+
target,
|
|
10
|
+
card,
|
|
11
|
+
viewport,
|
|
12
|
+
placement,
|
|
13
|
+
margin = 12
|
|
14
|
+
}) {
|
|
15
|
+
if (!target) {
|
|
16
|
+
return {
|
|
17
|
+
top: (viewport.height - card.height) / 2,
|
|
18
|
+
left: (viewport.width - card.width) / 2,
|
|
19
|
+
side: placement === "auto" ? "bottom" : placement
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const room = {
|
|
23
|
+
top: target.top,
|
|
24
|
+
bottom: viewport.height - (target.top + target.height),
|
|
25
|
+
left: target.left,
|
|
26
|
+
right: viewport.width - (target.left + target.width)
|
|
27
|
+
};
|
|
28
|
+
const needed = (side2) => (side2 === "top" || side2 === "bottom" ? card.height : card.width) + margin * 2;
|
|
29
|
+
const fits = (side2) => room[side2] >= needed(side2);
|
|
30
|
+
let side;
|
|
31
|
+
if (placement === "auto") {
|
|
32
|
+
const roomiest = (candidates) => candidates.reduce(
|
|
33
|
+
(best, next) => room[next] > room[best] ? next : best
|
|
34
|
+
);
|
|
35
|
+
const fitting = SIDES.filter(fits);
|
|
36
|
+
side = roomiest(fitting.length > 0 ? fitting : SIDES);
|
|
37
|
+
} else {
|
|
38
|
+
side = !fits(placement) && fits(OPPOSITE[placement]) ? OPPOSITE[placement] : placement;
|
|
39
|
+
}
|
|
40
|
+
const centreX = target.left + target.width / 2 - card.width / 2;
|
|
41
|
+
const centreY = target.top + target.height / 2 - card.height / 2;
|
|
42
|
+
let top;
|
|
43
|
+
let left;
|
|
44
|
+
switch (side) {
|
|
45
|
+
case "bottom":
|
|
46
|
+
top = target.top + target.height + margin;
|
|
47
|
+
left = centreX;
|
|
48
|
+
break;
|
|
49
|
+
case "top":
|
|
50
|
+
top = target.top - margin - card.height;
|
|
51
|
+
left = centreX;
|
|
52
|
+
break;
|
|
53
|
+
case "right":
|
|
54
|
+
top = centreY;
|
|
55
|
+
left = target.left + target.width + margin;
|
|
56
|
+
break;
|
|
57
|
+
case "left":
|
|
58
|
+
top = centreY;
|
|
59
|
+
left = target.left - margin - card.width;
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
top: Math.max(
|
|
64
|
+
margin,
|
|
65
|
+
Math.min(top, viewport.height - card.height - margin)
|
|
66
|
+
),
|
|
67
|
+
left: Math.max(
|
|
68
|
+
margin,
|
|
69
|
+
Math.min(left, viewport.width - card.width - margin)
|
|
70
|
+
),
|
|
71
|
+
side
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function tourSpotlightPath(target) {
|
|
75
|
+
const right = target.left + target.width;
|
|
76
|
+
const bottom = target.top + target.height;
|
|
77
|
+
return `polygon(0% 0%, 0% 100%, ${target.left}px 100%, ${target.left}px ${target.top}px, ${right}px ${target.top}px, ${right}px ${bottom}px, ${target.left}px ${bottom}px, ${target.left}px 100%, 100% 100%, 100% 0%)`;
|
|
78
|
+
}
|
|
79
|
+
export {
|
|
80
|
+
placeTourCard,
|
|
81
|
+
tourSpotlightPath
|
|
82
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type MicroStore } from "../store/micro-store.js";
|
|
2
|
+
import type { CheloneStore } from "../store/store.js";
|
|
3
|
+
/** Where the onboarding tour keeps its done flag in a `CheloneStore`. */
|
|
4
|
+
export declare function onboardingTourKey(id: string): string;
|
|
5
|
+
export interface TourState {
|
|
6
|
+
active: boolean;
|
|
7
|
+
index: number;
|
|
8
|
+
}
|
|
9
|
+
export type TourEnd = "finished" | "skipped";
|
|
10
|
+
export interface TourControllerOptions {
|
|
11
|
+
id: string;
|
|
12
|
+
stepCount: number;
|
|
13
|
+
store: CheloneStore;
|
|
14
|
+
/** Open on the first subscribe while the done flag is not `true`. */
|
|
15
|
+
autoStart?: boolean;
|
|
16
|
+
onComplete?: (reason: TourEnd) => void;
|
|
17
|
+
}
|
|
18
|
+
export interface TourController extends MicroStore<TourState> {
|
|
19
|
+
start(): void;
|
|
20
|
+
next(): void;
|
|
21
|
+
back(): void;
|
|
22
|
+
skip(): void;
|
|
23
|
+
finish(): void;
|
|
24
|
+
}
|
|
25
|
+
export declare function createTourController({ id, stepCount, store, autoStart, onComplete, }: TourControllerOptions): TourController;
|