dirk-cfx-react 1.1.56 → 1.1.62
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/components/index.cjs +251 -48
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +64 -16
- package/dist/components/index.d.ts +64 -16
- package/dist/components/index.js +252 -50
- package/dist/components/index.js.map +1 -1
- package/dist/hooks/index.cjs +35 -24
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.cts +27 -19
- package/dist/hooks/index.d.ts +27 -19
- package/dist/hooks/index.js +34 -23
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +345 -133
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +287 -76
- package/dist/index.js.map +1 -1
- package/dist/providers/index.cjs.map +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/utils/index.cjs +4 -4
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +4 -4
- package/dist/utils/index.js.map +1 -1
- package/package.json +6 -7
|
@@ -1299,6 +1299,7 @@ var localeStore = zustand.create((set, get) => {
|
|
|
1299
1299
|
var locale = localeStore.getState().locale;
|
|
1300
1300
|
registerInitialFetch("GET_LOCALES", void 0).then((data) => {
|
|
1301
1301
|
localeStore.setState({ locales: data });
|
|
1302
|
+
}).catch(() => {
|
|
1302
1303
|
});
|
|
1303
1304
|
var useItems = zustand.create(() => ({}));
|
|
1304
1305
|
var useItemsList = (excludeItemNames = []) => {
|
|
@@ -1312,6 +1313,7 @@ registerInitialFetch("FETCH_ALL_ITEMS", null, {
|
|
|
1312
1313
|
}).then((fetchedItems) => {
|
|
1313
1314
|
if (!fetchedItems) return;
|
|
1314
1315
|
useItems.setState(fetchedItems);
|
|
1316
|
+
}).catch(() => {
|
|
1315
1317
|
});
|
|
1316
1318
|
|
|
1317
1319
|
// src/utils/inputMapper.ts
|
|
@@ -2548,6 +2550,7 @@ function Modal({
|
|
|
2548
2550
|
children
|
|
2549
2551
|
}) {
|
|
2550
2552
|
const theme = core.useMantineTheme();
|
|
2553
|
+
const pointerDownOnOverlay = react.useRef(false);
|
|
2551
2554
|
return /* @__PURE__ */ jsxRuntime.jsx(core.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2552
2555
|
framerMotion.motion.div,
|
|
2553
2556
|
{
|
|
@@ -2563,7 +2566,14 @@ function Modal({
|
|
|
2563
2566
|
justifyContent: "center",
|
|
2564
2567
|
background: "rgba(0,0,0,0.65)"
|
|
2565
2568
|
},
|
|
2566
|
-
|
|
2569
|
+
onPointerDown: (e) => {
|
|
2570
|
+
pointerDownOnOverlay.current = e.target === e.currentTarget;
|
|
2571
|
+
},
|
|
2572
|
+
onClick: (e) => {
|
|
2573
|
+
if (clickOutside && e.target === e.currentTarget && pointerDownOnOverlay.current) {
|
|
2574
|
+
onClose();
|
|
2575
|
+
}
|
|
2576
|
+
},
|
|
2567
2577
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2568
2578
|
framerMotion.motion.div,
|
|
2569
2579
|
{
|
|
@@ -2571,7 +2581,6 @@ function Modal({
|
|
|
2571
2581
|
animate: { opacity: 1, scale: 1, y: 0 },
|
|
2572
2582
|
exit: { opacity: 0, scale: 0.96, y: 8 },
|
|
2573
2583
|
transition: { duration: 0.18, ease: "easeOut" },
|
|
2574
|
-
onClick: (e) => e.stopPropagation(),
|
|
2575
2584
|
style: {
|
|
2576
2585
|
background: core.alpha(theme.colors.dark[9], 0.98),
|
|
2577
2586
|
border: `0.1vh solid ${theme.colors.dark[7]}`,
|
|
@@ -2668,7 +2677,7 @@ function Modal({
|
|
|
2668
2677
|
children: description
|
|
2669
2678
|
}
|
|
2670
2679
|
) }),
|
|
2671
|
-
children
|
|
2680
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, minHeight: 0, display: "flex", flexDirection: "column" }, children })
|
|
2672
2681
|
]
|
|
2673
2682
|
}
|
|
2674
2683
|
)
|
|
@@ -3291,10 +3300,10 @@ function useFormActions() {
|
|
|
3291
3300
|
}
|
|
3292
3301
|
return store.getState();
|
|
3293
3302
|
}
|
|
3294
|
-
function
|
|
3295
|
-
throw new Error("[dirk-cfx-react]
|
|
3303
|
+
function getScriptConfigInstance() {
|
|
3304
|
+
throw new Error("[dirk-cfx-react] createScriptConfig must be called before using ConfigPanel");
|
|
3296
3305
|
}
|
|
3297
|
-
var
|
|
3306
|
+
var configPanelQueryClient = new reactQuery.QueryClient({
|
|
3298
3307
|
defaultOptions: { queries: { staleTime: 3e4, gcTime: 5 * 6e4 } }
|
|
3299
3308
|
});
|
|
3300
3309
|
function NavItemButton({
|
|
@@ -3338,7 +3347,7 @@ function NavItemButton({
|
|
|
3338
3347
|
}
|
|
3339
3348
|
);
|
|
3340
3349
|
}
|
|
3341
|
-
function
|
|
3350
|
+
function ConfigJsonModal({
|
|
3342
3351
|
onClose,
|
|
3343
3352
|
schema
|
|
3344
3353
|
}) {
|
|
@@ -3375,7 +3384,7 @@ function SettingsJsonModal({
|
|
|
3375
3384
|
setError(e.message);
|
|
3376
3385
|
}
|
|
3377
3386
|
};
|
|
3378
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { title: "
|
|
3387
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { title: "Config JSON", icon: lucideReact.Code2, iconColor: color, onClose, width: "60vh", maxHeight: "80vh", zIndex: 200, children: [
|
|
3379
3388
|
/* @__PURE__ */ jsxRuntime.jsxs(core.Box, { flex: 1, p: "0.8vh", style: { overflowY: "auto" }, children: [
|
|
3380
3389
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3381
3390
|
core.JsonInput,
|
|
@@ -3517,10 +3526,10 @@ function HistoryTableHeader() {
|
|
|
3517
3526
|
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.45)", children: "Version" })
|
|
3518
3527
|
] });
|
|
3519
3528
|
}
|
|
3520
|
-
function
|
|
3529
|
+
function ConfigHistoryModal({
|
|
3521
3530
|
onClose
|
|
3522
3531
|
}) {
|
|
3523
|
-
const { getHistory } =
|
|
3532
|
+
const { getHistory } = getScriptConfigInstance();
|
|
3524
3533
|
const theme = core.useMantineTheme();
|
|
3525
3534
|
const color = theme.colors[theme.primaryColor][5];
|
|
3526
3535
|
const [queryInput, setQueryInput] = react.useState("");
|
|
@@ -3532,7 +3541,7 @@ function SettingsHistoryModal({
|
|
|
3532
3541
|
const [expandedKey, setExpandedKey] = react.useState(null);
|
|
3533
3542
|
const filters = react.useMemo(() => ({ query, path, admin }), [query, path, admin]);
|
|
3534
3543
|
const historyQuery = reactQuery.useInfiniteQuery({
|
|
3535
|
-
queryKey: ["
|
|
3544
|
+
queryKey: ["scriptConfigHistory", filters],
|
|
3536
3545
|
initialPageParam: 0,
|
|
3537
3546
|
queryFn: async ({ pageParam }) => {
|
|
3538
3547
|
const response = await getHistory({
|
|
@@ -3543,7 +3552,7 @@ function SettingsHistoryModal({
|
|
|
3543
3552
|
admin: filters.admin || void 0
|
|
3544
3553
|
});
|
|
3545
3554
|
if (!response?.success || !response.data) {
|
|
3546
|
-
throw new Error(response?._error || "Failed to load
|
|
3555
|
+
throw new Error(response?._error || "Failed to load config history");
|
|
3547
3556
|
}
|
|
3548
3557
|
return response.data;
|
|
3549
3558
|
},
|
|
@@ -3557,7 +3566,7 @@ function SettingsHistoryModal({
|
|
|
3557
3566
|
historyQuery.fetchNextPage();
|
|
3558
3567
|
}
|
|
3559
3568
|
};
|
|
3560
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { title: "
|
|
3569
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { title: "Config History", icon: lucideReact.History, iconColor: color, onClose, width: "88vh", maxHeight: "82vh", zIndex: 260, children: [
|
|
3561
3570
|
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { flex: 1, minHeight: 0 }, children: [
|
|
3562
3571
|
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { gap: "xs", p: "sm", style: { borderBottom: `0.1vh solid ${core.alpha(theme.colors.dark[7], 0.8)}` }, children: [
|
|
3563
3572
|
/* @__PURE__ */ jsxRuntime.jsx(core.TextInput, { leftSection: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { size: "1.4vh" }), placeholder: "Search path/admin/value", value: queryInput, onChange: (e) => setQueryInput(e.currentTarget.value), size: "xs", style: { flex: 1 } }),
|
|
@@ -3606,7 +3615,7 @@ function SettingsHistoryModal({
|
|
|
3606
3615
|
) })
|
|
3607
3616
|
] });
|
|
3608
3617
|
}
|
|
3609
|
-
function
|
|
3618
|
+
function ConfigPanelInner({
|
|
3610
3619
|
navItems,
|
|
3611
3620
|
title,
|
|
3612
3621
|
subtitle,
|
|
@@ -3615,28 +3624,37 @@ function SettingsPanelInner({
|
|
|
3615
3624
|
onClose,
|
|
3616
3625
|
schema,
|
|
3617
3626
|
resetConfirmText,
|
|
3618
|
-
|
|
3627
|
+
defaultConfig,
|
|
3619
3628
|
width,
|
|
3620
3629
|
height
|
|
3621
3630
|
}) {
|
|
3622
|
-
const {
|
|
3631
|
+
const { updateConfig, resetConfig, getHistory } = getScriptConfigInstance();
|
|
3623
3632
|
const form = useForm();
|
|
3624
3633
|
const theme = core.useMantineTheme();
|
|
3625
3634
|
const color = theme.colors[theme.primaryColor][5];
|
|
3626
3635
|
const version = useSettings((s) => s.resourceVersion);
|
|
3627
3636
|
const [activeTab, setActiveTab] = react.useState(navItems[0]?.id ?? "");
|
|
3637
|
+
const firstMountRef = react.useRef(true);
|
|
3628
3638
|
const [jsonOpen, setJsonOpen] = react.useState(false);
|
|
3629
3639
|
const [historyOpen, setHistoryOpen] = react.useState(false);
|
|
3630
3640
|
const [resetOpen, setResetOpen] = react.useState(false);
|
|
3631
|
-
const [
|
|
3641
|
+
const [pendingAction, setPendingAction] = react.useState(null);
|
|
3632
3642
|
const changedCount = form.changedCount ?? 0;
|
|
3633
3643
|
const isDirty = changedCount > 0;
|
|
3644
|
+
const goBack = () => fetchNui("CONFIG_PANEL_BACK");
|
|
3645
|
+
const handleBack = () => {
|
|
3646
|
+
if (isDirty) {
|
|
3647
|
+
setPendingAction("back");
|
|
3648
|
+
return;
|
|
3649
|
+
}
|
|
3650
|
+
goBack();
|
|
3651
|
+
};
|
|
3634
3652
|
react.useEffect(() => {
|
|
3635
3653
|
function handleKeyDown(e) {
|
|
3636
3654
|
if (e.key !== "Escape") return;
|
|
3637
3655
|
if (isDirty) {
|
|
3638
3656
|
e.preventDefault();
|
|
3639
|
-
|
|
3657
|
+
setPendingAction("close");
|
|
3640
3658
|
return;
|
|
3641
3659
|
}
|
|
3642
3660
|
onClose();
|
|
@@ -3645,34 +3663,40 @@ function SettingsPanelInner({
|
|
|
3645
3663
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
3646
3664
|
}, [isDirty, onClose]);
|
|
3647
3665
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3648
|
-
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: jsonOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3649
|
-
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: historyOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3666
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: jsonOpen && /* @__PURE__ */ jsxRuntime.jsx(ConfigJsonModal, { onClose: () => setJsonOpen(false), schema }) }),
|
|
3667
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: historyOpen && /* @__PURE__ */ jsxRuntime.jsx(ConfigHistoryModal, { onClose: () => setHistoryOpen(false) }) }),
|
|
3650
3668
|
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: resetOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3651
3669
|
ConfirmModal,
|
|
3652
3670
|
{
|
|
3653
3671
|
title: "Reset to Defaults",
|
|
3654
|
-
description: "This will permanently reset ALL
|
|
3655
|
-
confirmLabel: "Reset
|
|
3672
|
+
description: "This will permanently reset ALL config back to the defaults. Every value you have configured will be overwritten. This cannot be undone.",
|
|
3673
|
+
confirmLabel: "Reset Config",
|
|
3656
3674
|
confirmText: resetConfirmText,
|
|
3657
|
-
onConfirm: () => {
|
|
3658
|
-
updateSettings(defaultSettings).then(() => form.reinitialize(cloneSettings(defaultSettings)));
|
|
3675
|
+
onConfirm: async () => {
|
|
3659
3676
|
setResetOpen(false);
|
|
3677
|
+
const result = await resetConfig();
|
|
3678
|
+
if (result?.success) {
|
|
3679
|
+
const { store } = getScriptConfigInstance();
|
|
3680
|
+
form.reinitialize(cloneConfig(store.getState()));
|
|
3681
|
+
}
|
|
3660
3682
|
},
|
|
3661
3683
|
onClose: () => setResetOpen(false),
|
|
3662
3684
|
zIndex: 300
|
|
3663
3685
|
}
|
|
3664
3686
|
) }),
|
|
3665
|
-
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children:
|
|
3687
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: pendingAction !== null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3666
3688
|
ConfirmModal,
|
|
3667
3689
|
{
|
|
3668
3690
|
title: "Discard Unsaved Changes?",
|
|
3669
|
-
description: "You have unsaved changes. Closing now will discard them.",
|
|
3670
|
-
confirmLabel: "Close Without Saving",
|
|
3691
|
+
description: pendingAction === "back" ? "You have unsaved changes. Going back now will discard them." : "You have unsaved changes. Closing now will discard them.",
|
|
3692
|
+
confirmLabel: pendingAction === "back" ? "Go Back Without Saving" : "Close Without Saving",
|
|
3671
3693
|
onConfirm: () => {
|
|
3672
|
-
|
|
3673
|
-
|
|
3694
|
+
const action = pendingAction;
|
|
3695
|
+
setPendingAction(null);
|
|
3696
|
+
if (action === "back") goBack();
|
|
3697
|
+
else onClose();
|
|
3674
3698
|
},
|
|
3675
|
-
onClose: () =>
|
|
3699
|
+
onClose: () => setPendingAction(null),
|
|
3676
3700
|
zIndex: 300
|
|
3677
3701
|
}
|
|
3678
3702
|
) }),
|
|
@@ -3699,9 +3723,33 @@ function SettingsPanelInner({
|
|
|
3699
3723
|
exit: { scale: 0.3, opacity: 0, transform: "translate(-50%, -50%)" },
|
|
3700
3724
|
children: [
|
|
3701
3725
|
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { width: "18vh", flexShrink: 0, borderRight: `0.1vh solid ${core.alpha(theme.colors.dark[6], 0.8)}`, background: core.alpha(theme.colors.dark[8], 0.6), overflow: "hidden" }, children: [
|
|
3702
|
-
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "
|
|
3703
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3704
|
-
|
|
3726
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "0.6vh", px: "sm", py: "sm", style: { borderBottom: `0.1vh solid ${core.alpha(theme.colors.dark[6], 0.5)}`, flexShrink: 0 }, children: [
|
|
3727
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3728
|
+
framerMotion.motion.button,
|
|
3729
|
+
{
|
|
3730
|
+
title: "Back to script list",
|
|
3731
|
+
onClick: handleBack,
|
|
3732
|
+
whileHover: { background: core.alpha(color, 0.16), borderColor: core.alpha(color, 0.45) },
|
|
3733
|
+
whileTap: { scale: 0.95 },
|
|
3734
|
+
style: {
|
|
3735
|
+
aspectRatio: "1 / 1",
|
|
3736
|
+
height: "2.4vh",
|
|
3737
|
+
background: core.alpha(color, 0.08),
|
|
3738
|
+
border: `0.1vh solid ${core.alpha(color, 0.3)}`,
|
|
3739
|
+
borderRadius: theme.radius.xs,
|
|
3740
|
+
cursor: "pointer",
|
|
3741
|
+
display: "flex",
|
|
3742
|
+
alignItems: "center",
|
|
3743
|
+
justifyContent: "center",
|
|
3744
|
+
flexShrink: 0
|
|
3745
|
+
},
|
|
3746
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { size: "1.4vh", color })
|
|
3747
|
+
}
|
|
3748
|
+
),
|
|
3749
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { minWidth: 0, lineHeight: 1 }, children: [
|
|
3750
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "lg", ff: "Akrobat Bold", tt: "uppercase", lts: "0.04em", truncate: true, children: title }),
|
|
3751
|
+
subtitle && /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.08em", c: color, truncate: true, children: subtitle })
|
|
3752
|
+
] })
|
|
3705
3753
|
] }),
|
|
3706
3754
|
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { gap: "xxs", px: "xs", py: "xs", style: { borderBottom: `0.1vh solid ${core.alpha(theme.colors.dark[6], 0.4)}`, flexShrink: 0 }, children: [
|
|
3707
3755
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3804,7 +3852,7 @@ function SettingsPanelInner({
|
|
|
3804
3852
|
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3805
3853
|
framerMotion.motion.div,
|
|
3806
3854
|
{
|
|
3807
|
-
initial: { opacity: 0, y: 4 },
|
|
3855
|
+
initial: firstMountRef.current ? (firstMountRef.current = false, false) : { opacity: 0, y: 4 },
|
|
3808
3856
|
animate: { opacity: 1, y: 0 },
|
|
3809
3857
|
exit: { opacity: 0, y: -4 },
|
|
3810
3858
|
transition: { duration: 0.15 },
|
|
@@ -3818,15 +3866,15 @@ function SettingsPanelInner({
|
|
|
3818
3866
|
)
|
|
3819
3867
|
] });
|
|
3820
3868
|
}
|
|
3821
|
-
function
|
|
3869
|
+
function cloneConfig(value) {
|
|
3822
3870
|
return JSON.parse(JSON.stringify(value));
|
|
3823
3871
|
}
|
|
3824
3872
|
function ServerOnlyFetcher() {
|
|
3825
|
-
const {
|
|
3873
|
+
const { fetchConfig } = getScriptConfigInstance();
|
|
3826
3874
|
const { reinitialize } = useFormActions();
|
|
3827
3875
|
react.useEffect(() => {
|
|
3828
3876
|
let cancelled = false;
|
|
3829
|
-
|
|
3877
|
+
fetchConfig().then((full) => {
|
|
3830
3878
|
if (!cancelled && full) reinitialize(full);
|
|
3831
3879
|
}).catch(() => {
|
|
3832
3880
|
});
|
|
@@ -3837,28 +3885,28 @@ function ServerOnlyFetcher() {
|
|
|
3837
3885
|
return null;
|
|
3838
3886
|
}
|
|
3839
3887
|
var defaultOnClose = () => fetchNui("CLOSE_ADMIN_SECTION");
|
|
3840
|
-
function
|
|
3888
|
+
function ConfigPanel(props) {
|
|
3841
3889
|
const { open, onClose = defaultOnClose } = props;
|
|
3842
|
-
const { store,
|
|
3890
|
+
const { store, updateConfig } = getScriptConfigInstance();
|
|
3843
3891
|
const [isSaving, setIsSaving] = react.useState(false);
|
|
3844
3892
|
if (!open) return null;
|
|
3845
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client:
|
|
3893
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: configPanelQueryClient, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3846
3894
|
FormProvider,
|
|
3847
3895
|
{
|
|
3848
|
-
initialValues:
|
|
3896
|
+
initialValues: cloneConfig(store.getState()),
|
|
3849
3897
|
onSubmit: async (form) => {
|
|
3850
3898
|
if (isSaving) return;
|
|
3851
3899
|
setIsSaving(true);
|
|
3852
3900
|
try {
|
|
3853
|
-
const result = await
|
|
3901
|
+
const result = await updateConfig(form.values);
|
|
3854
3902
|
if (result?.success) {
|
|
3855
|
-
form.reinitialize(
|
|
3856
|
-
|
|
3903
|
+
form.reinitialize(cloneConfig(form.values));
|
|
3904
|
+
configPanelQueryClient.invalidateQueries({ queryKey: ["scriptConfigHistory"] });
|
|
3857
3905
|
return;
|
|
3858
3906
|
}
|
|
3859
|
-
form.reinitialize(
|
|
3907
|
+
form.reinitialize(cloneConfig(store.getState()));
|
|
3860
3908
|
if (result?._error) {
|
|
3861
|
-
console.warn(`[
|
|
3909
|
+
console.warn(`[ConfigPanel] config save failed: ${result._error}`);
|
|
3862
3910
|
}
|
|
3863
3911
|
} finally {
|
|
3864
3912
|
setIsSaving(false);
|
|
@@ -3867,7 +3915,7 @@ function SettingsPanel(props) {
|
|
|
3867
3915
|
children: [
|
|
3868
3916
|
/* @__PURE__ */ jsxRuntime.jsx(ServerOnlyFetcher, {}),
|
|
3869
3917
|
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: open && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3870
|
-
|
|
3918
|
+
ConfigPanelInner,
|
|
3871
3919
|
{
|
|
3872
3920
|
...props,
|
|
3873
3921
|
onClose,
|
|
@@ -4075,12 +4123,167 @@ function AdminPageTitle(props) {
|
|
|
4075
4123
|
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", tt: "uppercase", lts: "0.1em", size: "sm", c: "rgba(255,255,255,0.6)", children: locale(props.title) })
|
|
4076
4124
|
] });
|
|
4077
4125
|
}
|
|
4126
|
+
var loadPersistedState = (storageKey) => {
|
|
4127
|
+
try {
|
|
4128
|
+
const raw = localStorage.getItem(storageKey);
|
|
4129
|
+
return raw ? JSON.parse(raw) : {};
|
|
4130
|
+
} catch {
|
|
4131
|
+
return {};
|
|
4132
|
+
}
|
|
4133
|
+
};
|
|
4134
|
+
var savePersistedState = (storageKey, state) => {
|
|
4135
|
+
try {
|
|
4136
|
+
localStorage.setItem(storageKey, JSON.stringify(state));
|
|
4137
|
+
} catch {
|
|
4138
|
+
}
|
|
4139
|
+
};
|
|
4140
|
+
function TestBed({
|
|
4141
|
+
items,
|
|
4142
|
+
storageKey = "testbed:open-state",
|
|
4143
|
+
disablePersistence = false,
|
|
4144
|
+
title = "TestBed"
|
|
4145
|
+
}) {
|
|
4146
|
+
const [open, setOpen] = react.useState(false);
|
|
4147
|
+
const itemsRef = react.useRef(items);
|
|
4148
|
+
itemsRef.current = items;
|
|
4149
|
+
react.useEffect(() => {
|
|
4150
|
+
if (!isEnvBrowser() || disablePersistence) return;
|
|
4151
|
+
const persisted = loadPersistedState(storageKey);
|
|
4152
|
+
itemsRef.current.forEach((item) => {
|
|
4153
|
+
const persistedValue = persisted[item.key];
|
|
4154
|
+
if (typeof persistedValue === "boolean" && persistedValue !== item.active) {
|
|
4155
|
+
item.onToggle(persistedValue);
|
|
4156
|
+
}
|
|
4157
|
+
});
|
|
4158
|
+
}, []);
|
|
4159
|
+
if (!isEnvBrowser()) return null;
|
|
4160
|
+
const toggle = (item) => {
|
|
4161
|
+
const next = !item.active;
|
|
4162
|
+
item.onToggle(next);
|
|
4163
|
+
if (!disablePersistence) {
|
|
4164
|
+
const persisted = loadPersistedState(storageKey);
|
|
4165
|
+
persisted[item.key] = next;
|
|
4166
|
+
savePersistedState(storageKey, persisted);
|
|
4167
|
+
}
|
|
4168
|
+
};
|
|
4169
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4170
|
+
"div",
|
|
4171
|
+
{
|
|
4172
|
+
style: {
|
|
4173
|
+
position: "fixed",
|
|
4174
|
+
top: "1vh",
|
|
4175
|
+
left: "1vh",
|
|
4176
|
+
zIndex: 2147483647,
|
|
4177
|
+
pointerEvents: "auto",
|
|
4178
|
+
fontSize: "1.4vh"
|
|
4179
|
+
},
|
|
4180
|
+
children: [
|
|
4181
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4182
|
+
core.Flex,
|
|
4183
|
+
{
|
|
4184
|
+
align: "center",
|
|
4185
|
+
gap: "xs",
|
|
4186
|
+
px: "sm",
|
|
4187
|
+
py: "xs",
|
|
4188
|
+
onClick: () => setOpen((v) => !v),
|
|
4189
|
+
style: {
|
|
4190
|
+
cursor: "pointer",
|
|
4191
|
+
background: "rgba(0,0,0,0.55)",
|
|
4192
|
+
backdropFilter: "blur(0.6vh)",
|
|
4193
|
+
WebkitBackdropFilter: "blur(0.6vh)",
|
|
4194
|
+
border: "0.1vh solid rgba(255,255,255,0.1)",
|
|
4195
|
+
borderRadius: "var(--mantine-radius-sm)",
|
|
4196
|
+
userSelect: "none",
|
|
4197
|
+
minWidth: "16vh"
|
|
4198
|
+
},
|
|
4199
|
+
children: [
|
|
4200
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.FlaskConical, { size: 14, color: "rgba(255,255,255,0.7)" }),
|
|
4201
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4202
|
+
core.Text,
|
|
4203
|
+
{
|
|
4204
|
+
size: "xs",
|
|
4205
|
+
ff: "Akrobat Bold",
|
|
4206
|
+
tt: "uppercase",
|
|
4207
|
+
lts: "0.08em",
|
|
4208
|
+
c: "rgba(255,255,255,0.85)",
|
|
4209
|
+
style: { flex: 1 },
|
|
4210
|
+
children: title
|
|
4211
|
+
}
|
|
4212
|
+
),
|
|
4213
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.ActionIcon, { size: "xs", variant: "transparent", c: "rgba(255,255,255,0.6)", children: open ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { size: 14 }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: 14 }) })
|
|
4214
|
+
]
|
|
4215
|
+
}
|
|
4216
|
+
),
|
|
4217
|
+
open && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4218
|
+
core.Stack,
|
|
4219
|
+
{
|
|
4220
|
+
gap: 4,
|
|
4221
|
+
mt: "xxs",
|
|
4222
|
+
p: "xs",
|
|
4223
|
+
style: {
|
|
4224
|
+
background: "rgba(0,0,0,0.55)",
|
|
4225
|
+
backdropFilter: "blur(0.6vh)",
|
|
4226
|
+
WebkitBackdropFilter: "blur(0.6vh)",
|
|
4227
|
+
border: "0.1vh solid rgba(255,255,255,0.1)",
|
|
4228
|
+
borderRadius: "var(--mantine-radius-sm)",
|
|
4229
|
+
minWidth: "16vh",
|
|
4230
|
+
maxHeight: "80vh",
|
|
4231
|
+
overflowY: "auto"
|
|
4232
|
+
},
|
|
4233
|
+
children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4234
|
+
core.Flex,
|
|
4235
|
+
{
|
|
4236
|
+
align: "center",
|
|
4237
|
+
justify: "space-between",
|
|
4238
|
+
gap: "xs",
|
|
4239
|
+
px: "xs",
|
|
4240
|
+
py: "xxs",
|
|
4241
|
+
onClick: () => toggle(item),
|
|
4242
|
+
style: {
|
|
4243
|
+
cursor: "pointer",
|
|
4244
|
+
borderRadius: "var(--mantine-radius-xs)",
|
|
4245
|
+
background: item.active ? "rgba(245,158,11,0.15)" : "rgba(255,255,255,0.03)",
|
|
4246
|
+
border: `0.1vh solid ${item.active ? "rgba(245,158,11,0.35)" : "rgba(255,255,255,0.05)"}`,
|
|
4247
|
+
userSelect: "none"
|
|
4248
|
+
},
|
|
4249
|
+
children: [
|
|
4250
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4251
|
+
core.Text,
|
|
4252
|
+
{
|
|
4253
|
+
size: "xs",
|
|
4254
|
+
ff: "Akrobat Bold",
|
|
4255
|
+
c: item.active ? "#f59e0b" : "rgba(255,255,255,0.75)",
|
|
4256
|
+
children: item.label
|
|
4257
|
+
}
|
|
4258
|
+
),
|
|
4259
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4260
|
+
core.Text,
|
|
4261
|
+
{
|
|
4262
|
+
size: "xxs",
|
|
4263
|
+
ff: "Akrobat Bold",
|
|
4264
|
+
tt: "uppercase",
|
|
4265
|
+
lts: "0.06em",
|
|
4266
|
+
c: item.active ? "#f59e0b" : "rgba(255,255,255,0.35)",
|
|
4267
|
+
children: item.active ? "On" : "Off"
|
|
4268
|
+
}
|
|
4269
|
+
)
|
|
4270
|
+
]
|
|
4271
|
+
},
|
|
4272
|
+
item.key
|
|
4273
|
+
))
|
|
4274
|
+
}
|
|
4275
|
+
)
|
|
4276
|
+
]
|
|
4277
|
+
}
|
|
4278
|
+
);
|
|
4279
|
+
}
|
|
4078
4280
|
|
|
4079
4281
|
exports.AdminPageTitle = AdminPageTitle;
|
|
4080
4282
|
exports.AsyncSaveButton = AsyncSaveButton;
|
|
4081
4283
|
exports.BlipColorSelect = BlipColorSelect;
|
|
4082
4284
|
exports.BlipIconSelect = BlipIconSelect;
|
|
4083
4285
|
exports.BorderedIcon = BorderedIcon;
|
|
4286
|
+
exports.ConfigPanel = ConfigPanel;
|
|
4084
4287
|
exports.ConfirmModal = ConfirmModal;
|
|
4085
4288
|
exports.Counter = Counter;
|
|
4086
4289
|
exports.FiveMKeyBindInput = FiveMKeyBindInput;
|
|
@@ -4103,7 +4306,7 @@ exports.PromptModal = PromptModal;
|
|
|
4103
4306
|
exports.SegmentedControl = SegmentedControl;
|
|
4104
4307
|
exports.SegmentedProgress = SegmentedProgress;
|
|
4105
4308
|
exports.SelectItem = SelectItem;
|
|
4106
|
-
exports.
|
|
4309
|
+
exports.TestBed = TestBed;
|
|
4107
4310
|
exports.Title = Title;
|
|
4108
4311
|
exports.useModal = useModal;
|
|
4109
4312
|
exports.useModalActions = useModalActions;
|