@svgrid/enterprise 3.1.22 → 3.1.23

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.
Files changed (55) hide show
  1. package/dist/SvGridBoard.svelte +39 -0
  2. package/dist/SvGridGallery.svelte +23 -0
  3. package/dist/SvGridScheduler.svelte +25 -7
  4. package/dist/cdn/svgrid-enterprise.svelte-external.js +13739 -13667
  5. package/dist/designer/assets/index-CHx3F4Ij.css +1 -0
  6. package/dist/designer/assets/{index-ICCQKTGR.js → index-CIxqRzKJ.js} +318 -318
  7. package/dist/designer/assets/merges-Bg-KqPEl.js +1 -0
  8. package/dist/designer/index.html +2 -2
  9. package/dist/fields/RecordView.svelte +5 -2
  10. package/dist/fields/activity.svelte.d.ts +5 -2
  11. package/dist/fields/activity.svelte.js +4 -3
  12. package/dist/fields/grid-access.d.ts +1 -1
  13. package/dist/fields/grid-access.js +13 -3
  14. package/dist/fields/index.d.ts +18 -0
  15. package/dist/fields/index.js +31 -0
  16. package/dist/node/studio.js +2 -2
  17. package/dist/review/GhostCell.svelte +60 -0
  18. package/dist/review/GhostCell.svelte.d.ts +14 -0
  19. package/dist/review/RichCellMark.svelte +72 -0
  20. package/dist/review/RichCellMark.svelte.d.ts +8 -0
  21. package/dist/review/SvReviewPanel.svelte +759 -0
  22. package/dist/review/SvReviewPanel.svelte.d.ts +16 -0
  23. package/dist/review/adapters.d.ts +79 -0
  24. package/dist/review/adapters.js +119 -0
  25. package/dist/review/agent.d.ts +52 -0
  26. package/dist/review/agent.js +232 -0
  27. package/dist/review/card-marks.svelte.d.ts +42 -0
  28. package/dist/review/card-marks.svelte.js +51 -0
  29. package/dist/review/cluster.d.ts +26 -0
  30. package/dist/review/cluster.js +377 -0
  31. package/dist/review/equal.d.ts +9 -0
  32. package/dist/review/equal.js +35 -0
  33. package/dist/review/formats.d.ts +31 -0
  34. package/dist/review/formats.js +37 -0
  35. package/dist/review/ghost.d.ts +17 -0
  36. package/dist/review/ghost.js +104 -0
  37. package/dist/review/index.d.ts +42 -0
  38. package/dist/review/index.js +36 -0
  39. package/dist/review/messages.d.ts +113 -0
  40. package/dist/review/messages.js +135 -0
  41. package/dist/review/model.svelte.d.ts +262 -0
  42. package/dist/review/model.svelte.js +883 -0
  43. package/dist/review/pending-filter.d.ts +26 -0
  44. package/dist/review/pending-filter.js +71 -0
  45. package/dist/review/rich-cells.d.ts +1 -0
  46. package/dist/review/rich-cells.js +36 -0
  47. package/dist/review/types.d.ts +83 -0
  48. package/dist/review/types.js +7 -0
  49. package/dist/upgrade-prompt.d.ts +1 -1
  50. package/dist/version.d.ts +2 -2
  51. package/dist/version.js +2 -2
  52. package/dist/wc/merges-DQTOlMWM.js +109 -0
  53. package/dist/wc/sv-sheet-element.js +5688 -5735
  54. package/package.json +9 -3
  55. package/dist/designer/assets/index-9APkRkTg.css +0 -1
