@pstdio/ui 0.40.0 → 0.42.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/{MermaidComponent-81jr28u4.js → MermaidComponent-D7vhkpka.js} +3 -3
- package/dist/{MermaidComponent-81jr28u4.js.map → MermaidComponent-D7vhkpka.js.map} +1 -1
- package/dist/alert-MQ47wy7f.js +388 -0
- package/dist/alert-MQ47wy7f.js.map +1 -0
- package/dist/chat-ui.d.ts +129 -23
- package/dist/chat-ui.js +2596 -1591
- package/dist/chat-ui.js.map +1 -1
- package/dist/{types-DWA3enV6.d.ts → collection-view-fields-D3cysHNT.d.ts} +87 -37
- package/dist/collection-view-grouping-D4nZk8-3.js +90 -0
- package/dist/collection-view-grouping-D4nZk8-3.js.map +1 -0
- package/dist/collection-view-search-CpjJy76w.js +1973 -0
- package/dist/collection-view-search-CpjJy76w.js.map +1 -0
- package/dist/collection-view.d.ts +4 -0
- package/dist/collection-view.js +2 -0
- package/dist/{data-table-stats-row-CpRe_xK2.js → data-table-stats-row-64magT2g.js} +2 -2
- package/dist/{data-table-stats-row-CpRe_xK2.js.map → data-table-stats-row-64magT2g.js.map} +1 -1
- package/dist/data-table.d.ts +29 -7
- package/dist/data-table.js +1043 -878
- package/dist/data-table.js.map +1 -1
- package/dist/diff-bubble-DewUd_2w.js +61 -0
- package/dist/diff-bubble-DewUd_2w.js.map +1 -0
- package/dist/{diff-drawer-45rpk3aq.js → diff-drawer-IYpQ-QQK.js} +264 -242
- package/dist/diff-drawer-IYpQ-QQK.js.map +1 -0
- package/dist/diff-viewer-C-0VAt9P.js +574 -0
- package/dist/diff-viewer-C-0VAt9P.js.map +1 -0
- package/dist/diff.d.ts +11 -0
- package/dist/diff.js +107 -98
- package/dist/diff.js.map +1 -1
- package/dist/display-sort-control-f3rbILsV.js +588 -0
- package/dist/display-sort-control-f3rbILsV.js.map +1 -0
- package/dist/drop-indicator-HjlBSIeV.js +27 -0
- package/dist/drop-indicator-HjlBSIeV.js.map +1 -0
- package/dist/edit-mode-data-table-DnMB2jiy.js +1449 -0
- package/dist/edit-mode-data-table-DnMB2jiy.js.map +1 -0
- package/dist/host-storage-BIo5azql.js +31 -0
- package/dist/host-storage-BIo5azql.js.map +1 -0
- package/dist/host-storage-J0089Hyk.d.ts +17 -0
- package/dist/{slider-hwHYe98I.js → icon-options-Tt6Wzhtv.js} +86 -201
- package/dist/icon-options-Tt6Wzhtv.js.map +1 -0
- package/dist/{index-Bfddrlz8.d.ts → index-B79hwNcB.d.ts} +66 -14
- package/dist/index-CKsd23jv.d.ts +80 -0
- package/dist/{index-CbtbcvKm.d.ts → index-DlmvvQ6x.d.ts} +1 -1
- package/dist/index-ICoad2I_.d.ts +282 -0
- package/dist/index.d.ts +63 -22
- package/dist/index.js +1149 -1054
- package/dist/index.js.map +1 -1
- package/dist/kanban-renderer.d.ts +3 -326
- package/dist/kanban-renderer.js +980 -596
- package/dist/kanban-renderer.js.map +1 -1
- package/dist/list-row-Z4SHkseA.js +1195 -0
- package/dist/list-row-Z4SHkseA.js.map +1 -0
- package/dist/markdown-editor-Dd4mor7l.js +3236 -0
- package/dist/markdown-editor-Dd4mor7l.js.map +1 -0
- package/dist/{mermaid-renderer-DImi0fDp.js → mermaid-renderer-0PmNkOXI.js} +29 -29
- package/dist/mermaid-renderer-0PmNkOXI.js.map +1 -0
- package/dist/mermaid.js +1 -1
- package/dist/number-input-7K66wnSC.js +63 -0
- package/dist/number-input-7K66wnSC.js.map +1 -0
- package/dist/{param-editor-BQd4AOUP.js → param-editor-Dnix-fJo.js} +2 -2
- package/dist/{param-editor-BQd4AOUP.js.map → param-editor-Dnix-fJo.js.map} +1 -1
- package/dist/{param-editor-field-BJ_rLUnV.js → param-editor-field-B3vLST-B.js} +1436 -1427
- package/dist/param-editor-field-B3vLST-B.js.map +1 -0
- package/dist/param-editor.js +4 -3
- package/dist/prism-OG4H7Hu4.js +334 -0
- package/dist/prism-OG4H7Hu4.js.map +1 -0
- package/dist/queued-follow-up-Bj_vtMgd.js +208 -0
- package/dist/queued-follow-up-Bj_vtMgd.js.map +1 -0
- package/dist/{resource-badge-95WPVlZf.d.ts → resource-badge-nOWPqxFU.d.ts} +1 -0
- package/dist/rich-text-BgEnAHr2.js +1160 -0
- package/dist/rich-text-BgEnAHr2.js.map +1 -0
- package/dist/rich-text.d.ts +2 -2
- package/dist/rich-text.js +4 -2
- package/dist/style.css +1 -1
- package/dist/terminal.d.ts +5 -63
- package/dist/terminal.js +102 -122
- package/dist/terminal.js.map +1 -1
- package/dist/{theme-CbmSEbRF.js → theme-CMJdH59Z.js} +589 -265
- package/dist/theme-CMJdH59Z.js.map +1 -0
- package/dist/theme-kKuLN2jb.js +80 -0
- package/dist/theme-kKuLN2jb.js.map +1 -0
- package/dist/theme-preference-BV4cbJNB.js +115 -0
- package/dist/theme-preference-BV4cbJNB.js.map +1 -0
- package/dist/theme.js +3 -2
- package/dist/tree-list-jarhD31R.js +1652 -0
- package/dist/tree-list-jarhD31R.js.map +1 -0
- package/dist/use-virtualizer-uj43XjBp.js +10 -0
- package/dist/use-virtualizer-uj43XjBp.js.map +1 -0
- package/dist/{workspace-badge-Brm3Xr3m.d.ts → workspace-badge-BKtB805G.d.ts} +5 -1
- package/package.json +8 -4
- package/dist/diff-bubble-DZsarmSG.js +0 -61
- package/dist/diff-bubble-DZsarmSG.js.map +0 -1
- package/dist/diff-drawer-45rpk3aq.js.map +0 -1
- package/dist/diff-viewer-BP_mI6Wx.js +0 -558
- package/dist/diff-viewer-BP_mI6Wx.js.map +0 -1
- package/dist/list-row-uqD-q4gv.js +0 -1018
- package/dist/list-row-uqD-q4gv.js.map +0 -1
- package/dist/mermaid-renderer-DImi0fDp.js.map +0 -1
- package/dist/param-editor-field-BJ_rLUnV.js.map +0 -1
- package/dist/prism-BStPsJSB.js +0 -658
- package/dist/prism-BStPsJSB.js.map +0 -1
- package/dist/rich-text-VYAmEigU.js +0 -6979
- package/dist/rich-text-VYAmEigU.js.map +0 -1
- package/dist/slider-hwHYe98I.js.map +0 -1
- package/dist/theme-CbmSEbRF.js.map +0 -1
- package/dist/theme-preference-pzfuK5cH.js +0 -101
- package/dist/theme-preference-pzfuK5cH.js.map +0 -1
- package/dist/tree-list-BNZwjQZA.js +0 -1616
- package/dist/tree-list-BNZwjQZA.js.map +0 -1
|
@@ -1,9 +1,42 @@
|
|
|
1
|
+
import "./host-storage-J0089Hyk.js";
|
|
1
2
|
import { ReactNode } from "react";
|
|
3
|
+
import { ViewFilterCondition, ViewFilterGroup, ViewFilterGroup as ViewFilterGroup$1, ViewFilterRule, ViewFilterRule as ViewFilterRule$1, ViewSort, ViewSort as ViewSort$1, ViewSortDirection } from "@pstdio/sdk/extensions";
|
|
4
|
+
//#region src/components/collection-view/collection-view-types.d.ts
|
|
5
|
+
declare const EMPTY_VIEW_FILTER: ViewFilterGroup;
|
|
6
|
+
/** What a saved view stores. Search, selection, and collapsed groups are screen state and never saved. */
|
|
7
|
+
interface CollectionSavedView<TSettings> {
|
|
8
|
+
id: string;
|
|
9
|
+
title: string;
|
|
10
|
+
settings: TSettings;
|
|
11
|
+
filter: ViewFilterGroup;
|
|
12
|
+
sorts: ViewSort[];
|
|
13
|
+
/** @deprecated Use defaultActiveViewId instead. */
|
|
14
|
+
isDefault?: boolean;
|
|
15
|
+
}
|
|
16
|
+
interface CollectionViewState<TSettings> {
|
|
17
|
+
settings: TSettings;
|
|
18
|
+
filter: ViewFilterGroup;
|
|
19
|
+
sorts: ViewSort[];
|
|
20
|
+
}
|
|
21
|
+
interface CollectionViewsSource<TSettings> {
|
|
22
|
+
views: (CollectionSavedView<TSettings> & {
|
|
23
|
+
builtIn: boolean;
|
|
24
|
+
})[];
|
|
25
|
+
defaultViewId: string;
|
|
26
|
+
onCreateView: (input: CollectionViewState<TSettings> & {
|
|
27
|
+
title: string;
|
|
28
|
+
copyFrom?: string;
|
|
29
|
+
}) => Promise<CollectionSavedView<TSettings>>;
|
|
30
|
+
onUpdateView: (id: string, input: Partial<CollectionViewState<TSettings>> & {
|
|
31
|
+
title?: string;
|
|
32
|
+
}) => Promise<void>;
|
|
33
|
+
onDeleteView: (id: string) => Promise<void>;
|
|
34
|
+
onSetDefaultView: (id: string | null) => Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
2
37
|
//#region src/components/kanban-renderer/types.d.ts
|
|
3
38
|
type ViewMode = "board" | "list";
|
|
4
|
-
type SortDirection = "asc" | "desc";
|
|
5
39
|
declare const NO_GROUPING = "none";
|
|
6
|
-
declare const MANUAL_ORDERING = "manual";
|
|
7
40
|
interface EnumOption {
|
|
8
41
|
value: string;
|
|
9
42
|
label: string;
|
|
@@ -27,6 +60,9 @@ type AttributeType = {
|
|
|
27
60
|
} | {
|
|
28
61
|
kind: "enum-multi";
|
|
29
62
|
options: EnumOptions;
|
|
63
|
+
} | {
|
|
64
|
+
kind: "boolean";
|
|
65
|
+
legacyValues?: Record<string, boolean>;
|
|
30
66
|
} | {
|
|
31
67
|
kind: "string";
|
|
32
68
|
} | {
|
|
@@ -96,26 +132,14 @@ interface KanbanRendererRow {
|
|
|
96
132
|
resource?: unknown;
|
|
97
133
|
attributes: Record<string, unknown>;
|
|
98
134
|
}
|
|
99
|
-
|
|
100
|
-
attributeId: string | typeof MANUAL_ORDERING;
|
|
101
|
-
direction: SortDirection;
|
|
102
|
-
}
|
|
135
|
+
/** Board display settings. Order lives in the view's sorts. */
|
|
103
136
|
interface KanbanRendererSettings {
|
|
104
137
|
viewMode: ViewMode;
|
|
105
138
|
columnGrouping: string | typeof NO_GROUPING;
|
|
106
139
|
rowGrouping: string | typeof NO_GROUPING;
|
|
107
|
-
ordering: KanbanRendererOrdering;
|
|
108
140
|
displayProperties: string[];
|
|
109
141
|
}
|
|
110
|
-
type
|
|
111
|
-
interface KanbanRendererSavedView {
|
|
112
|
-
id: string;
|
|
113
|
-
title: string;
|
|
114
|
-
settings: KanbanRendererSettings;
|
|
115
|
-
filters: KanbanRendererFilterState;
|
|
116
|
-
/** @deprecated Use defaultActiveViewId instead. */
|
|
117
|
-
isDefault?: boolean;
|
|
118
|
-
}
|
|
142
|
+
type KanbanRendererSavedView = CollectionSavedView<KanbanRendererSettings>;
|
|
119
143
|
type KanbanRendererCreateFieldType = "text" | "longtext" | "markdown" | "number" | "boolean" | "select" | "multi-select" | "files";
|
|
120
144
|
interface KanbanRendererCreateField {
|
|
121
145
|
id: string;
|
|
@@ -155,28 +179,54 @@ interface KanbanRendererCreateSubmission {
|
|
|
155
179
|
declare const DEFAULT_KANBAN_RENDERER_SETTINGS: KanbanRendererSettings;
|
|
156
180
|
/**
|
|
157
181
|
* Look up an attribute by id from a contribution-provided descriptor list.
|
|
158
|
-
* Returns undefined for
|
|
182
|
+
* Returns undefined for the "none" grouping or unknown ids.
|
|
159
183
|
*/
|
|
160
184
|
declare const findAttribute: (attributes: AttributeDescriptor[], id: string | undefined) => AttributeDescriptor | undefined;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
185
|
+
type KanbanRendererViewsSource = CollectionViewsSource<KanbanRendererSettings>;
|
|
186
|
+
//#endregion
|
|
187
|
+
//#region src/components/collection-view/use-collection-view-store.d.ts
|
|
188
|
+
/** The unsaved state of one renderer: the active view and the edits made on top of it. */
|
|
189
|
+
interface CollectionViewSnapshot<TSettings> {
|
|
190
|
+
settings: TSettings;
|
|
191
|
+
filter: ViewFilterGroup;
|
|
192
|
+
sorts: ViewSort[];
|
|
193
|
+
expandedGroups: Record<string, boolean>;
|
|
194
|
+
activeViewId: string;
|
|
195
|
+
}
|
|
196
|
+
type CollectionViewMenu = "filter";
|
|
197
|
+
interface CollectionViewStoreInitialState<TSettings> {
|
|
198
|
+
settings: TSettings;
|
|
199
|
+
filter?: ViewFilterGroup;
|
|
200
|
+
sorts?: ViewSort[];
|
|
201
|
+
}
|
|
202
|
+
interface CollectionViewStoreState<TSettings> extends CollectionViewSnapshot<TSettings> {
|
|
203
|
+
/** The view bar menu that is open. Screen state: never persisted. */
|
|
204
|
+
openMenu: CollectionViewMenu | null;
|
|
205
|
+
/** The root rule whose pill editor is open. Screen state: never persisted. */
|
|
206
|
+
openRuleIndex: number | null;
|
|
207
|
+
setOpenMenu: (menu: CollectionViewMenu | null) => void;
|
|
208
|
+
setOpenRuleIndex: (index: number | null) => void;
|
|
209
|
+
/** Adds a rule for the field and opens its pill editor. */
|
|
210
|
+
startRule: (field: AttributeDescriptor) => void;
|
|
211
|
+
/** Commits picker values; scalar values transfer editing to their bubble. */
|
|
212
|
+
selectRule: (rule: ViewFilterRule) => void;
|
|
213
|
+
setSettings: (settings: Partial<TSettings>) => void;
|
|
214
|
+
setFilter: (filter: ViewFilterGroup) => void;
|
|
215
|
+
setSorts: (sorts: ViewSort[]) => void;
|
|
216
|
+
setExpandedGroup: (groupId: string, isExpanded: boolean) => void;
|
|
217
|
+
activateView: (view: CollectionSavedView<TSettings>) => void;
|
|
218
|
+
reset: () => void;
|
|
219
|
+
}
|
|
220
|
+
declare const useCollectionViewStore: <TSettings, T>(storageKey: string, initialState: CollectionViewStoreInitialState<TSettings>, selector: (state: CollectionViewStoreState<TSettings>) => T) => T;
|
|
221
|
+
//#endregion
|
|
222
|
+
//#region src/components/collection-view/collection-view-fields.d.ts
|
|
223
|
+
declare const withTitleField: (attributes: AttributeDescriptor[]) => AttributeDescriptor[];
|
|
224
|
+
/**
|
|
225
|
+
* Read a typed attribute value out of a row. enum-multi normalizes to an array;
|
|
226
|
+
* single-valued kinds normalize to undefined when missing.
|
|
227
|
+
*/
|
|
228
|
+
declare const getAttributeValue: (row: KanbanRendererRow, descriptor: AttributeDescriptor) => unknown;
|
|
229
|
+
declare const getAttributeStringValues: (row: KanbanRendererRow, descriptor: AttributeDescriptor) => string[];
|
|
180
230
|
//#endregion
|
|
181
|
-
export {
|
|
231
|
+
export { CollectionSavedView as A, KanbanRendererSettings as C, findAttribute as D, ViewMode as E, ViewFilterGroup$1 as F, ViewFilterRule$1 as I, ViewSort$1 as L, CollectionViewsSource as M, EMPTY_VIEW_FILTER as N, isAttributesSource as O, ViewFilterCondition as P, ViewSortDirection as R, KanbanRendererSavedView as S, NO_GROUPING as T, KanbanRendererCreateField as _, CollectionViewStoreState as a, KanbanRendererCreateSubmission as b, AttributeDisplayDescriptor as c, AttributesSource as d, CollectionBadgeItem as f, EnumOptionsSource as g, EnumOptions as h, CollectionViewStoreInitialState as i, CollectionViewState as j, isEnumOptionsSource as k, AttributeKind as l, EnumOption as m, getAttributeValue as n, useCollectionViewStore as o, DEFAULT_KANBAN_RENDERER_SETTINGS as p, withTitleField as r, AttributeDescriptor as s, getAttributeStringValues as t, AttributeType as u, KanbanRendererCreateFieldType as v, KanbanRendererViewsSource as w, KanbanRendererRow as x, KanbanRendererCreateRowConfig as y };
|
|
182
232
|
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { S as e, _ as t, b as n, g as r, m as i, p as a, t as o, v as s } from "./collection-view-search-CpjJy76w.js";
|
|
2
|
+
import { Box as c } from "@chakra-ui/react";
|
|
3
|
+
import { jsx as l } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/collection-view/highlighted-text.tsx
|
|
5
|
+
var u = (e) => {
|
|
6
|
+
let { text: t, query: n } = e, r = o(t, n);
|
|
7
|
+
if (r.length === 0) return t;
|
|
8
|
+
let i = [], a = 0;
|
|
9
|
+
for (let [e, n] of r) e > a && i.push({
|
|
10
|
+
text: t.slice(a, e),
|
|
11
|
+
match: !1,
|
|
12
|
+
start: a
|
|
13
|
+
}), i.push({
|
|
14
|
+
text: t.slice(e, n),
|
|
15
|
+
match: !0,
|
|
16
|
+
start: e
|
|
17
|
+
}), a = n;
|
|
18
|
+
return a < t.length && i.push({
|
|
19
|
+
text: t.slice(a),
|
|
20
|
+
match: !1,
|
|
21
|
+
start: a
|
|
22
|
+
}), i.map((e) => e.match ? /* @__PURE__ */ l(c, {
|
|
23
|
+
as: "mark",
|
|
24
|
+
bg: "bg.warning",
|
|
25
|
+
color: "inherit",
|
|
26
|
+
borderRadius: "2xs",
|
|
27
|
+
children: e.text
|
|
28
|
+
}, e.start) : e.text);
|
|
29
|
+
}, d = (t, n, r) => {
|
|
30
|
+
if (r.kind !== "enum" && r.kind !== "enum-multi") return 0;
|
|
31
|
+
let i = e(r), a = (e) => {
|
|
32
|
+
if (e === void 0) return i.length;
|
|
33
|
+
let t = i.findIndex((t) => t.value === e);
|
|
34
|
+
return t === -1 ? i.length + 1 : t;
|
|
35
|
+
};
|
|
36
|
+
return a(t) - a(n);
|
|
37
|
+
}, f = (e) => s(e)?.getTime() ?? NaN, p = (e, n, i) => {
|
|
38
|
+
let a = t(e, i), o = t(n, i);
|
|
39
|
+
if (i.compare) return i.compare(a, o);
|
|
40
|
+
if (i.type.kind === "date") return f(a) - f(o);
|
|
41
|
+
if (i.type.kind === "number") return Number(a) - Number(o);
|
|
42
|
+
if (i.type.kind === "enum") {
|
|
43
|
+
let [t] = r(e, i), [a] = r(n, i);
|
|
44
|
+
return d(t, a, i.type);
|
|
45
|
+
}
|
|
46
|
+
return String(a).localeCompare(String(o), void 0, {
|
|
47
|
+
numeric: !0,
|
|
48
|
+
sensitivity: "base"
|
|
49
|
+
});
|
|
50
|
+
}, m = (e, n) => {
|
|
51
|
+
if (n.type.kind === "date") return s(t(e, n)) === void 0;
|
|
52
|
+
let [i] = r(e, n);
|
|
53
|
+
return i === void 0 || n.type.kind === "number" && !Number.isFinite(Number(i));
|
|
54
|
+
}, h = (e, t) => {
|
|
55
|
+
let n = i(t, e.attributeId);
|
|
56
|
+
if (!n || !a(n)) return;
|
|
57
|
+
let r = e.direction === "asc" ? 1 : -1;
|
|
58
|
+
return (e, t) => {
|
|
59
|
+
let i = m(e, n), a = m(t, n);
|
|
60
|
+
return i || a ? Number(i) - Number(a) : r * p(e, t, n);
|
|
61
|
+
};
|
|
62
|
+
}, g = (e, t, n) => {
|
|
63
|
+
let r = t[0], i = r ? h(r, n) : void 0;
|
|
64
|
+
return i ? [...e].sort(i) : e;
|
|
65
|
+
}, _ = (e) => `No ${e.label.toLowerCase()}`, v = (e, t) => e === _(t) ? e : t.type.kind === "enum" || t.type.kind === "enum-multi" ? n(t.type, e) : e, y = (t, n) => {
|
|
66
|
+
if (t !== void 0) return n.type.kind !== "enum" && n.type.kind !== "enum-multi" || e(n.type).some((e) => e.value === t) ? t : void 0;
|
|
67
|
+
}, b = (e, t) => {
|
|
68
|
+
let [n] = r(e, t);
|
|
69
|
+
return y(n, t) ?? _(t);
|
|
70
|
+
}, x = (e, t, n) => {
|
|
71
|
+
let r = _(n);
|
|
72
|
+
if (e === r || t === r) return Number(e === r) - Number(t === r);
|
|
73
|
+
let i = d(e, t, n.type);
|
|
74
|
+
return i === 0 ? e.localeCompare(t, void 0, { numeric: !0 }) : i;
|
|
75
|
+
}, S = (e, t, n = []) => {
|
|
76
|
+
let r = new Map(n.map((e) => [e, []]));
|
|
77
|
+
for (let n of e) {
|
|
78
|
+
let e = b(n, t), i = r.get(e);
|
|
79
|
+
i ? i.push(n) : r.set(e, [n]);
|
|
80
|
+
}
|
|
81
|
+
return [...r.entries()].sort(([e], [n]) => x(e, n, t)).map(([e, n]) => ({
|
|
82
|
+
key: e,
|
|
83
|
+
label: v(e, t),
|
|
84
|
+
rows: n
|
|
85
|
+
}));
|
|
86
|
+
};
|
|
87
|
+
//#endregion
|
|
88
|
+
export { u as a, g as i, b as n, S as r, _ as t };
|
|
89
|
+
|
|
90
|
+
//# sourceMappingURL=collection-view-grouping-D4nZk8-3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collection-view-grouping-D4nZk8-3.js","names":["Box","findSearchRanges","HighlightedTextProps","text","query","HighlightedText","props","ranges","length","parts","Array","match","start","cursor","end","push","slice","map","part","ViewSort","getEnumOptions","AttributeDescriptor","AttributeType","KanbanRendererRow","canSortField","findField","getAttributeStringValues","getAttributeValue","parseViewDate","compareEnumValues","left","right","type","kind","options","toIndex","value","undefined","length","index","findIndex","option","toTime","getTime","Number","NaN","compareFieldValues","a","b","field","compare","leftValue","rightValue","String","localeCompare","numeric","sensitivity","isEmpty","row","isFinite","compileSort","sort","fields","attributeId","direction","leftEmpty","rightEmpty","sortRowsByView","rows","TRow","sorts","enumOptionLabel","getEnumOptions","AttributeDescriptor","KanbanRendererRow","getAttributeStringValues","compareEnumValues","CollectionRowGroup","key","label","rows","TRow","emptyGroupKey","field","toLowerCase","groupLabel","type","kind","resolveGroupValue","value","undefined","some","option","groupKey","row","compareGroupKeys","left","right","empty","Number","ordered","localeCompare","numeric","groupRowsByField","knownKeys","groups","Map","map","group","get","push","set","entries","sort","groupRows","getEnumOptions","getAttributeValue","enumOptionLabel","getAttributeStringValues","findField","canSortField","findSearchRanges","parseViewDate","HighlightedText","props","ranges","text","query","parts","cursor","start","end","part","Box","compareEnumValues","type","options","toIndex","value","index","option","left","right","toTime","compareFieldValues","a","field","b","leftValue","rightValue","isEmpty","row","compileSort","fields","sort","direction","leftEmpty","rightEmpty","sortRowsByView","sorts","compare","rows","emptyGroupKey","groupLabel","key","resolveGroupValue","groupKey","compareGroupKeys","empty","ordered","groupRowsByField","groups","knownKeys","group","groupRows"],"sources":["../src/components/collection-view/highlighted-text.tsx","../src/components/collection-view/collection-view-sort.ts","../src/components/collection-view/collection-view-grouping.ts"],"sourcesContent":["import { Box } from \"@chakra-ui/react\";\nimport { findSearchRanges } from \"./collection-view-search\";\n\nexport interface HighlightedTextProps {\n text: string;\n /** The view's search text. Every match in `text` is marked. */\n query: string;\n}\n\nexport const HighlightedText = (props: HighlightedTextProps) => {\n const { text, query } = props;\n const ranges = findSearchRanges(text, query);\n if (ranges.length === 0) return text;\n const parts: Array<{ text: string; match: boolean; start: number }> = [];\n let cursor = 0;\n for (const [start, end] of ranges) {\n if (start > cursor) parts.push({ text: text.slice(cursor, start), match: false, start: cursor });\n parts.push({ text: text.slice(start, end), match: true, start });\n cursor = end;\n }\n if (cursor < text.length) parts.push({ text: text.slice(cursor), match: false, start: cursor });\n\n return parts.map((part) =>\n part.match ? (\n <Box as=\"mark\" key={part.start} bg=\"bg.warning\" color=\"inherit\" borderRadius=\"2xs\">\n {part.text}\n </Box>\n ) : (\n part.text\n ),\n );\n};\n","import type { ViewSort } from \"@pstdio/sdk/extensions\";\nimport { getEnumOptions } from \"../kanban-renderer/kanban-renderer-enum-helpers\";\nimport type { AttributeDescriptor, AttributeType, KanbanRendererRow } from \"../kanban-renderer/types\";\nimport {\n canSortField,\n findField,\n getAttributeStringValues,\n getAttributeValue,\n parseViewDate,\n} from \"./collection-view-fields\";\n\n/** Option order: declared options first, unknown values after them, missing values last. */\nexport const compareEnumValues = (left: string | undefined, right: string | undefined, type: AttributeType) => {\n if (type.kind !== \"enum\" && type.kind !== \"enum-multi\") return 0;\n const options = getEnumOptions(type);\n const toIndex = (value: string | undefined) => {\n if (value === undefined) return options.length;\n const index = options.findIndex((option) => option.value === value);\n return index === -1 ? options.length + 1 : index;\n };\n return toIndex(left) - toIndex(right);\n};\n\nconst toTime = (value: unknown) => parseViewDate(value)?.getTime() ?? Number.NaN;\n\nconst compareFieldValues = (a: KanbanRendererRow, b: KanbanRendererRow, field: AttributeDescriptor) => {\n const left = getAttributeValue(a, field);\n const right = getAttributeValue(b, field);\n if (field.compare) return field.compare(left, right);\n if (field.type.kind === \"date\") return toTime(left) - toTime(right);\n if (field.type.kind === \"number\") return Number(left) - Number(right);\n if (field.type.kind === \"enum\") {\n const [leftValue] = getAttributeStringValues(a, field);\n const [rightValue] = getAttributeStringValues(b, field);\n return compareEnumValues(leftValue, rightValue, field.type);\n }\n return String(left).localeCompare(String(right), undefined, { numeric: true, sensitivity: \"base\" });\n};\n\nconst isEmpty = (row: KanbanRendererRow, field: AttributeDescriptor) => {\n if (field.type.kind === \"date\") return parseViewDate(getAttributeValue(row, field)) === undefined;\n const [value] = getAttributeStringValues(row, field);\n if (value === undefined) return true;\n if (field.type.kind === \"number\") return !Number.isFinite(Number(value));\n return false;\n};\n\nconst compileSort = (sort: ViewSort, fields: AttributeDescriptor[]) => {\n const field = findField(fields, sort.attributeId);\n if (!field || !canSortField(field)) return undefined;\n const direction = sort.direction === \"asc\" ? 1 : -1;\n // Rows without a value stay last in both directions.\n return (a: KanbanRendererRow, b: KanbanRendererRow) => {\n const leftEmpty = isEmpty(a, field);\n const rightEmpty = isEmpty(b, field);\n if (leftEmpty || rightEmpty) return Number(leftEmpty) - Number(rightEmpty);\n return direction * compareFieldValues(a, b, field);\n };\n};\n\n/** One field decides the order; ties keep their incoming order. */\nexport const sortRowsByView = <TRow extends KanbanRendererRow>(\n rows: TRow[],\n sorts: ViewSort[],\n fields: AttributeDescriptor[],\n) => {\n const sort = sorts[0];\n const compare = sort ? compileSort(sort, fields) : undefined;\n return compare ? [...rows].sort(compare) : rows;\n};\n","import { enumOptionLabel, getEnumOptions } from \"../kanban-renderer/kanban-renderer-enum-helpers\";\nimport type { AttributeDescriptor, KanbanRendererRow } from \"../kanban-renderer/types\";\nimport { getAttributeStringValues } from \"./collection-view-fields\";\nimport { compareEnumValues } from \"./collection-view-sort\";\n\nexport interface CollectionRowGroup<TRow extends KanbanRendererRow = KanbanRendererRow> {\n key: string;\n label: string;\n rows: TRow[];\n}\n\nexport const emptyGroupKey = (field: AttributeDescriptor) => `No ${field.label.toLowerCase()}`;\n\nexport const groupLabel = (key: string, field: AttributeDescriptor) => {\n if (key === emptyGroupKey(field)) return key;\n if (field.type.kind === \"enum\" || field.type.kind === \"enum-multi\") return enumOptionLabel(field.type, key);\n return key;\n};\n\n// Drops values that are no longer a declared option, so rows pointing at a removed\n// status join the \"No <field>\" group instead of an orphaned group for the deleted value.\nconst resolveGroupValue = (value: string | undefined, field: AttributeDescriptor) => {\n if (value === undefined) return undefined;\n if (field.type.kind !== \"enum\" && field.type.kind !== \"enum-multi\") return value;\n return getEnumOptions(field.type).some((option) => option.value === value) ? value : undefined;\n};\n\n/** One group per row. A multi-value field is not offered for grouping, so its first value decides. */\nexport const groupKey = (row: KanbanRendererRow, field: AttributeDescriptor) => {\n const [value] = getAttributeStringValues(row, field);\n return resolveGroupValue(value, field) ?? emptyGroupKey(field);\n};\n\n/** Option fields follow option order, other fields go A to Z, and the \"No <field>\" group comes last. */\nexport const compareGroupKeys = (left: string, right: string, field: AttributeDescriptor) => {\n const empty = emptyGroupKey(field);\n if (left === empty || right === empty) return Number(left === empty) - Number(right === empty);\n const ordered = compareEnumValues(left, right, field.type);\n if (ordered !== 0) return ordered;\n return left.localeCompare(right, undefined, { numeric: true });\n};\n\nexport const groupRowsByField = <TRow extends KanbanRendererRow>(\n rows: TRow[],\n field: AttributeDescriptor,\n knownKeys: string[] = [],\n): CollectionRowGroup<TRow>[] => {\n const groups = new Map<string, TRow[]>(knownKeys.map((key) => [key, []]));\n for (const row of rows) {\n const key = groupKey(row, field);\n const group = groups.get(key);\n if (group) group.push(row);\n else groups.set(key, [row]);\n }\n return [...groups.entries()]\n .sort(([left], [right]) => compareGroupKeys(left, right, field))\n .map(([key, groupRows]) => ({ key, label: groupLabel(key, field), rows: groupRows }));\n};\n"],"mappings":"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"}
|