@ai-matrx/records-ui 0.93.140 → 0.93.146
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/CHANGELOG.md +76 -0
- package/dist/index.cjs +2147 -1574
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +71 -40
- package/dist/index.d.ts +71 -40
- package/dist/index.js +2094 -1522
- package/dist/index.js.map +1 -1
- package/dist/object-actions.cjs +127 -28
- package/dist/object-actions.cjs.map +1 -1
- package/dist/object-actions.d.cts +1 -1
- package/dist/object-actions.d.ts +1 -1
- package/dist/object-actions.js +125 -26
- package/dist/object-actions.js.map +1 -1
- package/dist/{objectActions-BSbblgf-.d.cts → objectActions-Dgdr0E4b.d.cts} +52 -11
- package/dist/{objectActions-BSbblgf-.d.ts → objectActions-Dgdr0E4b.d.ts} +52 -11
- package/dist/pickers.cjs +76 -28
- package/dist/pickers.cjs.map +1 -1
- package/dist/pickers.d.cts +12 -1
- package/dist/pickers.d.ts +12 -1
- package/dist/pickers.js +76 -28
- package/dist/pickers.js.map +1 -1
- package/dist/table-shape.cjs +3 -9
- package/dist/table-shape.cjs.map +1 -1
- package/dist/table-shape.js +3 -9
- package/dist/table-shape.js.map +1 -1
- package/package.json +2 -2
|
@@ -42,12 +42,18 @@ declare function whatYouMayDoWithTable(table: Table | null | undefined, level: P
|
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* A Lucide icon NAME, kebab-case — the same currency `Table.icon` already uses.
|
|
45
|
-
* Closed on purpose: each renderer maps every member to its own
|
|
45
|
+
* Closed on purpose: each renderer maps every member to its own glyph, and a
|
|
46
46
|
* new member fails that renderer's typecheck until it is mapped.
|
|
47
47
|
*/
|
|
48
48
|
type ObjectActionIcon = "folder-open" | "external-link" | "link" | "pencil" | "copy" | "folder-input" | "star" | "star-off" | "share-2" | "download" | "upload" | "columns-3" | "settings" | "history" | "blocks" | "file-text" | "calendar-clock" | "list-checks" | "bell" | "door-open" | "inbox" | "layout-dashboard" | "archive-restore" | "archive" | "link-2" | "layout-grid";
|
|
49
49
|
/** The groups, in their one order. Separators fall out of group boundaries. */
|
|
50
50
|
type ObjectActionGroup = "open" | "organize" | "share" | "manage" | "built-on" | "danger";
|
|
51
|
+
/**
|
|
52
|
+
* THE STANDARD VERBS every object's menu shares — what the icon strip draws. One
|
|
53
|
+
* per meaning; an object maps its action onto the verb, never a second "share".
|
|
54
|
+
*/
|
|
55
|
+
type StandardVerbId = "open" | "open-new-tab" | "copy-link" | "rename" | "duplicate" | "move" | "favorite" | "share" | "export" | "import" | "settings" | "history" | "archive";
|
|
56
|
+
declare const STANDARD_VERBS: readonly StandardVerbId[];
|
|
51
57
|
interface ObjectActionGroupDef {
|
|
52
58
|
id: ObjectActionGroup;
|
|
53
59
|
/** Present only on a group that renders as a submenu. */
|
|
@@ -64,6 +70,10 @@ interface ObjectAction {
|
|
|
64
70
|
label: string;
|
|
65
71
|
icon: ObjectActionIcon;
|
|
66
72
|
group: ObjectActionGroup;
|
|
73
|
+
/** The standard verb this action IS (a strip icon). Absent = a feature row. */
|
|
74
|
+
verb?: StandardVerbId;
|
|
75
|
+
/** A feature row's place among the rows, 1 first. Ignored when `verb` is set. */
|
|
76
|
+
rank?: number;
|
|
67
77
|
/** Display-only hint ("⌘D"). */
|
|
68
78
|
shortcut?: string;
|
|
69
79
|
destructive?: boolean;
|
|
@@ -101,14 +111,26 @@ interface TableActionHost {
|
|
|
101
111
|
addColumn?: Handler;
|
|
102
112
|
settings?: Handler;
|
|
103
113
|
history?: Handler;
|
|
114
|
+
/** Make the layout on screen the table's default. Leave out when it already is. */
|
|
115
|
+
makeDefault?: Handler;
|
|
116
|
+
/** The layout on screen, for "Make Kanban the default". */
|
|
117
|
+
layoutLabel?: string;
|
|
104
118
|
/** The "Built on it" destinations, one handler for all eight. */
|
|
105
119
|
openBuiltOn?: (destination: BuiltOnDestination, table: TableActionSubject) => void;
|
|
106
120
|
archive?: Handler;
|
|
107
121
|
/**
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
|
|
122
|
+
* Why an action whose handler is left out is unavailable here, by action id
|
|
123
|
+
* (≤ 60 chars) — e.g. `make-default: "Already the default"`. Unnamed ids say
|
|
124
|
+
* "Not available here". Never used when rights already refuse.
|
|
125
|
+
*/
|
|
126
|
+
unavailableReasons?: Readonly<Record<string, string>>;
|
|
127
|
+
/**
|
|
128
|
+
* ANOTHER LANE'S ENTRIES ("Link a record…", a hub tile's verbs, a feature's own
|
|
129
|
+
* row such as "When a row changes, run an agent…"). Return the same ids whatever
|
|
130
|
+
* `rights` say — express rights as `disabledReason`. Each entry lands at the END
|
|
131
|
+
* of its named group, in the order returned. Refused, loudly: the `danger` group
|
|
132
|
+
* (Archive is always last), a group that does not exist, and an id already in
|
|
133
|
+
* the list.
|
|
112
134
|
*/
|
|
113
135
|
extend?: (table: TableActionSubject, rights: WhatYouMayDo) => readonly ObjectAction[];
|
|
114
136
|
}
|
|
@@ -127,14 +149,15 @@ declare const ACTION_PLATFORM_TABLE_REASON = "Platform tables can't be changed h
|
|
|
127
149
|
/** Why `rights` refuse `what`, in one short line — or null when they allow it. */
|
|
128
150
|
declare function rightsReason(rights: WhatYouMayDo, what: Capability, table?: TableActionSubject): string | null;
|
|
129
151
|
/**
|
|
130
|
-
* THE TABLE'S ACTIONS, in the one order. Same ids, same order,
|
|
131
|
-
* and every host — only `disabledReason` varies.
|
|
152
|
+
* THE TABLE'S ACTIONS, in the one order. Same ids, same order, same verbs and
|
|
153
|
+
* ranks, for every seat and every host — only `disabledReason` varies.
|
|
132
154
|
*/
|
|
133
155
|
declare function tableActions(input: TableActionsInput): ObjectAction[];
|
|
134
156
|
/**
|
|
135
157
|
* Another lane's entries, placed deterministically: each at the end of its
|
|
136
|
-
* group, in the order given. Loud on
|
|
137
|
-
* invariants — a `danger` entry (Archive must stay last)
|
|
158
|
+
* group, in the order given. Loud on every mistake that would break the
|
|
159
|
+
* invariants — a `danger` entry (Archive must stay last), a group that does not
|
|
160
|
+
* exist (it would be dropped by every renderer) and a duplicate id.
|
|
138
161
|
*/
|
|
139
162
|
declare function withExtensions(base: readonly ObjectAction[], extra: readonly ObjectAction[]): ObjectAction[];
|
|
140
163
|
/** A run of actions that renders together: a plain section, or one submenu. */
|
|
@@ -162,7 +185,25 @@ type ObjectActionDropdownEntry = {
|
|
|
162
185
|
actions: ObjectAction[];
|
|
163
186
|
};
|
|
164
187
|
declare function toDropdownEntries(actions: readonly ObjectAction[]): ObjectActionDropdownEntry[];
|
|
165
|
-
/** The
|
|
188
|
+
/** The actions a dropdown draws, in order — what G1 compares. */
|
|
189
|
+
declare function dropdownActions(entries: readonly ObjectActionDropdownEntry[]): ObjectAction[];
|
|
190
|
+
/** The action ids a dropdown draws, in order. */
|
|
166
191
|
declare function dropdownActionIds(entries: readonly ObjectActionDropdownEntry[]): string[];
|
|
192
|
+
/** The icon-strip menu: standard verbs as icons, then the first feature rows, then the rest. */
|
|
193
|
+
interface StripAndRows {
|
|
194
|
+
/** Every action with a `verb`, in the list's order. */
|
|
195
|
+
strip: ObjectAction[];
|
|
196
|
+
/** The first `rowCount` feature actions by rank (ties keep list order). */
|
|
197
|
+
rows: ObjectAction[];
|
|
198
|
+
/** The remaining feature actions, behind "More … options", same ordering. */
|
|
199
|
+
more: ObjectAction[];
|
|
200
|
+
}
|
|
201
|
+
declare const STRIP_FEATURE_ROWS = 4;
|
|
202
|
+
/**
|
|
203
|
+
* THE STRIP RENDERER'S SPLIT of the same list. Nothing is added or dropped: every
|
|
204
|
+
* id lands in exactly one of strip / rows / more (G1). Unranked feature actions
|
|
205
|
+
* (an extension that gave none) follow every ranked one.
|
|
206
|
+
*/
|
|
207
|
+
declare function toStripAndRows(actions: readonly ObjectAction[], rowCount?: number): StripAndRows;
|
|
167
208
|
|
|
168
|
-
export { ACTION_CHECKING_ACCESS_REASON as A, type BuiltOnDestination as B, type Capability as C, DEFAULT_ACTION_ORIGIN as D, KERNEL_REASON as K, LEVEL_WORD as L, NOT_ANSWERED_YET as N, type ObjectAction as O, type TableActionHost as T, type WhatYouMayDo as W,
|
|
209
|
+
export { ACTION_CHECKING_ACCESS_REASON as A, type BuiltOnDestination as B, type Capability as C, DEFAULT_ACTION_ORIGIN as D, KERNEL_REASON as K, LEVEL_WORD as L, NOT_ANSWERED_YET as N, type ObjectAction as O, STANDARD_VERBS as S, type TableActionHost as T, type WhatYouMayDo as W, type ObjectActionIcon as a, ACTION_NOT_HERE_REASON as b, ACTION_NO_ACCESS_REASON as c, ACTION_PLATFORM_TABLE_REASON as d, OBJECT_ACTION_GROUPS as e, type ObjectActionDropdownEntry as f, type ObjectActionGroup as g, type ObjectActionGroupDef as h, type ObjectActionSection as i, STRIP_FEATURE_ROWS as j, type StandardVerbId as k, type StripAndRows as l, type TableActionSubject as m, type TableActionsInput as n, dropdownActionIds as o, dropdownActions as p, groupObjectActions as q, levelNeededFor as r, rightsReason as s, tableActions as t, tableLink as u, toDropdownEntries as v, toStripAndRows as w, whatYouMayDo as x, whatYouMayDoWithTable as y, withExtensions as z };
|
package/dist/pickers.cjs
CHANGED
|
@@ -26,6 +26,7 @@ __export(pickers_exports, {
|
|
|
26
26
|
DATA_BINDING_MISSING: () => DATA_BINDING_MISSING,
|
|
27
27
|
DATA_BINDING_SHAPES: () => DATA_BINDING_SHAPES,
|
|
28
28
|
DataBindingPicker: () => DataBindingPicker,
|
|
29
|
+
HeldChangeDecision: () => HeldChangeDecision,
|
|
29
30
|
RecordNameText: () => RecordNameText,
|
|
30
31
|
RecordPicker: () => RecordPicker,
|
|
31
32
|
TableNameText: () => TableNameText,
|
|
@@ -407,21 +408,35 @@ function BarcodeControl({ value, onChange, disabled, id }) {
|
|
|
407
408
|
|
|
408
409
|
// src/parity.ts
|
|
409
410
|
var import_records2 = require("@ai-matrx/records");
|
|
411
|
+
var import_text_case = require("@ai-matrx/kit/text-case");
|
|
412
|
+
|
|
413
|
+
// src/docs.ts
|
|
414
|
+
function isSignatureField(field) {
|
|
415
|
+
return field.type === "text" && (field.format ?? "").toLowerCase() === "signature";
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// src/parity.ts
|
|
419
|
+
var kernelId = (name) => import_records2.KERNEL_TABLES.find((t) => t.name === name)?.id ?? "";
|
|
420
|
+
var KERNEL_FILE_TABLE = kernelId("File");
|
|
421
|
+
var KERNEL_PERSON_TABLE = kernelId("Person");
|
|
422
|
+
var PARITY_MADE_OF = Object.fromEntries(
|
|
423
|
+
import_records2.PARITY_FIELD_TYPES.map((p) => [p.parity_type, p.made_of])
|
|
424
|
+
);
|
|
425
|
+
var KERNEL = { file: KERNEL_FILE_TABLE, person: KERNEL_PERSON_TABLE };
|
|
426
|
+
function editorKindFor(field) {
|
|
427
|
+
return (0, import_records2.fieldKindFor)(field, KERNEL);
|
|
428
|
+
}
|
|
410
429
|
|
|
411
430
|
// src/names.ts
|
|
412
431
|
var import_uuid = require("@ai-matrx/kit/uuid");
|
|
413
|
-
|
|
414
|
-
const words = token.replace(/[_\-.]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").trim();
|
|
415
|
-
if (words === "") return token;
|
|
416
|
-
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
417
|
-
}
|
|
432
|
+
var import_text_case2 = require("@ai-matrx/kit/text-case");
|
|
418
433
|
function fieldName(field) {
|
|
419
434
|
const label = (field.label ?? "").trim();
|
|
420
|
-
if (label !== "" && label === field.key && /^[a-z0-9]+(?:[_.-][a-z0-9]+)+$/.test(label)) return
|
|
435
|
+
if (label !== "" && label === field.key && /^[a-z0-9]+(?:[_.-][a-z0-9]+)+$/.test(label)) return (0, import_text_case2.humanizeIdentifier)(label);
|
|
421
436
|
if (label !== "") return label;
|
|
422
437
|
const name = (field.name ?? "").trim();
|
|
423
438
|
if (name !== "") return name;
|
|
424
|
-
return
|
|
439
|
+
return (0, import_text_case2.humanizeIdentifier)(field.key);
|
|
425
440
|
}
|
|
426
441
|
function recordName(document2, titleKey, fallback = "Untitled") {
|
|
427
442
|
const data = document2 ?? {};
|
|
@@ -444,23 +459,7 @@ function rowNameIn(table, row, fallback = "Untitled") {
|
|
|
444
459
|
return recordName(row?.document, table?.title_field ?? null, fallback);
|
|
445
460
|
}
|
|
446
461
|
var WITHHELD_RECORD_LABEL = "A record you have not been given access to";
|
|
447
|
-
|
|
448
|
-
// src/docs.ts
|
|
449
|
-
function isSignatureField(field) {
|
|
450
|
-
return field.type === "text" && (field.format ?? "").toLowerCase() === "signature";
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
// src/parity.ts
|
|
454
|
-
var kernelId = (name) => import_records2.KERNEL_TABLES.find((t) => t.name === name)?.id ?? "";
|
|
455
|
-
var KERNEL_FILE_TABLE = kernelId("File");
|
|
456
|
-
var KERNEL_PERSON_TABLE = kernelId("Person");
|
|
457
|
-
var PARITY_MADE_OF = Object.fromEntries(
|
|
458
|
-
import_records2.PARITY_FIELD_TYPES.map((p) => [p.parity_type, p.made_of])
|
|
459
|
-
);
|
|
460
|
-
var KERNEL = { file: KERNEL_FILE_TABLE, person: KERNEL_PERSON_TABLE };
|
|
461
|
-
function editorKindFor(field) {
|
|
462
|
-
return (0, import_records2.fieldKindFor)(field, KERNEL);
|
|
463
|
-
}
|
|
462
|
+
var UNREAD_RECORD_LABEL = "Couldn't load this name";
|
|
464
463
|
|
|
465
464
|
// src/RelationPicker.tsx
|
|
466
465
|
var import_react3 = require("react");
|
|
@@ -943,7 +942,7 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
|
|
|
943
942
|
const learned = {};
|
|
944
943
|
for (const id2 of wanted) {
|
|
945
944
|
const said = result.ok ? result.data[id2] : void 0;
|
|
946
|
-
learned[id2] = typeof said === "string" && said !== "" ? said : WITHHELD_RECORD_LABEL;
|
|
945
|
+
learned[id2] = !result.ok ? UNREAD_RECORD_LABEL : typeof said === "string" && said !== "" ? said : WITHHELD_RECORD_LABEL;
|
|
947
946
|
}
|
|
948
947
|
setWords((current) => ({ ...current, ...learned }));
|
|
949
948
|
});
|
|
@@ -1538,7 +1537,7 @@ function RecordLabelProvider({ children }) {
|
|
|
1538
1537
|
});
|
|
1539
1538
|
for (const id of wanted) {
|
|
1540
1539
|
const words = result.ok ? result.data[id] : void 0;
|
|
1541
|
-
learned[id] = typeof words === "string" && words !== "" ? words : WITHHELD_RECORD_LABEL;
|
|
1540
|
+
learned[id] = !result.ok ? UNREAD_RECORD_LABEL : typeof words === "string" && words !== "" ? words : WITHHELD_RECORD_LABEL;
|
|
1542
1541
|
}
|
|
1543
1542
|
if (result.ok) for (const id of result.archived ?? []) archivedNow[`${field.id}:${id}`] = true;
|
|
1544
1543
|
})
|
|
@@ -4190,6 +4189,7 @@ var import_design_system18 = require("@ai-matrx/design-system");
|
|
|
4190
4189
|
|
|
4191
4190
|
// src/kindValues.ts
|
|
4192
4191
|
var import_directives = require("@ai-matrx/content-ir/directives");
|
|
4192
|
+
var import_text_case3 = require("@ai-matrx/kit/text-case");
|
|
4193
4193
|
var KIND_KEY = "__kind";
|
|
4194
4194
|
var WHOLE_FENCE = /^\s*```(?:matrx|json)?[ \t]*\r?\n?([\s\S]*?)\r?\n?[ \t]*```\s*$/;
|
|
4195
4195
|
function asObject(value) {
|
|
@@ -4235,8 +4235,7 @@ function kindValueWords(kv) {
|
|
|
4235
4235
|
return kindLabel(kv.kind);
|
|
4236
4236
|
}
|
|
4237
4237
|
function kindLabel(kind) {
|
|
4238
|
-
|
|
4239
|
-
return words ? words.charAt(0).toUpperCase() + words.slice(1) : "Structured value";
|
|
4238
|
+
return (0, import_text_case3.humanizeIdentifier)(kind.replace(/^directive_v\d+_/, "").replace(/_v\d+$/, "")) || "Structured value";
|
|
4240
4239
|
}
|
|
4241
4240
|
|
|
4242
4241
|
// src/ReferenceChips.tsx
|
|
@@ -4484,6 +4483,7 @@ function TableNameText({ dataSource, tableId }) {
|
|
|
4484
4483
|
const tables = useTablesAnywhere(dataSource);
|
|
4485
4484
|
if (!tableId) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "\u2014" });
|
|
4486
4485
|
if (tables.loading) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "\u2026" });
|
|
4486
|
+
if (tables.error) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "Couldn't load the table's name" });
|
|
4487
4487
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: tables.rows.find((t) => t.table_id === tableId)?.table_name ?? "\u2014" });
|
|
4488
4488
|
}
|
|
4489
4489
|
function ColumnValuesText({
|
|
@@ -4499,8 +4499,10 @@ function ColumnValuesWords({ tableId, value }) {
|
|
|
4499
4499
|
const fields = (0, import_react33.useFields)(tableId);
|
|
4500
4500
|
const labels = useRecordLabels(fields.data ?? void 0);
|
|
4501
4501
|
if (fields.loading) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "\u2026" });
|
|
4502
|
+
if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "Couldn't load this table's columns" });
|
|
4502
4503
|
const parts = [];
|
|
4503
4504
|
for (const [key, stored] of Object.entries(value)) {
|
|
4505
|
+
if (key.startsWith("_")) continue;
|
|
4504
4506
|
const field = (fields.data ?? []).find((f) => f.key === key);
|
|
4505
4507
|
if (parts.length) parts.push(/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: ", " }, `${key}-sep`));
|
|
4506
4508
|
parts.push(
|
|
@@ -4526,7 +4528,53 @@ function RecordNameWords({ tableId, recordId }) {
|
|
|
4526
4528
|
const table = (0, import_react33.useTable)(tableId);
|
|
4527
4529
|
const record = (0, import_react33.useRecord)(recordId);
|
|
4528
4530
|
if (record.loading || table.loading) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "\u2026" });
|
|
4531
|
+
if (record.error) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "Couldn't load this record" });
|
|
4529
4532
|
if (!record.data) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "A record you cannot open" });
|
|
4530
4533
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: recordName(record.data.document, table.data?.title_field ?? null) });
|
|
4531
4534
|
}
|
|
4535
|
+
|
|
4536
|
+
// src/HeldChangeDecision.tsx
|
|
4537
|
+
var import_react34 = require("react");
|
|
4538
|
+
var import_react35 = require("@ai-matrx/records/react");
|
|
4539
|
+
var import_design_system20 = require("@ai-matrx/design-system");
|
|
4540
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
4541
|
+
function HeldChangeDecision({ dataSource, userId, organizationId, approvalId, onDecided }) {
|
|
4542
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react35.RecordsProvider, { config: { dataSource, actor: personActor(userId), organizationId }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Decision, { approvalId, onDecided }) });
|
|
4543
|
+
}
|
|
4544
|
+
function Decision({ approvalId, onDecided }) {
|
|
4545
|
+
const client = (0, import_react35.useRecordsClient)();
|
|
4546
|
+
const [may, setMay] = (0, import_react34.useState)(null);
|
|
4547
|
+
const [busy, setBusy] = (0, import_react34.useState)(null);
|
|
4548
|
+
const [error, setError] = (0, import_react34.useState)(null);
|
|
4549
|
+
(0, import_react34.useEffect)(() => {
|
|
4550
|
+
let live = true;
|
|
4551
|
+
void client.workApprovalMayDecide({ approval_id: approvalId }).then((res) => {
|
|
4552
|
+
if (!live) return;
|
|
4553
|
+
if (res.ok) setMay(res.data);
|
|
4554
|
+
else {
|
|
4555
|
+
setMay(false);
|
|
4556
|
+
setError(res.error);
|
|
4557
|
+
}
|
|
4558
|
+
});
|
|
4559
|
+
return () => {
|
|
4560
|
+
live = false;
|
|
4561
|
+
};
|
|
4562
|
+
}, [client, approvalId]);
|
|
4563
|
+
const decide = async (approve) => {
|
|
4564
|
+
setBusy(approve ? "approve" : "refuse");
|
|
4565
|
+
setError(null);
|
|
4566
|
+
const res = await client.workApprovalDecide({ approval_id: approvalId, approve });
|
|
4567
|
+
setBusy(null);
|
|
4568
|
+
if (res.ok) onDecided(approve);
|
|
4569
|
+
else setError(res.error);
|
|
4570
|
+
};
|
|
4571
|
+
if (may === null) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-muted-foreground", children: "Checking who can decide\u2026" });
|
|
4572
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
|
|
4573
|
+
may ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex gap-2", children: [
|
|
4574
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_design_system20.Button, { type: "button", size: "sm", disabled: busy !== null, onClick: () => void decide(true), children: busy === "approve" ? "Approving\u2026" : "Approve" }),
|
|
4575
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_design_system20.Button, { type: "button", size: "sm", variant: "outline", disabled: busy !== null, onClick: () => void decide(false), children: busy === "refuse" ? "Refusing\u2026" : "Refuse" })
|
|
4576
|
+
] }) : !error && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-muted-foreground", children: "An owner or admin of this organization decides this." }),
|
|
4577
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(RefusalLine, { error }) : null
|
|
4578
|
+
] });
|
|
4579
|
+
}
|
|
4532
4580
|
//# sourceMappingURL=pickers.cjs.map
|