@@ -0,0 +1,26 @@
1
+ /**
2
+ * "Only rows with changes": a condition kind of the expression language
3
+ * (`registerPredicateKind`) that matches rows with a pending or conflicting
4
+ * proposal, ANDed onto the user's own advanced filter and taken back off
5
+ * without touching the rest of it.
6
+ *
7
+ * The advanced filter hands its predicate the grid's rows, whose `id` is the
8
+ * grid's row id, which is what proposals are keyed by.
9
+ */
10
+ import type { GridPredicateExpr } from '@svgrid/grid';
11
+ export declare const PENDING_KIND = "reviewPending";
12
+ type Source = {
13
+ hasPendingRow(rowId: string): boolean;
14
+ };
15
+ /** Make a review's rows filterable; returns the token its filter node names. */
16
+ export declare function trackPendingSource(token: string, source: Source): void;
17
+ /** The user's expression without any of our nodes; null when nothing is left. */
18
+ export declare function stripPending(expr: GridPredicateExpr | null): GridPredicateExpr | null;
19
+ /**
20
+ * The user's expression with our node ANDed on. `nonce` changes the node, so
21
+ * the grid filters again after proposals were decided.
22
+ */
23
+ export declare function withPending(expr: GridPredicateExpr | null, token: string, nonce: number): GridPredicateExpr;
24
+ /** Whether an expression holds our node. */
25
+ export declare function hasPending(expr: GridPredicateExpr | null): boolean;
26
+ export {};
@@ -0,0 +1,71 @@
1
+ import { enableAdvancedFilter } from '../advanced-filter-enable.js';
2
+ import { registerPredicateKind } from '../expressions/kinds.js';
3
+ export const PENDING_KIND = 'reviewPending';
4
+ // Weak: the review holds its source; once the review is gone, so is the entry's target.
5
+ const sources = new Map();
6
+ let registered = false;
7
+ function register() {
8
+ if (registered)
9
+ return;
10
+ registered = true;
11
+ registerPredicateKind(PENDING_KIND, {
12
+ compile: (payload) => {
13
+ const token = payload?.token ?? '';
14
+ const source = sources.get(token)?.deref();
15
+ if (!source) {
16
+ sources.delete(token);
17
+ return null;
18
+ }
19
+ return (row) => {
20
+ const id = row?.id;
21
+ return id != null && source.hasPendingRow(String(id));
22
+ };
23
+ },
24
+ describe: () => 'Has a proposed change',
25
+ });
26
+ }
27
+ /** Make a review's rows filterable; returns the token its filter node names. */
28
+ export function trackPendingSource(token, source) {
29
+ register();
30
+ enableAdvancedFilter();
31
+ sources.set(token, new WeakRef(source));
32
+ }
33
+ /** The user's expression without any of our nodes; null when nothing is left. */
34
+ export function stripPending(expr) {
35
+ if (!expr)
36
+ return null;
37
+ if (expr.kind === 'ext' && expr.type === PENDING_KIND)
38
+ return null;
39
+ if (expr.kind === 'and' || expr.kind === 'or') {
40
+ const parts = expr.parts.map(stripPending).filter((p) => p !== null);
41
+ if (!parts.length)
42
+ return null;
43
+ return parts.length === 1 && expr.kind === 'and' ? parts[0] : { ...expr, parts };
44
+ }
45
+ if (expr.kind === 'not') {
46
+ const inner = stripPending(expr.expr);
47
+ return inner ? { kind: 'not', expr: inner } : null;
48
+ }
49
+ return expr;
50
+ }
51
+ /**
52
+ * The user's expression with our node ANDed on. `nonce` changes the node, so
53
+ * the grid filters again after proposals were decided.
54
+ */
55
+ export function withPending(expr, token, nonce) {
56
+ const node = { kind: 'ext', type: PENDING_KIND, payload: { token, nonce } };
57
+ const rest = stripPending(expr);
58
+ return rest ? { kind: 'and', parts: [rest, node] } : node;
59
+ }
60
+ /** Whether an expression holds our node. */
61
+ export function hasPending(expr) {
62
+ if (!expr)
63
+ return false;
64
+ if (expr.kind === 'ext')
65
+ return expr.type === PENDING_KIND;
66
+ if (expr.kind === 'and' || expr.kind === 'or')
67
+ return expr.parts.some(hasPending);
68
+ if (expr.kind === 'not')
69
+ return hasPending(expr.expr);
70
+ return false;
71
+ }
@@ -0,0 +1 @@
1
+ export declare function registerRichCellMarks(): void;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The proposed value beside a cell the in-cell wrapper (`ghost.ts`) cannot
3
+ * take: a select, a rating, a person, a checkbox, a field type with a cell of
4
+ * its own. The grid's `cellDecor` slot draws a mark after the cell's own
5
+ * content, so the cell stays as it is and "-> Closed" follows it.
6
+ *
7
+ * Registered once, by the first review: `cellDecor` takes every cell off the
8
+ * grid's plain-text fast path, which an app without a review should not pay.
9
+ */
10
+ import { getGridExtension, registerGridExtension } from '@svgrid/grid';
11
+ import { cellProposalFor } from './card-marks.svelte.js';
12
+ import { canGhost } from './ghost.js';
13
+ import RichCellMark from './RichCellMark.svelte';
14
+ let registered = false;
15
+ export function registerRichCellMarks() {
16
+ if (registered)
17
+ return;
18
+ registered = true;
19
+ const before = getGridExtension()?.cellDecor;
20
+ registerGridExtension({
21
+ cellDecor: (ctrl, row, column) => {
22
+ const own = before?.(ctrl, row, column);
23
+ if (own)
24
+ return own;
25
+ const def = column?.columnDef;
26
+ if (!def?.field || !row || row.original === undefined)
27
+ return null;
28
+ // Cheap lookups first: this runs for every cell of every grid.
29
+ const p = cellProposalFor(ctrl?.props?.getRowId, row.original, String(row.id), def.field);
30
+ if (!p)
31
+ return null;
32
+ // The wrapper draws the proposal in cells it can wrap.
33
+ return canGhost(def, row.original?.[def.field]) ? null : RichCellMark;
34
+ },
35
+ });
36
+ }
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Change review types. A proposal is a write nobody typed (an AI result, an
3
+ * agent edit, an import, a sync) held apart from the data until a person
4
+ * accepts it. Pure types, so the clustering and the adapters stay free of
5
+ * Svelte and testable on their own.
6
+ */
7
+ /** What produced a proposal. `id` keeps two runs of the same kind apart. */
8
+ export type ProposalSource = {
9
+ kind: 'agent' | 'ai' | 'import' | 'bulk' | 'sync' | 'rule' | 'user';
10
+ id: string;
11
+ label: string;
12
+ };
13
+ export type ProposalStatus = 'pending' | 'accepted' | 'rejected' | 'stale' | 'conflict';
14
+ export type Proposal = {
15
+ id: string;
16
+ /** Only `update` in this release; inserts and deletes come later. */
17
+ op: 'update';
18
+ /** The grid's row id (its `getRowId`), never a row index. */
19
+ rowId: string;
20
+ /** The field on the row object the value is written to. */
21
+ field: string;
22
+ /** The value when the proposal was made, which is what staleness compares with. */
23
+ before: unknown;
24
+ after: unknown;
25
+ source: ProposalSource;
26
+ /** Why, in the producer's words (an AI rationale, an import file name). */
27
+ reason?: string;
28
+ /** 0..1, when the producer has one. */
29
+ confidence?: number;
30
+ createdAt: number;
31
+ status: ProposalStatus;
32
+ /** Why a proposal is stale, skipped or in conflict, for the panel. */
33
+ note?: string;
34
+ decidedBy?: string;
35
+ decidedAt?: number;
36
+ };
37
+ /** What a producer hands over: a proposal without the fields the review fills in. */
38
+ export type ProposalInput = Omit<Proposal, 'id' | 'op' | 'source' | 'createdAt' | 'status' | 'note' | 'decidedBy' | 'decidedAt'> & {
39
+ id?: string;
40
+ confidence?: number;
41
+ };
42
+ /** One batch from one producer. */
43
+ export type ChangeSet = {
44
+ id: string;
45
+ title: string;
46
+ source: ProposalSource;
47
+ createdAt: number;
48
+ proposals: Proposal[];
49
+ };
50
+ /**
51
+ * How a group's members relate. The first four are rule groups: every member
52
+ * is proven to follow the rule. The rest are judgment groups, where a person
53
+ * has to look.
54
+ */
55
+ export type GroupKind = 'whitespace' | 'case' | 'format' | 'scale' | 'same-mapping' | 'fill-empty' | 'constant-target' | 'unpatterned';
56
+ export type ProposalGroup = {
57
+ /** Stable while the group's members do not change: source, field, kind and param. */
58
+ key: string;
59
+ kind: GroupKind;
60
+ /** True for the four rule kinds. */
61
+ rule: boolean;
62
+ /** What the members share, in the detector's terms ('upper', '100', a value...). */
63
+ param: string;
64
+ label: string;
65
+ field: string;
66
+ sourceId: string;
67
+ ids: string[];
68
+ count: number;
69
+ /** Lowest and mean confidence over the members that have one; undefined when none do. */
70
+ minConfidence?: number;
71
+ avgConfidence?: number;
72
+ /** Up to five ids to look at first: the least confident, then spread across the group. */
73
+ sample: string[];
74
+ /**
75
+ * For `constant-target` and `same-mapping`: the five most common `before`
76
+ * values and how many of each, then one `other` entry for the rest.
77
+ */
78
+ beforeDistribution?: Array<{
79
+ value: unknown;
80
+ count: number;
81
+ other?: true;
82
+ }>;
83
+ };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Change review types. A proposal is a write nobody typed (an AI result, an
3
+ * agent edit, an import, a sync) held apart from the data until a person
4
+ * accepts it. Pure types, so the clustering and the adapters stay free of
5
+ * Svelte and testable on their own.
6
+ */
7
+ export {};
@@ -1,5 +1,5 @@
1
1
  /** Human-readable labels for the Enterprise surfaces that gate behind a license. */
