dirk-cfx-react 1.1.70 → 1.1.72
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 +468 -36
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +49 -1
- package/dist/components/index.d.ts +49 -1
- package/dist/components/index.js +465 -39
- package/dist/components/index.js.map +1 -1
- package/dist/index.cjs +468 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +465 -39
- package/dist/index.js.map +1 -1
- package/package.json +113 -113
package/dist/index.cjs
CHANGED
|
@@ -10,6 +10,7 @@ var framerMotion = require('framer-motion');
|
|
|
10
10
|
var lucideReact = require('lucide-react');
|
|
11
11
|
var clickSoundUrl = require('./click_sound-PNCRRTM4.mp3');
|
|
12
12
|
var hoverSoundUrl = require('./hover_sound-NBUA222C.mp3');
|
|
13
|
+
var notifications = require('@mantine/notifications');
|
|
13
14
|
var reactQuery = require('@tanstack/react-query');
|
|
14
15
|
require('@mantine/core/styles.css');
|
|
15
16
|
require('@mantine/notifications/styles.css');
|
|
@@ -1250,11 +1251,11 @@ var colorNames = {
|
|
|
1250
1251
|
Yellow: { r: 255, g: 255, b: 0 },
|
|
1251
1252
|
YellowGreen: { r: 154, g: 205, b: 50 }
|
|
1252
1253
|
};
|
|
1253
|
-
function colorWithAlpha(color,
|
|
1254
|
+
function colorWithAlpha(color, alpha10) {
|
|
1254
1255
|
const lowerCasedColor = color.toLowerCase();
|
|
1255
1256
|
if (colorNames[lowerCasedColor]) {
|
|
1256
1257
|
const rgb = colorNames[lowerCasedColor];
|
|
1257
|
-
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${
|
|
1258
|
+
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha10})`;
|
|
1258
1259
|
}
|
|
1259
1260
|
if (/^#([A-Fa-f0-9]{6})$/.test(color)) {
|
|
1260
1261
|
const hex = color.slice(1);
|
|
@@ -1262,12 +1263,12 @@ function colorWithAlpha(color, alpha9) {
|
|
|
1262
1263
|
const r = bigint >> 16 & 255;
|
|
1263
1264
|
const g = bigint >> 8 & 255;
|
|
1264
1265
|
const b = bigint & 255;
|
|
1265
|
-
return `rgba(${r}, ${g}, ${b}, ${
|
|
1266
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha10})`;
|
|
1266
1267
|
}
|
|
1267
1268
|
if (/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/.test(color)) {
|
|
1268
1269
|
const result = color.match(/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/);
|
|
1269
1270
|
if (result) {
|
|
1270
|
-
return `rgba(${result[1]}, ${result[2]}, ${result[3]}, ${
|
|
1271
|
+
return `rgba(${result[1]}, ${result[2]}, ${result[3]}, ${alpha10})`;
|
|
1271
1272
|
}
|
|
1272
1273
|
}
|
|
1273
1274
|
return color;
|
|
@@ -3815,6 +3816,246 @@ function ConfirmModal({
|
|
|
3815
3816
|
}
|
|
3816
3817
|
) });
|
|
3817
3818
|
}
|
|
3819
|
+
var TABS = [
|
|
3820
|
+
{ id: "ox", label: "ox_inventory" },
|
|
3821
|
+
{ id: "qb", label: "qb-inventory" },
|
|
3822
|
+
{ id: "esx", label: "ESX legacy SQL" }
|
|
3823
|
+
];
|
|
3824
|
+
var useMissingItemsAudit = zustand.create((set, get) => ({
|
|
3825
|
+
data: null,
|
|
3826
|
+
loaded: false,
|
|
3827
|
+
inFlight: false,
|
|
3828
|
+
refresh: async () => {
|
|
3829
|
+
if (get().inFlight) return;
|
|
3830
|
+
set({ inFlight: true });
|
|
3831
|
+
try {
|
|
3832
|
+
const res = await fetchNui("GET_MISSING_ITEMS", void 0, {
|
|
3833
|
+
success: true,
|
|
3834
|
+
data: { missing: [], snippets: { ox: "", qb: "", esx: "" } }
|
|
3835
|
+
});
|
|
3836
|
+
if (res?.success && res.data) {
|
|
3837
|
+
set({ data: res.data, loaded: true });
|
|
3838
|
+
} else {
|
|
3839
|
+
set({ loaded: true });
|
|
3840
|
+
}
|
|
3841
|
+
} catch {
|
|
3842
|
+
set({ loaded: true });
|
|
3843
|
+
} finally {
|
|
3844
|
+
set({ inFlight: false });
|
|
3845
|
+
}
|
|
3846
|
+
}
|
|
3847
|
+
}));
|
|
3848
|
+
function MissingItemsBanner() {
|
|
3849
|
+
const theme2 = core.useMantineTheme();
|
|
3850
|
+
const audit = useMissingItemsAudit((s) => s.data);
|
|
3851
|
+
const loaded = useMissingItemsAudit((s) => s.loaded);
|
|
3852
|
+
const inFlight = useMissingItemsAudit((s) => s.inFlight);
|
|
3853
|
+
const refresh = useMissingItemsAudit((s) => s.refresh);
|
|
3854
|
+
const [expanded, setExpanded] = React6.useState(false);
|
|
3855
|
+
const [activeTab, setActiveTab] = React6.useState("ox");
|
|
3856
|
+
const [hoveredTab, setHoveredTab] = React6.useState(null);
|
|
3857
|
+
const [copied, setCopied] = React6.useState(null);
|
|
3858
|
+
React6.useEffect(() => {
|
|
3859
|
+
if (!loaded) refresh();
|
|
3860
|
+
}, [loaded, refresh]);
|
|
3861
|
+
const handleCopy = React6.useCallback((tab) => {
|
|
3862
|
+
if (!audit) return;
|
|
3863
|
+
const text = audit.snippets[tab] ?? "";
|
|
3864
|
+
navigator.clipboard.writeText(text).then(() => {
|
|
3865
|
+
setCopied(tab);
|
|
3866
|
+
setTimeout(() => setCopied((c) => c === tab ? null : c), 1500);
|
|
3867
|
+
}).catch(() => {
|
|
3868
|
+
});
|
|
3869
|
+
}, [audit]);
|
|
3870
|
+
const handleRefresh = React6.useCallback((e) => {
|
|
3871
|
+
e.stopPropagation();
|
|
3872
|
+
refresh();
|
|
3873
|
+
}, [refresh]);
|
|
3874
|
+
if (!audit || audit.missing.length === 0) return null;
|
|
3875
|
+
const warnColor = "#f59e0b";
|
|
3876
|
+
const names = audit.missing.map((m) => m.name);
|
|
3877
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3878
|
+
"div",
|
|
3879
|
+
{
|
|
3880
|
+
style: {
|
|
3881
|
+
background: core.alpha(warnColor, 0.06),
|
|
3882
|
+
border: `0.1vh solid ${core.alpha(warnColor, 0.35)}`,
|
|
3883
|
+
borderLeft: `0.3vh solid ${warnColor}`,
|
|
3884
|
+
borderRadius: theme2.radius.xs,
|
|
3885
|
+
margin: "0.6vh 1vh",
|
|
3886
|
+
overflow: "hidden"
|
|
3887
|
+
},
|
|
3888
|
+
children: [
|
|
3889
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "0.8vh", p: "0.8vh 1vh", style: { cursor: "pointer" }, onClick: () => setExpanded((e) => !e), children: [
|
|
3890
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { size: "1.8vh", color: warnColor, strokeWidth: 2.5 }),
|
|
3891
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { flex: 1, minWidth: 0 }, children: [
|
|
3892
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xs", tt: "uppercase", lts: "0.07em", c: warnColor, children: audit.missing.length === 1 ? "1 item missing from your inventory" : `${audit.missing.length} items missing from your inventory` }),
|
|
3893
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.5)", lineClamp: 1, style: { fontFamily: "monospace" }, children: names.join(", ") })
|
|
3894
|
+
] }),
|
|
3895
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3896
|
+
"button",
|
|
3897
|
+
{
|
|
3898
|
+
onClick: handleRefresh,
|
|
3899
|
+
disabled: inFlight,
|
|
3900
|
+
style: {
|
|
3901
|
+
background: "transparent",
|
|
3902
|
+
border: "none",
|
|
3903
|
+
padding: "0.3vh",
|
|
3904
|
+
cursor: inFlight ? "wait" : "pointer",
|
|
3905
|
+
display: "flex",
|
|
3906
|
+
alignItems: "center",
|
|
3907
|
+
justifyContent: "center",
|
|
3908
|
+
opacity: inFlight ? 0.4 : 0.7
|
|
3909
|
+
},
|
|
3910
|
+
title: "Re-check",
|
|
3911
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3912
|
+
framerMotion.motion.span,
|
|
3913
|
+
{
|
|
3914
|
+
animate: { rotate: inFlight ? 360 : 0 },
|
|
3915
|
+
transition: inFlight ? { duration: 1, repeat: Infinity, ease: "linear" } : { duration: 0 },
|
|
3916
|
+
style: { display: "flex", alignItems: "center", justifyContent: "center" },
|
|
3917
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { size: "1.5vh", color: core.alpha(warnColor, 0.7) })
|
|
3918
|
+
}
|
|
3919
|
+
)
|
|
3920
|
+
}
|
|
3921
|
+
),
|
|
3922
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3923
|
+
framerMotion.motion.div,
|
|
3924
|
+
{
|
|
3925
|
+
animate: { rotate: expanded ? 180 : 0 },
|
|
3926
|
+
transition: { duration: 0.18 },
|
|
3927
|
+
style: { display: "flex", alignItems: "center", justifyContent: "center" },
|
|
3928
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: "1.8vh", color: core.alpha(warnColor, 0.7) })
|
|
3929
|
+
}
|
|
3930
|
+
)
|
|
3931
|
+
] }),
|
|
3932
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, children: expanded && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3933
|
+
framerMotion.motion.div,
|
|
3934
|
+
{
|
|
3935
|
+
initial: { height: 0, opacity: 0 },
|
|
3936
|
+
animate: { height: "auto", opacity: 1 },
|
|
3937
|
+
exit: { height: 0, opacity: 0 },
|
|
3938
|
+
transition: { duration: 0.18, ease: "easeOut" },
|
|
3939
|
+
style: { overflow: "hidden", borderTop: `0.1vh solid ${core.alpha(warnColor, 0.18)}` },
|
|
3940
|
+
children: [
|
|
3941
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Flex, { gap: "0", style: { borderBottom: `0.1vh solid ${core.alpha(warnColor, 0.18)}` }, children: TABS.map((tab) => {
|
|
3942
|
+
const active = tab.id === activeTab;
|
|
3943
|
+
const hovered = hoveredTab === tab.id;
|
|
3944
|
+
let bg = "transparent";
|
|
3945
|
+
if (active) bg = core.alpha(warnColor, 0.12);
|
|
3946
|
+
else if (hovered) bg = core.alpha(warnColor, 0.08);
|
|
3947
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3948
|
+
"button",
|
|
3949
|
+
{
|
|
3950
|
+
onClick: (e) => {
|
|
3951
|
+
e.stopPropagation();
|
|
3952
|
+
setActiveTab(tab.id);
|
|
3953
|
+
},
|
|
3954
|
+
onMouseEnter: () => setHoveredTab(tab.id),
|
|
3955
|
+
onMouseLeave: () => setHoveredTab((h) => h === tab.id ? null : h),
|
|
3956
|
+
style: {
|
|
3957
|
+
flex: 1,
|
|
3958
|
+
background: bg,
|
|
3959
|
+
border: "none",
|
|
3960
|
+
borderBottom: active ? `0.2vh solid ${warnColor}` : "0.2vh solid transparent",
|
|
3961
|
+
padding: "0.3vh 1vh",
|
|
3962
|
+
cursor: active ? "default" : "pointer",
|
|
3963
|
+
color: active ? warnColor : "rgba(255,255,255,0.5)",
|
|
3964
|
+
fontFamily: "Akrobat Bold",
|
|
3965
|
+
fontSize: "var(--mantine-font-size-xxs)",
|
|
3966
|
+
letterSpacing: "0.07em",
|
|
3967
|
+
textTransform: "uppercase",
|
|
3968
|
+
transition: "background 0.12s"
|
|
3969
|
+
},
|
|
3970
|
+
children: tab.label
|
|
3971
|
+
},
|
|
3972
|
+
tab.id
|
|
3973
|
+
);
|
|
3974
|
+
}) }),
|
|
3975
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3976
|
+
CodeView,
|
|
3977
|
+
{
|
|
3978
|
+
code: audit.snippets[activeTab] ?? "",
|
|
3979
|
+
copied: copied === activeTab,
|
|
3980
|
+
onCopy: (e) => {
|
|
3981
|
+
e.stopPropagation();
|
|
3982
|
+
handleCopy(activeTab);
|
|
3983
|
+
},
|
|
3984
|
+
warnColor
|
|
3985
|
+
}
|
|
3986
|
+
)
|
|
3987
|
+
]
|
|
3988
|
+
},
|
|
3989
|
+
"expanded"
|
|
3990
|
+
) })
|
|
3991
|
+
]
|
|
3992
|
+
}
|
|
3993
|
+
);
|
|
3994
|
+
}
|
|
3995
|
+
function CodeView({
|
|
3996
|
+
code,
|
|
3997
|
+
copied,
|
|
3998
|
+
onCopy,
|
|
3999
|
+
warnColor
|
|
4000
|
+
}) {
|
|
4001
|
+
const theme2 = core.useMantineTheme();
|
|
4002
|
+
const [hovered, setHovered] = React6.useState(false);
|
|
4003
|
+
const lines = code === "" ? [""] : code.split("\n");
|
|
4004
|
+
const lineNumWidth = String(lines.length).length;
|
|
4005
|
+
const copyBg = copied ? core.alpha("#22c55e", 0.15) : hovered ? core.alpha(warnColor, 0.18) : core.alpha(warnColor, 0.1);
|
|
4006
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
|
|
4007
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4008
|
+
"button",
|
|
4009
|
+
{
|
|
4010
|
+
onClick: onCopy,
|
|
4011
|
+
onMouseEnter: () => setHovered(true),
|
|
4012
|
+
onMouseLeave: () => setHovered(false),
|
|
4013
|
+
style: {
|
|
4014
|
+
position: "absolute",
|
|
4015
|
+
top: "0.6vh",
|
|
4016
|
+
right: "0.8vh",
|
|
4017
|
+
zIndex: 2,
|
|
4018
|
+
background: copyBg,
|
|
4019
|
+
border: `0.1vh solid ${core.alpha(copied ? "#22c55e" : warnColor, 0.35)}`,
|
|
4020
|
+
borderRadius: theme2.radius.xs,
|
|
4021
|
+
padding: "0.4vh 0.7vh",
|
|
4022
|
+
cursor: "pointer",
|
|
4023
|
+
display: "flex",
|
|
4024
|
+
alignItems: "center",
|
|
4025
|
+
gap: "0.4vh",
|
|
4026
|
+
transition: "background 0.12s"
|
|
4027
|
+
},
|
|
4028
|
+
children: [
|
|
4029
|
+
copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { size: "1.4vh", color: "#22c55e" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { size: "1.4vh", color: warnColor }),
|
|
4030
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: copied ? "#22c55e" : warnColor, children: copied ? "Copied" : "Copy" })
|
|
4031
|
+
]
|
|
4032
|
+
}
|
|
4033
|
+
),
|
|
4034
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
4035
|
+
background: core.alpha(theme2.colors.dark[9], 0.6),
|
|
4036
|
+
maxHeight: "40vh",
|
|
4037
|
+
overflowY: "auto",
|
|
4038
|
+
overflowX: "auto",
|
|
4039
|
+
padding: "0.6vh 0"
|
|
4040
|
+
}, children: /* @__PURE__ */ jsxRuntime.jsx("table", { style: { borderCollapse: "collapse", width: "100%", fontFamily: "monospace", fontSize: "1.2vh", lineHeight: 1.5 }, children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: lines.map((line, i) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
4041
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { style: {
|
|
4042
|
+
width: `${lineNumWidth + 2}ch`,
|
|
4043
|
+
textAlign: "right",
|
|
4044
|
+
padding: "0 0.8vh 0 1vh",
|
|
4045
|
+
color: "rgba(255,255,255,0.25)",
|
|
4046
|
+
userSelect: "none",
|
|
4047
|
+
whiteSpace: "nowrap",
|
|
4048
|
+
verticalAlign: "top"
|
|
4049
|
+
}, children: i + 1 }),
|
|
4050
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { style: {
|
|
4051
|
+
padding: "0 1vh",
|
|
4052
|
+
color: "rgba(255,255,255,0.85)",
|
|
4053
|
+
whiteSpace: "pre",
|
|
4054
|
+
verticalAlign: "top"
|
|
4055
|
+
}, children: line || "\u200B" })
|
|
4056
|
+
] }, i)) }) }) })
|
|
4057
|
+
] });
|
|
4058
|
+
}
|
|
3818
4059
|
function getNested(obj, path) {
|
|
3819
4060
|
return path.split(".").reduce((acc, key) => acc ? acc[key] : void 0, obj);
|
|
3820
4061
|
}
|
|
@@ -4541,7 +4782,8 @@ function ConfigPanelInner({
|
|
|
4541
4782
|
resetConfirmText,
|
|
4542
4783
|
defaultConfig,
|
|
4543
4784
|
width,
|
|
4544
|
-
height
|
|
4785
|
+
height,
|
|
4786
|
+
suppressMissingItemsBanner
|
|
4545
4787
|
}) {
|
|
4546
4788
|
const { updateConfig, resetConfig, getHistory } = getScriptConfigInstance();
|
|
4547
4789
|
const form = useForm();
|
|
@@ -4764,18 +5006,21 @@ function ConfigPanelInner({
|
|
|
4764
5006
|
] })
|
|
4765
5007
|
] })
|
|
4766
5008
|
] }),
|
|
4767
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4768
|
-
|
|
4769
|
-
{
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
5009
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { flex: 1, minWidth: 0, overflow: "hidden" }, children: [
|
|
5010
|
+
!suppressMissingItemsBanner && /* @__PURE__ */ jsxRuntime.jsx(MissingItemsBanner, {}),
|
|
5011
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5012
|
+
framerMotion.motion.div,
|
|
5013
|
+
{
|
|
5014
|
+
initial: firstMountRef.current ? (firstMountRef.current = false, false) : { opacity: 0, y: 4 },
|
|
5015
|
+
animate: { opacity: 1, y: 0 },
|
|
5016
|
+
exit: { opacity: 0, y: -4 },
|
|
5017
|
+
transition: { duration: 0.15 },
|
|
5018
|
+
style: { flex: 1, display: "flex", flexDirection: "column", overflowY: "auto" },
|
|
5019
|
+
children: children(activeTab)
|
|
5020
|
+
},
|
|
5021
|
+
activeTab
|
|
5022
|
+
) })
|
|
5023
|
+
] })
|
|
4779
5024
|
]
|
|
4780
5025
|
}
|
|
4781
5026
|
)
|
|
@@ -4817,12 +5062,26 @@ function ConfigPanel(props) {
|
|
|
4817
5062
|
if (result?.success) {
|
|
4818
5063
|
form.reinitialize(cloneConfig(form.values));
|
|
4819
5064
|
configPanelQueryClient.invalidateQueries({ queryKey: ["scriptConfigHistory"] });
|
|
5065
|
+
useMissingItemsAudit.getState().refresh();
|
|
5066
|
+
notifications.notifications.show({
|
|
5067
|
+
color: "green",
|
|
5068
|
+
title: locale("ConfigSaveSuccessTitle"),
|
|
5069
|
+
message: locale("ConfigSaveSuccessBody"),
|
|
5070
|
+
autoClose: 3e3
|
|
5071
|
+
});
|
|
4820
5072
|
return;
|
|
4821
5073
|
}
|
|
4822
5074
|
form.reinitialize(cloneConfig(store.getState()));
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
5075
|
+
const err = result?._error || "Unknown";
|
|
5076
|
+
console.warn(`[ConfigPanel] config save failed: ${err}`);
|
|
5077
|
+
const titleKey = err === "NoPermission" ? "ConfigSaveNoPermissionTitle" : err === "VersionConflict" ? "ConfigSaveVersionConflictTitle" : err === "NotReady" ? "ConfigSaveNotReadyTitle" : "ConfigSaveFailedTitle";
|
|
5078
|
+
const bodyKey = err === "NoPermission" ? "ConfigSaveNoPermissionBody" : err === "VersionConflict" ? "ConfigSaveVersionConflictBody" : err === "NotReady" ? "ConfigSaveNotReadyBody" : "ConfigSaveFailedBody";
|
|
5079
|
+
notifications.notifications.show({
|
|
5080
|
+
color: "red",
|
|
5081
|
+
title: locale(titleKey),
|
|
5082
|
+
message: locale(bodyKey, err),
|
|
5083
|
+
autoClose: 6e3
|
|
5084
|
+
});
|
|
4826
5085
|
} finally {
|
|
4827
5086
|
setIsSaving(false);
|
|
4828
5087
|
}
|
|
@@ -4841,6 +5100,7 @@ function ConfigPanel(props) {
|
|
|
4841
5100
|
}
|
|
4842
5101
|
) });
|
|
4843
5102
|
}
|
|
5103
|
+
var MISSING_COLOR = "#f59e0b";
|
|
4844
5104
|
function LazyImage({ src, style }) {
|
|
4845
5105
|
const [visible, setVisible] = React6.useState(false);
|
|
4846
5106
|
const ref = React6.useRef(null);
|
|
@@ -4858,14 +5118,19 @@ function LazyImage({ src, style }) {
|
|
|
4858
5118
|
}
|
|
4859
5119
|
function SelectItem(props) {
|
|
4860
5120
|
const invItems = useItems();
|
|
5121
|
+
const isMissing = !!props.value && !invItems[props.value];
|
|
4861
5122
|
const formattedItems = React6.useMemo(() => {
|
|
4862
5123
|
const seen = /* @__PURE__ */ new Set();
|
|
4863
|
-
|
|
5124
|
+
const list = useItemsList(props.excludeItemNames ?? []).filter((item) => {
|
|
4864
5125
|
if (seen.has(item.name)) return false;
|
|
4865
5126
|
seen.add(item.name);
|
|
4866
5127
|
return true;
|
|
4867
5128
|
}).map((item) => ({ value: item.name, label: item.label, image: item.image }));
|
|
4868
|
-
|
|
5129
|
+
if (isMissing) {
|
|
5130
|
+
list.unshift({ value: props.value, label: props.value, image: "" });
|
|
5131
|
+
}
|
|
5132
|
+
return list;
|
|
5133
|
+
}, [invItems, props.excludeItemNames, props.value, isMissing]);
|
|
4869
5134
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4870
5135
|
core.Select,
|
|
4871
5136
|
{
|
|
@@ -4880,10 +5145,11 @@ function SelectItem(props) {
|
|
|
4880
5145
|
data: formattedItems,
|
|
4881
5146
|
allowDeselect: false,
|
|
4882
5147
|
searchable: true,
|
|
5148
|
+
styles: isMissing ? { input: { color: MISSING_COLOR } } : void 0,
|
|
4883
5149
|
comboboxProps: { withinPortal: true, zIndex: 2e3 },
|
|
4884
5150
|
leftSectionWidth: "4vh",
|
|
4885
5151
|
leftSectionPointerEvents: "none",
|
|
4886
|
-
leftSection: props.value ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5152
|
+
leftSection: isMissing ? /* @__PURE__ */ jsxRuntime.jsx(core.Flex, { align: "center", justify: "center", w: "4vh", h: "4vh", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { size: "2vh", color: MISSING_COLOR, strokeWidth: 2.5 }) }) : props.value ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4887
5153
|
core.Image,
|
|
4888
5154
|
{
|
|
4889
5155
|
fallbackSrc: "/placeholder.png",
|
|
@@ -4894,19 +5160,37 @@ function SelectItem(props) {
|
|
|
4894
5160
|
}
|
|
4895
5161
|
) : null,
|
|
4896
5162
|
nothingFoundMessage: locale("NoItemsFound"),
|
|
4897
|
-
renderOption: (item) =>
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
{
|
|
4901
|
-
|
|
4902
|
-
style: {
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
5163
|
+
renderOption: (item) => {
|
|
5164
|
+
const optionMissing = !invItems[item.option.value] && item.option.value === props.value;
|
|
5165
|
+
if (optionMissing) {
|
|
5166
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "xs", w: "100%", children: [
|
|
5167
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Flex, { align: "center", justify: "center", w: "4vh", h: "4vh", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { size: "2vh", color: MISSING_COLOR, strokeWidth: 2.5 }) }),
|
|
5168
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { flex: 1, minWidth: 0 }, children: [
|
|
5169
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "sm", c: MISSING_COLOR, style: { fontFamily: "monospace" }, children: item.option.value }),
|
|
5170
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "xxs", c: "dimmed", children: locale("ItemNotInInventory") })
|
|
5171
|
+
] }),
|
|
5172
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
5173
|
+
background: "rgba(245,158,11,0.12)",
|
|
5174
|
+
border: `0.1vh solid ${MISSING_COLOR}59`,
|
|
5175
|
+
borderRadius: "0.3vh",
|
|
5176
|
+
padding: "0.1vh 0.6vh"
|
|
5177
|
+
}, children: /* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "xxs", c: MISSING_COLOR, ff: "Akrobat Bold", tt: "uppercase", lts: "0.06em", children: locale("Missing") }) })
|
|
5178
|
+
] });
|
|
5179
|
+
}
|
|
5180
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "xs", w: "100%", children: [
|
|
5181
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5182
|
+
LazyImage,
|
|
5183
|
+
{
|
|
5184
|
+
src: invItems[item.option.value]?.image || "",
|
|
5185
|
+
style: { aspectRatio: "1 / 1" }
|
|
5186
|
+
}
|
|
5187
|
+
),
|
|
5188
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", children: [
|
|
5189
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "sm", children: item.option.label }),
|
|
5190
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "xxs", c: "dimmed", children: item.option.value })
|
|
5191
|
+
] })
|
|
5192
|
+
] });
|
|
5193
|
+
}
|
|
4910
5194
|
}
|
|
4911
5195
|
);
|
|
4912
5196
|
}
|
|
@@ -5123,6 +5407,148 @@ function PickerButton({
|
|
|
5123
5407
|
}
|
|
5124
5408
|
) });
|
|
5125
5409
|
}
|
|
5410
|
+
function fmtV4(n) {
|
|
5411
|
+
return Number.isFinite(n) ? n.toFixed(2) : "0.00";
|
|
5412
|
+
}
|
|
5413
|
+
function Vector4Display({ value }) {
|
|
5414
|
+
const theme2 = core.useMantineTheme();
|
|
5415
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5416
|
+
core.Flex,
|
|
5417
|
+
{
|
|
5418
|
+
align: "center",
|
|
5419
|
+
gap: "xs",
|
|
5420
|
+
p: "xs",
|
|
5421
|
+
style: {
|
|
5422
|
+
background: core.alpha(theme2.colors.dark[5], 0.35),
|
|
5423
|
+
border: "0.1vh solid rgba(255,255,255,0.05)",
|
|
5424
|
+
borderRadius: theme2.radius.xs
|
|
5425
|
+
},
|
|
5426
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5427
|
+
core.Text,
|
|
5428
|
+
{
|
|
5429
|
+
ff: "monospace",
|
|
5430
|
+
size: "xxs",
|
|
5431
|
+
c: "rgba(255,255,255,0.85)",
|
|
5432
|
+
style: { flex: 1, letterSpacing: "0.02em", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" },
|
|
5433
|
+
children: [
|
|
5434
|
+
"vector4(",
|
|
5435
|
+
fmtV4(value.x),
|
|
5436
|
+
", ",
|
|
5437
|
+
fmtV4(value.y),
|
|
5438
|
+
", ",
|
|
5439
|
+
fmtV4(value.z),
|
|
5440
|
+
", ",
|
|
5441
|
+
fmtV4(value.w),
|
|
5442
|
+
")"
|
|
5443
|
+
]
|
|
5444
|
+
}
|
|
5445
|
+
)
|
|
5446
|
+
}
|
|
5447
|
+
);
|
|
5448
|
+
}
|
|
5449
|
+
function Vector4ActionButton({
|
|
5450
|
+
icon,
|
|
5451
|
+
label: label2,
|
|
5452
|
+
tooltip,
|
|
5453
|
+
onClick,
|
|
5454
|
+
color,
|
|
5455
|
+
compact
|
|
5456
|
+
}) {
|
|
5457
|
+
const theme2 = core.useMantineTheme();
|
|
5458
|
+
return /* @__PURE__ */ jsxRuntime.jsx(core.Tooltip, { label: tooltip, position: "top", withArrow: true, withinPortal: true, zIndex: 2e3, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5459
|
+
framerMotion.motion.button,
|
|
5460
|
+
{
|
|
5461
|
+
onClick,
|
|
5462
|
+
whileHover: { background: core.alpha(color, 0.18) },
|
|
5463
|
+
whileTap: { scale: 0.95 },
|
|
5464
|
+
style: {
|
|
5465
|
+
background: core.alpha(color, 0.1),
|
|
5466
|
+
border: `0.1vh solid ${core.alpha(color, 0.35)}`,
|
|
5467
|
+
borderRadius: theme2.radius.xs,
|
|
5468
|
+
padding: compact ? "0.25vh 0.6vh" : "0.5vh 0.8vh",
|
|
5469
|
+
cursor: "pointer",
|
|
5470
|
+
display: "flex",
|
|
5471
|
+
alignItems: "center",
|
|
5472
|
+
gap: compact ? "0.3vh" : "0.4vh"
|
|
5473
|
+
},
|
|
5474
|
+
children: [
|
|
5475
|
+
icon,
|
|
5476
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: color, children: label2 })
|
|
5477
|
+
]
|
|
5478
|
+
}
|
|
5479
|
+
) });
|
|
5480
|
+
}
|
|
5481
|
+
function WorldPositionSetButton({
|
|
5482
|
+
value,
|
|
5483
|
+
onChange,
|
|
5484
|
+
compact
|
|
5485
|
+
}) {
|
|
5486
|
+
const theme2 = core.useMantineTheme();
|
|
5487
|
+
const color = theme2.colors[theme2.primaryColor][5];
|
|
5488
|
+
const grab = async () => {
|
|
5489
|
+
try {
|
|
5490
|
+
const resp = await fetchNui("GET_POSITION", {}, value);
|
|
5491
|
+
if (!resp || typeof resp !== "object") return;
|
|
5492
|
+
onChange({
|
|
5493
|
+
x: Number(resp.x ?? 0),
|
|
5494
|
+
y: Number(resp.y ?? 0),
|
|
5495
|
+
z: Number(resp.z ?? 0),
|
|
5496
|
+
w: Number(resp.w ?? 0)
|
|
5497
|
+
});
|
|
5498
|
+
} catch {
|
|
5499
|
+
}
|
|
5500
|
+
};
|
|
5501
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5502
|
+
Vector4ActionButton,
|
|
5503
|
+
{
|
|
5504
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Crosshair, { size: compact ? "1.1vh" : "1.3vh", color }),
|
|
5505
|
+
label: locale("Set"),
|
|
5506
|
+
tooltip: locale("SetWorldTooltip"),
|
|
5507
|
+
onClick: grab,
|
|
5508
|
+
color,
|
|
5509
|
+
compact
|
|
5510
|
+
}
|
|
5511
|
+
);
|
|
5512
|
+
}
|
|
5513
|
+
function WorldPositionGotoButton({
|
|
5514
|
+
value,
|
|
5515
|
+
compact
|
|
5516
|
+
}) {
|
|
5517
|
+
const theme2 = core.useMantineTheme();
|
|
5518
|
+
const color = theme2.colors[theme2.primaryColor][5];
|
|
5519
|
+
const goto = () => {
|
|
5520
|
+
fetchNui("GOTO_POSITION", value).catch(() => {
|
|
5521
|
+
});
|
|
5522
|
+
};
|
|
5523
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5524
|
+
Vector4ActionButton,
|
|
5525
|
+
{
|
|
5526
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MapPin, { size: compact ? "1.1vh" : "1.3vh", color }),
|
|
5527
|
+
label: locale("Goto"),
|
|
5528
|
+
tooltip: locale("GotoWorldTooltip"),
|
|
5529
|
+
onClick: goto,
|
|
5530
|
+
color,
|
|
5531
|
+
compact
|
|
5532
|
+
}
|
|
5533
|
+
);
|
|
5534
|
+
}
|
|
5535
|
+
function Vector4DeleteButton({
|
|
5536
|
+
onClick,
|
|
5537
|
+
compact
|
|
5538
|
+
}) {
|
|
5539
|
+
const color = "#ef4444";
|
|
5540
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5541
|
+
Vector4ActionButton,
|
|
5542
|
+
{
|
|
5543
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { size: compact ? "1.1vh" : "1.3vh", color }),
|
|
5544
|
+
label: locale("Delete"),
|
|
5545
|
+
tooltip: locale("Delete"),
|
|
5546
|
+
onClick,
|
|
5547
|
+
color,
|
|
5548
|
+
compact
|
|
5549
|
+
}
|
|
5550
|
+
);
|
|
5551
|
+
}
|
|
5126
5552
|
var GroupSelectContext = React6.createContext(null);
|
|
5127
5553
|
function GroupSelect({
|
|
5128
5554
|
value,
|
|
@@ -5905,6 +6331,7 @@ exports.InfoBox = InfoBox;
|
|
|
5905
6331
|
exports.InputContainer = InputContainer;
|
|
5906
6332
|
exports.LevelBanner = LevelBanner;
|
|
5907
6333
|
exports.LevelPanel = LevelPanel;
|
|
6334
|
+
exports.MissingItemsBanner = MissingItemsBanner;
|
|
5908
6335
|
exports.Modal = Modal;
|
|
5909
6336
|
exports.ModalContext = ModalContext;
|
|
5910
6337
|
exports.ModalProvider = ModalProvider;
|
|
@@ -5923,6 +6350,10 @@ exports.SelectItem = SelectItem;
|
|
|
5923
6350
|
exports.TestBed = TestBed;
|
|
5924
6351
|
exports.Title = Title;
|
|
5925
6352
|
exports.TornEdgeSVGFilter = TornEdgeSVGFilter;
|
|
6353
|
+
exports.Vector4DeleteButton = Vector4DeleteButton;
|
|
6354
|
+
exports.Vector4Display = Vector4Display;
|
|
6355
|
+
exports.WorldPositionGotoButton = WorldPositionGotoButton;
|
|
6356
|
+
exports.WorldPositionSetButton = WorldPositionSetButton;
|
|
5926
6357
|
exports.colorWithAlpha = colorWithAlpha;
|
|
5927
6358
|
exports.copyToClipboard = copyToClipboard;
|
|
5928
6359
|
exports.createFormStore = createFormStore;
|
|
@@ -5967,6 +6398,7 @@ exports.useFormFields = useFormFields;
|
|
|
5967
6398
|
exports.useFrameworkGroups = useFrameworkGroups;
|
|
5968
6399
|
exports.useItems = useItems;
|
|
5969
6400
|
exports.useItemsList = useItemsList;
|
|
6401
|
+
exports.useMissingItemsAudit = useMissingItemsAudit;
|
|
5970
6402
|
exports.useModal = useModal;
|
|
5971
6403
|
exports.useModalActions = useModalActions;
|
|
5972
6404
|
exports.useNavigation = useNavigation;
|