@ai-matrx/design-system 0.86.356 → 0.86.358
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 +16 -0
- package/dist/auth-gate-dialog.js +2 -2
- package/dist/carousel.js +11 -10
- package/dist/carousel.js.map +1 -1
- package/dist/{chunk-UWTODOMD.js → chunk-2BQAHLU3.js} +4 -4
- package/dist/{chunk-T4D7WAV7.js → chunk-42GFQMLA.js} +2 -2
- package/dist/chunk-5Z5GTXKL.js +79 -0
- package/dist/chunk-5Z5GTXKL.js.map +1 -0
- package/dist/{chunk-POJ3RR3K.js → chunk-B5D3VIMC.js} +1 -1
- package/dist/{chunk-POJ3RR3K.js.map → chunk-B5D3VIMC.js.map} +1 -1
- package/dist/{chunk-4WSXAP24.js → chunk-BB5LA7FQ.js} +3 -1
- package/dist/chunk-BB5LA7FQ.js.map +1 -0
- package/dist/{chunk-FRJ4PPA2.js → chunk-CZGZV35G.js} +2 -2
- package/dist/{chunk-RLM4RSED.js → chunk-GUGBVQ4T.js} +6 -4
- package/dist/{chunk-RLM4RSED.js.map → chunk-GUGBVQ4T.js.map} +1 -1
- package/dist/{chunk-LJKF267O.js → chunk-HS6GMHKZ.js} +18 -76
- package/dist/chunk-HS6GMHKZ.js.map +1 -0
- package/dist/{chunk-2PO3N42Q.js → chunk-K3XWUACX.js} +5 -5
- package/dist/{chunk-ZMUPFGQO.js → chunk-K5ZQROWN.js} +5 -5
- package/dist/{chunk-U46XUQI7.js → chunk-KSCSH7AO.js} +16 -14
- package/dist/chunk-KSCSH7AO.js.map +1 -0
- package/dist/{chunk-MTE6N7XU.js → chunk-NFJ63LIH.js} +2 -2
- package/dist/{chunk-CFUXEGW2.js → chunk-OUQT72UL.js} +4 -4
- package/dist/{chunk-WUD23YTG.js → chunk-P56Y43RL.js} +6 -6
- package/dist/{chunk-GMNROZQJ.js → chunk-QTPW44IJ.js} +2 -2
- package/dist/{chunk-QA7EHFRX.js → chunk-T3FKFPCW.js} +5 -5
- package/dist/{chunk-X6ZRHJQP.js → chunk-T57DLONB.js} +20 -11
- package/dist/chunk-T57DLONB.js.map +1 -0
- package/dist/{chunk-SOCNWQMX.js → chunk-TEMAM5ET.js} +3 -3
- package/dist/{chunk-CH2NWSES.js → chunk-TIV6M7Q7.js} +3 -3
- package/dist/{chunk-6XNYYROM.js → chunk-WVEDW5VO.js} +2 -2
- package/dist/clipboard-fallback-dialog.js +4 -4
- package/dist/controls.cjs +34 -13
- package/dist/controls.cjs.map +1 -1
- package/dist/controls.js +9 -8
- package/dist/data-table/data-row-inspector.cjs +99 -11
- package/dist/data-table/data-row-inspector.cjs.map +1 -1
- package/dist/data-table/data-row-inspector.js +8 -7
- package/dist/data-table/data-row-window.cjs +99 -11
- package/dist/data-table/data-row-window.cjs.map +1 -1
- package/dist/data-table/data-row-window.js +11 -10
- package/dist/data-table/drill-chart.cjs +15 -3
- package/dist/data-table/drill-chart.cjs.map +1 -1
- package/dist/data-table/drill-chart.js +2 -1
- package/dist/data-table/drill-chart.js.map +1 -1
- package/dist/data-table/host.cjs.map +1 -1
- package/dist/data-table/host.d.cts +6 -2
- package/dist/data-table/host.d.ts +6 -2
- package/dist/data-table/host.js +1 -1
- package/dist/data-table/index.cjs +54 -40
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.d.cts +6 -2
- package/dist/data-table/index.d.ts +6 -2
- package/dist/data-table/index.js +25 -28
- package/dist/data-table/index.js.map +1 -1
- package/dist/data-table/pagination.cjs +19 -10
- package/dist/data-table/pagination.cjs.map +1 -1
- package/dist/data-table/pagination.js +4 -4
- package/dist/data-table/uuid-cell.cjs +99 -11
- package/dist/data-table/uuid-cell.cjs.map +1 -1
- package/dist/data-table/uuid-cell.js +5 -4
- package/dist/desktop.cjs +45 -15
- package/dist/desktop.cjs.map +1 -1
- package/dist/desktop.js +23 -15
- package/dist/desktop.js.map +1 -1
- package/dist/email-input-dialog.cjs +15 -3
- package/dist/email-input-dialog.cjs.map +1 -1
- package/dist/email-input-dialog.js +4 -3
- package/dist/email-input-dialog.js.map +1 -1
- package/dist/error-sentence.cjs +130 -0
- package/dist/error-sentence.cjs.map +1 -0
- package/dist/error-sentence.d.cts +49 -0
- package/dist/error-sentence.d.ts +49 -0
- package/dist/error-sentence.js +22 -0
- package/dist/error-sentence.js.map +1 -0
- package/dist/index.cjs +47 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -10
- package/dist/index.d.ts +12 -10
- package/dist/index.js +30 -28
- package/dist/index.js.map +1 -1
- package/dist/item.cjs +19 -10
- package/dist/item.cjs.map +1 -1
- package/dist/item.js +7 -7
- package/dist/lite-table.cjs +15 -3
- package/dist/lite-table.cjs.map +1 -1
- package/dist/lite-table.js +5 -4
- package/dist/lite-table.js.map +1 -1
- package/dist/menu-look.cjs +19 -10
- package/dist/menu-look.cjs.map +1 -1
- package/dist/menu-look.js +2 -2
- package/dist/notice-stack.cjs +2 -0
- package/dist/notice-stack.cjs.map +1 -1
- package/dist/notice-stack.d.cts +11 -1
- package/dist/notice-stack.d.ts +11 -1
- package/dist/notice-stack.js +3 -1
- package/dist/record-list.cjs +34 -13
- package/dist/record-list.cjs.map +1 -1
- package/dist/record-list.js +8 -7
- package/dist/record-list.js.map +1 -1
- package/dist/sandbox-gate-dialog.js +2 -2
- package/dist/scope-mismatch-dialog.js +2 -2
- package/dist/settings.js +3 -3
- package/dist/swipe-deck.cjs +15 -3
- package/dist/swipe-deck.cjs.map +1 -1
- package/dist/swipe-deck.js +2 -1
- package/dist/swipe-deck.js.map +1 -1
- package/dist/text-input-dialog.cjs +15 -3
- package/dist/text-input-dialog.cjs.map +1 -1
- package/dist/text-input-dialog.js +4 -3
- package/dist/text-input-dialog.js.map +1 -1
- package/dist/value-prompts-dialog.js +2 -2
- package/dist/writing-field.js +5 -5
- package/package.json +12 -2
- package/dist/chunk-4WSXAP24.js.map +0 -1
- package/dist/chunk-LJKF267O.js.map +0 -1
- package/dist/chunk-U46XUQI7.js.map +0 -1
- package/dist/chunk-X6ZRHJQP.js.map +0 -1
- /package/dist/{chunk-UWTODOMD.js.map → chunk-2BQAHLU3.js.map} +0 -0
- /package/dist/{chunk-T4D7WAV7.js.map → chunk-42GFQMLA.js.map} +0 -0
- /package/dist/{chunk-FRJ4PPA2.js.map → chunk-CZGZV35G.js.map} +0 -0
- /package/dist/{chunk-2PO3N42Q.js.map → chunk-K3XWUACX.js.map} +0 -0
- /package/dist/{chunk-ZMUPFGQO.js.map → chunk-K5ZQROWN.js.map} +0 -0
- /package/dist/{chunk-MTE6N7XU.js.map → chunk-NFJ63LIH.js.map} +0 -0
- /package/dist/{chunk-CFUXEGW2.js.map → chunk-OUQT72UL.js.map} +0 -0
- /package/dist/{chunk-WUD23YTG.js.map → chunk-P56Y43RL.js.map} +0 -0
- /package/dist/{chunk-GMNROZQJ.js.map → chunk-QTPW44IJ.js.map} +0 -0
- /package/dist/{chunk-QA7EHFRX.js.map → chunk-T3FKFPCW.js.map} +0 -0
- /package/dist/{chunk-SOCNWQMX.js.map → chunk-TEMAM5ET.js.map} +0 -0
- /package/dist/{chunk-CH2NWSES.js.map → chunk-TIV6M7Q7.js.map} +0 -0
- /package/dist/{chunk-6XNYYROM.js.map → chunk-WVEDW5VO.js.map} +0 -0
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-XERGQT2M.js";
|
|
8
8
|
import {
|
|
9
9
|
ErrorActions
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5Z5GTXKL.js";
|
|
11
11
|
import {
|
|
12
12
|
Dialog,
|
|
13
13
|
DialogContent,
|
|
@@ -15,12 +15,13 @@ import {
|
|
|
15
15
|
DialogFooter,
|
|
16
16
|
DialogHeader,
|
|
17
17
|
DialogTitle
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-2BQAHLU3.js";
|
|
19
|
+
import "./chunk-LEPD6TV7.js";
|
|
19
20
|
import "./chunk-U24MOJWK.js";
|
|
20
21
|
import "./chunk-NDTDBBMM.js";
|
|
21
|
-
import "./chunk-LEPD6TV7.js";
|
|
22
22
|
import "./chunk-BKCJUFD3.js";
|
|
23
23
|
import "./chunk-MOZRIHJF.js";
|
|
24
|
+
import "./chunk-HS6GMHKZ.js";
|
|
24
25
|
import "./chunk-WFITMVDB.js";
|
|
25
26
|
import "./chunk-WAT2XW7L.js";
|
|
26
27
|
import {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/email-input-dialog.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * EmailInputDialog — moved from matrx-frontend components/dialogs/EmailInputDialog.tsx.\n *\n * Reusable dialog for collecting an email address (public / signed-out features that need one).\n * The send itself is the host's: `onSubmit(email)` resolves on success (the dialog closes) or throws\n * (the message shows under the field).\n */\n\nimport * as React from \"react\";\n\nimport { Button } from \"./button\";\nimport { Input } from \"./controls/doors\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"./dialog\";\nimport { ErrorActions } from \"./error-box\";\nimport { Loader2Icon, MailIcon } from \"./icons\";\nimport { Label } from \"./label\";\n\nexport interface EmailInputDialogProps {\n isOpen: boolean;\n onClose: () => void;\n onSubmit: (email: string) => Promise<void>;\n title?: string;\n description?: string;\n submitLabel?: string;\n}\n\nconst isValidEmail = (email: string) => /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n\nexport function EmailInputDialog({\n isOpen,\n onClose,\n onSubmit,\n title = \"Email to yourself\",\n description = \"Enter your email address to receive the content.\",\n submitLabel = \"Send Email\",\n}: EmailInputDialogProps) {\n const [email, setEmail] = React.useState(\"\");\n const [loading, setLoading] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!email.trim()) {\n setError(\"Email is required\");\n return;\n }\n if (!isValidEmail(email)) {\n setError(\"Please enter a valid email address\");\n return;\n }\n setLoading(true);\n setError(null);\n try {\n await onSubmit(email);\n setEmail(\"\");\n onClose();\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to send email\");\n } finally {\n setLoading(false);\n }\n };\n\n const handleClose = () => {\n if (loading) return;\n setEmail(\"\");\n setError(null);\n onClose();\n };\n\n return (\n <Dialog open={isOpen} onOpenChange={handleClose}>\n <DialogContent size=\"sm\">\n <form onSubmit={handleSubmit} noValidate className=\"flex flex-col gap-4\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2\">\n <MailIcon className=\"h-5 w-5 text-primary\" />\n {title}\n </DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"email-input-dialog-email\">Email address</Label>\n <Input\n id=\"email-input-dialog-email\"\n type=\"email\"\n placeholder=\"you@example.com\"\n value={email}\n onChange={(e) => {\n setEmail(e.target.value);\n setError(null);\n }}\n disabled={loading}\n autoFocus\n />\n {error ? (\n <p className=\"text-sm text-destructive\">\n {error}\n <ErrorActions\n message={error}\n operation=\"Email this content\"\n source=\"inline\"\n origin=\"design-system/EmailInputDialog\"\n />\n </p>\n ) : email.trim() && !isValidEmail(email.trim()) ? (\n // An offer, never a block: Send stays enabled; pressing it names the problem.\n <p className=\"text-sm text-muted-foreground\" data-email-hint>\n Not a full address yet, like you@example.com\n </p>\n ) : null}\n </div>\n\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={handleClose} disabled={loading}>\n Cancel\n </Button>\n <Button variant=\"primary\" type=\"submit\" disabled={loading || !email.trim()}>\n {loading ? (\n <>\n <Loader2Icon className=\"mr-2 h-4 w-4 matrx-spin\" />\n Sending...\n </>\n ) : (\n <>\n <MailIcon className=\"mr-2 h-4 w-4\" />\n {submitLabel}\n </>\n )}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n\nexport default EmailInputDialog;\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/email-input-dialog.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * EmailInputDialog — moved from matrx-frontend components/dialogs/EmailInputDialog.tsx.\n *\n * Reusable dialog for collecting an email address (public / signed-out features that need one).\n * The send itself is the host's: `onSubmit(email)` resolves on success (the dialog closes) or throws\n * (the message shows under the field).\n */\n\nimport * as React from \"react\";\n\nimport { Button } from \"./button\";\nimport { Input } from \"./controls/doors\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"./dialog\";\nimport { ErrorActions } from \"./error-box\";\nimport { Loader2Icon, MailIcon } from \"./icons\";\nimport { Label } from \"./label\";\n\nexport interface EmailInputDialogProps {\n isOpen: boolean;\n onClose: () => void;\n onSubmit: (email: string) => Promise<void>;\n title?: string;\n description?: string;\n submitLabel?: string;\n}\n\nconst isValidEmail = (email: string) => /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n\nexport function EmailInputDialog({\n isOpen,\n onClose,\n onSubmit,\n title = \"Email to yourself\",\n description = \"Enter your email address to receive the content.\",\n submitLabel = \"Send Email\",\n}: EmailInputDialogProps) {\n const [email, setEmail] = React.useState(\"\");\n const [loading, setLoading] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!email.trim()) {\n setError(\"Email is required\");\n return;\n }\n if (!isValidEmail(email)) {\n setError(\"Please enter a valid email address\");\n return;\n }\n setLoading(true);\n setError(null);\n try {\n await onSubmit(email);\n setEmail(\"\");\n onClose();\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to send email\");\n } finally {\n setLoading(false);\n }\n };\n\n const handleClose = () => {\n if (loading) return;\n setEmail(\"\");\n setError(null);\n onClose();\n };\n\n return (\n <Dialog open={isOpen} onOpenChange={handleClose}>\n <DialogContent size=\"sm\">\n <form onSubmit={handleSubmit} noValidate className=\"flex flex-col gap-4\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2\">\n <MailIcon className=\"h-5 w-5 text-primary\" />\n {title}\n </DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"email-input-dialog-email\">Email address</Label>\n <Input\n id=\"email-input-dialog-email\"\n type=\"email\"\n placeholder=\"you@example.com\"\n value={email}\n onChange={(e) => {\n setEmail(e.target.value);\n setError(null);\n }}\n disabled={loading}\n autoFocus\n />\n {error ? (\n <p className=\"text-sm text-destructive\">\n {error}\n <ErrorActions\n message={error}\n operation=\"Email this content\"\n source=\"inline\"\n origin=\"design-system/EmailInputDialog\"\n />\n </p>\n ) : email.trim() && !isValidEmail(email.trim()) ? (\n // An offer, never a block: Send stays enabled; pressing it names the problem.\n <p className=\"text-sm text-muted-foreground\" data-email-hint>\n Not a full address yet, like you@example.com\n </p>\n ) : null}\n </div>\n\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={handleClose} disabled={loading}>\n Cancel\n </Button>\n <Button variant=\"primary\" type=\"submit\" disabled={loading || !email.trim()}>\n {loading ? (\n <>\n <Loader2Icon className=\"mr-2 h-4 w-4 matrx-spin\" />\n Sending...\n </>\n ) : (\n <>\n <MailIcon className=\"mr-2 h-4 w-4\" />\n {submitLabel}\n </>\n )}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n\nexport default EmailInputDialog;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,YAAY,WAAW;AA0EX,SA6CI,UA5CF,KADF;AAjDZ,IAAM,eAAe,CAAC,UAAkB,6BAA6B,KAAK,KAAK;AAExE,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,cAAc;AAChB,GAA0B;AACxB,QAAM,CAAC,OAAO,QAAQ,IAAU,eAAS,EAAE;AAC3C,QAAM,CAAC,SAAS,UAAU,IAAU,eAAS,KAAK;AAClD,QAAM,CAAC,OAAO,QAAQ,IAAU,eAAwB,IAAI;AAE5D,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAe;AACjB,QAAI,CAAC,MAAM,KAAK,GAAG;AACjB,eAAS,mBAAmB;AAC5B;AAAA,IACF;AACA,QAAI,CAAC,aAAa,KAAK,GAAG;AACxB,eAAS,oCAAoC;AAC7C;AAAA,IACF;AACA,eAAW,IAAI;AACf,aAAS,IAAI;AACb,QAAI;AACF,YAAM,SAAS,KAAK;AACpB,eAAS,EAAE;AACX,cAAQ;AAAA,IACV,SAAS,KAAK;AACZ,eAAS,eAAe,QAAQ,IAAI,UAAU,sBAAsB;AAAA,IACtE,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF;AAEA,QAAM,cAAc,MAAM;AACxB,QAAI,QAAS;AACb,aAAS,EAAE;AACX,aAAS,IAAI;AACb,YAAQ;AAAA,EACV;AAEA,SACE,oBAAC,UAAO,MAAM,QAAQ,cAAc,aAClC,8BAAC,iBAAc,MAAK,MAClB,+BAAC,UAAK,UAAU,cAAc,YAAU,MAAC,WAAU,uBACjD;AAAA,yBAAC,gBACC;AAAA,2BAAC,eAAY,WAAU,2BACrB;AAAA,4BAAC,YAAS,WAAU,wBAAuB;AAAA,QAC1C;AAAA,SACH;AAAA,MACA,oBAAC,qBAAmB,uBAAY;AAAA,OAClC;AAAA,IAEA,qBAAC,SAAI,WAAU,aACb;AAAA,0BAAC,SAAM,SAAQ,4BAA2B,2BAAa;AAAA,MACvD;AAAA,QAAC;AAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,aAAY;AAAA,UACZ,OAAO;AAAA,UACP,UAAU,CAAC,MAAM;AACf,qBAAS,EAAE,OAAO,KAAK;AACvB,qBAAS,IAAI;AAAA,UACf;AAAA,UACA,UAAU;AAAA,UACV,WAAS;AAAA;AAAA,MACX;AAAA,MACC,QACC,qBAAC,OAAE,WAAU,4BACV;AAAA;AAAA,QACD;AAAA,UAAC;AAAA;AAAA,YACC,SAAS;AAAA,YACT,WAAU;AAAA,YACV,QAAO;AAAA,YACP,QAAO;AAAA;AAAA,QACT;AAAA,SACF,IACE,MAAM,KAAK,KAAK,CAAC,aAAa,MAAM,KAAK,CAAC;AAAA;AAAA,QAE5C,oBAAC,OAAE,WAAU,iCAAgC,mBAAe,MAAC,0DAE7D;AAAA,UACE;AAAA,OACN;AAAA,IAEA,qBAAC,gBACC;AAAA,0BAAC,UAAO,MAAK,UAAS,SAAQ,WAAU,SAAS,aAAa,UAAU,SAAS,oBAEjF;AAAA,MACA,oBAAC,UAAO,SAAQ,WAAU,MAAK,UAAS,UAAU,WAAW,CAAC,MAAM,KAAK,GACtE,oBACC,iCACE;AAAA,4BAAC,eAAY,WAAU,2BAA0B;AAAA,QAAE;AAAA,SAErD,IAEA,iCACE;AAAA,4BAAC,YAAS,WAAU,gBAAe;AAAA,QAClC;AAAA,SACH,GAEJ;AAAA,OACF;AAAA,KACF,GACF,GACF;AAEJ;AAEA,IAAO,6BAAQ;","names":[]}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/error-sentence.ts
|
|
22
|
+
var error_sentence_exports = {};
|
|
23
|
+
__export(error_sentence_exports, {
|
|
24
|
+
CARD_ERROR_LINE: () => CARD_ERROR_LINE,
|
|
25
|
+
FALLBACK_ERROR_SENTENCE: () => FALLBACK_ERROR_SENTENCE,
|
|
26
|
+
TIMED_OUT_SENTENCE: () => TIMED_OUT_SENTENCE,
|
|
27
|
+
errorSentenceOf: () => errorSentenceOf,
|
|
28
|
+
isOfflineError: () => isOfflineError,
|
|
29
|
+
isRawErrorText: () => isRawErrorText,
|
|
30
|
+
isTimedOutError: () => isTimedOutError,
|
|
31
|
+
peopleErrorSentence: () => peopleErrorSentence
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(error_sentence_exports);
|
|
34
|
+
|
|
35
|
+
// src/desktop/errors.ts
|
|
36
|
+
var RULES = [
|
|
37
|
+
{ code: "ENOENT", test: /\b(spawn\s+\S+\s+)?ENOENT\b|command not found|no such file or directory/i, cause: "A program or file it needs isn't on this computer. Install it or update Matrx, then try again." },
|
|
38
|
+
{ code: "EACCES", test: /\bEACCES\b|\bEPERM\b|permission denied|operation not permitted|not authori[sz]ed by the user/i, cause: "Matrx isn't allowed to do that. Grant access in System Settings \u203A Privacy & Security, then try again." },
|
|
39
|
+
{ code: "EADDRINUSE", test: /\bEADDRINUSE\b|address already in use|port .* (is )?(already )?in use/i, cause: "Another program is already using that port. Stop it, or choose another port." },
|
|
40
|
+
{ code: "ECONNREFUSED", test: /\bECONNREFUSED\b|connection refused/i, cause: "The service isn't answering. It may have stopped; start it again." },
|
|
41
|
+
{ code: "OFFLINE", test: /\bENOTFOUND\b|\bEAI_AGAIN\b|\bENETUNREACH\b|getaddrinfo|network (is )?unreachable|failed to fetch|offline/i, cause: "Can't reach the internet. Check the connection and try again." },
|
|
42
|
+
{ code: "TIMEOUT", test: /\bETIMEDOUT\b|timed? ?out|\bTIMEOUT\b|deadline exceeded/i, cause: "It took too long to answer. Try again in a moment." },
|
|
43
|
+
{ code: "ENOSPC", test: /\bENOSPC\b|no space left/i, cause: "The disk is full. Free some space, then try again." },
|
|
44
|
+
{ code: "ENOMEM", test: /\bENOMEM\b|out of memory|cannot allocate memory/i, cause: "The computer ran out of memory. Close something and try again." },
|
|
45
|
+
{ code: "UNAUTHORIZED", test: /\b401\b|unauthori[sz]ed|invalid (api )?key|not signed in|jwt expired|session expired/i, cause: "You're signed out, or the key was refused. Sign in again." },
|
|
46
|
+
{ code: "FORBIDDEN", test: /\b403\b|forbidden/i, cause: "This account isn't allowed to do that." },
|
|
47
|
+
{ code: "NOT_FOUND", test: /\b404\b|not found/i, cause: "It isn't there any more. Refresh and try again." },
|
|
48
|
+
{ code: "RATE_LIMIT", test: /\b429\b|rate.?limit|too many requests/i, cause: "Too many requests just now. Wait a moment and try again." },
|
|
49
|
+
{ code: "SERVER", test: /\b5\d\d\b|internal server error|bad gateway|service unavailable/i, cause: "The server had a problem. Try again in a moment." },
|
|
50
|
+
{ code: "EXITED", test: /exited with code|process exited|crashed|SIGKILL|SIGSEGV|SIGTERM/i, cause: "The service stopped unexpectedly. Start it again; Copy details if it keeps happening." }
|
|
51
|
+
];
|
|
52
|
+
var RAW = /\b[A-Z]{2,}[A-Z_]*\b|[\\/][\w.-]+[\\/]|\bat \S+ \(|\{|\}|errno|stack|undefined|null|\bspawn\b/;
|
|
53
|
+
function rawText(error) {
|
|
54
|
+
if (error instanceof Error) return error.message || error.name;
|
|
55
|
+
if (typeof error === "string") return error;
|
|
56
|
+
if (error && typeof error === "object" && "message" in error && typeof error.message === "string") {
|
|
57
|
+
return error.message;
|
|
58
|
+
}
|
|
59
|
+
return "";
|
|
60
|
+
}
|
|
61
|
+
function describeError(error, fallback = "Something went wrong. Try again.") {
|
|
62
|
+
const detail = rawText(error).trim();
|
|
63
|
+
if (!detail) return { cause: fallback, detail: "" };
|
|
64
|
+
for (const rule of RULES) {
|
|
65
|
+
if (rule.test.test(detail)) return { cause: rule.cause, detail, code: rule.code };
|
|
66
|
+
}
|
|
67
|
+
if (!RAW.test(detail) && detail.length <= 160) return { cause: detail, detail: "" };
|
|
68
|
+
return { cause: fallback, detail };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/error-sentence.ts
|
|
72
|
+
function errorSentenceOf(error) {
|
|
73
|
+
if (error == null || error === true || error === false) return "";
|
|
74
|
+
if (typeof error === "string") return error;
|
|
75
|
+
if (typeof error !== "object") return String(error);
|
|
76
|
+
const message = error.message;
|
|
77
|
+
return typeof message === "string" ? message : "";
|
|
78
|
+
}
|
|
79
|
+
var TIMED_OUT_SENTENCE = "That took too long. Nothing was lost; try again.";
|
|
80
|
+
var FALLBACK_ERROR_SENTENCE = "Something went wrong. Try again.";
|
|
81
|
+
var CARD_ERROR_LINE = {
|
|
82
|
+
OFFLINE: "No connection",
|
|
83
|
+
TIMEOUT: "Took too long. Nothing was lost.",
|
|
84
|
+
UNAUTHORIZED: "Signed out. Sign in again.",
|
|
85
|
+
FORBIDDEN: "Not allowed for this account",
|
|
86
|
+
NOT_FOUND: "Not found. Refresh and retry.",
|
|
87
|
+
RATE_LIMIT: "Too many requests. Wait a moment.",
|
|
88
|
+
SERVER: "Server problem. Try again soon.",
|
|
89
|
+
FALLBACK: "Something went wrong"
|
|
90
|
+
};
|
|
91
|
+
function isTimedOutError(error, message, code) {
|
|
92
|
+
if (code === "57014" || code === "timed_out") return true;
|
|
93
|
+
if (error && typeof error === "object") {
|
|
94
|
+
const o = error;
|
|
95
|
+
if (o.code === "57014" || o.code === "timed_out" || o.sqlstate === "57014") return true;
|
|
96
|
+
}
|
|
97
|
+
const text = `${message ?? ""} ${errorSentenceOf(error)}`;
|
|
98
|
+
return /canceling statement due to statement timeout/i.test(text);
|
|
99
|
+
}
|
|
100
|
+
function isOfflineError(error, message) {
|
|
101
|
+
if (typeof navigator !== "undefined" && navigator.onLine === false) return true;
|
|
102
|
+
return offlineText(`${message ?? ""} ${errorSentenceOf(error)}`);
|
|
103
|
+
}
|
|
104
|
+
function offlineText(text) {
|
|
105
|
+
const t = text.trim();
|
|
106
|
+
return t !== "" && (describeError(t).code === "OFFLINE" || /networkerror|network request failed|load failed/i.test(t));
|
|
107
|
+
}
|
|
108
|
+
var ANY_HOST_CODES = /* @__PURE__ */ new Set(["OFFLINE", "TIMEOUT", "UNAUTHORIZED", "FORBIDDEN", "NOT_FOUND", "RATE_LIMIT", "SERVER"]);
|
|
109
|
+
var MACHINE_PREFIX = /^\s*(?:\[[\w./-]+\]\s*|[a-z][\w]*(?:[._][\w]+)+:\s+)/;
|
|
110
|
+
var RAW_TEXT = /\b(?:Type|Reference|Syntax|Range|Internal|Eval|URI)Error\b|\bat\s+[\w$.<>]+\s*\(|\.(?:[cm]?[jt]sx?|py):\d+|(?:^|[\s(])(?:\/[\w.@-]+){2,}|\bundefined is not\b|\bcannot read propert(?:y|ies)\b|\bis not a function\b|\bunexpected token\b/i;
|
|
111
|
+
function isRawErrorText(text) {
|
|
112
|
+
return MACHINE_PREFIX.test(text) || RAW_TEXT.test(text);
|
|
113
|
+
}
|
|
114
|
+
function peopleErrorSentence(error, message, options = {}) {
|
|
115
|
+
const card = options.card === true;
|
|
116
|
+
if (isTimedOutError(error, message, options.code)) return card ? CARD_ERROR_LINE.TIMEOUT : TIMED_OUT_SENTENCE;
|
|
117
|
+
const fallback = options.fallback ?? (card ? CARD_ERROR_LINE.FALLBACK : FALLBACK_ERROR_SENTENCE);
|
|
118
|
+
const raw = message?.trim() || errorSentenceOf(error).trim();
|
|
119
|
+
if (!raw) return fallback;
|
|
120
|
+
let text = raw;
|
|
121
|
+
for (let i = 0; i < 3 && MACHINE_PREFIX.test(text); i++) text = text.replace(MACHINE_PREFIX, "").trim();
|
|
122
|
+
if (!text) return fallback;
|
|
123
|
+
if (offlineText(text) || RAW_TEXT.test(text) || text !== raw) {
|
|
124
|
+
const said = describeError(text, fallback);
|
|
125
|
+
if (!said.code || !ANY_HOST_CODES.has(said.code)) return fallback;
|
|
126
|
+
return card ? CARD_ERROR_LINE[said.code] : said.cause;
|
|
127
|
+
}
|
|
128
|
+
return text;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=error-sentence.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/error-sentence.ts","../src/desktop/errors.ts"],"sourcesContent":["/**\n * THE SENTENCE A PERSON READS FOR AN ERROR — the one funnel every error surface draws through\n * (ErrorNotice, ErrorBox, the desktop Banner). Raw error text never reaches the screen: no\n * \"TypeError: Failed to fetch\", no `sidebar_conversations:` RPC prefix, no stack frame or file\n * path (Arman, 2026-10-24: notices are small and plain). The raw error still travels to the\n * Alchemy Menu / AI payload through the `error` prop; only the screen gets the sentence.\n *\n * The wording table is desktop/errors.ts `describeError` (one table for every screen); this file\n * adds what decides WHEN a sentence must go through it, narrow enough that an app's own sentence\n * (\"PDF too large\") passes untouched.\n */\nimport { describeError } from \"./desktop/errors\";\n\n/**\n * The sentence an error carries: its own message (string, Error, or any\n * object with a `message`). Empty when it has none.\n */\nexport function errorSentenceOf(error: unknown): string {\n if (error == null || error === true || error === false) return \"\";\n if (typeof error === \"string\") return error;\n if (typeof error !== \"object\") return String(error);\n const message = (error as { message?: unknown }).message;\n return typeof message === \"string\" ? message : \"\";\n}\n\n/**\n * What a person reads when the store cancelled a call at its statement timeout\n * (SQLSTATE 57014). Postgres' own \"canceling statement due to statement\n * timeout\" is about the database, not the person; the cancelled call rolled\n * back, so nothing was written (lane AT-SLOW, 2026-10-19). The same sentence\n * @ai-matrx/records' `TIMED_OUT_MESSAGE` gives.\n */\nexport const TIMED_OUT_SENTENCE = \"That took too long. Nothing was lost; try again.\";\n\n/** What a person reads when an error says nothing a person can use. */\nexport const FALLBACK_ERROR_SENTENCE = \"Something went wrong. Try again.\";\n\n/**\n * A notice CARD's words (the web toast, Matrx 2's floating card): a card is ~22 rem at most and its\n * action shares the row, so a line is a few words (notice-stack.ts NOTICE_TEXT_BUDGET). The same\n * causes as the sentences above, said short enough to fit at the smallest window, never cut by \"…\".\n */\nexport const CARD_ERROR_LINE = {\n OFFLINE: \"No connection\",\n TIMEOUT: \"Took too long. Nothing was lost.\",\n UNAUTHORIZED: \"Signed out. Sign in again.\",\n FORBIDDEN: \"Not allowed for this account\",\n NOT_FOUND: \"Not found. Refresh and retry.\",\n RATE_LIMIT: \"Too many requests. Wait a moment.\",\n SERVER: \"Server problem. Try again soon.\",\n FALLBACK: \"Something went wrong\",\n} as const;\n\n/** True when an error, its code, or its sentence is the store's statement timeout. */\nexport function isTimedOutError(error: unknown, message?: string | null, code?: string | number): boolean {\n if (code === \"57014\" || code === \"timed_out\") return true;\n if (error && typeof error === \"object\") {\n const o = error as { code?: unknown; sqlstate?: unknown };\n if (o.code === \"57014\" || o.code === \"timed_out\" || o.sqlstate === \"57014\") return true;\n }\n const text = `${message ?? \"\"} ${errorSentenceOf(error)}`;\n return /canceling statement due to statement timeout/i.test(text);\n}\n\n/** True when the call failed because the device is offline or the network never answered. */\nexport function isOfflineError(error: unknown, message?: string | null): boolean {\n if (typeof navigator !== \"undefined\" && navigator.onLine === false) return true;\n return offlineText(`${message ?? \"\"} ${errorSentenceOf(error)}`);\n}\n\nfunction offlineText(text: string): boolean {\n const t = text.trim();\n return t !== \"\" && (describeError(t).code === \"OFFLINE\" || /networkerror|network request failed|load failed/i.test(t));\n}\n\n/** describeError's causes that hold on every host (its process codes — ENOENT, EACCES, ports — are\n * the desktop's words for a local program and would mislead on a database refusal). */\nconst ANY_HOST_CODES = new Set([\"OFFLINE\", \"TIMEOUT\", \"UNAUTHORIZED\", \"FORBIDDEN\", \"NOT_FOUND\", \"RATE_LIMIT\", \"SERVER\"]);\n\n/** A leading machine label: `sidebar_conversations: …`, `chat.rpc_name: …`, `[chat-sidebar] …`. */\nconst MACHINE_PREFIX = /^\\s*(?:\\[[\\w./-]+\\]\\s*|[a-z][\\w]*(?:[._][\\w]+)+:\\s+)/;\n/** Text no person should read: JS error class names, stack frames, source paths. */\nconst RAW_TEXT =\n /\\b(?:Type|Reference|Syntax|Range|Internal|Eval|URI)Error\\b|\\bat\\s+[\\w$.<>]+\\s*\\(|\\.(?:[cm]?[jt]sx?|py):\\d+|(?:^|[\\s(])(?:\\/[\\w.@-]+){2,}|\\bundefined is not\\b|\\bcannot read propert(?:y|ies)\\b|\\bis not a function\\b|\\bunexpected token\\b/i;\n\n/** True when a sentence carries raw error text or a code path (what the guard refuses on screen). */\nexport function isRawErrorText(text: string): boolean {\n return MACHINE_PREFIX.test(text) || RAW_TEXT.test(text);\n}\n\n/**\n * `card: true` = the short CARD_ERROR_LINE words for a notice card. Otherwise:\n * the sentence for the screen: the timeout sentence for a statement timeout; a caller's plain\n * sentence as is; a machine label stripped from the front; anything raw or offline worded by\n * `describeError` (its table, else `fallback`).\n */\nexport function peopleErrorSentence(\n error: unknown,\n message?: string | null,\n options: { code?: string | number | undefined; fallback?: string | undefined; card?: boolean | undefined } = {},\n): string {\n const card = options.card === true;\n if (isTimedOutError(error, message, options.code)) return card ? CARD_ERROR_LINE.TIMEOUT : TIMED_OUT_SENTENCE;\n const fallback = options.fallback ?? (card ? CARD_ERROR_LINE.FALLBACK : FALLBACK_ERROR_SENTENCE);\n const raw = message?.trim() || errorSentenceOf(error).trim();\n if (!raw) return fallback;\n let text = raw;\n for (let i = 0; i < 3 && MACHINE_PREFIX.test(text); i++) text = text.replace(MACHINE_PREFIX, \"\").trim();\n if (!text) return fallback;\n if (offlineText(text) || RAW_TEXT.test(text) || text !== raw) {\n const said = describeError(text, fallback);\n if (!said.code || !ANY_HOST_CODES.has(said.code)) return fallback;\n return card ? CARD_ERROR_LINE[said.code as keyof typeof CARD_ERROR_LINE] : said.cause;\n }\n return text;\n}\n","/**\n * THE error-wording layer. A failure is shown as a cause the person can act on (\"A program it\n * needs isn't installed\"), never as the raw text a process threw (\"spawn uv ENOENT\"). The raw text\n * is kept, whole, as `detail` — the banner offers it behind Copy details and a tooltip, for a bug\n * report or an agent. One table, so every screen and every service says the same thing.\n */\n\nexport interface DescribedError {\n /** One plain sentence: what went wrong and, where it helps, what to do. */\n cause: string;\n /** The raw text, unedited (empty when it would only repeat `cause`). */\n detail: string;\n /** A short machine code when one was recognized (\"ENOENT\", \"TIMEOUT\"). */\n code?: string;\n}\n\ninterface Rule {\n code: string;\n test: RegExp;\n cause: string;\n}\n\n/** Ordered: the first rule whose pattern matches the raw text wins. */\nconst RULES: ReadonlyArray<Rule> = [\n { code: \"ENOENT\", test: /\\b(spawn\\s+\\S+\\s+)?ENOENT\\b|command not found|no such file or directory/i, cause: \"A program or file it needs isn't on this computer. Install it or update Matrx, then try again.\" },\n { code: \"EACCES\", test: /\\bEACCES\\b|\\bEPERM\\b|permission denied|operation not permitted|not authori[sz]ed by the user/i, cause: \"Matrx isn't allowed to do that. Grant access in System Settings › Privacy & Security, then try again.\" },\n { code: \"EADDRINUSE\", test: /\\bEADDRINUSE\\b|address already in use|port .* (is )?(already )?in use/i, cause: \"Another program is already using that port. Stop it, or choose another port.\" },\n { code: \"ECONNREFUSED\", test: /\\bECONNREFUSED\\b|connection refused/i, cause: \"The service isn't answering. It may have stopped; start it again.\" },\n { code: \"OFFLINE\", test: /\\bENOTFOUND\\b|\\bEAI_AGAIN\\b|\\bENETUNREACH\\b|getaddrinfo|network (is )?unreachable|failed to fetch|offline/i, cause: \"Can't reach the internet. Check the connection and try again.\" },\n { code: \"TIMEOUT\", test: /\\bETIMEDOUT\\b|timed? ?out|\\bTIMEOUT\\b|deadline exceeded/i, cause: \"It took too long to answer. Try again in a moment.\" },\n { code: \"ENOSPC\", test: /\\bENOSPC\\b|no space left/i, cause: \"The disk is full. Free some space, then try again.\" },\n { code: \"ENOMEM\", test: /\\bENOMEM\\b|out of memory|cannot allocate memory/i, cause: \"The computer ran out of memory. Close something and try again.\" },\n { code: \"UNAUTHORIZED\", test: /\\b401\\b|unauthori[sz]ed|invalid (api )?key|not signed in|jwt expired|session expired/i, cause: \"You're signed out, or the key was refused. Sign in again.\" },\n { code: \"FORBIDDEN\", test: /\\b403\\b|forbidden/i, cause: \"This account isn't allowed to do that.\" },\n { code: \"NOT_FOUND\", test: /\\b404\\b|not found/i, cause: \"It isn't there any more. Refresh and try again.\" },\n { code: \"RATE_LIMIT\", test: /\\b429\\b|rate.?limit|too many requests/i, cause: \"Too many requests just now. Wait a moment and try again.\" },\n { code: \"SERVER\", test: /\\b5\\d\\d\\b|internal server error|bad gateway|service unavailable/i, cause: \"The server had a problem. Try again in a moment.\" },\n { code: \"EXITED\", test: /exited with code|process exited|crashed|SIGKILL|SIGSEGV|SIGTERM/i, cause: \"The service stopped unexpectedly. Start it again; Copy details if it keeps happening.\" },\n];\n\nconst RAW = /\\b[A-Z]{2,}[A-Z_]*\\b|[\\\\/][\\w.-]+[\\\\/]|\\bat \\S+ \\(|\\{|\\}|errno|stack|undefined|null|\\bspawn\\b/;\n\nfunction rawText(error: unknown): string {\n if (error instanceof Error) return error.message || error.name;\n if (typeof error === \"string\") return error;\n if (error && typeof error === \"object\" && \"message\" in error && typeof (error as { message: unknown }).message === \"string\") {\n return (error as { message: string }).message;\n }\n return \"\";\n}\n\n/**\n * Turn any thrown or returned error into words a person can act on. Already-humane text (a full\n * sentence the app wrote itself, with no codes, paths or stack) passes through unchanged.\n */\nexport function describeError(error: unknown, fallback = \"Something went wrong. Try again.\"): DescribedError {\n const detail = rawText(error).trim();\n if (!detail) return { cause: fallback, detail: \"\" };\n for (const rule of RULES) {\n if (rule.test.test(detail)) return { cause: rule.cause, detail, code: rule.code };\n }\n if (!RAW.test(detail) && detail.length <= 160) return { cause: detail, detail: \"\" };\n return { cause: fallback, detail };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACuBA,IAAM,QAA6B;AAAA,EACjC,EAAE,MAAM,UAAU,MAAM,4EAA4E,OAAO,iGAAiG;AAAA,EAC5M,EAAE,MAAM,UAAU,MAAM,iGAAiG,OAAO,6GAAwG;AAAA,EACxO,EAAE,MAAM,cAAc,MAAM,0EAA0E,OAAO,+EAA+E;AAAA,EAC5L,EAAE,MAAM,gBAAgB,MAAM,wCAAwC,OAAO,oEAAoE;AAAA,EACjJ,EAAE,MAAM,WAAW,MAAM,8GAA8G,OAAO,gEAAgE;AAAA,EAC9M,EAAE,MAAM,WAAW,MAAM,4DAA4D,OAAO,qDAAqD;AAAA,EACjJ,EAAE,MAAM,UAAU,MAAM,6BAA6B,OAAO,qDAAqD;AAAA,EACjH,EAAE,MAAM,UAAU,MAAM,oDAAoD,OAAO,iEAAiE;AAAA,EACpJ,EAAE,MAAM,gBAAgB,MAAM,yFAAyF,OAAO,4DAA4D;AAAA,EAC1L,EAAE,MAAM,aAAa,MAAM,sBAAsB,OAAO,yCAAyC;AAAA,EACjG,EAAE,MAAM,aAAa,MAAM,sBAAsB,OAAO,kDAAkD;AAAA,EAC1G,EAAE,MAAM,cAAc,MAAM,0CAA0C,OAAO,2DAA2D;AAAA,EACxI,EAAE,MAAM,UAAU,MAAM,oEAAoE,OAAO,mDAAmD;AAAA,EACtJ,EAAE,MAAM,UAAU,MAAM,oEAAoE,OAAO,wFAAwF;AAC7L;AAEA,IAAM,MAAM;AAEZ,SAAS,QAAQ,OAAwB;AACvC,MAAI,iBAAiB,MAAO,QAAO,MAAM,WAAW,MAAM;AAC1D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,SAAS,OAAO,UAAU,YAAY,aAAa,SAAS,OAAQ,MAA+B,YAAY,UAAU;AAC3H,WAAQ,MAA8B;AAAA,EACxC;AACA,SAAO;AACT;AAMO,SAAS,cAAc,OAAgB,WAAW,oCAAoD;AAC3G,QAAM,SAAS,QAAQ,KAAK,EAAE,KAAK;AACnC,MAAI,CAAC,OAAQ,QAAO,EAAE,OAAO,UAAU,QAAQ,GAAG;AAClD,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,KAAK,KAAK,MAAM,EAAG,QAAO,EAAE,OAAO,KAAK,OAAO,QAAQ,MAAM,KAAK,KAAK;AAAA,EAClF;AACA,MAAI,CAAC,IAAI,KAAK,MAAM,KAAK,OAAO,UAAU,IAAK,QAAO,EAAE,OAAO,QAAQ,QAAQ,GAAG;AAClF,SAAO,EAAE,OAAO,UAAU,OAAO;AACnC;;;AD9CO,SAAS,gBAAgB,OAAwB;AACtD,MAAI,SAAS,QAAQ,UAAU,QAAQ,UAAU,MAAO,QAAO;AAC/D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,SAAU,QAAO,OAAO,KAAK;AAClD,QAAM,UAAW,MAAgC;AACjD,SAAO,OAAO,YAAY,WAAW,UAAU;AACjD;AASO,IAAM,qBAAqB;AAG3B,IAAM,0BAA0B;AAOhC,IAAM,kBAAkB;AAAA,EAC7B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,cAAc;AAAA,EACd,WAAW;AAAA,EACX,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,UAAU;AACZ;AAGO,SAAS,gBAAgB,OAAgB,SAAyB,MAAiC;AACxG,MAAI,SAAS,WAAW,SAAS,YAAa,QAAO;AACrD,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,IAAI;AACV,QAAI,EAAE,SAAS,WAAW,EAAE,SAAS,eAAe,EAAE,aAAa,QAAS,QAAO;AAAA,EACrF;AACA,QAAM,OAAO,GAAG,WAAW,EAAE,IAAI,gBAAgB,KAAK,CAAC;AACvD,SAAO,gDAAgD,KAAK,IAAI;AAClE;AAGO,SAAS,eAAe,OAAgB,SAAkC;AAC/E,MAAI,OAAO,cAAc,eAAe,UAAU,WAAW,MAAO,QAAO;AAC3E,SAAO,YAAY,GAAG,WAAW,EAAE,IAAI,gBAAgB,KAAK,CAAC,EAAE;AACjE;AAEA,SAAS,YAAY,MAAuB;AAC1C,QAAM,IAAI,KAAK,KAAK;AACpB,SAAO,MAAM,OAAO,cAAc,CAAC,EAAE,SAAS,aAAa,mDAAmD,KAAK,CAAC;AACtH;AAIA,IAAM,iBAAiB,oBAAI,IAAI,CAAC,WAAW,WAAW,gBAAgB,aAAa,aAAa,cAAc,QAAQ,CAAC;AAGvH,IAAM,iBAAiB;AAEvB,IAAM,WACJ;AAGK,SAAS,eAAe,MAAuB;AACpD,SAAO,eAAe,KAAK,IAAI,KAAK,SAAS,KAAK,IAAI;AACxD;AAQO,SAAS,oBACd,OACA,SACA,UAA6G,CAAC,GACtG;AACR,QAAM,OAAO,QAAQ,SAAS;AAC9B,MAAI,gBAAgB,OAAO,SAAS,QAAQ,IAAI,EAAG,QAAO,OAAO,gBAAgB,UAAU;AAC3F,QAAM,WAAW,QAAQ,aAAa,OAAO,gBAAgB,WAAW;AACxE,QAAM,MAAM,SAAS,KAAK,KAAK,gBAAgB,KAAK,EAAE,KAAK;AAC3D,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,KAAK,eAAe,KAAK,IAAI,GAAG,IAAK,QAAO,KAAK,QAAQ,gBAAgB,EAAE,EAAE,KAAK;AACtG,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,YAAY,IAAI,KAAK,SAAS,KAAK,IAAI,KAAK,SAAS,KAAK;AAC5D,UAAM,OAAO,cAAc,MAAM,QAAQ;AACzC,QAAI,CAAC,KAAK,QAAQ,CAAC,eAAe,IAAI,KAAK,IAAI,EAAG,QAAO;AACzD,WAAO,OAAO,gBAAgB,KAAK,IAAoC,IAAI,KAAK;AAAA,EAClF;AACA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sentence an error carries: its own message (string, Error, or any
|
|
3
|
+
* object with a `message`). Empty when it has none.
|
|
4
|
+
*/
|
|
5
|
+
declare function errorSentenceOf(error: unknown): string;
|
|
6
|
+
/**
|
|
7
|
+
* What a person reads when the store cancelled a call at its statement timeout
|
|
8
|
+
* (SQLSTATE 57014). Postgres' own "canceling statement due to statement
|
|
9
|
+
* timeout" is about the database, not the person; the cancelled call rolled
|
|
10
|
+
* back, so nothing was written (lane AT-SLOW, 2026-10-19). The same sentence
|
|
11
|
+
* @ai-matrx/records' `TIMED_OUT_MESSAGE` gives.
|
|
12
|
+
*/
|
|
13
|
+
declare const TIMED_OUT_SENTENCE = "That took too long. Nothing was lost; try again.";
|
|
14
|
+
/** What a person reads when an error says nothing a person can use. */
|
|
15
|
+
declare const FALLBACK_ERROR_SENTENCE = "Something went wrong. Try again.";
|
|
16
|
+
/**
|
|
17
|
+
* A notice CARD's words (the web toast, Matrx 2's floating card): a card is ~22 rem at most and its
|
|
18
|
+
* action shares the row, so a line is a few words (notice-stack.ts NOTICE_TEXT_BUDGET). The same
|
|
19
|
+
* causes as the sentences above, said short enough to fit at the smallest window, never cut by "…".
|
|
20
|
+
*/
|
|
21
|
+
declare const CARD_ERROR_LINE: {
|
|
22
|
+
readonly OFFLINE: "No connection";
|
|
23
|
+
readonly TIMEOUT: "Took too long. Nothing was lost.";
|
|
24
|
+
readonly UNAUTHORIZED: "Signed out. Sign in again.";
|
|
25
|
+
readonly FORBIDDEN: "Not allowed for this account";
|
|
26
|
+
readonly NOT_FOUND: "Not found. Refresh and retry.";
|
|
27
|
+
readonly RATE_LIMIT: "Too many requests. Wait a moment.";
|
|
28
|
+
readonly SERVER: "Server problem. Try again soon.";
|
|
29
|
+
readonly FALLBACK: "Something went wrong";
|
|
30
|
+
};
|
|
31
|
+
/** True when an error, its code, or its sentence is the store's statement timeout. */
|
|
32
|
+
declare function isTimedOutError(error: unknown, message?: string | null, code?: string | number): boolean;
|
|
33
|
+
/** True when the call failed because the device is offline or the network never answered. */
|
|
34
|
+
declare function isOfflineError(error: unknown, message?: string | null): boolean;
|
|
35
|
+
/** True when a sentence carries raw error text or a code path (what the guard refuses on screen). */
|
|
36
|
+
declare function isRawErrorText(text: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* `card: true` = the short CARD_ERROR_LINE words for a notice card. Otherwise:
|
|
39
|
+
* the sentence for the screen: the timeout sentence for a statement timeout; a caller's plain
|
|
40
|
+
* sentence as is; a machine label stripped from the front; anything raw or offline worded by
|
|
41
|
+
* `describeError` (its table, else `fallback`).
|
|
42
|
+
*/
|
|
43
|
+
declare function peopleErrorSentence(error: unknown, message?: string | null, options?: {
|
|
44
|
+
code?: string | number | undefined;
|
|
45
|
+
fallback?: string | undefined;
|
|
46
|
+
card?: boolean | undefined;
|
|
47
|
+
}): string;
|
|
48
|
+
|
|
49
|
+
export { CARD_ERROR_LINE, FALLBACK_ERROR_SENTENCE, TIMED_OUT_SENTENCE, errorSentenceOf, isOfflineError, isRawErrorText, isTimedOutError, peopleErrorSentence };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sentence an error carries: its own message (string, Error, or any
|
|
3
|
+
* object with a `message`). Empty when it has none.
|
|
4
|
+
*/
|
|
5
|
+
declare function errorSentenceOf(error: unknown): string;
|
|
6
|
+
/**
|
|
7
|
+
* What a person reads when the store cancelled a call at its statement timeout
|
|
8
|
+
* (SQLSTATE 57014). Postgres' own "canceling statement due to statement
|
|
9
|
+
* timeout" is about the database, not the person; the cancelled call rolled
|
|
10
|
+
* back, so nothing was written (lane AT-SLOW, 2026-10-19). The same sentence
|
|
11
|
+
* @ai-matrx/records' `TIMED_OUT_MESSAGE` gives.
|
|
12
|
+
*/
|
|
13
|
+
declare const TIMED_OUT_SENTENCE = "That took too long. Nothing was lost; try again.";
|
|
14
|
+
/** What a person reads when an error says nothing a person can use. */
|
|
15
|
+
declare const FALLBACK_ERROR_SENTENCE = "Something went wrong. Try again.";
|
|
16
|
+
/**
|
|
17
|
+
* A notice CARD's words (the web toast, Matrx 2's floating card): a card is ~22 rem at most and its
|
|
18
|
+
* action shares the row, so a line is a few words (notice-stack.ts NOTICE_TEXT_BUDGET). The same
|
|
19
|
+
* causes as the sentences above, said short enough to fit at the smallest window, never cut by "…".
|
|
20
|
+
*/
|
|
21
|
+
declare const CARD_ERROR_LINE: {
|
|
22
|
+
readonly OFFLINE: "No connection";
|
|
23
|
+
readonly TIMEOUT: "Took too long. Nothing was lost.";
|
|
24
|
+
readonly UNAUTHORIZED: "Signed out. Sign in again.";
|
|
25
|
+
readonly FORBIDDEN: "Not allowed for this account";
|
|
26
|
+
readonly NOT_FOUND: "Not found. Refresh and retry.";
|
|
27
|
+
readonly RATE_LIMIT: "Too many requests. Wait a moment.";
|
|
28
|
+
readonly SERVER: "Server problem. Try again soon.";
|
|
29
|
+
readonly FALLBACK: "Something went wrong";
|
|
30
|
+
};
|
|
31
|
+
/** True when an error, its code, or its sentence is the store's statement timeout. */
|
|
32
|
+
declare function isTimedOutError(error: unknown, message?: string | null, code?: string | number): boolean;
|
|
33
|
+
/** True when the call failed because the device is offline or the network never answered. */
|
|
34
|
+
declare function isOfflineError(error: unknown, message?: string | null): boolean;
|
|
35
|
+
/** True when a sentence carries raw error text or a code path (what the guard refuses on screen). */
|
|
36
|
+
declare function isRawErrorText(text: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* `card: true` = the short CARD_ERROR_LINE words for a notice card. Otherwise:
|
|
39
|
+
* the sentence for the screen: the timeout sentence for a statement timeout; a caller's plain
|
|
40
|
+
* sentence as is; a machine label stripped from the front; anything raw or offline worded by
|
|
41
|
+
* `describeError` (its table, else `fallback`).
|
|
42
|
+
*/
|
|
43
|
+
declare function peopleErrorSentence(error: unknown, message?: string | null, options?: {
|
|
44
|
+
code?: string | number | undefined;
|
|
45
|
+
fallback?: string | undefined;
|
|
46
|
+
card?: boolean | undefined;
|
|
47
|
+
}): string;
|
|
48
|
+
|
|
49
|
+
export { CARD_ERROR_LINE, FALLBACK_ERROR_SENTENCE, TIMED_OUT_SENTENCE, errorSentenceOf, isOfflineError, isRawErrorText, isTimedOutError, peopleErrorSentence };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
CARD_ERROR_LINE,
|
|
4
|
+
FALLBACK_ERROR_SENTENCE,
|
|
5
|
+
TIMED_OUT_SENTENCE,
|
|
6
|
+
errorSentenceOf,
|
|
7
|
+
isOfflineError,
|
|
8
|
+
isRawErrorText,
|
|
9
|
+
isTimedOutError,
|
|
10
|
+
peopleErrorSentence
|
|
11
|
+
} from "./chunk-HS6GMHKZ.js";
|
|
12
|
+
export {
|
|
13
|
+
CARD_ERROR_LINE,
|
|
14
|
+
FALLBACK_ERROR_SENTENCE,
|
|
15
|
+
TIMED_OUT_SENTENCE,
|
|
16
|
+
errorSentenceOf,
|
|
17
|
+
isOfflineError,
|
|
18
|
+
isRawErrorText,
|
|
19
|
+
isTimedOutError,
|
|
20
|
+
peopleErrorSentence
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=error-sentence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -1377,8 +1377,9 @@ function isRawErrorText(text) {
|
|
|
1377
1377
|
return MACHINE_PREFIX.test(text) || RAW_TEXT.test(text);
|
|
1378
1378
|
}
|
|
1379
1379
|
function peopleErrorSentence(error, message, options = {}) {
|
|
1380
|
-
|
|
1381
|
-
|
|
1380
|
+
const card = options.card === true;
|
|
1381
|
+
if (isTimedOutError(error, message, options.code)) return card ? CARD_ERROR_LINE.TIMEOUT : TIMED_OUT_SENTENCE;
|
|
1382
|
+
const fallback = options.fallback ?? (card ? CARD_ERROR_LINE.FALLBACK : FALLBACK_ERROR_SENTENCE);
|
|
1382
1383
|
const raw = message?.trim() || errorSentenceOf(error).trim();
|
|
1383
1384
|
if (!raw) return fallback;
|
|
1384
1385
|
let text = raw;
|
|
@@ -1386,17 +1387,28 @@ function peopleErrorSentence(error, message, options = {}) {
|
|
|
1386
1387
|
if (!text) return fallback;
|
|
1387
1388
|
if (offlineText(text) || RAW_TEXT.test(text) || text !== raw) {
|
|
1388
1389
|
const said = describeError(text, fallback);
|
|
1389
|
-
|
|
1390
|
+
if (!said.code || !ANY_HOST_CODES.has(said.code)) return fallback;
|
|
1391
|
+
return card ? CARD_ERROR_LINE[said.code] : said.cause;
|
|
1390
1392
|
}
|
|
1391
1393
|
return text;
|
|
1392
1394
|
}
|
|
1393
|
-
var TIMED_OUT_SENTENCE, FALLBACK_ERROR_SENTENCE, ANY_HOST_CODES, MACHINE_PREFIX, RAW_TEXT;
|
|
1395
|
+
var TIMED_OUT_SENTENCE, FALLBACK_ERROR_SENTENCE, CARD_ERROR_LINE, ANY_HOST_CODES, MACHINE_PREFIX, RAW_TEXT;
|
|
1394
1396
|
var init_error_sentence = __esm({
|
|
1395
1397
|
"src/error-sentence.ts"() {
|
|
1396
1398
|
"use strict";
|
|
1397
1399
|
init_errors();
|
|
1398
1400
|
TIMED_OUT_SENTENCE = "That took too long. Nothing was lost; try again.";
|
|
1399
1401
|
FALLBACK_ERROR_SENTENCE = "Something went wrong. Try again.";
|
|
1402
|
+
CARD_ERROR_LINE = {
|
|
1403
|
+
OFFLINE: "No connection",
|
|
1404
|
+
TIMEOUT: "Took too long. Nothing was lost.",
|
|
1405
|
+
UNAUTHORIZED: "Signed out. Sign in again.",
|
|
1406
|
+
FORBIDDEN: "Not allowed for this account",
|
|
1407
|
+
NOT_FOUND: "Not found. Refresh and retry.",
|
|
1408
|
+
RATE_LIMIT: "Too many requests. Wait a moment.",
|
|
1409
|
+
SERVER: "Server problem. Try again soon.",
|
|
1410
|
+
FALLBACK: "Something went wrong"
|
|
1411
|
+
};
|
|
1400
1412
|
ANY_HOST_CODES = /* @__PURE__ */ new Set(["OFFLINE", "TIMEOUT", "UNAUTHORIZED", "FORBIDDEN", "NOT_FOUND", "RATE_LIMIT", "SERVER"]);
|
|
1401
1413
|
MACHINE_PREFIX = /^\s*(?:\[[\w./-]+\]\s*|[a-z][\w]*(?:[._][\w]+)+:\s+)/;
|
|
1402
1414
|
RAW_TEXT = /\b(?:Type|Reference|Syntax|Range|Internal|Eval|URI)Error\b|\bat\s+[\w$.<>]+\s*\(|\.(?:[cm]?[jt]sx?|py):\d+|(?:^|[\s(])(?:\/[\w.@-]+){2,}|\bundefined is not\b|\bcannot read propert(?:y|ies)\b|\bis not a function\b|\bunexpected token\b/i;
|
|
@@ -2732,18 +2744,20 @@ var init_dialog = __esm({
|
|
|
2732
2744
|
});
|
|
2733
2745
|
|
|
2734
2746
|
// src/dropdown-menu.tsx
|
|
2735
|
-
function readTopClearance() {
|
|
2736
|
-
return readClearance("var(--matrx-floating-top-clearance, var(--shell-header-h, 0px))");
|
|
2737
|
-
}
|
|
2738
|
-
function readBottomClearance() {
|
|
2739
|
-
return readClearance("var(--matrx-floating-clearance, 0px)");
|
|
2740
|
-
}
|
|
2741
2747
|
function menuCollisionPadding(caller, top, bottom, fallback = 0) {
|
|
2742
2748
|
const side = (key) => typeof caller === "number" ? caller : caller?.[key] ?? fallback;
|
|
2743
2749
|
return { top: Math.max(side("top"), top), right: side("right"), bottom: Math.max(side("bottom"), bottom), left: side("left") };
|
|
2744
2750
|
}
|
|
2745
|
-
function readClearance(height) {
|
|
2751
|
+
function readClearance(height, shared = false) {
|
|
2746
2752
|
if (typeof document === "undefined") return 0;
|
|
2753
|
+
const now = clock();
|
|
2754
|
+
const held = shared ? clearanceCache.get(height) : void 0;
|
|
2755
|
+
if (held && now - held.at < CLEARANCE_REUSE_MS) return held.px;
|
|
2756
|
+
const px3 = measureClearance(height);
|
|
2757
|
+
clearanceCache.set(height, { px: px3, at: now });
|
|
2758
|
+
return px3;
|
|
2759
|
+
}
|
|
2760
|
+
function measureClearance(height) {
|
|
2747
2761
|
const probe2 = document.createElement("div");
|
|
2748
2762
|
probe2.style.cssText = `position:fixed;top:0;left:0;width:0;visibility:hidden;pointer-events:none;height:${height}`;
|
|
2749
2763
|
document.body.appendChild(probe2);
|
|
@@ -2751,7 +2765,7 @@ function readClearance(height) {
|
|
|
2751
2765
|
probe2.remove();
|
|
2752
2766
|
return Number.isFinite(px3) ? Math.ceil(px3) : 0;
|
|
2753
2767
|
}
|
|
2754
|
-
var DropdownMenuPrimitive, React27, import_jsx_runtime36, DropdownMenu, DropdownMenuTrigger, DropdownMenuGroup, DropdownMenuPortal, DropdownMenuSub, DropdownMenuRadioGroup, MENU_SURFACE_CLASS, MENU_ITEM_CLASS, MENU_INDICATOR_ITEM_CLASS, DropdownMenuSubTrigger, DropdownMenuSubContent, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut;
|
|
2768
|
+
var DropdownMenuPrimitive, React27, import_jsx_runtime36, DropdownMenu, DropdownMenuTrigger, DropdownMenuGroup, DropdownMenuPortal, DropdownMenuSub, DropdownMenuRadioGroup, MENU_SURFACE_CLASS, MENU_ITEM_CLASS, MENU_INDICATOR_ITEM_CLASS, DropdownMenuSubTrigger, DropdownMenuSubContent, CLEARANCE_REUSE_MS, clearanceCache, clock, TOP_CLEARANCE, BOTTOM_CLEARANCE, sharedTopClearance, sharedBottomClearance, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut;
|
|
2755
2769
|
var init_dropdown_menu = __esm({
|
|
2756
2770
|
"src/dropdown-menu.tsx"() {
|
|
2757
2771
|
"use strict";
|
|
@@ -2797,7 +2811,7 @@ var init_dropdown_menu = __esm({
|
|
|
2797
2811
|
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
2798
2812
|
DropdownMenuSubContent = React27.forwardRef(({ className, container, surface = "default", sideOffset = 2, alignOffset = -4, collisionPadding, onFocusOutside, children, ...props }, ref) => {
|
|
2799
2813
|
const portalContainer = usePortalContainer(container);
|
|
2800
|
-
const [bottomClearance] = React27.useState(
|
|
2814
|
+
const [bottomClearance] = React27.useState(sharedBottomClearance);
|
|
2801
2815
|
const padding = menuCollisionPadding(collisionPadding ?? 8, 0, bottomClearance);
|
|
2802
2816
|
const nested = useNestedSubmenuPlacement(ref, padding);
|
|
2803
2817
|
const keep = useSubmenuSurvivesParentPanelFocus(nested.ref, onFocusOutside);
|
|
@@ -2819,10 +2833,17 @@ var init_dropdown_menu = __esm({
|
|
|
2819
2833
|
) });
|
|
2820
2834
|
});
|
|
2821
2835
|
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
2836
|
+
CLEARANCE_REUSE_MS = 500;
|
|
2837
|
+
clearanceCache = /* @__PURE__ */ new Map();
|
|
2838
|
+
clock = () => typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
2839
|
+
TOP_CLEARANCE = "var(--matrx-floating-top-clearance, var(--shell-header-h, 0px))";
|
|
2840
|
+
BOTTOM_CLEARANCE = "var(--matrx-floating-clearance, 0px)";
|
|
2841
|
+
sharedTopClearance = () => readClearance(TOP_CLEARANCE, true);
|
|
2842
|
+
sharedBottomClearance = () => readClearance(BOTTOM_CLEARANCE, true);
|
|
2822
2843
|
DropdownMenuContent = React27.forwardRef(({ className, sideOffset = 4, container, surface = "default", children, onCloseAutoFocus, collisionPadding, ...props }, ref) => {
|
|
2823
2844
|
const portalContainer = usePortalContainer(container);
|
|
2824
|
-
const [topClearance] = React27.useState(
|
|
2825
|
-
const [bottomClearance] = React27.useState(
|
|
2845
|
+
const [topClearance] = React27.useState(sharedTopClearance);
|
|
2846
|
+
const [bottomClearance] = React27.useState(sharedBottomClearance);
|
|
2826
2847
|
const edges = useMenuScrollEdges(ref);
|
|
2827
2848
|
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(DropdownMenuPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
2828
2849
|
DropdownMenuPrimitive.Content,
|
|
@@ -10303,13 +10324,14 @@ function useTableNotice() {
|
|
|
10303
10324
|
const [message, setMessage] = (0, import_react10.useState)(null);
|
|
10304
10325
|
const notify = (0, import_react10.useMemo)(
|
|
10305
10326
|
() => ({
|
|
10306
|
-
|
|
10307
|
-
|
|
10308
|
-
|
|
10327
|
+
// A card is a short title and an optional line (NOTICE_TEXT_BUDGET); the inline fallback joins them.
|
|
10328
|
+
success(text, options) {
|
|
10329
|
+
if (host.notify) host.notify.success(text, options);
|
|
10330
|
+
else setMessage({ text: options?.description ? `${text}. ${options.description}` : text, error: false });
|
|
10309
10331
|
},
|
|
10310
|
-
error(text) {
|
|
10311
|
-
if (host.notify) host.notify.error(text);
|
|
10312
|
-
else setMessage({ text, error: true });
|
|
10332
|
+
error(text, options) {
|
|
10333
|
+
if (host.notify) host.notify.error(text, options);
|
|
10334
|
+
else setMessage({ text: options?.description ? `${text}. ${options.description}` : text, error: true });
|
|
10313
10335
|
}
|
|
10314
10336
|
}),
|
|
10315
10337
|
[host]
|
|
@@ -10344,6 +10366,7 @@ function displayId(id, show = "auto") {
|
|
|
10344
10366
|
}
|
|
10345
10367
|
|
|
10346
10368
|
// src/record-id.tsx
|
|
10369
|
+
init_error_sentence();
|
|
10347
10370
|
var import_jsx_runtime71 = require("react/jsx-runtime");
|
|
10348
10371
|
function RecordId({
|
|
10349
10372
|
value,
|
|
@@ -10404,7 +10427,7 @@ function RecordId({
|
|
|
10404
10427
|
e.preventDefault();
|
|
10405
10428
|
void (0, import_clipboard.copyText)(value).then((ok) => {
|
|
10406
10429
|
if (!ok) {
|
|
10407
|
-
notify?.error(
|
|
10430
|
+
notify?.error("Not copied", { description: copyLabel });
|
|
10408
10431
|
return;
|
|
10409
10432
|
}
|
|
10410
10433
|
setCopied(true);
|
|
@@ -10420,12 +10443,10 @@ function RecordId({
|
|
|
10420
10443
|
try {
|
|
10421
10444
|
const result = await onOpen(value);
|
|
10422
10445
|
if (result === "forbidden") {
|
|
10423
|
-
notify?.error("
|
|
10446
|
+
notify?.error("No access", { description: "This account can't open this record" });
|
|
10424
10447
|
}
|
|
10425
10448
|
} catch (err) {
|
|
10426
|
-
notify?.error(
|
|
10427
|
-
`Couldn't open: ${err instanceof Error ? err.message : String(err)}`
|
|
10428
|
-
);
|
|
10449
|
+
notify?.error("Not opened", { description: peopleErrorSentence(err, null, { card: true }) });
|
|
10429
10450
|
} finally {
|
|
10430
10451
|
setOpening(false);
|
|
10431
10452
|
}
|