2
- export type EnterpriseFeatureLabel = 'Export' | 'Import' | 'Print' | 'AI assistant' | 'Pivot' | 'Server-side row model' | 'Spreadsheet' | 'SvGrid Base' | 'Studio';
2
+ export type EnterpriseFeatureLabel = 'Export' | 'Import' | 'Print' | 'AI assistant' | 'Pivot' | 'Server-side row model' | 'Spreadsheet' | 'SvGrid Base' | 'Studio' | 'Change review';
3
3
  /**
4
4
  * Show the contextual upgrade prompt for `feature`. No-ops if one has already
5
5
  * been shown this session, a card is already up, or we're on the server. Safe
package/dist/version.d.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * `version.test.ts` asserts this matches `package.json`, so the two cannot drift.
12
12
  */
13
- export declare const SVGRID_VERSION = "3.1.22";
13
+ export declare const SVGRID_VERSION = "3.1.23";
14
14
  /**
15
15
  * The version of `@svgrid/grid`, which releases on its own line: enterprise is
16
16
  * on 3.1.x while the grid is on 3.0.x.
@@ -23,4 +23,4 @@ export declare const SVGRID_VERSION = "3.1.22";
23
23
  *
24
24
  * `version.test.ts` asserts this matches packages/grid/package.json.
25
25
  */
