@panneau/lists 4.1.1 → 5.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -0
- package/dist/List.d.ts +26 -0
- package/dist/List.d.ts.map +1 -0
- package/dist/List.js +38 -0
- package/dist/List.js.map +1 -0
- package/dist/ListView.css +101 -0
- package/dist/ListView.d.ts +70 -0
- package/dist/ListView.d.ts.map +1 -0
- package/dist/ListView.js +322 -0
- package/dist/ListView.js.map +1 -0
- package/dist/ListView.module.js +28 -0
- package/dist/ListView.module.js.map +1 -0
- package/dist/actions/ActionButton.d.ts +15 -0
- package/dist/actions/ActionButton.d.ts.map +1 -0
- package/dist/actions/ActionButton.js +34 -0
- package/dist/actions/ActionButton.js.map +1 -0
- package/dist/actions/Actions.css +58 -0
- package/dist/actions/Actions.module.js +20 -0
- package/dist/actions/Actions.module.js.map +1 -0
- package/dist/actions/ConfirmDialog.d.ts +15 -0
- package/dist/actions/ConfirmDialog.d.ts.map +1 -0
- package/dist/actions/ConfirmDialog.js +157 -0
- package/dist/actions/ConfirmDialog.js.map +1 -0
- package/dist/actions/RowActions.d.ts +17 -0
- package/dist/actions/RowActions.d.ts.map +1 -0
- package/dist/actions/RowActions.js +95 -0
- package/dist/actions/RowActions.js.map +1 -0
- package/dist/actions/actions.d.ts +23 -0
- package/dist/actions/actions.d.ts.map +1 -0
- package/dist/actions/actions.js +56 -0
- package/dist/actions/actions.js.map +1 -0
- package/dist/actions/icons.d.ts +5 -0
- package/dist/actions/icons.d.ts.map +1 -0
- package/dist/actions/icons.js +23 -0
- package/dist/actions/icons.js.map +1 -0
- package/dist/cx.d.ts +3 -0
- package/dist/cx.d.ts.map +1 -0
- package/dist/cx.js +9 -0
- package/dist/cx.js.map +1 -0
- package/dist/displays/Displays.css +71 -0
- package/dist/displays/Displays.module.js +30 -0
- package/dist/displays/Displays.module.js.map +1 -0
- package/dist/displays/displays.d.ts +36 -0
- package/dist/displays/displays.d.ts.map +1 -0
- package/dist/displays/displays.js +570 -0
- package/dist/displays/displays.js.map +1 -0
- package/dist/filters/Filters.css +71 -0
- package/dist/filters/Filters.d.ts +38 -0
- package/dist/filters/Filters.d.ts.map +1 -0
- package/dist/filters/Filters.js +240 -0
- package/dist/filters/Filters.js.map +1 -0
- package/dist/filters/Filters.module.js +24 -0
- package/dist/filters/Filters.module.js.map +1 -0
- package/dist/filters/controls.d.ts +23 -0
- package/dist/filters/controls.d.ts.map +1 -0
- package/dist/filters/controls.js +405 -0
- package/dist/filters/controls.js.map +1 -0
- package/dist/filters/format.d.ts +16 -0
- package/dist/filters/format.d.ts.map +1 -0
- package/dist/filters/format.js +43 -0
- package/dist/filters/format.js.map +1 -0
- package/dist/index.d.ts +18 -10
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -66
- package/dist/layouts/CardsLayout.css +72 -0
- package/dist/layouts/CardsLayout.d.ts +4 -0
- package/dist/layouts/CardsLayout.d.ts.map +1 -0
- package/dist/layouts/CardsLayout.js +111 -0
- package/dist/layouts/CardsLayout.js.map +1 -0
- package/dist/layouts/CardsLayout.module.js +24 -0
- package/dist/layouts/CardsLayout.module.js.map +1 -0
- package/dist/layouts/ItemTitle.d.ts +10 -0
- package/dist/layouts/ItemTitle.d.ts.map +1 -0
- package/dist/layouts/ItemTitle.js +30 -0
- package/dist/layouts/ItemTitle.js.map +1 -0
- package/dist/layouts/TableLayout.css +177 -0
- package/dist/layouts/TableLayout.d.ts +9 -0
- package/dist/layouts/TableLayout.d.ts.map +1 -0
- package/dist/layouts/TableLayout.js +208 -0
- package/dist/layouts/TableLayout.js.map +1 -0
- package/dist/layouts/TableLayout.module.js +32 -0
- package/dist/layouts/TableLayout.module.js.map +1 -0
- package/dist/layouts/builtIn.d.ts +6 -0
- package/dist/layouts/builtIn.d.ts.map +1 -0
- package/dist/layouts/builtIn.js +12 -0
- package/dist/layouts/builtIn.js.map +1 -0
- package/dist/layouts/link.css +16 -0
- package/dist/layouts/link.module.js +8 -0
- package/dist/layouts/link.module.js.map +1 -0
- package/dist/messages.d.ts +2 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +1 -0
- package/dist/plugin.d.ts +13 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +19 -0
- package/dist/plugin.js.map +1 -0
- package/dist/query.d.ts +21 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +65 -0
- package/dist/query.js.map +1 -0
- package/dist/selection.d.ts +9 -0
- package/dist/selection.d.ts.map +1 -0
- package/dist/selection.js +19 -0
- package/dist/selection.js.map +1 -0
- package/dist/toolbar/LayoutSwitch.d.ts +8 -0
- package/dist/toolbar/LayoutSwitch.d.ts.map +1 -0
- package/dist/toolbar/LayoutSwitch.js +108 -0
- package/dist/toolbar/LayoutSwitch.js.map +1 -0
- package/dist/toolbar/Pagination.d.ts +13 -0
- package/dist/toolbar/Pagination.d.ts.map +1 -0
- package/dist/toolbar/Pagination.js +62 -0
- package/dist/toolbar/Pagination.js.map +1 -0
- package/dist/toolbar/SearchField.d.ts +9 -0
- package/dist/toolbar/SearchField.d.ts.map +1 -0
- package/dist/toolbar/SearchField.js +64 -0
- package/dist/toolbar/SearchField.js.map +1 -0
- package/dist/toolbar/SortSelect.d.ts +9 -0
- package/dist/toolbar/SortSelect.d.ts.map +1 -0
- package/dist/toolbar/SortSelect.js +90 -0
- package/dist/toolbar/SortSelect.js.map +1 -0
- package/dist/toolbar/Toolbar.css +72 -0
- package/dist/toolbar/Toolbar.module.js +22 -0
- package/dist/toolbar/Toolbar.module.js.map +1 -0
- package/dist/types.d.ts +105 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/useDraft.d.ts +11 -0
- package/dist/useDraft.d.ts.map +1 -0
- package/dist/useDraft.js +77 -0
- package/dist/useDraft.js.map +1 -0
- package/dist/useListState.d.ts +4 -0
- package/dist/useListState.d.ts.map +1 -0
- package/dist/useListState.js +10 -0
- package/dist/useListState.js.map +1 -0
- package/dist/values.d.ts +21 -0
- package/dist/values.d.ts.map +1 -0
- package/dist/values.js +52 -0
- package/dist/values.js.map +1 -0
- package/package.json +27 -57
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { messages } from "../messages.js";
|
|
2
|
+
import Actions_module_default from "./Actions.module.js";
|
|
3
|
+
import { c } from "react/compiler-runtime";
|
|
4
|
+
import { Button, Dialog, usePanneauIntl } from "@panneau/ui";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/actions/ConfirmDialog.tsx
|
|
7
|
+
/** Formats an ICU message of the definition (`{count, plural, …}`) in the locale. */
|
|
8
|
+
function formatDefinitionMessage(intl, message, values) {
|
|
9
|
+
try {
|
|
10
|
+
return String(intl.formatters.getMessageFormat(message, intl.locale).format(values));
|
|
11
|
+
} catch {
|
|
12
|
+
return message;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/** Whether an action needs a confirmation: it asks for one, or some selected items are skipped. */
|
|
16
|
+
function needsConfirmation(event) {
|
|
17
|
+
const { confirm } = event.action;
|
|
18
|
+
return confirm !== void 0 && confirm !== false || event.skipped.length > 0;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Asks before running an action (decision 0017): the action's `confirm` title and message (an ICU
|
|
22
|
+
* message with `{count}`), or default ones, and how many selected items will be skipped.
|
|
23
|
+
*/
|
|
24
|
+
function ConfirmDialog(t0) {
|
|
25
|
+
const $ = c(40);
|
|
26
|
+
const { event, onConfirm, onCancel } = t0;
|
|
27
|
+
const intl = usePanneauIntl();
|
|
28
|
+
if (event === null) return null;
|
|
29
|
+
const { action, count, skipped } = event;
|
|
30
|
+
let T0;
|
|
31
|
+
let t1;
|
|
32
|
+
let t2;
|
|
33
|
+
let t3;
|
|
34
|
+
let t4;
|
|
35
|
+
let t5;
|
|
36
|
+
let t6;
|
|
37
|
+
let t7;
|
|
38
|
+
let t8;
|
|
39
|
+
let t9;
|
|
40
|
+
if ($[0] !== action.confirm || $[1] !== action.destructive || $[2] !== action.label || $[3] !== count || $[4] !== event || $[5] !== intl || $[6] !== onCancel || $[7] !== onConfirm) {
|
|
41
|
+
const confirm = typeof action.confirm === "object" ? action.confirm : {};
|
|
42
|
+
const values = {
|
|
43
|
+
count,
|
|
44
|
+
action: action.label
|
|
45
|
+
};
|
|
46
|
+
T0 = Dialog;
|
|
47
|
+
t3 = true;
|
|
48
|
+
if ($[18] !== onCancel) {
|
|
49
|
+
t4 = (open) => {
|
|
50
|
+
if (!open) onCancel();
|
|
51
|
+
};
|
|
52
|
+
$[18] = onCancel;
|
|
53
|
+
$[19] = t4;
|
|
54
|
+
} else t4 = $[19];
|
|
55
|
+
t5 = "alertdialog";
|
|
56
|
+
t6 = false;
|
|
57
|
+
t7 = "sm";
|
|
58
|
+
t8 = confirm.title !== void 0 ? formatDefinitionMessage(intl, confirm.title, values) : intl.formatMessage(messages.confirmTitle, { action: action.label });
|
|
59
|
+
let t10;
|
|
60
|
+
if ($[20] !== event || $[21] !== onConfirm) {
|
|
61
|
+
t10 = () => onConfirm(event);
|
|
62
|
+
$[20] = event;
|
|
63
|
+
$[21] = onConfirm;
|
|
64
|
+
$[22] = t10;
|
|
65
|
+
} else t10 = $[22];
|
|
66
|
+
t9 = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button, {
|
|
67
|
+
variant: "ghost",
|
|
68
|
+
onPress: onCancel,
|
|
69
|
+
children: confirm.cancelLabel ?? intl.formatMessage(messages.cancel)
|
|
70
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
71
|
+
variant: action.destructive === true ? "danger" : "primary",
|
|
72
|
+
autoFocus: true,
|
|
73
|
+
onPress: t10,
|
|
74
|
+
children: confirm.confirmLabel ?? action.label
|
|
75
|
+
})] });
|
|
76
|
+
t1 = Actions_module_default.message;
|
|
77
|
+
t2 = confirm.message !== void 0 ? formatDefinitionMessage(intl, confirm.message, values) : intl.formatMessage(messages.confirmMessage, values);
|
|
78
|
+
$[0] = action.confirm;
|
|
79
|
+
$[1] = action.destructive;
|
|
80
|
+
$[2] = action.label;
|
|
81
|
+
$[3] = count;
|
|
82
|
+
$[4] = event;
|
|
83
|
+
$[5] = intl;
|
|
84
|
+
$[6] = onCancel;
|
|
85
|
+
$[7] = onConfirm;
|
|
86
|
+
$[8] = T0;
|
|
87
|
+
$[9] = t1;
|
|
88
|
+
$[10] = t2;
|
|
89
|
+
$[11] = t3;
|
|
90
|
+
$[12] = t4;
|
|
91
|
+
$[13] = t5;
|
|
92
|
+
$[14] = t6;
|
|
93
|
+
$[15] = t7;
|
|
94
|
+
$[16] = t8;
|
|
95
|
+
$[17] = t9;
|
|
96
|
+
} else {
|
|
97
|
+
T0 = $[8];
|
|
98
|
+
t1 = $[9];
|
|
99
|
+
t2 = $[10];
|
|
100
|
+
t3 = $[11];
|
|
101
|
+
t4 = $[12];
|
|
102
|
+
t5 = $[13];
|
|
103
|
+
t6 = $[14];
|
|
104
|
+
t7 = $[15];
|
|
105
|
+
t8 = $[16];
|
|
106
|
+
t9 = $[17];
|
|
107
|
+
}
|
|
108
|
+
let t10;
|
|
109
|
+
if ($[23] !== t1 || $[24] !== t2) {
|
|
110
|
+
t10 = /* @__PURE__ */ jsx("p", {
|
|
111
|
+
className: t1,
|
|
112
|
+
children: t2
|
|
113
|
+
});
|
|
114
|
+
$[23] = t1;
|
|
115
|
+
$[24] = t2;
|
|
116
|
+
$[25] = t10;
|
|
117
|
+
} else t10 = $[25];
|
|
118
|
+
let t11;
|
|
119
|
+
if ($[26] !== intl || $[27] !== skipped.length) {
|
|
120
|
+
t11 = skipped.length > 0 ? /* @__PURE__ */ jsx("p", {
|
|
121
|
+
className: Actions_module_default.skipped,
|
|
122
|
+
children: intl.formatMessage(messages.confirmSkipped, { count: skipped.length })
|
|
123
|
+
}) : null;
|
|
124
|
+
$[26] = intl;
|
|
125
|
+
$[27] = skipped.length;
|
|
126
|
+
$[28] = t11;
|
|
127
|
+
} else t11 = $[28];
|
|
128
|
+
let t12;
|
|
129
|
+
if ($[29] !== T0 || $[30] !== t10 || $[31] !== t11 || $[32] !== t3 || $[33] !== t4 || $[34] !== t5 || $[35] !== t6 || $[36] !== t7 || $[37] !== t8 || $[38] !== t9) {
|
|
130
|
+
t12 = /* @__PURE__ */ jsxs(T0, {
|
|
131
|
+
isOpen: t3,
|
|
132
|
+
onOpenChange: t4,
|
|
133
|
+
role: t5,
|
|
134
|
+
isDismissable: t6,
|
|
135
|
+
size: t7,
|
|
136
|
+
title: t8,
|
|
137
|
+
footer: t9,
|
|
138
|
+
children: [t10, t11]
|
|
139
|
+
});
|
|
140
|
+
$[29] = T0;
|
|
141
|
+
$[30] = t10;
|
|
142
|
+
$[31] = t11;
|
|
143
|
+
$[32] = t3;
|
|
144
|
+
$[33] = t4;
|
|
145
|
+
$[34] = t5;
|
|
146
|
+
$[35] = t6;
|
|
147
|
+
$[36] = t7;
|
|
148
|
+
$[37] = t8;
|
|
149
|
+
$[38] = t9;
|
|
150
|
+
$[39] = t12;
|
|
151
|
+
} else t12 = $[39];
|
|
152
|
+
return t12;
|
|
153
|
+
}
|
|
154
|
+
//#endregion
|
|
155
|
+
export { ConfirmDialog, needsConfirmation };
|
|
156
|
+
|
|
157
|
+
//# sourceMappingURL=ConfirmDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfirmDialog.js","names":["onCancel","_c","_Fragment","styles"],"sources":["../../src/actions/ConfirmDialog.tsx"],"sourcesContent":["import type { IntlShape } from 'react-intl';\n\nimport { Button, Dialog, usePanneauIntl } from '@panneau/ui';\n\nimport { messages } from '../messages';\nimport type { ListActionEvent } from '../types';\nimport styles from './Actions.module.css';\n\n/** Formats an ICU message of the definition (`{count, plural, …}`) in the locale. */\nfunction formatDefinitionMessage(\n intl: IntlShape,\n message: string,\n values: Record<string, unknown>,\n) {\n try {\n return String(\n intl.formatters\n .getMessageFormat(message, intl.locale)\n .format(values as Record<string, string | number>),\n );\n } catch {\n return message;\n }\n}\n\n/** Whether an action needs a confirmation: it asks for one, or some selected items are skipped. */\nexport function needsConfirmation(event: ListActionEvent): boolean {\n const { confirm } = event.action;\n return (confirm !== undefined && confirm !== false) || event.skipped.length > 0;\n}\n\nexport interface ConfirmDialogProps {\n /** The action to confirm, or `null` when the dialog is closed. */\n event: ListActionEvent | null;\n onConfirm: (event: ListActionEvent) => void;\n onCancel: () => void;\n}\n\n/**\n * Asks before running an action (decision 0017): the action's `confirm` title and message (an ICU\n * message with `{count}`), or default ones, and how many selected items will be skipped.\n */\nexport function ConfirmDialog({ event, onConfirm, onCancel }: ConfirmDialogProps) {\n const intl = usePanneauIntl();\n if (event === null) {\n return null;\n }\n const { action, count, skipped } = event;\n const confirm = typeof action.confirm === 'object' ? action.confirm : {};\n const values = { count, action: action.label };\n return (\n <Dialog\n isOpen\n onOpenChange={(open) => {\n if (!open) {\n onCancel();\n }\n }}\n role=\"alertdialog\"\n isDismissable={false}\n size=\"sm\"\n title={\n confirm.title !== undefined\n ? formatDefinitionMessage(intl, confirm.title, values)\n : intl.formatMessage(messages.confirmTitle, { action: action.label })\n }\n footer={\n <>\n <Button variant=\"ghost\" onPress={onCancel}>\n {confirm.cancelLabel ?? intl.formatMessage(messages.cancel)}\n </Button>\n <Button\n variant={action.destructive === true ? 'danger' : 'primary'}\n autoFocus\n onPress={() => onConfirm(event)}\n >\n {confirm.confirmLabel ?? action.label}\n </Button>\n </>\n }\n >\n <p className={styles.message}>\n {confirm.message !== undefined\n ? formatDefinitionMessage(intl, confirm.message, values)\n : intl.formatMessage(messages.confirmMessage, values)}\n </p>\n {skipped.length > 0 ? (\n <p className={styles.skipped}>\n {intl.formatMessage(messages.confirmSkipped, { count: skipped.length })}\n </p>\n ) : null}\n </Dialog>\n );\n}\n"],"mappings":";;;;;;;AASA,SAAS,wBACL,MACA,SACA,QACF;CACE,IAAI;EACA,OAAO,OACH,KAAK,WACA,iBAAiB,SAAS,KAAK,MAAM,CAAC,CACtC,OAAO,MAAyC,CACzD;CACJ,QAAQ;EACJ,OAAO;CACX;AACJ;;AAGA,SAAgB,kBAAkB,OAAiC;CAC/D,MAAM,EAAE,YAAY,MAAM;CAC1B,OAAQ,YAAY,KAAA,KAAa,YAAY,SAAU,MAAM,QAAQ,SAAS;AAClF;;;;;AAaA,SAAO,cAAA,IAAA;CAAA,MAAA,IAAAC,EAAA,EAAA;CAAuB,MAAA,EAAA,OAAA,WAAA,aAAA;CAC1B,MAAA,OAAa,eAAe;CAC5B,IAAI,UAAU,MAAI,OACP;CAEX,MAAA,EAAA,QAAA,OAAA,YAAmC;CAAM,IAAA;CAAA,IAAA;CAAA,IAAA;CAAA,IAAA;CAAA,IAAA;CAAA,IAAA;CAAA,IAAA;CAAA,IAAA;CAAA,IAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,OAAA,WAAA,EAAA,OAAA,OAAA,eAAA,EAAA,OAAA,OAAA,SAAA,EAAA,OAAA,SAAA,EAAA,OAAA,SAAA,EAAA,OAAA,QAAA,EAAA,OAAA,YAAA,EAAA,OAAA,WAAA;EACzC,MAAA,UAAgB,OAAO,OAAM,YAAa,WAAW,OAAM,UAA3C,CAAuD;EACvE,MAAA,SAAe;GAAA;GAAA,QAAiB,OAAM;EAAO;EAExC,KAAA;EACG,KAAA;EAAM,IAAA,EAAA,QAAA,UAAA;GACQ,MAAA,SAAA;IACV,IAAI,CAAC,MACD,SAAS;GACZ;GACJ,EAAA,MAAA;GAAA,EAAA,MAAA;EAAA,OAAA,KAAA,EAAA;EACI,KAAA;EACU,KAAA;EACV,KAAA;EAED,KAAA,QAAO,UAAW,KAAA,IACZ,wBAAwB,MAAM,QAAO,OAAQ,MACqB,IAAlE,KAAI,cAAe,SAAQ,cAAe,EAAA,QAAU,OAAM,MAAO,CAAC;EAAC,IAAA;EAAA,IAAA,EAAA,QAAA,SAAA,EAAA,QAAA,WAAA;GAUxD,YAAM,UAAU,KAAK;GAAC,EAAA,MAAA;GAAA,EAAA,MAAA;GAAA,EAAA,MAAA;EAAA,OAAA,MAAA,EAAA;EAPvC,KAAA,qBAAAC,UAAA,EAAA,UAAA,CACI,oBAAC,QAAD;GAAgB,SAAA;GAAiBF,SAAA;GAC5B,UAAA,QAAO,eAAgB,KAAI,cAAe,SAAQ,MAAO;EADvD,CAAA,GAGP,oBAAC,QAAD;GACa,SAAA,OAAM,gBAAiB,OAAvB,WAAA;GACT,WAAA;GACS,SAAA;GAER,UAAA,QAAO,gBAAiB,OAAM;EAL5B,CAAA,CAME,EAAA,CAAA;EAIH,KAAAG,uBAAM;EACf,KAAA,QAAO,YAAa,KAAA,IACf,wBAAwB,MAAM,QAAO,SAAU,MACG,IAAlD,KAAI,cAAe,SAAQ,gBAAiB,MAAM;EAAC,EAAA,KAAA,OAAA;EAAA,EAAA,KAAA,OAAA;EAAA,EAAA,KAAA,OAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;CAAA,OAAA;EAAA,KAAA,EAAA;EAAA,KAAA,EAAA;EAAA,KAAA,EAAA;EAAA,KAAA,EAAA;EAAA,KAAA,EAAA;EAAA,KAAA,EAAA;EAAA,KAAA,EAAA;EAAA,KAAA,EAAA;EAAA,KAAA,EAAA;EAAA,KAAA,EAAA;CAAA;CAAA,IAAA;CAAA,IAAA,EAAA,QAAA,MAAA,EAAA,QAAA,IAAA;EAH7D,MAAA,oBAAA,KAAA;GAAc,WAAA;GACT,UAAA;EAGD,CAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;CAAA,OAAA,MAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,QAAA,QAAA,EAAA,QAAA,QAAA,QAAA;EACH,MAAA,QAAO,SAAU,IACd,oBAAA,KAAA;GAAc,WAAAA,uBAAM;GACf,UAAA,KAAI,cAAe,SAAQ,gBAAiB,EAAA,OAAS,QAAO,OAAQ,CAAC;EACtE,CAAA,IAHP;EAIO,EAAA,MAAA;EAAA,EAAA,MAAA,QAAA;EAAA,EAAA,MAAA;CAAA,OAAA,MAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,QAAA,MAAA,EAAA,QAAA,OAAA,EAAA,QAAA,OAAA,EAAA,QAAA,MAAA,EAAA,QAAA,MAAA,EAAA,QAAA,MAAA,EAAA,QAAA,MAAA,EAAA,QAAA,MAAA,EAAA,QAAA,MAAA,EAAA,QAAA,IAAA;EAvCZ,MAAA,qBAAC,IAAD;GACI,QAAA;GACc,cAAA;GAKT,MAAA;GACU,eAAA;GACV,MAAA;GAED,OAAA;GAKA,QAAA;GAhBR,UAAA,CA8BI,KAKC,GAnCE;;EAwCE,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;CAAA,OAAA,MAAA,EAAA;CAAA,OAxCT;AAwCS"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Action } from '@panneau/protocol';
|
|
2
|
+
import type { ListItem } from '../types';
|
|
3
|
+
export interface RowActionsProps {
|
|
4
|
+
item: ListItem;
|
|
5
|
+
/** The label of the item, for the accessible names of its actions. */
|
|
6
|
+
itemLabel: string;
|
|
7
|
+
/** Actions shown as buttons. */
|
|
8
|
+
actions: readonly Action[];
|
|
9
|
+
/** Actions in the overflow menu. */
|
|
10
|
+
menu: readonly Action[];
|
|
11
|
+
/** Id of the action that is running on this item, if any. */
|
|
12
|
+
pending: string | null;
|
|
13
|
+
onRun: (action: Action) => void;
|
|
14
|
+
}
|
|
15
|
+
/** The actions of a row: buttons, then an overflow menu. */
|
|
16
|
+
export declare function RowActions({ item, itemLabel, actions, menu, pending, onRun }: RowActionsProps): import("react").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=RowActions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RowActions.d.ts","sourceRoot":"","sources":["../../src/actions/RowActions.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAIhD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAMzC,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,oCAAoC;IACpC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,6DAA6D;IAC7D,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,4DAA4D;AAC5D,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,eAAe,+BAuD7F"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { getActionHref } from "./actions.js";
|
|
2
|
+
import { messages } from "../messages.js";
|
|
3
|
+
import Actions_module_default from "./Actions.module.js";
|
|
4
|
+
import { getActionIcon } from "./icons.js";
|
|
5
|
+
import { ActionButton } from "./ActionButton.js";
|
|
6
|
+
import { c } from "react/compiler-runtime";
|
|
7
|
+
import { IconButton, Menu, MenuItem, MenuTrigger, usePanneauIntl } from "@panneau/ui";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { Ellipsis } from "lucide-react";
|
|
10
|
+
//#region src/actions/RowActions.tsx
|
|
11
|
+
/** The actions of a row: buttons, then an overflow menu. */
|
|
12
|
+
function RowActions(t0) {
|
|
13
|
+
const $ = c(23);
|
|
14
|
+
const { item, itemLabel, actions, menu, pending, onRun } = t0;
|
|
15
|
+
const intl = usePanneauIntl();
|
|
16
|
+
let t1;
|
|
17
|
+
if ($[0] !== actions || $[1] !== intl || $[2] !== item || $[3] !== itemLabel || $[4] !== onRun || $[5] !== pending) {
|
|
18
|
+
let t2;
|
|
19
|
+
if ($[7] !== intl || $[8] !== item || $[9] !== itemLabel || $[10] !== onRun || $[11] !== pending) {
|
|
20
|
+
t2 = (action) => /* @__PURE__ */ jsx(ActionButton, {
|
|
21
|
+
action,
|
|
22
|
+
href: getActionHref(action, item),
|
|
23
|
+
isPending: pending === action.id,
|
|
24
|
+
isDisabled: pending !== null && pending !== action.id,
|
|
25
|
+
"aria-label": intl.formatMessage(messages.actionOnItem, {
|
|
26
|
+
action: action.label,
|
|
27
|
+
item: itemLabel
|
|
28
|
+
}),
|
|
29
|
+
onPress: () => onRun(action)
|
|
30
|
+
}, action.id);
|
|
31
|
+
$[7] = intl;
|
|
32
|
+
$[8] = item;
|
|
33
|
+
$[9] = itemLabel;
|
|
34
|
+
$[10] = onRun;
|
|
35
|
+
$[11] = pending;
|
|
36
|
+
$[12] = t2;
|
|
37
|
+
} else t2 = $[12];
|
|
38
|
+
t1 = actions.map(t2);
|
|
39
|
+
$[0] = actions;
|
|
40
|
+
$[1] = intl;
|
|
41
|
+
$[2] = item;
|
|
42
|
+
$[3] = itemLabel;
|
|
43
|
+
$[4] = onRun;
|
|
44
|
+
$[5] = pending;
|
|
45
|
+
$[6] = t1;
|
|
46
|
+
} else t1 = $[6];
|
|
47
|
+
let t2;
|
|
48
|
+
if ($[13] !== intl || $[14] !== item || $[15] !== itemLabel || $[16] !== menu || $[17] !== onRun || $[18] !== pending) {
|
|
49
|
+
t2 = menu.length > 0 ? /* @__PURE__ */ jsxs(MenuTrigger, { children: [/* @__PURE__ */ jsx(IconButton, {
|
|
50
|
+
icon: Ellipsis,
|
|
51
|
+
size: "sm",
|
|
52
|
+
label: intl.formatMessage(messages.itemActions, { item: itemLabel }),
|
|
53
|
+
isPending: pending !== null && menu.some((action_0) => action_0.id === pending)
|
|
54
|
+
}), /* @__PURE__ */ jsx(Menu, {
|
|
55
|
+
placement: "bottom end",
|
|
56
|
+
onAction: (key) => {
|
|
57
|
+
const action_1 = menu.find((candidate) => candidate.id === key);
|
|
58
|
+
if (action_1 !== void 0 && getActionHref(action_1, item) === null) onRun(action_1);
|
|
59
|
+
},
|
|
60
|
+
children: menu.map((action_2) => {
|
|
61
|
+
const href = getActionHref(action_2, item);
|
|
62
|
+
const icon = getActionIcon(action_2);
|
|
63
|
+
return /* @__PURE__ */ jsx(MenuItem, {
|
|
64
|
+
id: action_2.id,
|
|
65
|
+
isDanger: action_2.destructive === true,
|
|
66
|
+
...icon !== void 0 ? { icon } : {},
|
|
67
|
+
...href !== null ? { href } : {},
|
|
68
|
+
children: action_2.label
|
|
69
|
+
}, action_2.id);
|
|
70
|
+
})
|
|
71
|
+
})] }) : null;
|
|
72
|
+
$[13] = intl;
|
|
73
|
+
$[14] = item;
|
|
74
|
+
$[15] = itemLabel;
|
|
75
|
+
$[16] = menu;
|
|
76
|
+
$[17] = onRun;
|
|
77
|
+
$[18] = pending;
|
|
78
|
+
$[19] = t2;
|
|
79
|
+
} else t2 = $[19];
|
|
80
|
+
let t3;
|
|
81
|
+
if ($[20] !== t1 || $[21] !== t2) {
|
|
82
|
+
t3 = /* @__PURE__ */ jsxs("div", {
|
|
83
|
+
className: Actions_module_default.row,
|
|
84
|
+
children: [t1, t2]
|
|
85
|
+
});
|
|
86
|
+
$[20] = t1;
|
|
87
|
+
$[21] = t2;
|
|
88
|
+
$[22] = t3;
|
|
89
|
+
} else t3 = $[22];
|
|
90
|
+
return t3;
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
export { RowActions };
|
|
94
|
+
|
|
95
|
+
//# sourceMappingURL=RowActions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RowActions.js","names":["action","Ellipsis","_c","styles"],"sources":["../../src/actions/RowActions.tsx"],"sourcesContent":["import { Ellipsis } from 'lucide-react';\n\nimport type { Action } from '@panneau/protocol';\nimport { IconButton, Menu, MenuItem, MenuTrigger, usePanneauIntl } from '@panneau/ui';\n\nimport { messages } from '../messages';\nimport type { ListItem } from '../types';\nimport { ActionButton } from './ActionButton';\nimport styles from './Actions.module.css';\nimport { getActionHref } from './actions';\nimport { getActionIcon } from './icons';\n\nexport interface RowActionsProps {\n item: ListItem;\n /** The label of the item, for the accessible names of its actions. */\n itemLabel: string;\n /** Actions shown as buttons. */\n actions: readonly Action[];\n /** Actions in the overflow menu. */\n menu: readonly Action[];\n /** Id of the action that is running on this item, if any. */\n pending: string | null;\n onRun: (action: Action) => void;\n}\n\n/** The actions of a row: buttons, then an overflow menu. */\nexport function RowActions({ item, itemLabel, actions, menu, pending, onRun }: RowActionsProps) {\n const intl = usePanneauIntl();\n return (\n <div className={styles.row}>\n {actions.map((action) => (\n <ActionButton\n key={action.id}\n action={action}\n href={getActionHref(action, item)}\n isPending={pending === action.id}\n isDisabled={pending !== null && pending !== action.id}\n aria-label={intl.formatMessage(messages.actionOnItem, {\n action: action.label,\n item: itemLabel,\n })}\n onPress={() => onRun(action)}\n />\n ))}\n {menu.length > 0 ? (\n <MenuTrigger>\n <IconButton\n icon={Ellipsis}\n size=\"sm\"\n label={intl.formatMessage(messages.itemActions, { item: itemLabel })}\n isPending={pending !== null && menu.some((action) => action.id === pending)}\n />\n <Menu\n placement=\"bottom end\"\n onAction={(key) => {\n const action = menu.find((candidate) => candidate.id === key);\n if (action !== undefined && getActionHref(action, item) === null) {\n onRun(action);\n }\n }}\n >\n {menu.map((action) => {\n const href = getActionHref(action, item);\n const icon = getActionIcon(action);\n return (\n <MenuItem\n key={action.id}\n id={action.id}\n isDanger={action.destructive === true}\n {...(icon !== undefined ? { icon } : {})}\n {...(href !== null ? { href } : {})}\n >\n {action.label}\n </MenuItem>\n );\n })}\n </Menu>\n </MenuTrigger>\n ) : null}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;AA0BA,SAAO,WAAA,IAAA;CAAA,MAAA,IAAAE,EAAA,EAAA;CAAoB,MAAA,EAAA,MAAA,WAAA,SAAA,MAAA,SAAA,UAAA;CACvB,MAAA,OAAa,eAAe;CAAE,IAAA;CAAA,IAAA,EAAA,OAAA,WAAA,EAAA,OAAA,QAAA,EAAA,OAAA,QAAA,EAAA,OAAA,aAAA,EAAA,OAAA,SAAA,EAAA,OAAA,SAAA;EAAA,IAAA;EAAA,IAAA,EAAA,OAAA,QAAA,EAAA,OAAA,QAAA,EAAA,OAAA,aAAA,EAAA,QAAA,SAAA,EAAA,QAAA,SAAA;GAGT,MAAA,WACT,oBAAC,cAAD;IAEY;IACF,MAAA,cAAc,QAAQ,IAAI;IACrB,WAAA,YAAY,OAAM;IACjB,YAAA,YAAY,QAAQ,YAAY,OAAM;IACtC,cAAA,KAAI,cAAe,SAAQ,cAAe;KAAA,QAC1C,OAAM;KAAM,MACd;IACV,CAAC;IACQ,eAAM,MAAM,MAAM;GAAC,GATvB,OAAM,EASiB;GAEnC,EAAA,KAAA;GAAA,EAAA,KAAA;GAAA,EAAA,KAAA;GAAA,EAAA,MAAA;GAAA,EAAA,MAAA;GAAA,EAAA,MAAA;EAAA,OAAA,KAAA,EAAA;EAbA,KAAA,QAAO,IAAK,EAaZ;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,QAAA,QAAA,EAAA,QAAA,QAAA,EAAA,QAAA,aAAA,EAAA,QAAA,QAAA,EAAA,QAAA,SAAA,EAAA,QAAA,SAAA;EACD,KAAA,KAAI,SAAU,IACX,qBAAC,aAAD,EAAA,UAAA,CACI,oBAAC,YAAD;GACUD,MAAA;GACD,MAAA;GACE,OAAA,KAAI,cAAe,SAAQ,aAAc,EAAA,MAAQ,UAAU,CAAC;GACxD,WAAA,YAAY,QAAQ,KAAI,MAAM,aAAYD,SAAM,OAAQ,OAAO;EAAC,CAAA,GAE/E,oBAAC,MAAD;GACc,WAAA;GACA,WAAA,QAAA;IACN,MAAA,WAAe,KAAI,MAAM,cAAe,UAAS,OAAQ,GAAG;IAC5D,IAAIA,aAAW,KAAA,KAAa,cAAcA,UAAQ,IAAI,MAAM,MACxD,MAAMA,QAAM;GACf;GAGJ,UAAA,KAAI,KAAK,aAAA;IACN,MAAA,OAAa,cAAcA,UAAQ,IAAI;IACvC,MAAA,OAAa,cAAcA,QAAM;IAAE,OAE/B,oBAAC,UAAD;KAEQ,IAAAA,SAAM;KACA,UAAAA,SAAM,gBAAiB;KAAI,GAChC,SAAS,KAAA,IAAT,EAAA,KAAiC,IAAjC,CAAiC;KAAC,GAClC,SAAS,OAAT,EAAA,KAA4B,IAA5B,CAA4B;KAEhCA,UAAAA,SAAM;IAPF,GACAA,SAAM,EADN;GAQE,CAElB;EAvBA,CAAA,CAPG,EAAA,CAAA,IADf;EAkCO,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,QAAA,MAAA,EAAA,QAAA,IAAA;EAjDZ,KAAA,qBAAA,OAAA;GAAgB,WAAAG,uBAAM;GAAtB,UAAA,CACK,IAcA,EAmCC;;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;CAAA,OAAA,KAAA,EAAA;CAAA,OAlDN;AAkDM"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Action, ActionPlacement } from '@panneau/protocol';
|
|
2
|
+
import type { ListItem } from '../types';
|
|
3
|
+
/** Actions of a list: a list (grouped by their placements), or already grouped by placement. */
|
|
4
|
+
export type ListActions = readonly Action[] | Partial<Record<ActionPlacement, readonly Action[]>>;
|
|
5
|
+
/**
|
|
6
|
+
* Groups actions by placement, without those the user can't run on the resource
|
|
7
|
+
* (`abilities.run`). Actions already grouped (as `resolveList()` does) are filtered the same way.
|
|
8
|
+
*/
|
|
9
|
+
export declare function groupListActions(actions: ListActions | undefined): Record<ActionPlacement, Action[]>;
|
|
10
|
+
/**
|
|
11
|
+
* Whether an action is available on an item (decision 0011). Without abilities, the item allows
|
|
12
|
+
* everything and the backend decides. With abilities, a link is allowed unless the item says
|
|
13
|
+
* otherwise, and other actions only when the item lists their id.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isAllowedOn(action: Action, item: ListItem): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* The link of a `link` action for an item: its `url` template with `{id}` (and other `{field}`
|
|
18
|
+
* values of the item) filled in, or `null` for an action with a `route` or without an item.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getActionHref(action: Action, item?: ListItem): string | null;
|
|
21
|
+
/** Whether an action's scope includes another one. */
|
|
22
|
+
export declare function hasScope(action: Action, scope: Action['scope'][number]): boolean;
|
|
23
|
+
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/actions/actions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,gGAAgG;AAChG,MAAM,MAAM,WAAW,GAAG,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;AAElG;;;GAGG;AACH,wBAAgB,gBAAgB,CAC5B,OAAO,EAAE,WAAW,GAAG,SAAS,GACjC,MAAM,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC,CASnC;AAMD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAWnE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAW5E;AAED,sDAAsD;AACtD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,OAAO,CAEhF"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { canRunAction, groupActions } from "@panneau/core";
|
|
2
|
+
//#region src/actions/actions.ts
|
|
3
|
+
/**
|
|
4
|
+
* Groups actions by placement, without those the user can't run on the resource
|
|
5
|
+
* (`abilities.run`). Actions already grouped (as `resolveList()` does) are filtered the same way.
|
|
6
|
+
*/
|
|
7
|
+
function groupListActions(actions) {
|
|
8
|
+
if (actions === void 0) return {
|
|
9
|
+
row: [],
|
|
10
|
+
toolbar: [],
|
|
11
|
+
form: [],
|
|
12
|
+
menu: []
|
|
13
|
+
};
|
|
14
|
+
if (isActionList(actions)) return groupActions(actions);
|
|
15
|
+
const pick = (placement) => (actions[placement] ?? []).filter(canRunAction);
|
|
16
|
+
return {
|
|
17
|
+
row: pick("row"),
|
|
18
|
+
toolbar: pick("toolbar"),
|
|
19
|
+
form: pick("form"),
|
|
20
|
+
menu: pick("menu")
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function isActionList(actions) {
|
|
24
|
+
return Array.isArray(actions);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Whether an action is available on an item (decision 0011). Without abilities, the item allows
|
|
28
|
+
* everything and the backend decides. With abilities, a link is allowed unless the item says
|
|
29
|
+
* otherwise, and other actions only when the item lists their id.
|
|
30
|
+
*/
|
|
31
|
+
function isAllowedOn(action, item) {
|
|
32
|
+
if (!canRunAction(action)) return false;
|
|
33
|
+
if (item.abilities === void 0) return true;
|
|
34
|
+
if (action.kind === "link") return item.abilities[action.id] !== false;
|
|
35
|
+
return item.abilities[action.id] === true;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The link of a `link` action for an item: its `url` template with `{id}` (and other `{field}`
|
|
39
|
+
* values of the item) filled in, or `null` for an action with a `route` or without an item.
|
|
40
|
+
*/
|
|
41
|
+
function getActionHref(action, item) {
|
|
42
|
+
if (action.kind !== "link" || action.url === void 0) return null;
|
|
43
|
+
const { url } = action;
|
|
44
|
+
return url.replace(/\{([^}]+)\}/g, (match, name) => {
|
|
45
|
+
const value = item?.[name];
|
|
46
|
+
return typeof value === "string" || typeof value === "number" ? encodeURIComponent(String(value)) : match;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** Whether an action's scope includes another one. */
|
|
50
|
+
function hasScope(action, scope) {
|
|
51
|
+
return action.scope.includes(scope);
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { getActionHref, groupListActions, hasScope, isAllowedOn };
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","names":[],"sources":["../../src/actions/actions.ts"],"sourcesContent":["import { canRunAction, groupActions } from '@panneau/core';\nimport type { Action, ActionPlacement } from '@panneau/protocol';\n\nimport type { ListItem } from '../types';\n\n/** Actions of a list: a list (grouped by their placements), or already grouped by placement. */\nexport type ListActions = readonly Action[] | Partial<Record<ActionPlacement, readonly Action[]>>;\n\n/**\n * Groups actions by placement, without those the user can't run on the resource\n * (`abilities.run`). Actions already grouped (as `resolveList()` does) are filtered the same way.\n */\nexport function groupListActions(\n actions: ListActions | undefined,\n): Record<ActionPlacement, Action[]> {\n if (actions === undefined) {\n return { row: [], toolbar: [], form: [], menu: [] };\n }\n if (isActionList(actions)) {\n return groupActions(actions);\n }\n const pick = (placement: ActionPlacement) => (actions[placement] ?? []).filter(canRunAction);\n return { row: pick('row'), toolbar: pick('toolbar'), form: pick('form'), menu: pick('menu') };\n}\n\nfunction isActionList(actions: ListActions): actions is readonly Action[] {\n return Array.isArray(actions);\n}\n\n/**\n * Whether an action is available on an item (decision 0011). Without abilities, the item allows\n * everything and the backend decides. With abilities, a link is allowed unless the item says\n * otherwise, and other actions only when the item lists their id.\n */\nexport function isAllowedOn(action: Action, item: ListItem): boolean {\n if (!canRunAction(action)) {\n return false;\n }\n if (item.abilities === undefined) {\n return true;\n }\n if (action.kind === 'link') {\n return item.abilities[action.id] !== false;\n }\n return item.abilities[action.id] === true;\n}\n\n/**\n * The link of a `link` action for an item: its `url` template with `{id}` (and other `{field}`\n * values of the item) filled in, or `null` for an action with a `route` or without an item.\n */\nexport function getActionHref(action: Action, item?: ListItem): string | null {\n if (action.kind !== 'link' || action.url === undefined) {\n return null;\n }\n const { url } = action;\n return url.replace(/\\{([^}]+)\\}/g, (match, name: string) => {\n const value = item?.[name];\n return typeof value === 'string' || typeof value === 'number'\n ? encodeURIComponent(String(value))\n : match;\n });\n}\n\n/** Whether an action's scope includes another one. */\nexport function hasScope(action: Action, scope: Action['scope'][number]): boolean {\n return action.scope.includes(scope);\n}\n"],"mappings":";;;;;;AAYA,SAAgB,iBACZ,SACiC;CACjC,IAAI,YAAY,KAAA,GACZ,OAAO;EAAE,KAAK,CAAA;EAAI,SAAS,CAAA;EAAI,MAAM,CAAA;EAAI,MAAM,CAAA;CAAG;CAEtD,IAAI,aAAa,OAAO,GACpB,OAAO,aAAa,OAAO;CAE/B,MAAM,QAAQ,eAAgC,QAAQ,cAAc,CAAA,EAAA,CAAI,OAAO,YAAY;CAC3F,OAAO;EAAE,KAAK,KAAK,KAAK;EAAG,SAAS,KAAK,SAAS;EAAG,MAAM,KAAK,MAAM;EAAG,MAAM,KAAK,MAAM;CAAE;AAChG;AAEA,SAAS,aAAa,SAAoD;CACtE,OAAO,MAAM,QAAQ,OAAO;AAChC;;;;;;AAOA,SAAgB,YAAY,QAAgB,MAAyB;CACjE,IAAI,CAAC,aAAa,MAAM,GACpB,OAAO;CAEX,IAAI,KAAK,cAAc,KAAA,GACnB,OAAO;CAEX,IAAI,OAAO,SAAS,QAChB,OAAO,KAAK,UAAU,OAAO,QAAQ;CAEzC,OAAO,KAAK,UAAU,OAAO,QAAQ;AACzC;;;;;AAMA,SAAgB,cAAc,QAAgB,MAAgC;CAC1E,IAAI,OAAO,SAAS,UAAU,OAAO,QAAQ,KAAA,GACzC,OAAO;CAEX,MAAM,EAAE,QAAQ;CAChB,OAAO,IAAI,QAAQ,iBAAiB,OAAO,SAAiB;EACxD,MAAM,QAAQ,OAAO;EACrB,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,WAC/C,mBAAmB,OAAO,KAAK,CAAC,IAChC;CACV,CAAC;AACL;;AAGA,SAAgB,SAAS,QAAgB,OAAyC;CAC9E,OAAO,OAAO,MAAM,SAAS,KAAK;AACtC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type LucideIcon } from 'lucide-react';
|
|
2
|
+
import type { Action } from '@panneau/protocol';
|
|
3
|
+
/** The icon of an action, for the built-in ones. */
|
|
4
|
+
export declare function getActionIcon(action: Action): LucideIcon | undefined;
|
|
5
|
+
//# sourceMappingURL=icons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/actions/icons.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,KAAK,UAAU,EAKlB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAgBhD,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAEpE"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Copy, Download, Eye, Pencil, RotateCcw, Trash2, Upload } from "lucide-react";
|
|
2
|
+
//#region src/actions/icons.ts
|
|
3
|
+
/**
|
|
4
|
+
* Icons of the built-in actions. Icons named in definitions (`"icon": "send"`) need a lookup by
|
|
5
|
+
* name, which comes with the actions of Phase 2 (decision 0020).
|
|
6
|
+
*/
|
|
7
|
+
var BUILT_IN_ICONS = {
|
|
8
|
+
show: Eye,
|
|
9
|
+
edit: Pencil,
|
|
10
|
+
duplicate: Copy,
|
|
11
|
+
delete: Trash2,
|
|
12
|
+
restore: RotateCcw,
|
|
13
|
+
export: Download,
|
|
14
|
+
import: Upload
|
|
15
|
+
};
|
|
16
|
+
/** The icon of an action, for the built-in ones. */
|
|
17
|
+
function getActionIcon(action) {
|
|
18
|
+
return BUILT_IN_ICONS[action.id];
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { getActionIcon };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=icons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.js","names":[],"sources":["../../src/actions/icons.ts"],"sourcesContent":["import {\n Copy,\n Download,\n Eye,\n type LucideIcon,\n Pencil,\n RotateCcw,\n Trash2,\n Upload,\n} from 'lucide-react';\n\nimport type { Action } from '@panneau/protocol';\n\n/**\n * Icons of the built-in actions. Icons named in definitions (`\"icon\": \"send\"`) need a lookup by\n * name, which comes with the actions of Phase 2 (decision 0020).\n */\nconst BUILT_IN_ICONS: Record<string, LucideIcon> = {\n show: Eye,\n edit: Pencil,\n duplicate: Copy,\n delete: Trash2,\n restore: RotateCcw,\n export: Download,\n import: Upload,\n};\n\n/** The icon of an action, for the built-in ones. */\nexport function getActionIcon(action: Action): LucideIcon | undefined {\n return BUILT_IN_ICONS[action.id];\n}\n"],"mappings":";;;;;;AAiBA,IAAM,iBAA6C;CAC/C,MAAM;CACN,MAAM;CACN,WAAW;CACX,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,QAAQ;AACZ;;AAGA,SAAgB,cAAc,QAAwC;CAClE,OAAO,eAAe,OAAO;AACjC"}
|
package/dist/cx.d.ts
ADDED
package/dist/cx.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cx.d.ts","sourceRoot":"","sources":["../src/cx.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,wBAAgB,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,GAAG,MAAM,CAE/E"}
|
package/dist/cx.js
ADDED
package/dist/cx.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cx.js","names":[],"sources":["../src/cx.ts"],"sourcesContent":["/** Joins class names, skipping empty ones. */\nexport function cx(...classNames: (string | false | null | undefined)[]): string {\n return classNames.filter(Boolean).join(' ');\n}\n"],"mappings":";;AACA,SAAgB,GAAG,GAAG,YAA2D;CAC7E,OAAO,WAAW,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;AAC9C"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
.panneau-empty-xEtZBq {
|
|
2
|
+
color: var(--panneau-color-text-muted);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.panneau-text-vty-EA {
|
|
6
|
+
display: -webkit-box;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
-webkit-line-clamp: 2;
|
|
9
|
+
line-clamp: 2;
|
|
10
|
+
-webkit-box-orient: vertical;
|
|
11
|
+
overflow-wrap: anywhere;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.panneau-badges-2n5UJa {
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
flex-wrap: wrap;
|
|
17
|
+
gap: var(--panneau-space-1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.panneau-boolean-vvV7kf {
|
|
21
|
+
display: inline-flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.panneau-true-Iu6Hsd {
|
|
26
|
+
color: var(--panneau-color-success);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.panneau-false-zp5WgH {
|
|
30
|
+
color: var(--panneau-color-text-muted);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.panneau-number-yfICs7 {
|
|
34
|
+
font-variant-numeric: tabular-nums;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.panneau-link-nvMTOa {
|
|
38
|
+
color: var(--panneau-color-link);
|
|
39
|
+
overflow-wrap: anywhere;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.panneau-color-kkWQ1L {
|
|
43
|
+
display: inline-flex;
|
|
44
|
+
align-items: center;
|
|
45
|
+
gap: var(--panneau-space-2);
|
|
46
|
+
font-family: var(--panneau-font-family-mono);
|
|
47
|
+
font-size: var(--panneau-font-size-sm);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.panneau-swatch-50Qwvv {
|
|
51
|
+
flex: none;
|
|
52
|
+
width: 1rem;
|
|
53
|
+
height: 1rem;
|
|
54
|
+
border: var(--panneau-border-width) solid var(--panneau-color-border-control);
|
|
55
|
+
border-radius: var(--panneau-radius-sm);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.panneau-media-EOUwYg {
|
|
59
|
+
display: inline-flex;
|
|
60
|
+
align-items: center;
|
|
61
|
+
gap: var(--panneau-space-2);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.panneau-thumbnail-WgBzFY {
|
|
65
|
+
flex: none;
|
|
66
|
+
width: 2.5rem;
|
|
67
|
+
height: 2.5rem;
|
|
68
|
+
object-fit: cover;
|
|
69
|
+
background-color: var(--panneau-color-surface-sunken);
|
|
70
|
+
border-radius: var(--panneau-radius-sm);
|
|
71
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import "./Displays.css";
|
|
2
|
+
//#region src/displays/Displays.module.css
|
|
3
|
+
var empty = "panneau-empty-xEtZBq";
|
|
4
|
+
var text = "panneau-text-vty-EA";
|
|
5
|
+
var badges = "panneau-badges-2n5UJa";
|
|
6
|
+
var boolean = "panneau-boolean-vvV7kf";
|
|
7
|
+
var number = "panneau-number-yfICs7";
|
|
8
|
+
var link = "panneau-link-nvMTOa";
|
|
9
|
+
var color = "panneau-color-kkWQ1L";
|
|
10
|
+
var swatch = "panneau-swatch-50Qwvv";
|
|
11
|
+
var media = "panneau-media-EOUwYg";
|
|
12
|
+
var thumbnail = "panneau-thumbnail-WgBzFY";
|
|
13
|
+
var Displays_module_default = {
|
|
14
|
+
empty,
|
|
15
|
+
text,
|
|
16
|
+
badges,
|
|
17
|
+
boolean,
|
|
18
|
+
"true": "panneau-true-Iu6Hsd",
|
|
19
|
+
"false": "panneau-false-zp5WgH",
|
|
20
|
+
number,
|
|
21
|
+
link,
|
|
22
|
+
color,
|
|
23
|
+
swatch,
|
|
24
|
+
media,
|
|
25
|
+
thumbnail
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { badges, boolean, color, Displays_module_default as default, empty, link, media, number, swatch, text, thumbnail };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=Displays.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Displays.module.js","names":[],"sources":["../../src/displays/Displays.module.css"],"sourcesContent":[".empty {\n color: var(--panneau-color-text-muted);\n}\n\n.text {\n display: -webkit-box;\n overflow: hidden;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow-wrap: anywhere;\n}\n\n.badges {\n display: inline-flex;\n flex-wrap: wrap;\n gap: var(--panneau-space-1);\n}\n\n.boolean {\n display: inline-flex;\n align-items: center;\n}\n\n.true {\n color: var(--panneau-color-success);\n}\n\n.false {\n color: var(--panneau-color-text-muted);\n}\n\n.number {\n font-variant-numeric: tabular-nums;\n}\n\n.link {\n color: var(--panneau-color-link);\n overflow-wrap: anywhere;\n}\n\n.color {\n display: inline-flex;\n align-items: center;\n gap: var(--panneau-space-2);\n font-family: var(--panneau-font-family-mono);\n font-size: var(--panneau-font-size-sm);\n}\n\n.swatch {\n flex: none;\n width: 1rem;\n height: 1rem;\n border: var(--panneau-border-width) solid var(--panneau-color-border-control);\n border-radius: var(--panneau-radius-sm);\n}\n\n.media {\n display: inline-flex;\n align-items: center;\n gap: var(--panneau-space-2);\n}\n\n.thumbnail {\n flex: none;\n width: 2.5rem;\n height: 2.5rem;\n object-fit: cover;\n background-color: var(--panneau-color-surface-sunken);\n border-radius: var(--panneau-radius-sm);\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { DisplayEntry, DisplayProps } from '../types';
|
|
2
|
+
/** What a cell shows without a value. Hidden from assistive technologies, which skip the cell. */
|
|
3
|
+
export declare function EmptyValue(): import("react").JSX.Element;
|
|
4
|
+
/** Text, on two lines at most. The default display. */
|
|
5
|
+
export declare function TextDisplay({ value }: DisplayProps): import("react").JSX.Element;
|
|
6
|
+
/** HTML as plain text. */
|
|
7
|
+
export declare function RichTextDisplay({ value }: DisplayProps): import("react").JSX.Element;
|
|
8
|
+
/** A number, in the format of the locale. */
|
|
9
|
+
export declare function NumberDisplay({ value }: DisplayProps): import("react").JSX.Element;
|
|
10
|
+
/** Yes or no, as an icon with its label. */
|
|
11
|
+
export declare function BooleanDisplay({ value }: DisplayProps): import("react").JSX.Element;
|
|
12
|
+
/** A date, in the format of the locale. */
|
|
13
|
+
export declare function DateDisplay({ value }: DisplayProps): import("react").JSX.Element;
|
|
14
|
+
/** A date and a time, in the format and the time zone of the user. */
|
|
15
|
+
export declare function DateTimeDisplay({ value }: DisplayProps): import("react").JSX.Element;
|
|
16
|
+
/** A time of day (`14:30`), in the format of the locale. */
|
|
17
|
+
export declare function TimeDisplay({ value }: DisplayProps): import("react").JSX.Element;
|
|
18
|
+
/** The labels of the selected options, as badges. */
|
|
19
|
+
export declare function SelectDisplay({ value, field }: DisplayProps): import("react").JSX.Element;
|
|
20
|
+
/** The labels of related items. */
|
|
21
|
+
export declare function RelationDisplay({ value }: DisplayProps): import("react").JSX.Element;
|
|
22
|
+
/** A link that opens the URL. */
|
|
23
|
+
export declare function UrlDisplay({ value }: DisplayProps): import("react").JSX.Element;
|
|
24
|
+
/** A link that writes an email. */
|
|
25
|
+
export declare function EmailDisplay({ value }: DisplayProps): import("react").JSX.Element;
|
|
26
|
+
/** A swatch, with the color's code. */
|
|
27
|
+
export declare function ColorDisplay({ value }: DisplayProps): import("react").JSX.Element;
|
|
28
|
+
/** A thumbnail and the name of a media item (or of the first one). */
|
|
29
|
+
export declare function MediaDisplay({ value }: DisplayProps): import("react").JSX.Element;
|
|
30
|
+
/**
|
|
31
|
+
* The built-in displays, by name. A column's display is its `display`, its field's `display`, or
|
|
32
|
+
* its field's type: field types are display names. Values without a known display are shown as
|
|
33
|
+
* text.
|
|
34
|
+
*/
|
|
35
|
+
export declare const builtInDisplays: Readonly<Record<string, DisplayEntry>>;
|
|
36
|
+
//# sourceMappingURL=displays.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"displays.d.ts","sourceRoot":"","sources":["../../src/displays/displays.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAI3D,kGAAkG;AAClG,wBAAgB,UAAU,gCAMzB;AAWD,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAIlD;AAED,0BAA0B;AAC1B,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAStD;AAED,6CAA6C;AAC7C,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAQpD;AAED,4CAA4C;AAC5C,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAcrD;AAkBD,2CAA2C;AAC3C,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAOlD;AAED,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAWtD;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAQlD;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,YAAY,+BAa3D;AAED,mCAAmC;AACnC,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAUtD;AAED,iCAAiC;AACjC,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BASjD;AAED,mCAAmC;AACnC,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BASnD;AAED,uCAAuC;AACvC,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAUnD;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAenD;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAgBlE,CAAC"}
|