@ai-matrx/records-ui 0.115.34 → 0.115.36
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 +12 -0
- package/dist/first-page.cjs +18 -2
- package/dist/first-page.cjs.map +1 -1
- package/dist/first-page.d.cts +14 -21
- package/dist/first-page.d.ts +14 -21
- package/dist/first-page.js +18 -2
- package/dist/first-page.js.map +1 -1
- package/dist/index.cjs +6958 -5841
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +70 -29
- package/dist/index.d.ts +70 -29
- package/dist/index.js +5914 -4793
- package/dist/index.js.map +1 -1
- package/dist/pickers.cjs +412 -411
- package/dist/pickers.cjs.map +1 -1
- package/dist/pickers.js +374 -373
- package/dist/pickers.js.map +1 -1
- package/package.json +2 -2
package/dist/pickers.cjs
CHANGED
|
@@ -52,9 +52,9 @@ var askOnce_exports = {};
|
|
|
52
52
|
__reExport(askOnce_exports, require("@ai-matrx/records/versions"));
|
|
53
53
|
|
|
54
54
|
// src/AddChoicesInline.tsx
|
|
55
|
-
var
|
|
56
|
-
var
|
|
57
|
-
var
|
|
55
|
+
var import_react6 = require("react");
|
|
56
|
+
var import_react7 = require("@ai-matrx/records/react");
|
|
57
|
+
var import_design_system4 = require("@ai-matrx/design-system");
|
|
58
58
|
|
|
59
59
|
// src/ChoiceListEditor.tsx
|
|
60
60
|
var import_react = require("react");
|
|
@@ -576,14 +576,285 @@ function ChoiceSwatch({ words, color, onColor }) {
|
|
|
576
576
|
] });
|
|
577
577
|
}
|
|
578
578
|
|
|
579
|
-
// src/
|
|
579
|
+
// src/Refusal.tsx
|
|
580
|
+
var import_core = require("@ai-matrx/records/core");
|
|
581
|
+
var import_design_system3 = require("@ai-matrx/design-system");
|
|
582
|
+
|
|
583
|
+
// src/ArchivedOrganizationNotice.tsx
|
|
584
|
+
var import_react5 = require("react");
|
|
585
|
+
var import_design_system2 = require("@ai-matrx/design-system");
|
|
586
|
+
|
|
587
|
+
// src/host.tsx
|
|
588
|
+
var import_react3 = require("react");
|
|
589
|
+
var import_react4 = require("@ai-matrx/records/react");
|
|
590
|
+
|
|
591
|
+
// src/rights.ts
|
|
592
|
+
var import_records3 = require("@ai-matrx/records");
|
|
593
|
+
var LEVEL_WORD = {
|
|
594
|
+
viewer: "Viewer",
|
|
595
|
+
commenter: "Commenter",
|
|
596
|
+
edit_content: "Content editor",
|
|
597
|
+
editor: "Editor",
|
|
598
|
+
admin: "Admin"
|
|
599
|
+
};
|
|
600
|
+
var NEEDS = {
|
|
601
|
+
read: "viewer",
|
|
602
|
+
// custom.io_comment_write
|
|
603
|
+
comment: "commenter",
|
|
604
|
+
// custom.record_update / custom.record_write — `edit_content` changes rows and page content;
|
|
605
|
+
// columns, views and settings (structure) stay with admin below, and sharing with admin.
|
|
606
|
+
write: "edit_content",
|
|
607
|
+
// custom.view_designate / view_declare / migrate_merge / record_restore — all ask `editor`: more than
|
|
608
|
+
// changing content (`edit_content`), less than changing columns (`admin`).
|
|
609
|
+
organise: "editor",
|
|
610
|
+
// custom.record_delete
|
|
611
|
+
remove: "editor",
|
|
612
|
+
// custom.share_grant — passing your access on is an administrator's right
|
|
613
|
+
share: "admin",
|
|
614
|
+
// custom.field_declare / field_update / field_retire / table settings
|
|
615
|
+
structure: "admin"
|
|
616
|
+
};
|
|
617
|
+
var NOT_YET = "Still asking the store what you may do here. Nothing is offered until it has answered.";
|
|
618
|
+
var NOTHING_AT_ALL = "You have not been given this. Ask somebody who administers it to share it with you.";
|
|
619
|
+
function sentenceFor(what, level) {
|
|
620
|
+
if (level === null) return NOTHING_AT_ALL;
|
|
621
|
+
const need = LEVEL_WORD[NEEDS[what]];
|
|
622
|
+
const have = LEVEL_WORD[level];
|
|
623
|
+
const doing = {
|
|
624
|
+
read: "open this",
|
|
625
|
+
comment: "leave a comment",
|
|
626
|
+
write: "change anything here",
|
|
627
|
+
organise: "organise this",
|
|
628
|
+
remove: "delete this",
|
|
629
|
+
share: "pass this on to somebody else",
|
|
630
|
+
structure: "change the columns of this table"
|
|
631
|
+
};
|
|
632
|
+
return `You are ${have} here, and it takes ${need} to ${doing[what]}. Ask somebody who is Admin on it to move you up.`;
|
|
633
|
+
}
|
|
634
|
+
function whatYouMayDo(level, known = true) {
|
|
635
|
+
const may = (what) => known && (0, import_records3.atLeast)(level, NEEDS[what]);
|
|
636
|
+
return {
|
|
637
|
+
level: known ? level : null,
|
|
638
|
+
known,
|
|
639
|
+
read: may("read"),
|
|
640
|
+
comment: may("comment"),
|
|
641
|
+
write: may("write"),
|
|
642
|
+
organise: may("organise"),
|
|
643
|
+
remove: may("remove"),
|
|
644
|
+
share: may("share"),
|
|
645
|
+
structure: may("structure"),
|
|
646
|
+
why: (what) => known ? sentenceFor(what, level) : NOT_YET
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
var NOT_ANSWERED_YET = whatYouMayDo(null, false);
|
|
650
|
+
var KERNEL_REASON = "This is one of the tables the platform ships, so its columns are not changed from a screen. Make your own table to change columns.";
|
|
651
|
+
function whatYouMayDoWithTable(table, level, known) {
|
|
652
|
+
const base = whatYouMayDo(level, known);
|
|
653
|
+
if (!table?.is_kernel) return table && tableIsLocked(table) ? lockedStructure(base) : base;
|
|
654
|
+
return {
|
|
655
|
+
...base,
|
|
656
|
+
structure: false,
|
|
657
|
+
why: (what) => what === "structure" ? KERNEL_REASON : base.why(what)
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
function tableIsLocked(table) {
|
|
661
|
+
return table?.metadata?.["locked"] === true;
|
|
662
|
+
}
|
|
663
|
+
var DATABASE_LOCKED_REASON = "This database is locked, so its columns and settings are read-only. Unlock it to change them.";
|
|
664
|
+
function lockedStructure(base) {
|
|
665
|
+
return { ...base, structure: false, why: (what) => what === "structure" ? DATABASE_LOCKED_REASON : base.why(what) };
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// src/host.tsx
|
|
580
669
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
670
|
+
function tableRights(may, overallReason) {
|
|
671
|
+
return {
|
|
672
|
+
...may,
|
|
673
|
+
admin: may.structure,
|
|
674
|
+
reason: overallReason ?? (may.structure ? "" : may.why("structure"))
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
var NO_RIGHTS = tableRights(NOT_ANSWERED_YET);
|
|
678
|
+
var NO_MEMBERS_REASON = "This app cannot offer the people in your organization on this screen yet, so there is nobody to pick. Type the person's name into a text field for now, and tell us \u2014 it is on our list, not yours.";
|
|
679
|
+
var NO_UPLOAD_REASON = "This screen cannot take a file yet, so there is no chooser here rather than one that loses what you pick. Put a link to the file in a text field for now. It is on our list, not yours.";
|
|
680
|
+
var HostContext = (0, import_react3.createContext)(null);
|
|
681
|
+
function useRecordsUi() {
|
|
682
|
+
return (0, import_react3.useContext)(HostContext) ?? {};
|
|
683
|
+
}
|
|
684
|
+
function quiet(may, say) {
|
|
685
|
+
if (say !== false) return may;
|
|
686
|
+
return { ...may, why: () => "", ..."reason" in may ? { reason: "" } : {} };
|
|
687
|
+
}
|
|
688
|
+
function useTableRights(table) {
|
|
689
|
+
const host = useRecordsUi();
|
|
690
|
+
const asked2 = useTableRightsAsked(table, host);
|
|
691
|
+
return (0, import_react3.useMemo)(() => quiet(asked2, host.sayLevelNeeded), [asked2, host.sayLevelNeeded]);
|
|
692
|
+
}
|
|
693
|
+
function useTableRightsAsked(table, host) {
|
|
694
|
+
const bound = Boolean(host.rights);
|
|
695
|
+
const asked2 = (0, import_react4.useMyLevel)(bound || !table ? null : table.id);
|
|
696
|
+
return (0, import_react3.useMemo)(() => {
|
|
697
|
+
if (!table) return NO_RIGHTS;
|
|
698
|
+
if (host.rights) return host.rights(table);
|
|
699
|
+
if (asked2.loading) return tableRights(NOT_ANSWERED_YET);
|
|
700
|
+
const level = asked2.error ? null : asked2.data;
|
|
701
|
+
return tableRights(whatYouMayDoWithTable(table, level, true));
|
|
702
|
+
}, [host, table, bound, asked2.loading, asked2.error, asked2.data]);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
// src/ArchivedOrganizationNotice.tsx
|
|
706
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
707
|
+
function ArchivedOrganizationNotice({
|
|
708
|
+
organizationId,
|
|
709
|
+
error,
|
|
710
|
+
className
|
|
711
|
+
}) {
|
|
712
|
+
const port = useRecordsUi().archivedOrganization;
|
|
713
|
+
const [mayRestore, setMayRestore] = (0, import_react5.useState)(null);
|
|
714
|
+
const [busy, setBusy] = (0, import_react5.useState)(false);
|
|
715
|
+
const [failed, setFailed] = (0, import_react5.useState)(null);
|
|
716
|
+
(0, import_react5.useEffect)(() => {
|
|
717
|
+
let live = true;
|
|
718
|
+
if (!port) {
|
|
719
|
+
setMayRestore(false);
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
setMayRestore(null);
|
|
723
|
+
port.state(organizationId).then((answer) => {
|
|
724
|
+
if (live) setMayRestore(answer?.mayRestore === true);
|
|
725
|
+
}).catch(() => {
|
|
726
|
+
if (live) setMayRestore(false);
|
|
727
|
+
});
|
|
728
|
+
return () => {
|
|
729
|
+
live = false;
|
|
730
|
+
};
|
|
731
|
+
}, [organizationId, port?.state]);
|
|
732
|
+
const restore = async () => {
|
|
733
|
+
if (!port || busy) return;
|
|
734
|
+
setBusy(true);
|
|
735
|
+
setFailed(null);
|
|
736
|
+
try {
|
|
737
|
+
await port.restore(organizationId);
|
|
738
|
+
if (port.afterRestore) port.afterRestore();
|
|
739
|
+
else if (typeof window !== "undefined") window.location.reload();
|
|
740
|
+
} catch (thrown) {
|
|
741
|
+
setFailed(thrown instanceof Error && thrown.message ? thrown.message : "The organization could not be restored.");
|
|
742
|
+
setBusy(false);
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
746
|
+
import_design_system2.Alert,
|
|
747
|
+
{
|
|
748
|
+
variant: "destructive",
|
|
749
|
+
role: "alert",
|
|
750
|
+
"data-refusal-notice": "",
|
|
751
|
+
"data-archived-organization": organizationId,
|
|
752
|
+
className: (0, import_design_system2.cn)("text-xs", className),
|
|
753
|
+
errorFacts: { message: "This organization is archived", title: "This organization is archived", error, origin: "records-ui/ArchivedOrganizationNotice" },
|
|
754
|
+
children: [
|
|
755
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system2.AlertTitle, { className: "text-xs font-medium", children: "This organization is archived" }),
|
|
756
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system2.AlertDescription, { className: "space-y-1 text-xs", children: [
|
|
757
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "opacity-80", children: "Nothing was deleted. Everything here comes back the moment an owner of the organization, or a super admin, restores it." }),
|
|
758
|
+
mayRestore === true ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
759
|
+
"button",
|
|
760
|
+
{
|
|
761
|
+
type: "button",
|
|
762
|
+
"data-restore-organization": "",
|
|
763
|
+
disabled: busy,
|
|
764
|
+
className: "rounded border px-2 py-0.5 text-xs hover:bg-muted disabled:opacity-60",
|
|
765
|
+
onClick: () => void restore(),
|
|
766
|
+
children: busy ? "Restoring..." : "Restore organization"
|
|
767
|
+
}
|
|
768
|
+
) : null,
|
|
769
|
+
mayRestore === false ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { "data-restore-who": "", className: "opacity-80", children: "Ask an owner of this organization to restore it." }) : null,
|
|
770
|
+
failed ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { "data-restore-refused": "", children: failed }) : null
|
|
771
|
+
] })
|
|
772
|
+
]
|
|
773
|
+
}
|
|
774
|
+
);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
// src/Refusal.tsx
|
|
778
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
779
|
+
function RefusalNotice({
|
|
780
|
+
error,
|
|
781
|
+
className,
|
|
782
|
+
actions,
|
|
783
|
+
onKeepEditing,
|
|
784
|
+
onDiscard
|
|
785
|
+
}) {
|
|
786
|
+
const archivedOrg = (0, import_core.archivedOrganizationId)(error);
|
|
787
|
+
if (archivedOrg) {
|
|
788
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ArchivedOrganizationNotice, { organizationId: archivedOrg, error, className });
|
|
789
|
+
}
|
|
790
|
+
const plain = refusalForAPerson(error);
|
|
791
|
+
const doors = onKeepEditing || onDiscard ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-wrap items-center gap-1 pt-0.5", "data-refusal-doors": "", children: [
|
|
792
|
+
onKeepEditing ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
793
|
+
"button",
|
|
794
|
+
{
|
|
795
|
+
type: "button",
|
|
796
|
+
"data-refusal-keep-editing": "",
|
|
797
|
+
className: "rounded border px-2 py-0.5 text-xs hover:bg-muted",
|
|
798
|
+
onClick: onKeepEditing,
|
|
799
|
+
children: "Keep editing"
|
|
800
|
+
}
|
|
801
|
+
) : null,
|
|
802
|
+
onDiscard ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
803
|
+
"button",
|
|
804
|
+
{
|
|
805
|
+
type: "button",
|
|
806
|
+
"data-refusal-discard": "",
|
|
807
|
+
className: "rounded border px-2 py-0.5 text-xs hover:bg-muted",
|
|
808
|
+
onClick: onDiscard,
|
|
809
|
+
children: "Discard"
|
|
810
|
+
}
|
|
811
|
+
) : null
|
|
812
|
+
] }) : null;
|
|
813
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
814
|
+
import_design_system3.Alert,
|
|
815
|
+
{
|
|
816
|
+
variant: "destructive",
|
|
817
|
+
role: "alert",
|
|
818
|
+
"data-refusal-notice": "",
|
|
819
|
+
className: (0, import_design_system3.cn)("text-xs", className),
|
|
820
|
+
errorFacts: { message: plain.sentence, title: plain.title, error, origin: "records-ui/RefusalNotice" },
|
|
821
|
+
...plain.forEngineers ? { "data-for-engineers": plain.forEngineers } : {},
|
|
822
|
+
...error.sqlstate ? { "data-sqlstate": error.sqlstate } : {},
|
|
823
|
+
children: [
|
|
824
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system3.AlertTitle, { className: "text-xs font-medium", children: plain.storeSaid ? plain.sentence : plain.title }),
|
|
825
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system3.AlertDescription, { className: "space-y-1 text-xs", children: [
|
|
826
|
+
plain.storeSaid || plain.sentence.replace(/\.$/, "") === plain.title ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children: plain.sentence }),
|
|
827
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "opacity-80", children: plain.remedy }),
|
|
828
|
+
actions,
|
|
829
|
+
doors
|
|
830
|
+
] })
|
|
831
|
+
]
|
|
832
|
+
}
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
function RefusalLine({ error, className }) {
|
|
836
|
+
const plain = refusalForAPerson(error);
|
|
837
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
838
|
+
import_design_system3.ErrorBox,
|
|
839
|
+
{
|
|
840
|
+
"data-refusal-line": "",
|
|
841
|
+
className: (0, import_design_system3.cn)("text-xs text-destructive", className),
|
|
842
|
+
message: (0, import_core.archivedOrganizationId)(error) ? "This organization is archived. An owner can restore it." : refusalLineForAPerson(error),
|
|
843
|
+
error,
|
|
844
|
+
origin: "records-ui/RefusalLine",
|
|
845
|
+
...plain.forEngineers ? { "data-for-engineers": plain.forEngineers } : {}
|
|
846
|
+
}
|
|
847
|
+
);
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
// src/AddChoicesInline.tsx
|
|
851
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
581
852
|
function AddChoicesInline({ field, onAdded, disabled = false }) {
|
|
582
|
-
const client = (0,
|
|
583
|
-
const [open, setOpen] = (0,
|
|
584
|
-
const [rows, setRows] = (0,
|
|
585
|
-
const [saving, setSaving] = (0,
|
|
586
|
-
const [refused, setRefused] = (0,
|
|
853
|
+
const client = (0, import_react7.useOptionalRecordsClient)();
|
|
854
|
+
const [open, setOpen] = (0, import_react6.useState)(false);
|
|
855
|
+
const [rows, setRows] = (0, import_react6.useState)(() => [newChoiceRow([])]);
|
|
856
|
+
const [saving, setSaving] = (0, import_react6.useState)(false);
|
|
857
|
+
const [refused, setRefused] = (0, import_react6.useState)(null);
|
|
587
858
|
if (!client) return null;
|
|
588
859
|
const words = rows.map((r) => r.words.trim()).filter((w) => w !== "");
|
|
589
860
|
const missing = whatTheChoiceListIsMissing(rows);
|
|
@@ -593,19 +864,20 @@ function AddChoicesInline({ field, onAdded, disabled = false }) {
|
|
|
593
864
|
const done = await client.fieldUpdate({ field_id: field.id, patch: { options_add: words } });
|
|
594
865
|
setSaving(false);
|
|
595
866
|
if (!done.ok) {
|
|
596
|
-
setRefused(
|
|
867
|
+
setRefused(done.error);
|
|
597
868
|
return;
|
|
598
869
|
}
|
|
599
870
|
setOpen(false);
|
|
600
871
|
setRows([newChoiceRow([])]);
|
|
601
872
|
onAdded();
|
|
602
873
|
};
|
|
603
|
-
return /* @__PURE__ */ (0,
|
|
604
|
-
/* @__PURE__ */ (0,
|
|
605
|
-
/* @__PURE__ */ (0,
|
|
606
|
-
/* @__PURE__ */ (0,
|
|
607
|
-
missing
|
|
608
|
-
/* @__PURE__ */ (0,
|
|
874
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_design_system4.Popover, { open, onOpenChange: setOpen, children: [
|
|
875
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system4.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system4.Button, { type: "button", size: "sm", variant: "outline", className: "h-7 self-start text-xs", disabled, "data-records-add-choices": "", children: "Add choices" }) }),
|
|
876
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_design_system4.PopoverContent, { className: "w-72 space-y-2 p-3", align: "start", children: [
|
|
877
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChoiceListEditor, { isNew: true, rows, onRows: setRows }),
|
|
878
|
+
missing ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-[11px] text-muted-foreground", children: missing }) : null,
|
|
879
|
+
refused ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RefusalLine, { error: refused }) : null,
|
|
880
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system4.Button, { type: "button", size: "sm", className: "h-7 text-xs", disabled: saving || words.length === 0 || missing !== null, onClick: () => void save(), children: "Save choices" })
|
|
609
881
|
] })
|
|
610
882
|
] });
|
|
611
883
|
}
|
|
@@ -659,43 +931,43 @@ function isDateLike(value) {
|
|
|
659
931
|
}
|
|
660
932
|
|
|
661
933
|
// src/newerKindValues.tsx
|
|
662
|
-
var
|
|
934
|
+
var import_react8 = require("react");
|
|
663
935
|
var import_source = require("@ai-matrx/content-ir/source");
|
|
664
|
-
var
|
|
665
|
-
var
|
|
666
|
-
var
|
|
667
|
-
var own = (event) => event.stopPropagation();
|
|
668
|
-
function newerKindValue(field, value, opts = {}) {
|
|
669
|
-
switch ((0,
|
|
936
|
+
var import_records4 = require("@ai-matrx/records");
|
|
937
|
+
var import_design_system5 = require("@ai-matrx/design-system");
|
|
938
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
939
|
+
var own = (event) => event.stopPropagation();
|
|
940
|
+
function newerKindValue(field, value, opts = {}) {
|
|
941
|
+
switch ((0, import_records4.newerKindOf)(field)) {
|
|
670
942
|
case "duration": {
|
|
671
|
-
const words = (0,
|
|
672
|
-
return words === null ? void 0 : /* @__PURE__ */ (0,
|
|
943
|
+
const words = (0, import_records4.durationText)(value);
|
|
944
|
+
return words === null ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "tabular-nums", "data-records-duration": "", children: words });
|
|
673
945
|
}
|
|
674
946
|
case "created_by":
|
|
675
947
|
case "modified_by":
|
|
676
|
-
return (0,
|
|
948
|
+
return (0, import_records4.isPersonStamp)(value) ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PersonStampChip, { stamp: value }) : void 0;
|
|
677
949
|
case "address":
|
|
678
|
-
return (0,
|
|
950
|
+
return (0, import_records4.isAddressValue)(value) || typeof value === "string" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AddressLink, { value }) : void 0;
|
|
679
951
|
case "barcode":
|
|
680
|
-
return typeof value === "string" ? /* @__PURE__ */ (0,
|
|
681
|
-
/* @__PURE__ */ (0,
|
|
682
|
-
/* @__PURE__ */ (0,
|
|
952
|
+
return typeof value === "string" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "inline-flex min-w-0 items-center gap-1 font-mono text-xs", "data-records-barcode": "", title: value, children: [
|
|
953
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u25AE\u25AF\u25AE" }),
|
|
954
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "truncate", children: value })
|
|
683
955
|
] }) : void 0;
|
|
684
956
|
case "rich_text":
|
|
685
|
-
return typeof value === "string" ? /* @__PURE__ */ (0,
|
|
957
|
+
return typeof value === "string" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SafeMarkdown, { text: value, clipped: opts.inCell === true }) : void 0;
|
|
686
958
|
case "count":
|
|
687
|
-
return typeof value === "number" ? /* @__PURE__ */ (0,
|
|
959
|
+
return typeof value === "number" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "tabular-nums", children: value.toLocaleString() }) : void 0;
|
|
688
960
|
default:
|
|
689
961
|
return void 0;
|
|
690
962
|
}
|
|
691
963
|
}
|
|
692
964
|
function PersonStampChip({ stamp }) {
|
|
693
|
-
const words = (0,
|
|
965
|
+
const words = (0, import_records4.personStampText)(stamp) ?? import_records4.NOT_A_MEMBER_WORDS;
|
|
694
966
|
const tier = stamp.actor ?? "user";
|
|
695
967
|
const name = tier === "user" ? stamp.name : null;
|
|
696
968
|
const initial = tier === "system" ? "\u2699" : tier === "agent" ? "\u2726" : name && name.trim() !== "" ? name.trim()[0].toUpperCase() : "?";
|
|
697
|
-
return /* @__PURE__ */ (0,
|
|
698
|
-
/* @__PURE__ */ (0,
|
|
969
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "inline-flex min-w-0 items-center gap-1.5", "data-records-person-stamp": tier, children: [
|
|
970
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
699
971
|
"span",
|
|
700
972
|
{
|
|
701
973
|
"aria-hidden": "true",
|
|
@@ -703,14 +975,14 @@ function PersonStampChip({ stamp }) {
|
|
|
703
975
|
children: initial
|
|
704
976
|
}
|
|
705
977
|
),
|
|
706
|
-
/* @__PURE__ */ (0,
|
|
978
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: (0, import_design_system5.cn)("truncate", tier === "user" && !name ? "italic text-muted-foreground" : ""), children: words })
|
|
707
979
|
] });
|
|
708
980
|
}
|
|
709
981
|
function AddressLink({ value }) {
|
|
710
|
-
const words = (0,
|
|
711
|
-
const href = (0,
|
|
712
|
-
if (!words || !href) return /* @__PURE__ */ (0,
|
|
713
|
-
return /* @__PURE__ */ (0,
|
|
982
|
+
const words = (0, import_records4.addressText)(value);
|
|
983
|
+
const href = (0, import_records4.addressMapUrl)(value);
|
|
984
|
+
if (!words || !href) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
985
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
714
986
|
"a",
|
|
715
987
|
{
|
|
716
988
|
href,
|
|
@@ -721,19 +993,19 @@ function AddressLink({ value }) {
|
|
|
721
993
|
"data-records-address": "",
|
|
722
994
|
onClick: own,
|
|
723
995
|
children: [
|
|
724
|
-
/* @__PURE__ */ (0,
|
|
725
|
-
/* @__PURE__ */ (0,
|
|
996
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "aria-hidden": "true", children: "\u2316" }),
|
|
997
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "truncate", children: words })
|
|
726
998
|
]
|
|
727
999
|
}
|
|
728
1000
|
);
|
|
729
1001
|
}
|
|
730
1002
|
var STATUS_GROUP_MARK = { todo: "\u25CB", in_progress: "\u25D0", done: "\u25CF" };
|
|
731
1003
|
function statusMarkOf(field, value, document2) {
|
|
732
|
-
if ((0,
|
|
1004
|
+
if ((0, import_records4.newerKindOf)(field) !== "status" || typeof value !== "string") return null;
|
|
733
1005
|
const chosen = document2?.["_choices"]?.[field.key];
|
|
734
1006
|
const key = chosen && typeof chosen === "object" && typeof chosen.key === "string" ? chosen.key : value;
|
|
735
|
-
const group = (0,
|
|
736
|
-
return { mark: STATUS_GROUP_MARK[group], group, words:
|
|
1007
|
+
const group = (0, import_records4.statusGroupOf)(field, key);
|
|
1008
|
+
return { mark: STATUS_GROUP_MARK[group], group, words: import_records4.STATUS_GROUP_WORDS[group] };
|
|
737
1009
|
}
|
|
738
1010
|
function inline(text, key) {
|
|
739
1011
|
const out = [];
|
|
@@ -742,7 +1014,7 @@ function inline(text, key) {
|
|
|
742
1014
|
for (const r of (0, import_source.findInlineCodeSpans)(text)) {
|
|
743
1015
|
if (r.start < at) continue;
|
|
744
1016
|
if (r.start > at) out.push(...marks(text.slice(at, r.start), `${key}-m${n++}`));
|
|
745
|
-
out.push(/* @__PURE__ */ (0,
|
|
1017
|
+
out.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { className: "rounded bg-muted px-1 font-mono text-[0.9em]", children: (0, import_source.codeSpanText)(text.slice(r.start, r.end)) }, `${key}-c${n++}`));
|
|
746
1018
|
at = r.end;
|
|
747
1019
|
}
|
|
748
1020
|
if (at < text.length) out.push(...marks(text.slice(at), `${key}-m${n++}`));
|
|
@@ -758,14 +1030,14 @@ function marks(text, key) {
|
|
|
758
1030
|
if (at > last) out.push(text.slice(last, at));
|
|
759
1031
|
const tok = m[0];
|
|
760
1032
|
const k = `${key}-${i++}`;
|
|
761
|
-
if (tok.startsWith("**") || tok.startsWith("__")) out.push(/* @__PURE__ */ (0,
|
|
1033
|
+
if (tok.startsWith("**") || tok.startsWith("__")) out.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: tok.slice(2, -2) }, k));
|
|
762
1034
|
else if (tok.startsWith("[")) {
|
|
763
1035
|
const link = /^\[([^\]]+)\]\(([^)\s]+)\)$/.exec(tok);
|
|
764
|
-
const href = (0,
|
|
1036
|
+
const href = (0, import_records4.safeLinkHref)(link?.[2] ?? "");
|
|
765
1037
|
out.push(
|
|
766
|
-
href ? /* @__PURE__ */ (0,
|
|
1038
|
+
href ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("a", { href, target: "_blank", rel: "noopener noreferrer", className: "text-primary underline-offset-2 hover:underline", onClick: own, children: link?.[1] }, k) : link?.[1] ?? tok
|
|
767
1039
|
);
|
|
768
|
-
} else out.push(/* @__PURE__ */ (0,
|
|
1040
|
+
} else out.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("em", { children: tok.slice(1, -1) }, k));
|
|
769
1041
|
last = at + tok.length;
|
|
770
1042
|
}
|
|
771
1043
|
if (last < text.length) out.push(text.slice(last));
|
|
@@ -778,15 +1050,15 @@ function SafeMarkdown({ text, clipped }) {
|
|
|
778
1050
|
let para = [];
|
|
779
1051
|
const flushPara = () => {
|
|
780
1052
|
if (para.length > 0) {
|
|
781
|
-
blocks.push(/* @__PURE__ */ (0,
|
|
1053
|
+
blocks.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: inline(para.join(" "), `p${blocks.length}`) }, `p${blocks.length}`));
|
|
782
1054
|
para = [];
|
|
783
1055
|
}
|
|
784
1056
|
};
|
|
785
1057
|
const flushList = () => {
|
|
786
1058
|
if (list) {
|
|
787
|
-
const items = list.items.map((item, i) => /* @__PURE__ */ (0,
|
|
1059
|
+
const items = list.items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: inline(item, `l${blocks.length}-${i}`) }, i));
|
|
788
1060
|
blocks.push(
|
|
789
|
-
list.ordered ? /* @__PURE__ */ (0,
|
|
1061
|
+
list.ordered ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ol", { className: "ml-4 list-decimal", children: items }, `o${blocks.length}`) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { className: "ml-4 list-disc", children: items }, `u${blocks.length}`)
|
|
790
1062
|
);
|
|
791
1063
|
list = null;
|
|
792
1064
|
}
|
|
@@ -805,7 +1077,7 @@ function SafeMarkdown({ text, clipped }) {
|
|
|
805
1077
|
} else if (heading) {
|
|
806
1078
|
flushPara();
|
|
807
1079
|
flushList();
|
|
808
|
-
blocks.push(/* @__PURE__ */ (0,
|
|
1080
|
+
blocks.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "font-semibold", children: inline(heading[2], `h${blocks.length}`) }, `h${blocks.length}`));
|
|
809
1081
|
} else if (line.trim() === "") {
|
|
810
1082
|
flushPara();
|
|
811
1083
|
flushList();
|
|
@@ -816,40 +1088,40 @@ function SafeMarkdown({ text, clipped }) {
|
|
|
816
1088
|
}
|
|
817
1089
|
flushPara();
|
|
818
1090
|
flushList();
|
|
819
|
-
return /* @__PURE__ */ (0,
|
|
1091
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
820
1092
|
"span",
|
|
821
1093
|
{
|
|
822
|
-
className: (0,
|
|
1094
|
+
className: (0, import_design_system5.cn)("block min-w-0 space-y-1 whitespace-normal text-sm", clipped ? "max-h-[4.5em] overflow-hidden" : ""),
|
|
823
1095
|
"data-records-rich-text": "",
|
|
824
1096
|
children: blocks
|
|
825
1097
|
}
|
|
826
1098
|
);
|
|
827
1099
|
}
|
|
828
1100
|
function newerKindControl(props) {
|
|
829
|
-
switch ((0,
|
|
1101
|
+
switch ((0, import_records4.newerKindOf)(props.field)) {
|
|
830
1102
|
case "duration":
|
|
831
|
-
return /* @__PURE__ */ (0,
|
|
1103
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DurationControl, { ...props });
|
|
832
1104
|
case "address":
|
|
833
|
-
return /* @__PURE__ */ (0,
|
|
1105
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AddressControl, { ...props });
|
|
834
1106
|
case "barcode":
|
|
835
|
-
return /* @__PURE__ */ (0,
|
|
1107
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(BarcodeControl, { ...props });
|
|
836
1108
|
case "created_by":
|
|
837
1109
|
case "modified_by":
|
|
838
1110
|
case "count":
|
|
839
|
-
return /* @__PURE__ */ (0,
|
|
1111
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { id: props.id, className: "rounded border border-dashed px-2 py-1.5 text-xs text-muted-foreground", children: props.value === null || props.value === void 0 ? "\u2014" : newerKindValue(props.field, props.value) });
|
|
840
1112
|
default:
|
|
841
1113
|
return void 0;
|
|
842
1114
|
}
|
|
843
1115
|
}
|
|
844
1116
|
function DurationControl({ value, onChange, disabled, id }) {
|
|
845
|
-
const [text, setText] = (0,
|
|
846
|
-
const [wrong, setWrong] = (0,
|
|
847
|
-
(0,
|
|
848
|
-
setText((0,
|
|
1117
|
+
const [text, setText] = (0, import_react8.useState)(() => (0, import_records4.durationText)(value) ?? "");
|
|
1118
|
+
const [wrong, setWrong] = (0, import_react8.useState)(false);
|
|
1119
|
+
(0, import_react8.useEffect)(() => {
|
|
1120
|
+
setText((0, import_records4.durationText)(value) ?? "");
|
|
849
1121
|
}, [value]);
|
|
850
|
-
return /* @__PURE__ */ (0,
|
|
851
|
-
/* @__PURE__ */ (0,
|
|
852
|
-
|
|
1122
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "flex flex-col gap-1", children: [
|
|
1123
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1124
|
+
import_design_system5.BasicInput,
|
|
853
1125
|
{
|
|
854
1126
|
id,
|
|
855
1127
|
value: text,
|
|
@@ -865,16 +1137,16 @@ function DurationControl({ value, onChange, disabled, id }) {
|
|
|
865
1137
|
onChange(null);
|
|
866
1138
|
return;
|
|
867
1139
|
}
|
|
868
|
-
const seconds = (0,
|
|
1140
|
+
const seconds = (0, import_records4.readTypedDuration)(e.target.value);
|
|
869
1141
|
setWrong(seconds === null);
|
|
870
1142
|
if (seconds !== null) onChange(seconds);
|
|
871
1143
|
},
|
|
872
1144
|
onBlur: () => {
|
|
873
|
-
if (!wrong) setText((0,
|
|
1145
|
+
if (!wrong) setText((0, import_records4.durationText)(value) ?? "");
|
|
874
1146
|
}
|
|
875
1147
|
}
|
|
876
1148
|
),
|
|
877
|
-
wrong ? /* @__PURE__ */ (0,
|
|
1149
|
+
wrong ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-[11px] text-destructive", children: "Write it like 45 min, 1:30 or 1h 30m." }) : null
|
|
878
1150
|
] });
|
|
879
1151
|
}
|
|
880
1152
|
var ADDRESS_LABELS = {
|
|
@@ -892,14 +1164,14 @@ var ADDRESS_EXAMPLES = {
|
|
|
892
1164
|
country: "US"
|
|
893
1165
|
};
|
|
894
1166
|
function AddressControl({ value, onChange, disabled, id }) {
|
|
895
|
-
const held = (0,
|
|
1167
|
+
const held = (0, import_records4.isAddressValue)(value) ? value : typeof value === "string" && value.trim() !== "" ? { street: value } : {};
|
|
896
1168
|
const set = (part, words) => {
|
|
897
1169
|
const next = { ...held, [part]: words };
|
|
898
1170
|
const kept = Object.fromEntries(Object.entries(next).filter(([, v]) => typeof v === "string" && v.trim() !== ""));
|
|
899
1171
|
onChange(Object.keys(kept).length === 0 ? null : kept);
|
|
900
1172
|
};
|
|
901
|
-
return /* @__PURE__ */ (0,
|
|
902
|
-
|
|
1173
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { id, className: "grid grid-cols-2 gap-1.5", "data-records-address-control": "", children: import_records4.ADDRESS_PARTS.map((part) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1174
|
+
import_design_system5.BasicInput,
|
|
903
1175
|
{
|
|
904
1176
|
"aria-label": ADDRESS_LABELS[part],
|
|
905
1177
|
placeholder: ADDRESS_EXAMPLES[part],
|
|
@@ -917,13 +1189,13 @@ function barcodeDetector() {
|
|
|
917
1189
|
return typeof ctor === "function" ? ctor : null;
|
|
918
1190
|
}
|
|
919
1191
|
function BarcodeControl({ value, onChange, disabled, id }) {
|
|
920
|
-
const file = (0,
|
|
921
|
-
const [said2, setSaid] = (0,
|
|
1192
|
+
const file = (0, import_react8.useRef)(null);
|
|
1193
|
+
const [said2, setSaid] = (0, import_react8.useState)(null);
|
|
922
1194
|
const Detect = barcodeDetector();
|
|
923
|
-
return /* @__PURE__ */ (0,
|
|
924
|
-
/* @__PURE__ */ (0,
|
|
925
|
-
/* @__PURE__ */ (0,
|
|
926
|
-
|
|
1195
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "flex flex-col gap-1", children: [
|
|
1196
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "flex items-center gap-1.5", children: [
|
|
1197
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1198
|
+
import_design_system5.BasicInput,
|
|
927
1199
|
{
|
|
928
1200
|
id,
|
|
929
1201
|
className: "font-mono",
|
|
@@ -933,8 +1205,8 @@ function BarcodeControl({ value, onChange, disabled, id }) {
|
|
|
933
1205
|
onChange: (e) => onChange(e.target.value === "" ? null : e.target.value)
|
|
934
1206
|
}
|
|
935
1207
|
),
|
|
936
|
-
Detect && !disabled ? /* @__PURE__ */ (0,
|
|
937
|
-
/* @__PURE__ */ (0,
|
|
1208
|
+
Detect && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1209
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
938
1210
|
"button",
|
|
939
1211
|
{
|
|
940
1212
|
type: "button",
|
|
@@ -943,7 +1215,7 @@ function BarcodeControl({ value, onChange, disabled, id }) {
|
|
|
943
1215
|
children: "Scan"
|
|
944
1216
|
}
|
|
945
1217
|
),
|
|
946
|
-
/* @__PURE__ */ (0,
|
|
1218
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
947
1219
|
"input",
|
|
948
1220
|
{
|
|
949
1221
|
ref: file,
|
|
@@ -969,13 +1241,13 @@ function BarcodeControl({ value, onChange, disabled, id }) {
|
|
|
969
1241
|
)
|
|
970
1242
|
] }) : null
|
|
971
1243
|
] }),
|
|
972
|
-
said2 ? /* @__PURE__ */ (0,
|
|
1244
|
+
said2 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-[11px] text-muted-foreground", children: said2 }) : null
|
|
973
1245
|
] });
|
|
974
1246
|
}
|
|
975
1247
|
|
|
976
1248
|
// src/parity.ts
|
|
977
|
-
var import_records5 = require("@ai-matrx/records");
|
|
978
1249
|
var import_records6 = require("@ai-matrx/records");
|
|
1250
|
+
var import_records7 = require("@ai-matrx/records");
|
|
979
1251
|
var import_text_case = require("@ai-matrx/kit/text-case");
|
|
980
1252
|
|
|
981
1253
|
// src/docs.ts
|
|
@@ -984,7 +1256,7 @@ function isSignatureField(field) {
|
|
|
984
1256
|
}
|
|
985
1257
|
|
|
986
1258
|
// src/fieldTypes.ts
|
|
987
|
-
var
|
|
1259
|
+
var import_records5 = require("@ai-matrx/records");
|
|
988
1260
|
var LOOK_KINDS = {
|
|
989
1261
|
rating: { plain: "number", look: ({ ratingMax }) => ({ id: "rating", options: { ratingMax } }) },
|
|
990
1262
|
time: { plain: "text", look: () => ({ id: "time" }) }
|
|
@@ -993,9 +1265,9 @@ function declaredAsLook(kind) {
|
|
|
993
1265
|
return kind in LOOK_KINDS && !storePublishesKind(kind);
|
|
994
1266
|
}
|
|
995
1267
|
function storePublishesKind(kind) {
|
|
996
|
-
return
|
|
1268
|
+
return import_records5.DECLARABLE_FIELD_KINDS.some((row) => row.kind === kind);
|
|
997
1269
|
}
|
|
998
|
-
var STORE_PUBLISHES_ENTITY_REFERENCE =
|
|
1270
|
+
var STORE_PUBLISHES_ENTITY_REFERENCE = import_records5.DECLARABLE_FIELD_KINDS.some(
|
|
999
1271
|
(row) => row.kind === "entity_reference"
|
|
1000
1272
|
);
|
|
1001
1273
|
var SYSTEM_FIELD_KINDS = ["autonumber", "created_time", "modified_time"];
|
|
@@ -1043,7 +1315,7 @@ var FIELD_TYPE_CATALOGUE = [
|
|
|
1043
1315
|
{ id: "created_by", group: "Worked out", label: "Created by", explanation: "Who made each record. Nobody types it." },
|
|
1044
1316
|
{ id: "modified_by", group: "Worked out", label: "Last changed by", explanation: "Who last changed each record. Nobody types it." }
|
|
1045
1317
|
];
|
|
1046
|
-
var GATED_KINDS = /* @__PURE__ */ new Set(["entity_reference", ...
|
|
1318
|
+
var GATED_KINDS = /* @__PURE__ */ new Set(["entity_reference", ...import_records5.NEWER_FIELD_KINDS]);
|
|
1047
1319
|
var FIELD_TYPE_CHOICES = FIELD_TYPE_CATALOGUE.filter(
|
|
1048
1320
|
(c) => !GATED_KINDS.has(c.id) || storePublishesKind(c.id) || c.id in LOOK_KINDS
|
|
1049
1321
|
);
|
|
@@ -1064,26 +1336,26 @@ function isRelationFieldType(id) {
|
|
|
1064
1336
|
return id === "relation";
|
|
1065
1337
|
}
|
|
1066
1338
|
function isParityFieldType(id) {
|
|
1067
|
-
return
|
|
1339
|
+
return import_records5.PARITY_FIELD_TYPES.some((row) => row.parity_type === id);
|
|
1068
1340
|
}
|
|
1069
1341
|
var ADD_FIELD_SAVE_LABEL = "Create column";
|
|
1070
1342
|
var EDIT_FIELD_SAVE_LABEL = "Save column";
|
|
1071
1343
|
|
|
1072
1344
|
// src/parity.ts
|
|
1073
|
-
var kernelId = (name) =>
|
|
1345
|
+
var kernelId = (name) => import_records6.KERNEL_TABLES.find((t) => t.name === name)?.id ?? "";
|
|
1074
1346
|
var KERNEL_FILE_TABLE = kernelId("File");
|
|
1075
1347
|
var KERNEL_PERSON_TABLE = kernelId("Person");
|
|
1076
1348
|
var PARITY_MADE_OF = Object.fromEntries(
|
|
1077
|
-
|
|
1349
|
+
import_records6.PARITY_FIELD_TYPES.map((p) => [p.parity_type, p.made_of])
|
|
1078
1350
|
);
|
|
1079
1351
|
var KERNEL = { file: KERNEL_FILE_TABLE, person: KERNEL_PERSON_TABLE };
|
|
1080
1352
|
function editorKindFor(field) {
|
|
1081
|
-
return (0,
|
|
1353
|
+
return (0, import_records6.fieldKindFor)(field, KERNEL);
|
|
1082
1354
|
}
|
|
1083
1355
|
function pickableTypeOf(field) {
|
|
1084
1356
|
if (isSignatureField(field)) return "signature";
|
|
1085
|
-
if ((0,
|
|
1086
|
-
const newer = (0,
|
|
1357
|
+
if ((0, import_records7.isButtonField)(field)) return "button";
|
|
1358
|
+
const newer = (0, import_records6.newerKindOf)(field);
|
|
1087
1359
|
if (newer) return newer;
|
|
1088
1360
|
const look = displayFormatOf(field)?.id;
|
|
1089
1361
|
if (look === "rating" && field.type === "range") return "rating";
|
|
@@ -1142,23 +1414,23 @@ var import_react11 = require("@ai-matrx/records/react");
|
|
|
1142
1414
|
var import_design_system8 = require("@ai-matrx/design-system");
|
|
1143
1415
|
|
|
1144
1416
|
// src/PickOrAdd.tsx
|
|
1145
|
-
var
|
|
1417
|
+
var import_react9 = require("react");
|
|
1146
1418
|
|
|
1147
1419
|
// src/personChip.tsx
|
|
1148
|
-
var
|
|
1149
|
-
var
|
|
1420
|
+
var import_design_system6 = require("@ai-matrx/design-system");
|
|
1421
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1150
1422
|
function initialsOf(name) {
|
|
1151
1423
|
const words = name.replace(/@.*$/, "").split(/[\s._-]+/).filter((w) => /\p{L}|\d/u.test(w));
|
|
1152
1424
|
const letters = words.filter((w) => !/^(dr|mr|mrs|ms|prof)\.?$/i.test(w)).slice(0, 2).map((w) => (w.match(/[\p{L}\d]/u)?.[0] ?? "").toUpperCase());
|
|
1153
1425
|
return letters.join("") || "?";
|
|
1154
1426
|
}
|
|
1155
1427
|
function PersonAvatar({ name, size = "sm" }) {
|
|
1156
|
-
return /* @__PURE__ */ (0,
|
|
1428
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1157
1429
|
"span",
|
|
1158
1430
|
{
|
|
1159
1431
|
"aria-hidden": "true",
|
|
1160
1432
|
"data-records-person-avatar": "",
|
|
1161
|
-
className: (0,
|
|
1433
|
+
className: (0, import_design_system6.cn)(
|
|
1162
1434
|
"inline-flex shrink-0 items-center justify-center rounded-full bg-foreground/10 font-medium text-foreground/80",
|
|
1163
1435
|
size === "md" ? "size-5 text-[10px]" : "size-4 text-[9px]"
|
|
1164
1436
|
),
|
|
@@ -1167,35 +1439,35 @@ function PersonAvatar({ name, size = "sm" }) {
|
|
|
1167
1439
|
);
|
|
1168
1440
|
}
|
|
1169
1441
|
function PersonChip({ name, onRemove, className }) {
|
|
1170
|
-
return /* @__PURE__ */ (0,
|
|
1442
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1171
1443
|
"span",
|
|
1172
1444
|
{
|
|
1173
1445
|
"data-records-person-chip": "",
|
|
1174
1446
|
title: name,
|
|
1175
|
-
className: (0,
|
|
1447
|
+
className: (0, import_design_system6.cn)("inline-flex min-w-0 max-w-full items-center gap-1 rounded-full bg-muted px-1.5 py-0.5 text-[11px] text-foreground", className),
|
|
1176
1448
|
children: [
|
|
1177
|
-
/* @__PURE__ */ (0,
|
|
1178
|
-
/* @__PURE__ */ (0,
|
|
1179
|
-
onRemove ? /* @__PURE__ */ (0,
|
|
1449
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PersonAvatar, { name }),
|
|
1450
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "min-w-0 truncate", children: name }),
|
|
1451
|
+
onRemove ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", onClick: onRemove, "aria-label": `Remove ${name}`, className: "shrink-0 opacity-60 hover:opacity-100", children: "\xD7" }) : null
|
|
1180
1452
|
]
|
|
1181
1453
|
}
|
|
1182
1454
|
);
|
|
1183
1455
|
}
|
|
1184
1456
|
|
|
1185
1457
|
// src/PickOrAdd.tsx
|
|
1186
|
-
var
|
|
1187
|
-
var
|
|
1458
|
+
var import_design_system7 = require("@ai-matrx/design-system");
|
|
1459
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1188
1460
|
function Glyph({ d, className }) {
|
|
1189
|
-
return /* @__PURE__ */ (0,
|
|
1461
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, className, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d }) });
|
|
1190
1462
|
}
|
|
1191
1463
|
var TICK = "m5 12 4 4L19 6";
|
|
1192
1464
|
var CROSS = "M18 6 6 18M6 6l12 12";
|
|
1193
1465
|
var PLUS = "M12 5v14M5 12h14";
|
|
1194
1466
|
function useListKeys(args) {
|
|
1195
1467
|
const { count, resetOn, onPick, onNothing, onClose, onFinish, onBackspaceEmpty, searchEmpty } = args;
|
|
1196
|
-
const [highlight, setHighlight] = (0,
|
|
1197
|
-
const [moved, setMoved] = (0,
|
|
1198
|
-
(0,
|
|
1468
|
+
const [highlight, setHighlight] = (0, import_react9.useState)(0);
|
|
1469
|
+
const [moved, setMoved] = (0, import_react9.useState)(false);
|
|
1470
|
+
(0, import_react9.useEffect)(() => {
|
|
1199
1471
|
setHighlight(0);
|
|
1200
1472
|
setMoved(false);
|
|
1201
1473
|
}, [resetOn]);
|
|
@@ -1240,11 +1512,11 @@ function PickRow({
|
|
|
1240
1512
|
onPick,
|
|
1241
1513
|
onPoint
|
|
1242
1514
|
}) {
|
|
1243
|
-
const ref = (0,
|
|
1244
|
-
(0,
|
|
1515
|
+
const ref = (0, import_react9.useRef)(null);
|
|
1516
|
+
(0, import_react9.useEffect)(() => {
|
|
1245
1517
|
if (highlighted) ref.current?.scrollIntoView?.({ block: "nearest" });
|
|
1246
1518
|
}, [highlighted]);
|
|
1247
|
-
return /* @__PURE__ */ (0,
|
|
1519
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1248
1520
|
"button",
|
|
1249
1521
|
{
|
|
1250
1522
|
ref,
|
|
@@ -1257,19 +1529,19 @@ function PickRow({
|
|
|
1257
1529
|
title: title ?? label,
|
|
1258
1530
|
...attrs ?? {},
|
|
1259
1531
|
"data-pick-highlighted": highlighted ? "" : void 0,
|
|
1260
|
-
className: (0,
|
|
1532
|
+
className: (0, import_design_system7.cn)(
|
|
1261
1533
|
"flex w-full min-w-0 items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm outline-none disabled:opacity-50",
|
|
1262
1534
|
highlighted ? "bg-accent text-accent-foreground" : ""
|
|
1263
1535
|
),
|
|
1264
1536
|
children: [
|
|
1265
|
-
/* @__PURE__ */ (0,
|
|
1266
|
-
picked ? /* @__PURE__ */ (0,
|
|
1267
|
-
icon === "plus" ? /* @__PURE__ */ (0,
|
|
1537
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "flex size-3.5 shrink-0 items-center justify-center", children: [
|
|
1538
|
+
picked ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "data-pick-tick": "", className: "contents", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Glyph, { d: TICK, className: "size-3.5" }) }) : null,
|
|
1539
|
+
icon === "plus" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Glyph, { d: PLUS, className: "size-3.5 text-muted-foreground" }) : null
|
|
1268
1540
|
] }),
|
|
1269
|
-
person ? /* @__PURE__ */ (0,
|
|
1270
|
-
/* @__PURE__ */ (0,
|
|
1271
|
-
chip ? /* @__PURE__ */ (0,
|
|
1272
|
-
detail ? /* @__PURE__ */ (0,
|
|
1541
|
+
person ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PersonAvatar, { name: label, size: "md" }) : null,
|
|
1542
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "min-w-0 flex-1", children: [
|
|
1543
|
+
chip ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: (0, import_design_system7.cn)("inline-flex max-w-full truncate rounded-md border px-1.5 py-0.5 text-xs font-medium", chip), "data-records-choice-chip": "", children: label }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "block truncate", children: label }),
|
|
1544
|
+
detail ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "block truncate text-xs text-muted-foreground", "data-tell-apart": "", children: detail }) : null
|
|
1273
1545
|
] })
|
|
1274
1546
|
]
|
|
1275
1547
|
}
|
|
@@ -1277,26 +1549,26 @@ function PickRow({
|
|
|
1277
1549
|
}
|
|
1278
1550
|
function PickChips({ chips }) {
|
|
1279
1551
|
if (chips.length === 0) return null;
|
|
1280
|
-
return /* @__PURE__ */ (0,
|
|
1281
|
-
(c) => c.person ? /* @__PURE__ */ (0,
|
|
1552
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex flex-wrap gap-1 px-1 pb-1", "data-pick-chips": "", children: chips.map(
|
|
1553
|
+
(c) => c.person ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PersonChip, { name: c.label, onRemove: c.onRemove }, c.id) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1282
1554
|
"span",
|
|
1283
1555
|
{
|
|
1284
1556
|
"data-pick-chip": "",
|
|
1285
1557
|
title: c.label,
|
|
1286
|
-
className: (0,
|
|
1558
|
+
className: (0, import_design_system7.cn)(
|
|
1287
1559
|
"inline-flex max-w-full items-center gap-1 rounded-md border px-1.5 py-0.5 text-xs font-medium",
|
|
1288
1560
|
c.chip ?? "bg-secondary text-secondary-foreground"
|
|
1289
1561
|
),
|
|
1290
1562
|
children: [
|
|
1291
|
-
/* @__PURE__ */ (0,
|
|
1292
|
-
c.onRemove ? /* @__PURE__ */ (0,
|
|
1563
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "min-w-0 truncate", children: c.label }),
|
|
1564
|
+
c.onRemove ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1293
1565
|
"button",
|
|
1294
1566
|
{
|
|
1295
1567
|
type: "button",
|
|
1296
1568
|
"aria-label": `Remove ${c.label}`,
|
|
1297
1569
|
onClick: c.onRemove,
|
|
1298
1570
|
className: "shrink-0 rounded-sm opacity-60 hover:opacity-100",
|
|
1299
|
-
children: /* @__PURE__ */ (0,
|
|
1571
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Glyph, { d: CROSS, className: "size-3" })
|
|
1300
1572
|
}
|
|
1301
1573
|
) : null
|
|
1302
1574
|
]
|
|
@@ -1351,7 +1623,7 @@ function PickOrAdd({
|
|
|
1351
1623
|
searchEmpty: search === ""
|
|
1352
1624
|
});
|
|
1353
1625
|
const hasFoot = Boolean(foot) || Boolean(footNote);
|
|
1354
|
-
const addRowNode = addRow ? /* @__PURE__ */ (0,
|
|
1626
|
+
const addRowNode = addRow ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1355
1627
|
PickRow,
|
|
1356
1628
|
{
|
|
1357
1629
|
label: addRow.label,
|
|
@@ -1364,10 +1636,10 @@ function PickOrAdd({
|
|
|
1364
1636
|
onPoint: () => keys.setHighlight(addAt)
|
|
1365
1637
|
}
|
|
1366
1638
|
) : null;
|
|
1367
|
-
return /* @__PURE__ */ (0,
|
|
1368
|
-
anchored ? /* @__PURE__ */ (0,
|
|
1369
|
-
/* @__PURE__ */ (0,
|
|
1370
|
-
|
|
1639
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_design_system7.Popover, { open, onOpenChange, children: [
|
|
1640
|
+
anchored ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_design_system7.PopoverAnchor, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { "data-pick-anchor": "", className: "flex min-h-6 w-full min-w-0 flex-wrap items-center gap-1", "aria-label": triggerLabel, children }) }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_design_system7.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_design_system7.Button, { id: triggerId, type: "button", size: "sm", variant: "outline", className: triggerSize === "field" ? "h-9" : void 0, "aria-label": triggerLabel, children: triggerText }) }),
|
|
1641
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1642
|
+
import_design_system7.PopoverContent,
|
|
1371
1643
|
{
|
|
1372
1644
|
sizing: "content",
|
|
1373
1645
|
padding: "xs",
|
|
@@ -1388,9 +1660,9 @@ function PickOrAdd({
|
|
|
1388
1660
|
if (anchored) event.preventDefault();
|
|
1389
1661
|
},
|
|
1390
1662
|
children: [
|
|
1391
|
-
chips ? /* @__PURE__ */ (0,
|
|
1392
|
-
/* @__PURE__ */ (0,
|
|
1393
|
-
|
|
1663
|
+
chips ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PickChips, { chips }) : null,
|
|
1664
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1665
|
+
import_design_system7.BasicInput,
|
|
1394
1666
|
{
|
|
1395
1667
|
value: search,
|
|
1396
1668
|
onChange: (e) => onSearch(e.target.value),
|
|
@@ -1403,9 +1675,9 @@ function PickOrAdd({
|
|
|
1403
1675
|
}
|
|
1404
1676
|
),
|
|
1405
1677
|
notice,
|
|
1406
|
-
/* @__PURE__ */ (0,
|
|
1407
|
-
/* @__PURE__ */ (0,
|
|
1408
|
-
items.map((item, index) => /* @__PURE__ */ (0,
|
|
1678
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_design_system7.ScrollArea, { className: "max-h-64", children: [
|
|
1679
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { role: "listbox", "aria-label": triggerLabel, "aria-multiselectable": multi ? true : void 0, children: [
|
|
1680
|
+
items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1409
1681
|
PickRow,
|
|
1410
1682
|
{
|
|
1411
1683
|
label: item.label,
|
|
@@ -1426,7 +1698,7 @@ function PickOrAdd({
|
|
|
1426
1698
|
] }),
|
|
1427
1699
|
items.length === 0 && empty ? empty : null
|
|
1428
1700
|
] }),
|
|
1429
|
-
hasFoot ? /* @__PURE__ */ (0,
|
|
1701
|
+
hasFoot ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "mt-1 border-t pt-1", children: [
|
|
1430
1702
|
foot,
|
|
1431
1703
|
footNote
|
|
1432
1704
|
] }) : null
|
|
@@ -1436,277 +1708,6 @@ function PickOrAdd({
|
|
|
1436
1708
|
] });
|
|
1437
1709
|
}
|
|
1438
1710
|
|
|
1439
|
-
// src/Refusal.tsx
|
|
1440
|
-
var import_core = require("@ai-matrx/records/core");
|
|
1441
|
-
var import_design_system7 = require("@ai-matrx/design-system");
|
|
1442
|
-
|
|
1443
|
-
// src/ArchivedOrganizationNotice.tsx
|
|
1444
|
-
var import_react9 = require("react");
|
|
1445
|
-
var import_design_system6 = require("@ai-matrx/design-system");
|
|
1446
|
-
|
|
1447
|
-
// src/host.tsx
|
|
1448
|
-
var import_react7 = require("react");
|
|
1449
|
-
var import_react8 = require("@ai-matrx/records/react");
|
|
1450
|
-
|
|
1451
|
-
// src/rights.ts
|
|
1452
|
-
var import_records7 = require("@ai-matrx/records");
|
|
1453
|
-
var LEVEL_WORD = {
|
|
1454
|
-
viewer: "Viewer",
|
|
1455
|
-
commenter: "Commenter",
|
|
1456
|
-
edit_content: "Content editor",
|
|
1457
|
-
editor: "Editor",
|
|
1458
|
-
admin: "Admin"
|
|
1459
|
-
};
|
|
1460
|
-
var NEEDS = {
|
|
1461
|
-
read: "viewer",
|
|
1462
|
-
// custom.io_comment_write
|
|
1463
|
-
comment: "commenter",
|
|
1464
|
-
// custom.record_update / custom.record_write — `edit_content` changes rows and page content;
|
|
1465
|
-
// columns, views and settings (structure) stay with admin below, and sharing with admin.
|
|
1466
|
-
write: "edit_content",
|
|
1467
|
-
// custom.view_designate / view_declare / migrate_merge / record_restore — all ask `editor`: more than
|
|
1468
|
-
// changing content (`edit_content`), less than changing columns (`admin`).
|
|
1469
|
-
organise: "editor",
|
|
1470
|
-
// custom.record_delete
|
|
1471
|
-
remove: "editor",
|
|
1472
|
-
// custom.share_grant — passing your access on is an administrator's right
|
|
1473
|
-
share: "admin",
|
|
1474
|
-
// custom.field_declare / field_update / field_retire / table settings
|
|
1475
|
-
structure: "admin"
|
|
1476
|
-
};
|
|
1477
|
-
var NOT_YET = "Still asking the store what you may do here. Nothing is offered until it has answered.";
|
|
1478
|
-
var NOTHING_AT_ALL = "You have not been given this. Ask somebody who administers it to share it with you.";
|
|
1479
|
-
function sentenceFor(what, level) {
|
|
1480
|
-
if (level === null) return NOTHING_AT_ALL;
|
|
1481
|
-
const need = LEVEL_WORD[NEEDS[what]];
|
|
1482
|
-
const have = LEVEL_WORD[level];
|
|
1483
|
-
const doing = {
|
|
1484
|
-
read: "open this",
|
|
1485
|
-
comment: "leave a comment",
|
|
1486
|
-
write: "change anything here",
|
|
1487
|
-
organise: "organise this",
|
|
1488
|
-
remove: "delete this",
|
|
1489
|
-
share: "pass this on to somebody else",
|
|
1490
|
-
structure: "change the columns of this table"
|
|
1491
|
-
};
|
|
1492
|
-
return `You are ${have} here, and it takes ${need} to ${doing[what]}. Ask somebody who is Admin on it to move you up.`;
|
|
1493
|
-
}
|
|
1494
|
-
function whatYouMayDo(level, known = true) {
|
|
1495
|
-
const may = (what) => known && (0, import_records7.atLeast)(level, NEEDS[what]);
|
|
1496
|
-
return {
|
|
1497
|
-
level: known ? level : null,
|
|
1498
|
-
known,
|
|
1499
|
-
read: may("read"),
|
|
1500
|
-
comment: may("comment"),
|
|
1501
|
-
write: may("write"),
|
|
1502
|
-
organise: may("organise"),
|
|
1503
|
-
remove: may("remove"),
|
|
1504
|
-
share: may("share"),
|
|
1505
|
-
structure: may("structure"),
|
|
1506
|
-
why: (what) => known ? sentenceFor(what, level) : NOT_YET
|
|
1507
|
-
};
|
|
1508
|
-
}
|
|
1509
|
-
var NOT_ANSWERED_YET = whatYouMayDo(null, false);
|
|
1510
|
-
var KERNEL_REASON = "This is one of the tables the platform ships, so its columns are not changed from a screen. Make your own table to change columns.";
|
|
1511
|
-
function whatYouMayDoWithTable(table, level, known) {
|
|
1512
|
-
const base = whatYouMayDo(level, known);
|
|
1513
|
-
if (!table?.is_kernel) return table && tableIsLocked(table) ? lockedStructure(base) : base;
|
|
1514
|
-
return {
|
|
1515
|
-
...base,
|
|
1516
|
-
structure: false,
|
|
1517
|
-
why: (what) => what === "structure" ? KERNEL_REASON : base.why(what)
|
|
1518
|
-
};
|
|
1519
|
-
}
|
|
1520
|
-
function tableIsLocked(table) {
|
|
1521
|
-
return table?.metadata?.["locked"] === true;
|
|
1522
|
-
}
|
|
1523
|
-
var DATABASE_LOCKED_REASON = "This database is locked, so its columns and settings are read-only. Unlock it to change them.";
|
|
1524
|
-
function lockedStructure(base) {
|
|
1525
|
-
return { ...base, structure: false, why: (what) => what === "structure" ? DATABASE_LOCKED_REASON : base.why(what) };
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
// src/host.tsx
|
|
1529
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1530
|
-
function tableRights(may, overallReason) {
|
|
1531
|
-
return {
|
|
1532
|
-
...may,
|
|
1533
|
-
admin: may.structure,
|
|
1534
|
-
reason: overallReason ?? (may.structure ? "" : may.why("structure"))
|
|
1535
|
-
};
|
|
1536
|
-
}
|
|
1537
|
-
var NO_RIGHTS = tableRights(NOT_ANSWERED_YET);
|
|
1538
|
-
var NO_MEMBERS_REASON = "This app cannot offer the people in your organization on this screen yet, so there is nobody to pick. Type the person's name into a text field for now, and tell us \u2014 it is on our list, not yours.";
|
|
1539
|
-
var NO_UPLOAD_REASON = "This screen cannot take a file yet, so there is no chooser here rather than one that loses what you pick. Put a link to the file in a text field for now. It is on our list, not yours.";
|
|
1540
|
-
var HostContext = (0, import_react7.createContext)(null);
|
|
1541
|
-
function useRecordsUi() {
|
|
1542
|
-
return (0, import_react7.useContext)(HostContext) ?? {};
|
|
1543
|
-
}
|
|
1544
|
-
function quiet(may, say) {
|
|
1545
|
-
if (say !== false) return may;
|
|
1546
|
-
return { ...may, why: () => "", ..."reason" in may ? { reason: "" } : {} };
|
|
1547
|
-
}
|
|
1548
|
-
function useTableRights(table) {
|
|
1549
|
-
const host = useRecordsUi();
|
|
1550
|
-
const asked2 = useTableRightsAsked(table, host);
|
|
1551
|
-
return (0, import_react7.useMemo)(() => quiet(asked2, host.sayLevelNeeded), [asked2, host.sayLevelNeeded]);
|
|
1552
|
-
}
|
|
1553
|
-
function useTableRightsAsked(table, host) {
|
|
1554
|
-
const bound = Boolean(host.rights);
|
|
1555
|
-
const asked2 = (0, import_react8.useMyLevel)(bound || !table ? null : table.id);
|
|
1556
|
-
return (0, import_react7.useMemo)(() => {
|
|
1557
|
-
if (!table) return NO_RIGHTS;
|
|
1558
|
-
if (host.rights) return host.rights(table);
|
|
1559
|
-
if (asked2.loading) return tableRights(NOT_ANSWERED_YET);
|
|
1560
|
-
const level = asked2.error ? null : asked2.data;
|
|
1561
|
-
return tableRights(whatYouMayDoWithTable(table, level, true));
|
|
1562
|
-
}, [host, table, bound, asked2.loading, asked2.error, asked2.data]);
|
|
1563
|
-
}
|
|
1564
|
-
|
|
1565
|
-
// src/ArchivedOrganizationNotice.tsx
|
|
1566
|
-
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1567
|
-
function ArchivedOrganizationNotice({
|
|
1568
|
-
organizationId,
|
|
1569
|
-
error,
|
|
1570
|
-
className
|
|
1571
|
-
}) {
|
|
1572
|
-
const port = useRecordsUi().archivedOrganization;
|
|
1573
|
-
const [mayRestore, setMayRestore] = (0, import_react9.useState)(null);
|
|
1574
|
-
const [busy, setBusy] = (0, import_react9.useState)(false);
|
|
1575
|
-
const [failed, setFailed] = (0, import_react9.useState)(null);
|
|
1576
|
-
(0, import_react9.useEffect)(() => {
|
|
1577
|
-
let live = true;
|
|
1578
|
-
if (!port) {
|
|
1579
|
-
setMayRestore(false);
|
|
1580
|
-
return;
|
|
1581
|
-
}
|
|
1582
|
-
setMayRestore(null);
|
|
1583
|
-
port.state(organizationId).then((answer) => {
|
|
1584
|
-
if (live) setMayRestore(answer?.mayRestore === true);
|
|
1585
|
-
}).catch(() => {
|
|
1586
|
-
if (live) setMayRestore(false);
|
|
1587
|
-
});
|
|
1588
|
-
return () => {
|
|
1589
|
-
live = false;
|
|
1590
|
-
};
|
|
1591
|
-
}, [organizationId, port?.state]);
|
|
1592
|
-
const restore = async () => {
|
|
1593
|
-
if (!port || busy) return;
|
|
1594
|
-
setBusy(true);
|
|
1595
|
-
setFailed(null);
|
|
1596
|
-
try {
|
|
1597
|
-
await port.restore(organizationId);
|
|
1598
|
-
if (port.afterRestore) port.afterRestore();
|
|
1599
|
-
else if (typeof window !== "undefined") window.location.reload();
|
|
1600
|
-
} catch (thrown) {
|
|
1601
|
-
setFailed(thrown instanceof Error && thrown.message ? thrown.message : "The organization could not be restored.");
|
|
1602
|
-
setBusy(false);
|
|
1603
|
-
}
|
|
1604
|
-
};
|
|
1605
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1606
|
-
import_design_system6.Alert,
|
|
1607
|
-
{
|
|
1608
|
-
variant: "destructive",
|
|
1609
|
-
role: "alert",
|
|
1610
|
-
"data-refusal-notice": "",
|
|
1611
|
-
"data-archived-organization": organizationId,
|
|
1612
|
-
className: (0, import_design_system6.cn)("text-xs", className),
|
|
1613
|
-
errorFacts: { message: "This organization is archived", title: "This organization is archived", error, origin: "records-ui/ArchivedOrganizationNotice" },
|
|
1614
|
-
children: [
|
|
1615
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system6.AlertTitle, { className: "text-xs font-medium", children: "This organization is archived" }),
|
|
1616
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.AlertDescription, { className: "space-y-1 text-xs", children: [
|
|
1617
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "opacity-80", children: "Nothing was deleted. Everything here comes back the moment an owner of the organization, or a super admin, restores it." }),
|
|
1618
|
-
mayRestore === true ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1619
|
-
"button",
|
|
1620
|
-
{
|
|
1621
|
-
type: "button",
|
|
1622
|
-
"data-restore-organization": "",
|
|
1623
|
-
disabled: busy,
|
|
1624
|
-
className: "rounded border px-2 py-0.5 text-xs hover:bg-muted disabled:opacity-60",
|
|
1625
|
-
onClick: () => void restore(),
|
|
1626
|
-
children: busy ? "Restoring..." : "Restore organization"
|
|
1627
|
-
}
|
|
1628
|
-
) : null,
|
|
1629
|
-
mayRestore === false ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { "data-restore-who": "", className: "opacity-80", children: "Ask an owner of this organization to restore it." }) : null,
|
|
1630
|
-
failed ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { "data-restore-refused": "", children: failed }) : null
|
|
1631
|
-
] })
|
|
1632
|
-
]
|
|
1633
|
-
}
|
|
1634
|
-
);
|
|
1635
|
-
}
|
|
1636
|
-
|
|
1637
|
-
// src/Refusal.tsx
|
|
1638
|
-
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1639
|
-
function RefusalNotice({
|
|
1640
|
-
error,
|
|
1641
|
-
className,
|
|
1642
|
-
actions,
|
|
1643
|
-
onKeepEditing,
|
|
1644
|
-
onDiscard
|
|
1645
|
-
}) {
|
|
1646
|
-
const archivedOrg = (0, import_core.archivedOrganizationId)(error);
|
|
1647
|
-
if (archivedOrg) {
|
|
1648
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ArchivedOrganizationNotice, { organizationId: archivedOrg, error, className });
|
|
1649
|
-
}
|
|
1650
|
-
const plain = refusalForAPerson(error);
|
|
1651
|
-
const doors = onKeepEditing || onDiscard ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-wrap items-center gap-1 pt-0.5", "data-refusal-doors": "", children: [
|
|
1652
|
-
onKeepEditing ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1653
|
-
"button",
|
|
1654
|
-
{
|
|
1655
|
-
type: "button",
|
|
1656
|
-
"data-refusal-keep-editing": "",
|
|
1657
|
-
className: "rounded border px-2 py-0.5 text-xs hover:bg-muted",
|
|
1658
|
-
onClick: onKeepEditing,
|
|
1659
|
-
children: "Keep editing"
|
|
1660
|
-
}
|
|
1661
|
-
) : null,
|
|
1662
|
-
onDiscard ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1663
|
-
"button",
|
|
1664
|
-
{
|
|
1665
|
-
type: "button",
|
|
1666
|
-
"data-refusal-discard": "",
|
|
1667
|
-
className: "rounded border px-2 py-0.5 text-xs hover:bg-muted",
|
|
1668
|
-
onClick: onDiscard,
|
|
1669
|
-
children: "Discard"
|
|
1670
|
-
}
|
|
1671
|
-
) : null
|
|
1672
|
-
] }) : null;
|
|
1673
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1674
|
-
import_design_system7.Alert,
|
|
1675
|
-
{
|
|
1676
|
-
variant: "destructive",
|
|
1677
|
-
role: "alert",
|
|
1678
|
-
"data-refusal-notice": "",
|
|
1679
|
-
className: (0, import_design_system7.cn)("text-xs", className),
|
|
1680
|
-
errorFacts: { message: plain.sentence, title: plain.title, error, origin: "records-ui/RefusalNotice" },
|
|
1681
|
-
...plain.forEngineers ? { "data-for-engineers": plain.forEngineers } : {},
|
|
1682
|
-
...error.sqlstate ? { "data-sqlstate": error.sqlstate } : {},
|
|
1683
|
-
children: [
|
|
1684
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_design_system7.AlertTitle, { className: "text-xs font-medium", children: plain.storeSaid ? plain.sentence : plain.title }),
|
|
1685
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_design_system7.AlertDescription, { className: "space-y-1 text-xs", children: [
|
|
1686
|
-
plain.storeSaid || plain.sentence.replace(/\.$/, "") === plain.title ? null : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: plain.sentence }),
|
|
1687
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "opacity-80", children: plain.remedy }),
|
|
1688
|
-
actions,
|
|
1689
|
-
doors
|
|
1690
|
-
] })
|
|
1691
|
-
]
|
|
1692
|
-
}
|
|
1693
|
-
);
|
|
1694
|
-
}
|
|
1695
|
-
function RefusalLine({ error, className }) {
|
|
1696
|
-
const plain = refusalForAPerson(error);
|
|
1697
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1698
|
-
import_design_system7.ErrorBox,
|
|
1699
|
-
{
|
|
1700
|
-
"data-refusal-line": "",
|
|
1701
|
-
className: (0, import_design_system7.cn)("text-xs text-destructive", className),
|
|
1702
|
-
message: (0, import_core.archivedOrganizationId)(error) ? "This organization is archived. An owner can restore it." : refusalLineForAPerson(error),
|
|
1703
|
-
error,
|
|
1704
|
-
origin: "records-ui/RefusalLine",
|
|
1705
|
-
...plain.forEngineers ? { "data-for-engineers": plain.forEngineers } : {}
|
|
1706
|
-
}
|
|
1707
|
-
);
|
|
1708
|
-
}
|
|
1709
|
-
|
|
1710
1711
|
// src/refusals.ts
|
|
1711
1712
|
var refusals_exports = {};
|
|
1712
1713
|
__reExport(refusals_exports, require("@ai-matrx/records/versions"));
|