@arqel-dev/ui 0.9.1 → 0.9.3
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/dist/pages.js +532 -10
- package/dist/pages.js.map +1 -1
- package/package.json +6 -6
package/dist/pages.js
CHANGED
|
@@ -2,11 +2,12 @@ import { clsx } from 'clsx';
|
|
|
2
2
|
import { twMerge } from 'tailwind-merge';
|
|
3
3
|
import { useMemo, useState, useRef, useEffect, useCallback, useId } from 'react';
|
|
4
4
|
import { cva } from 'class-variance-authority';
|
|
5
|
-
import { Slot } from 'radix-ui';
|
|
5
|
+
import { Slot, DropdownMenu as DropdownMenu$1, Dialog as Dialog$1 } from 'radix-ui';
|
|
6
6
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
import { isFieldEntry, isLayoutEntry } from '@arqel-dev/types/forms';
|
|
8
8
|
import { useArqelForm } from '@arqel-dev/hooks';
|
|
9
9
|
import { usePage, router } from '@inertiajs/react';
|
|
10
|
+
import { XIcon } from 'lucide-react';
|
|
10
11
|
import { useReactTable, getCoreRowModel, flexRender } from '@tanstack/react-table';
|
|
11
12
|
|
|
12
13
|
var __defProp = Object.defineProperty;
|
|
@@ -865,6 +866,477 @@ var init_ArqelEditPage = __esm({
|
|
|
865
866
|
};
|
|
866
867
|
}
|
|
867
868
|
});
|
|
869
|
+
function DropdownMenu({
|
|
870
|
+
...props
|
|
871
|
+
}) {
|
|
872
|
+
return /* @__PURE__ */ jsx(DropdownMenu$1.Root, { "data-slot": "dropdown-menu", ...props });
|
|
873
|
+
}
|
|
874
|
+
function DropdownMenuTrigger({
|
|
875
|
+
...props
|
|
876
|
+
}) {
|
|
877
|
+
return /* @__PURE__ */ jsx(
|
|
878
|
+
DropdownMenu$1.Trigger,
|
|
879
|
+
{
|
|
880
|
+
"data-slot": "dropdown-menu-trigger",
|
|
881
|
+
...props
|
|
882
|
+
}
|
|
883
|
+
);
|
|
884
|
+
}
|
|
885
|
+
function DropdownMenuContent({
|
|
886
|
+
className,
|
|
887
|
+
sideOffset = 4,
|
|
888
|
+
...props
|
|
889
|
+
}) {
|
|
890
|
+
return /* @__PURE__ */ jsx(DropdownMenu$1.Portal, { children: /* @__PURE__ */ jsx(
|
|
891
|
+
DropdownMenu$1.Content,
|
|
892
|
+
{
|
|
893
|
+
"data-slot": "dropdown-menu-content",
|
|
894
|
+
sideOffset,
|
|
895
|
+
className: cn(
|
|
896
|
+
"z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
897
|
+
className
|
|
898
|
+
),
|
|
899
|
+
...props
|
|
900
|
+
}
|
|
901
|
+
) });
|
|
902
|
+
}
|
|
903
|
+
function DropdownMenuItem({
|
|
904
|
+
className,
|
|
905
|
+
inset,
|
|
906
|
+
variant = "default",
|
|
907
|
+
...props
|
|
908
|
+
}) {
|
|
909
|
+
return /* @__PURE__ */ jsx(
|
|
910
|
+
DropdownMenu$1.Item,
|
|
911
|
+
{
|
|
912
|
+
"data-slot": "dropdown-menu-item",
|
|
913
|
+
"data-inset": inset,
|
|
914
|
+
"data-variant": variant,
|
|
915
|
+
className: cn(
|
|
916
|
+
"relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-[variant=destructive]:*:[svg]:text-destructive!",
|
|
917
|
+
className
|
|
918
|
+
),
|
|
919
|
+
...props
|
|
920
|
+
}
|
|
921
|
+
);
|
|
922
|
+
}
|
|
923
|
+
var init_dropdown_menu = __esm({
|
|
924
|
+
"src/shadcn/ui/dropdown-menu.tsx"() {
|
|
925
|
+
"use client";
|
|
926
|
+
init_cn();
|
|
927
|
+
}
|
|
928
|
+
});
|
|
929
|
+
function Dialog({
|
|
930
|
+
...props
|
|
931
|
+
}) {
|
|
932
|
+
return /* @__PURE__ */ jsx(Dialog$1.Root, { "data-slot": "dialog", ...props });
|
|
933
|
+
}
|
|
934
|
+
function DialogPortal({
|
|
935
|
+
...props
|
|
936
|
+
}) {
|
|
937
|
+
return /* @__PURE__ */ jsx(Dialog$1.Portal, { "data-slot": "dialog-portal", ...props });
|
|
938
|
+
}
|
|
939
|
+
function DialogClose({
|
|
940
|
+
...props
|
|
941
|
+
}) {
|
|
942
|
+
return /* @__PURE__ */ jsx(Dialog$1.Close, { "data-slot": "dialog-close", ...props });
|
|
943
|
+
}
|
|
944
|
+
function DialogOverlay({
|
|
945
|
+
className,
|
|
946
|
+
...props
|
|
947
|
+
}) {
|
|
948
|
+
return /* @__PURE__ */ jsx(
|
|
949
|
+
Dialog$1.Overlay,
|
|
950
|
+
{
|
|
951
|
+
"data-slot": "dialog-overlay",
|
|
952
|
+
className: cn(
|
|
953
|
+
"fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
|
|
954
|
+
className
|
|
955
|
+
),
|
|
956
|
+
...props
|
|
957
|
+
}
|
|
958
|
+
);
|
|
959
|
+
}
|
|
960
|
+
function DialogContent({
|
|
961
|
+
className,
|
|
962
|
+
children,
|
|
963
|
+
showCloseButton = true,
|
|
964
|
+
...props
|
|
965
|
+
}) {
|
|
966
|
+
return /* @__PURE__ */ jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
|
|
967
|
+
/* @__PURE__ */ jsx(DialogOverlay, {}),
|
|
968
|
+
/* @__PURE__ */ jsxs(
|
|
969
|
+
Dialog$1.Content,
|
|
970
|
+
{
|
|
971
|
+
"data-slot": "dialog-content",
|
|
972
|
+
className: cn(
|
|
973
|
+
"fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg",
|
|
974
|
+
className
|
|
975
|
+
),
|
|
976
|
+
...props,
|
|
977
|
+
children: [
|
|
978
|
+
children,
|
|
979
|
+
showCloseButton && /* @__PURE__ */ jsxs(
|
|
980
|
+
Dialog$1.Close,
|
|
981
|
+
{
|
|
982
|
+
"data-slot": "dialog-close",
|
|
983
|
+
className: "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
984
|
+
children: [
|
|
985
|
+
/* @__PURE__ */ jsx(XIcon, {}),
|
|
986
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
|
|
987
|
+
]
|
|
988
|
+
}
|
|
989
|
+
)
|
|
990
|
+
]
|
|
991
|
+
}
|
|
992
|
+
)
|
|
993
|
+
] });
|
|
994
|
+
}
|
|
995
|
+
function DialogHeader({ className, ...props }) {
|
|
996
|
+
return /* @__PURE__ */ jsx(
|
|
997
|
+
"div",
|
|
998
|
+
{
|
|
999
|
+
"data-slot": "dialog-header",
|
|
1000
|
+
className: cn("flex flex-col gap-2 text-center sm:text-left", className),
|
|
1001
|
+
...props
|
|
1002
|
+
}
|
|
1003
|
+
);
|
|
1004
|
+
}
|
|
1005
|
+
function DialogFooter({
|
|
1006
|
+
className,
|
|
1007
|
+
showCloseButton = false,
|
|
1008
|
+
children,
|
|
1009
|
+
...props
|
|
1010
|
+
}) {
|
|
1011
|
+
return /* @__PURE__ */ jsxs(
|
|
1012
|
+
"div",
|
|
1013
|
+
{
|
|
1014
|
+
"data-slot": "dialog-footer",
|
|
1015
|
+
className: cn(
|
|
1016
|
+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
1017
|
+
className
|
|
1018
|
+
),
|
|
1019
|
+
...props,
|
|
1020
|
+
children: [
|
|
1021
|
+
children,
|
|
1022
|
+
showCloseButton && /* @__PURE__ */ jsx(Dialog$1.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "outline", children: "Close" }) })
|
|
1023
|
+
]
|
|
1024
|
+
}
|
|
1025
|
+
);
|
|
1026
|
+
}
|
|
1027
|
+
function DialogTitle({
|
|
1028
|
+
className,
|
|
1029
|
+
...props
|
|
1030
|
+
}) {
|
|
1031
|
+
return /* @__PURE__ */ jsx(
|
|
1032
|
+
Dialog$1.Title,
|
|
1033
|
+
{
|
|
1034
|
+
"data-slot": "dialog-title",
|
|
1035
|
+
className: cn("text-lg leading-none font-semibold", className),
|
|
1036
|
+
...props
|
|
1037
|
+
}
|
|
1038
|
+
);
|
|
1039
|
+
}
|
|
1040
|
+
function DialogDescription({
|
|
1041
|
+
className,
|
|
1042
|
+
...props
|
|
1043
|
+
}) {
|
|
1044
|
+
return /* @__PURE__ */ jsx(
|
|
1045
|
+
Dialog$1.Description,
|
|
1046
|
+
{
|
|
1047
|
+
"data-slot": "dialog-description",
|
|
1048
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
1049
|
+
...props
|
|
1050
|
+
}
|
|
1051
|
+
);
|
|
1052
|
+
}
|
|
1053
|
+
var init_dialog = __esm({
|
|
1054
|
+
"src/shadcn/ui/dialog.tsx"() {
|
|
1055
|
+
init_cn();
|
|
1056
|
+
init_button();
|
|
1057
|
+
}
|
|
1058
|
+
});
|
|
1059
|
+
function ActionFormModal({
|
|
1060
|
+
open,
|
|
1061
|
+
onOpenChange,
|
|
1062
|
+
action,
|
|
1063
|
+
fields,
|
|
1064
|
+
onSubmit,
|
|
1065
|
+
processing = false,
|
|
1066
|
+
errors = {},
|
|
1067
|
+
initialValues = {}
|
|
1068
|
+
}) {
|
|
1069
|
+
const [values, setValues] = useState(initialValues);
|
|
1070
|
+
const size = action.modalSize ?? "md";
|
|
1071
|
+
const schema = useMemo(
|
|
1072
|
+
() => ({
|
|
1073
|
+
schema: (action.form ?? []).map((entry) => ({
|
|
1074
|
+
kind: "field",
|
|
1075
|
+
name: entry.name,
|
|
1076
|
+
type: entry.type
|
|
1077
|
+
})),
|
|
1078
|
+
columns: 1,
|
|
1079
|
+
model: null,
|
|
1080
|
+
inline: false,
|
|
1081
|
+
disabled: false
|
|
1082
|
+
}),
|
|
1083
|
+
[action.form]
|
|
1084
|
+
);
|
|
1085
|
+
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (next) => onOpenChange(next), children: /* @__PURE__ */ jsxs(DialogContent, { className: cn("overflow-auto", SIZE_CLASSES[size]), children: [
|
|
1086
|
+
/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: action.label }) }),
|
|
1087
|
+
/* @__PURE__ */ jsxs(
|
|
1088
|
+
"form",
|
|
1089
|
+
{
|
|
1090
|
+
className: "flex flex-col gap-4",
|
|
1091
|
+
onSubmit: (e) => {
|
|
1092
|
+
e.preventDefault();
|
|
1093
|
+
onSubmit(values);
|
|
1094
|
+
},
|
|
1095
|
+
children: [
|
|
1096
|
+
/* @__PURE__ */ jsx(
|
|
1097
|
+
FormRenderer,
|
|
1098
|
+
{
|
|
1099
|
+
schema,
|
|
1100
|
+
fields,
|
|
1101
|
+
values,
|
|
1102
|
+
errors,
|
|
1103
|
+
onChange: (name, value) => setValues((prev) => ({ ...prev, [name]: value })),
|
|
1104
|
+
disabled: processing
|
|
1105
|
+
}
|
|
1106
|
+
),
|
|
1107
|
+
/* @__PURE__ */ jsx(
|
|
1108
|
+
FormActions,
|
|
1109
|
+
{
|
|
1110
|
+
processing,
|
|
1111
|
+
submitLabel: action.label,
|
|
1112
|
+
extra: /* @__PURE__ */ jsx(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", disabled: processing, children: "Cancel" }) })
|
|
1113
|
+
}
|
|
1114
|
+
)
|
|
1115
|
+
]
|
|
1116
|
+
}
|
|
1117
|
+
)
|
|
1118
|
+
] }) });
|
|
1119
|
+
}
|
|
1120
|
+
var SIZE_CLASSES;
|
|
1121
|
+
var init_ActionFormModal = __esm({
|
|
1122
|
+
"src/action/ActionFormModal.tsx"() {
|
|
1123
|
+
init_FormActions();
|
|
1124
|
+
init_FormRenderer();
|
|
1125
|
+
init_dialog();
|
|
1126
|
+
init_cn();
|
|
1127
|
+
init_Button();
|
|
1128
|
+
SIZE_CLASSES = {
|
|
1129
|
+
sm: "sm:max-w-[24rem]",
|
|
1130
|
+
md: "sm:max-w-[32rem]",
|
|
1131
|
+
lg: "sm:max-w-[44rem]",
|
|
1132
|
+
xl: "sm:max-w-[56rem]",
|
|
1133
|
+
full: "sm:max-w-[90vw] h-[90vh]"
|
|
1134
|
+
};
|
|
1135
|
+
}
|
|
1136
|
+
});
|
|
1137
|
+
function ConfirmDialog({
|
|
1138
|
+
open,
|
|
1139
|
+
onOpenChange,
|
|
1140
|
+
config,
|
|
1141
|
+
onConfirm,
|
|
1142
|
+
processing = false
|
|
1143
|
+
}) {
|
|
1144
|
+
const [typed, setTyped] = useState("");
|
|
1145
|
+
useEffect(() => {
|
|
1146
|
+
if (!open) setTyped("");
|
|
1147
|
+
}, [open]);
|
|
1148
|
+
const requiresText = config?.requiresText;
|
|
1149
|
+
const submitDisabled = processing || requiresText !== void 0 && typed !== requiresText;
|
|
1150
|
+
const variant = COLOR_VARIANT[config?.color ?? "destructive"];
|
|
1151
|
+
const submitLabel = config?.submitLabel ?? (config?.color === "info" ? "Confirm" : "Delete");
|
|
1152
|
+
const cancelLabel = config?.cancelLabel ?? "Cancel";
|
|
1153
|
+
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (next) => onOpenChange(next), children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-[28rem]", showCloseButton: false, children: [
|
|
1154
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
1155
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: config?.heading ?? "Are you sure?" }),
|
|
1156
|
+
config?.description && /* @__PURE__ */ jsx(DialogDescription, { children: config.description })
|
|
1157
|
+
] }),
|
|
1158
|
+
requiresText !== void 0 && /* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1 text-xs text-muted-foreground", children: [
|
|
1159
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
1160
|
+
"Type ",
|
|
1161
|
+
/* @__PURE__ */ jsx("code", { className: "font-mono text-foreground", children: requiresText }),
|
|
1162
|
+
" to confirm"
|
|
1163
|
+
] }),
|
|
1164
|
+
/* @__PURE__ */ jsx(
|
|
1165
|
+
"input",
|
|
1166
|
+
{
|
|
1167
|
+
type: "text",
|
|
1168
|
+
ref: (el) => el?.focus(),
|
|
1169
|
+
value: typed,
|
|
1170
|
+
onChange: (e) => setTyped(e.target.value),
|
|
1171
|
+
onKeyDown: (e) => {
|
|
1172
|
+
if (e.key === "Enter" && !submitDisabled) {
|
|
1173
|
+
e.preventDefault();
|
|
1174
|
+
onConfirm();
|
|
1175
|
+
}
|
|
1176
|
+
},
|
|
1177
|
+
className: "h-9 rounded-md border border-input bg-background px-3 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
1178
|
+
}
|
|
1179
|
+
)
|
|
1180
|
+
] }),
|
|
1181
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
1182
|
+
/* @__PURE__ */ jsx(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", disabled: processing, children: cancelLabel }) }),
|
|
1183
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant, disabled: submitDisabled, onClick: onConfirm, children: processing ? "Working\u2026" : submitLabel })
|
|
1184
|
+
] })
|
|
1185
|
+
] }) });
|
|
1186
|
+
}
|
|
1187
|
+
var COLOR_VARIANT;
|
|
1188
|
+
var init_ConfirmDialog = __esm({
|
|
1189
|
+
"src/action/ConfirmDialog.tsx"() {
|
|
1190
|
+
init_dialog();
|
|
1191
|
+
init_Button();
|
|
1192
|
+
COLOR_VARIANT = {
|
|
1193
|
+
destructive: "destructive",
|
|
1194
|
+
warning: "default",
|
|
1195
|
+
info: "default"
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1198
|
+
});
|
|
1199
|
+
function ActionButton({
|
|
1200
|
+
action,
|
|
1201
|
+
formFields = [],
|
|
1202
|
+
onInvoke,
|
|
1203
|
+
processing = false,
|
|
1204
|
+
errors,
|
|
1205
|
+
size = "default",
|
|
1206
|
+
className
|
|
1207
|
+
}) {
|
|
1208
|
+
const [confirmOpen, setConfirmOpen] = useState(false);
|
|
1209
|
+
const [formOpen, setFormOpen] = useState(false);
|
|
1210
|
+
const variant = VARIANT_OVERRIDE[action.variant] ?? COLOR_TO_VARIANT[action.color];
|
|
1211
|
+
const handleClick = () => {
|
|
1212
|
+
if (action.disabled) return;
|
|
1213
|
+
if (action.requiresConfirmation) {
|
|
1214
|
+
setConfirmOpen(true);
|
|
1215
|
+
} else if (action.form && action.form.length > 0) {
|
|
1216
|
+
setFormOpen(true);
|
|
1217
|
+
} else {
|
|
1218
|
+
onInvoke();
|
|
1219
|
+
}
|
|
1220
|
+
};
|
|
1221
|
+
const handleConfirm = () => {
|
|
1222
|
+
setConfirmOpen(false);
|
|
1223
|
+
if (action.form && action.form.length > 0) {
|
|
1224
|
+
setFormOpen(true);
|
|
1225
|
+
} else {
|
|
1226
|
+
onInvoke();
|
|
1227
|
+
}
|
|
1228
|
+
};
|
|
1229
|
+
const handleFormSubmit = (values) => {
|
|
1230
|
+
onInvoke(values);
|
|
1231
|
+
setFormOpen(false);
|
|
1232
|
+
};
|
|
1233
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1234
|
+
/* @__PURE__ */ jsx(
|
|
1235
|
+
Button,
|
|
1236
|
+
{
|
|
1237
|
+
variant,
|
|
1238
|
+
size,
|
|
1239
|
+
disabled: action.disabled === true || processing,
|
|
1240
|
+
title: action.tooltip,
|
|
1241
|
+
onClick: handleClick,
|
|
1242
|
+
className,
|
|
1243
|
+
children: action.label
|
|
1244
|
+
}
|
|
1245
|
+
),
|
|
1246
|
+
action.requiresConfirmation && /* @__PURE__ */ jsx(
|
|
1247
|
+
ConfirmDialog,
|
|
1248
|
+
{
|
|
1249
|
+
open: confirmOpen,
|
|
1250
|
+
onOpenChange: setConfirmOpen,
|
|
1251
|
+
config: action.confirmation,
|
|
1252
|
+
onConfirm: handleConfirm,
|
|
1253
|
+
processing
|
|
1254
|
+
}
|
|
1255
|
+
),
|
|
1256
|
+
action.form && action.form.length > 0 && /* @__PURE__ */ jsx(
|
|
1257
|
+
ActionFormModal,
|
|
1258
|
+
{
|
|
1259
|
+
open: formOpen,
|
|
1260
|
+
onOpenChange: setFormOpen,
|
|
1261
|
+
action,
|
|
1262
|
+
fields: formFields,
|
|
1263
|
+
onSubmit: handleFormSubmit,
|
|
1264
|
+
processing,
|
|
1265
|
+
errors
|
|
1266
|
+
}
|
|
1267
|
+
)
|
|
1268
|
+
] });
|
|
1269
|
+
}
|
|
1270
|
+
var COLOR_TO_VARIANT, VARIANT_OVERRIDE;
|
|
1271
|
+
var init_ActionButton = __esm({
|
|
1272
|
+
"src/action/ActionButton.tsx"() {
|
|
1273
|
+
init_ActionFormModal();
|
|
1274
|
+
init_Button();
|
|
1275
|
+
init_ConfirmDialog();
|
|
1276
|
+
COLOR_TO_VARIANT = {
|
|
1277
|
+
primary: "default",
|
|
1278
|
+
secondary: "outline",
|
|
1279
|
+
destructive: "destructive",
|
|
1280
|
+
success: "default",
|
|
1281
|
+
warning: "default",
|
|
1282
|
+
info: "default"
|
|
1283
|
+
};
|
|
1284
|
+
VARIANT_OVERRIDE = {
|
|
1285
|
+
default: "default",
|
|
1286
|
+
outline: "outline",
|
|
1287
|
+
ghost: "ghost",
|
|
1288
|
+
destructive: "destructive"
|
|
1289
|
+
};
|
|
1290
|
+
}
|
|
1291
|
+
});
|
|
1292
|
+
function ActionMenu({
|
|
1293
|
+
actions,
|
|
1294
|
+
formFieldsByAction = {},
|
|
1295
|
+
onInvoke,
|
|
1296
|
+
inlineThreshold = 3,
|
|
1297
|
+
processing = false,
|
|
1298
|
+
trigger,
|
|
1299
|
+
className
|
|
1300
|
+
}) {
|
|
1301
|
+
if (actions.length === 0) return null;
|
|
1302
|
+
if (actions.length <= inlineThreshold) {
|
|
1303
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex flex-wrap items-center gap-1", className), children: actions.map((action) => /* @__PURE__ */ jsx(
|
|
1304
|
+
ActionButton,
|
|
1305
|
+
{
|
|
1306
|
+
action,
|
|
1307
|
+
formFields: formFieldsByAction[action.name] ?? [],
|
|
1308
|
+
onInvoke: (values) => onInvoke(action, values),
|
|
1309
|
+
processing,
|
|
1310
|
+
size: "sm"
|
|
1311
|
+
},
|
|
1312
|
+
action.name
|
|
1313
|
+
)) });
|
|
1314
|
+
}
|
|
1315
|
+
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
1316
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: trigger ?? /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", "aria-label": "Actions", children: "\u22EF" }) }),
|
|
1317
|
+
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", sideOffset: 6, className: cn("min-w-[12rem]", className), children: actions.map((action) => /* @__PURE__ */ jsx(
|
|
1318
|
+
DropdownMenuItem,
|
|
1319
|
+
{
|
|
1320
|
+
disabled: action.disabled === true,
|
|
1321
|
+
variant: action.color === "destructive" ? "destructive" : "default",
|
|
1322
|
+
onSelect: () => {
|
|
1323
|
+
if (action.disabled) return;
|
|
1324
|
+
onInvoke(action);
|
|
1325
|
+
},
|
|
1326
|
+
children: action.label
|
|
1327
|
+
},
|
|
1328
|
+
action.name
|
|
1329
|
+
)) })
|
|
1330
|
+
] });
|
|
1331
|
+
}
|
|
1332
|
+
var init_ActionMenu = __esm({
|
|
1333
|
+
"src/action/ActionMenu.tsx"() {
|
|
1334
|
+
init_dropdown_menu();
|
|
1335
|
+
init_cn();
|
|
1336
|
+
init_ActionButton();
|
|
1337
|
+
init_Button();
|
|
1338
|
+
}
|
|
1339
|
+
});
|
|
868
1340
|
function TableCell({ column, value }) {
|
|
869
1341
|
switch (column.type) {
|
|
870
1342
|
case "text":
|
|
@@ -1575,11 +2047,23 @@ function pruneEmptyFilters(values) {
|
|
|
1575
2047
|
}
|
|
1576
2048
|
return out;
|
|
1577
2049
|
}
|
|
2050
|
+
function invokeAction(action, record, formValues) {
|
|
2051
|
+
const recordId = record?.id;
|
|
2052
|
+
const url = action.url ? action.url.replace("{id}", String(recordId ?? "")) : `/arqel-dev/actions/${action.name}`;
|
|
2053
|
+
const method = action.method.toLowerCase();
|
|
2054
|
+
const data = { ...formValues ?? {} };
|
|
2055
|
+
if (recordId !== void 0) data["record_id"] = recordId;
|
|
2056
|
+
router.visit(url, {
|
|
2057
|
+
method,
|
|
2058
|
+
data,
|
|
2059
|
+
preserveScroll: true
|
|
2060
|
+
});
|
|
2061
|
+
}
|
|
1578
2062
|
function buildQuery(params) {
|
|
1579
2063
|
const data = {};
|
|
1580
2064
|
const filters = pruneEmptyFilters(params.filters);
|
|
1581
2065
|
if (Object.keys(filters).length > 0) data["filter"] = filters;
|
|
1582
|
-
if (params.search) data["search"] = params.search;
|
|
2066
|
+
if (params.search !== void 0) data["search"] = params.search;
|
|
1583
2067
|
if (params.sort?.column) {
|
|
1584
2068
|
data["sort"] = params.sort.column;
|
|
1585
2069
|
if (params.sort.direction) data["direction"] = params.sort.direction;
|
|
@@ -1603,6 +2087,8 @@ function ArqelIndexPage() {
|
|
|
1603
2087
|
}, []);
|
|
1604
2088
|
const [filterValues, setFilterValues] = useState(initialFilters);
|
|
1605
2089
|
const [searchValue, setSearchValue] = useState(props.search ?? "");
|
|
2090
|
+
const [perPage, setPerPage] = useState(props.pagination?.perPage);
|
|
2091
|
+
const [selectedIds, setSelectedIds] = useState([]);
|
|
1606
2092
|
const searchDebounceRef = useRef(null);
|
|
1607
2093
|
const visit = (data) => {
|
|
1608
2094
|
const url = typeof window !== "undefined" ? window.location.pathname : page.url.split("?")[0];
|
|
@@ -1621,17 +2107,17 @@ function ArqelIndexPage() {
|
|
|
1621
2107
|
nextFilters[name] = value;
|
|
1622
2108
|
}
|
|
1623
2109
|
setFilterValues(nextFilters);
|
|
1624
|
-
visit(buildQuery({ filters: nextFilters, search: searchValue, sort: currentSort }));
|
|
2110
|
+
visit(buildQuery({ filters: nextFilters, search: searchValue, sort: currentSort, perPage }));
|
|
1625
2111
|
};
|
|
1626
2112
|
const handleClearFilters = () => {
|
|
1627
2113
|
setFilterValues({});
|
|
1628
|
-
visit(buildQuery({ filters: {}, search: searchValue, sort: currentSort }));
|
|
2114
|
+
visit(buildQuery({ filters: {}, search: searchValue, sort: currentSort, perPage }));
|
|
1629
2115
|
};
|
|
1630
2116
|
const handleSearchChange = (value) => {
|
|
1631
2117
|
setSearchValue(value);
|
|
1632
2118
|
if (searchDebounceRef.current) clearTimeout(searchDebounceRef.current);
|
|
1633
2119
|
searchDebounceRef.current = setTimeout(() => {
|
|
1634
|
-
visit(buildQuery({ filters: filterValues, search: value, sort: currentSort }));
|
|
2120
|
+
visit(buildQuery({ filters: filterValues, search: value, sort: currentSort, perPage }));
|
|
1635
2121
|
}, 300);
|
|
1636
2122
|
};
|
|
1637
2123
|
useEffect(
|
|
@@ -1645,7 +2131,8 @@ function ArqelIndexPage() {
|
|
|
1645
2131
|
buildQuery({
|
|
1646
2132
|
filters: filterValues,
|
|
1647
2133
|
search: searchValue,
|
|
1648
|
-
sort: { column, direction }
|
|
2134
|
+
sort: { column, direction },
|
|
2135
|
+
perPage
|
|
1649
2136
|
})
|
|
1650
2137
|
);
|
|
1651
2138
|
};
|
|
@@ -1655,20 +2142,50 @@ function ArqelIndexPage() {
|
|
|
1655
2142
|
filters: filterValues,
|
|
1656
2143
|
search: searchValue,
|
|
1657
2144
|
sort: currentSort,
|
|
1658
|
-
page: pageNum
|
|
2145
|
+
page: pageNum,
|
|
2146
|
+
perPage
|
|
1659
2147
|
})
|
|
1660
2148
|
);
|
|
1661
2149
|
};
|
|
1662
|
-
const handlePerPageChange = (
|
|
2150
|
+
const handlePerPageChange = (newPerPage) => {
|
|
2151
|
+
setPerPage(newPerPage);
|
|
1663
2152
|
visit(
|
|
1664
2153
|
buildQuery({
|
|
1665
2154
|
filters: filterValues,
|
|
1666
2155
|
search: searchValue,
|
|
1667
2156
|
sort: currentSort,
|
|
1668
|
-
perPage
|
|
2157
|
+
perPage: newPerPage
|
|
1669
2158
|
})
|
|
1670
2159
|
);
|
|
1671
2160
|
};
|
|
2161
|
+
const bulkActionsList = props.actions?.bulk ?? [];
|
|
2162
|
+
const bulkActions = bulkActionsList.length > 0 && selectedIds.length > 0 ? /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: bulkActionsList.map((action) => /* @__PURE__ */ jsx(
|
|
2163
|
+
"button",
|
|
2164
|
+
{
|
|
2165
|
+
type: "button",
|
|
2166
|
+
onClick: () => {
|
|
2167
|
+
const url = action.url ?? `/arqel-dev/actions/${action.name}`;
|
|
2168
|
+
const method = action.method.toLowerCase();
|
|
2169
|
+
router.visit(url, {
|
|
2170
|
+
method,
|
|
2171
|
+
data: { record_ids: selectedIds },
|
|
2172
|
+
preserveScroll: true,
|
|
2173
|
+
onSuccess: () => setSelectedIds([])
|
|
2174
|
+
});
|
|
2175
|
+
},
|
|
2176
|
+
className: "inline-flex h-8 items-center gap-1 rounded-sm border border-destructive/40 bg-destructive/10 px-3 text-xs font-medium text-destructive hover:bg-destructive/20",
|
|
2177
|
+
children: action.label
|
|
2178
|
+
},
|
|
2179
|
+
action.name
|
|
2180
|
+
)) }) : void 0;
|
|
2181
|
+
const rowActionsList = props.actions?.row ?? [];
|
|
2182
|
+
const rowActions = rowActionsList.length > 0 ? (record) => /* @__PURE__ */ jsx(
|
|
2183
|
+
ActionMenu,
|
|
2184
|
+
{
|
|
2185
|
+
actions: rowActionsList,
|
|
2186
|
+
onInvoke: (action, formValues) => invokeAction(action, record, formValues)
|
|
2187
|
+
}
|
|
2188
|
+
) : void 0;
|
|
1672
2189
|
return /* @__PURE__ */ jsx(
|
|
1673
2190
|
ResourceIndex,
|
|
1674
2191
|
{
|
|
@@ -1680,12 +2197,17 @@ function ArqelIndexPage() {
|
|
|
1680
2197
|
onSortChange: handleSortChange,
|
|
1681
2198
|
onPageChange: handlePageChange,
|
|
1682
2199
|
onPerPageChange: handlePerPageChange,
|
|
1683
|
-
search: searchValue
|
|
2200
|
+
search: searchValue,
|
|
2201
|
+
selectedIds,
|
|
2202
|
+
onSelectionChange: (ids) => setSelectedIds(ids),
|
|
2203
|
+
...rowActions ? { rowActions } : {},
|
|
2204
|
+
...bulkActions ? { bulkActions } : {}
|
|
1684
2205
|
}
|
|
1685
2206
|
);
|
|
1686
2207
|
}
|
|
1687
2208
|
var init_ArqelIndexPage = __esm({
|
|
1688
2209
|
"src/pages/ArqelIndexPage.tsx"() {
|
|
2210
|
+
init_ActionMenu();
|
|
1689
2211
|
init_ResourceIndex();
|
|
1690
2212
|
}
|
|
1691
2213
|
});
|