26
- export declare const GRID_VERSION = "3.0.21";
26
+ export declare const GRID_VERSION = "3.0.22";
package/dist/version.js CHANGED
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * `version.test.ts` asserts this matches `package.json`, so the two cannot drift.
12
12
  */
13
- export const SVGRID_VERSION = '3.1.22';
13
+ export const SVGRID_VERSION = '3.1.23';
14
14
  /**
15
15
  * The version of `@svgrid/grid`, which releases on its own line: enterprise is
16
16
  * on 3.1.x while the grid is on 3.0.x.
@@ -23,4 +23,4 @@ export const SVGRID_VERSION = '3.1.22';
23
23
  *
24
24
  * `version.test.ts` asserts this matches packages/grid/package.json.
25
25
  */
26
- export const GRID_VERSION = '3.0.21';
26
+ export const GRID_VERSION = '3.0.22';
@@ -0,0 +1,109 @@
1
+ //#region ../grid/dist/merges.js
2
+ var e = (e, t) => `${e}:${t}`;
3
+ function t(t) {
4
+ if (!t || t.length === 0) return null;
5
+ let n = /* @__PURE__ */ new Map(), r = [];
6
+ for (let i of t) {
7
+ let t = Math.max(1, Math.floor(i.rowSpan)), a = Math.max(1, Math.floor(i.colSpan));
8
+ if (t === 1 && a === 1) continue;
9
+ let o = {
10
+ rowIndex: i.rowIndex,
11
+ colIndex: i.colIndex,
12
+ rowSpan: t,
13
+ colSpan: a
14
+ };
15
+ r.push(o);
16
+ for (let r = o.rowIndex; r < o.rowIndex + t; r += 1) for (let t = o.colIndex; t < o.colIndex + a; t += 1) n.set(e(r, t), o);
17
+ }
18
+ return r.length ? {
19
+ list: r,
20
+ byCell: n
21
+ } : null;
22
+ }
23
+ function n(t, n, r) {
24
+ return t?.byCell.get(e(n, r));
25
+ }
26
+ function r(e, t, r) {
27
+ let i = n(e, t, r);
28
+ return !!i && (i.rowIndex !== t || i.colIndex !== r);
29
+ }
30
+ function i(e, t, r) {
31
+ let i = n(e, t, r);
32
+ return i ? {
33
+ rowIndex: i.rowIndex,
34
+ colIndex: i.colIndex
35
+ } : {
36
+ rowIndex: t,
37
+ colIndex: r
38
+ };
39
+ }
40
+ function a(e, t, r) {
41
+ let i = n(e, t, r);
42
+ return i ? {
43
+ rowIndex: i.rowIndex + i.rowSpan - 1,
44
+ colIndex: i.colIndex + i.colSpan - 1
45
+ } : {
46
+ rowIndex: t,
47
+ colIndex: r
48
+ };
49
+ }
50
+ function o(e, t) {
51
+ if (!e) return t;
52
+ let { minRow: n, maxRow: r, minCol: i, maxCol: a } = t;
53
+ for (let t = 0; t < 64; t += 1) {
54
+ let t = !1;
55
+ for (let o of e.list) {
56
+ let e = o.rowIndex + o.rowSpan - 1, s = o.colIndex + o.colSpan - 1;
57
+ o.rowIndex <= r && e >= n && o.colIndex <= a && s >= i && (o.rowIndex < n && (n = o.rowIndex, t = !0), e > r && (r = e, t = !0), o.colIndex < i && (i = o.colIndex, t = !0), s > a && (a = s, t = !0));
58
+ }
59
+ if (!t) break;
60
+ }
61
+ return n === t.minRow && r === t.maxRow && i === t.minCol && a === t.maxCol ? t : {
62
+ minRow: n,
63
+ maxRow: r,
64
+ minCol: i,
65
+ maxCol: a
66
+ };
67
+ }
68
+ function s(e, t, r, i) {
69
+ if (!e) return r;
70
+ let a = n(e, r.rowIndex, r.colIndex);
71
+ if (!a) return r;
72
+ if (n(e, t.rowIndex, t.colIndex) !== a) return {
73
+ rowIndex: a.rowIndex,
74
+ colIndex: a.colIndex
75
+ };
76
+ let o = Math.sign(r.rowIndex - t.rowIndex), s = Math.sign(r.colIndex - t.colIndex);
77
+ if (o === 0 && s === 0) return {
78
+ rowIndex: a.rowIndex,
79
+ colIndex: a.colIndex
80
+ };
81
+ let c = r.rowIndex, l = r.colIndex;
82
+ if (o > 0 ? c = a.rowIndex + a.rowSpan : o < 0 && (c = a.rowIndex - 1), s > 0 ? l = a.colIndex + a.colSpan : s < 0 && (l = a.colIndex - 1), c < 0 || c > i.maxRow || l < 0 || l > i.maxCol) return {
83
+ rowIndex: a.rowIndex,
84
+ colIndex: a.colIndex
85
+ };
86
+ let u = n(e, c, l);
87
+ return u ? {
88
+ rowIndex: u.rowIndex,
89
+ colIndex: u.colIndex
90
+ } : {
91
+ rowIndex: c,
92
+ colIndex: l
93
+ };
94
+ }
95
+ function c(e, t, r, i) {
96
+ let a = n(e, t, r);
97
+ if (!a) return null;
98
+ let o = Math.max(a.rowIndex, i.firstRow), s = Math.max(a.colIndex, i.firstCol);
99
+ if (t !== o || r !== s) return { kind: "skip" };
100
+ let c = o === a.rowIndex && s === a.colIndex, l = Math.max(1, Math.min(a.rowIndex + a.rowSpan - t, i.lastRow - t + 1)), u = Math.max(1, Math.min(a.colIndex + a.colSpan - r, i.lastCol - r + 1));
101
+ return {
102
+ kind: c ? "origin" : "continuation",
103
+ merge: a,
104
+ rowSpan: l,
105
+ colSpan: u
106
+ };
107
+ }
108
+ //#endregion
109
+ export { t as buildMergeIndex, a as endOf, o as expandRectToMerges, r as isCovered, n as mergeAt, c as mergeDrawAt, i as originOf, s as stepPastMerge };