@cobaltcore-dev/aurora 1.0.0 → 1.2.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 +59 -9
- package/dist/client/App.d.ts +2 -1
- package/dist/client/AuroraApp.d.ts +45 -0
- package/dist/client/{AuthProvider-5TyZKZkx.mjs → AuthProvider-CVSAwW9f.mjs} +23 -9
- package/dist/client/AuthProvider-CVSAwW9f.mjs.map +1 -0
- package/dist/client/{ContentHeader-D64NtKvo.mjs → ContentHeader-CPJbgYWn.mjs} +18 -18
- package/dist/client/{ContentHeader-D64NtKvo.mjs.map → ContentHeader-CPJbgYWn.mjs.map} +1 -1
- package/dist/client/DeleteFlavorModal-V44QCJBd.mjs +773 -0
- package/dist/client/DeleteFlavorModal-V44QCJBd.mjs.map +1 -0
- package/dist/client/DynamicBreadcrumbContext-CVcUQFou.mjs +26 -0
- package/dist/client/DynamicBreadcrumbContext-CVcUQFou.mjs.map +1 -0
- package/dist/client/{FiltersInput-Bw8TFfwb.mjs → FiltersInput-CKI6zWnm.mjs} +22 -22
- package/dist/client/{FiltersInput-Bw8TFfwb.mjs.map → FiltersInput-CKI6zWnm.mjs.map} +1 -1
- package/dist/client/FloatingIpActionModals-CwEC5GR-.mjs +460 -0
- package/dist/client/FloatingIpActionModals-CwEC5GR-.mjs.map +1 -0
- package/dist/client/ImageToastNotifications-m6c3tVPb.mjs +1152 -0
- package/dist/client/ImageToastNotifications-m6c3tVPb.mjs.map +1 -0
- package/dist/client/{SortInput-DysAXpB3.mjs → SortInput-4g7nSTHW.mjs} +14 -14
- package/dist/client/SortInput-4g7nSTHW.mjs.map +1 -0
- package/dist/client/{TwoColumnDescriptionList-B3xunXmz.mjs → TwoColumnDescriptionList-NvgvErua.mjs} +6 -6
- package/dist/client/{TwoColumnDescriptionList-B3xunXmz.mjs.map → TwoColumnDescriptionList-NvgvErua.mjs.map} +1 -1
- package/dist/client/_-CAsCx-Ay.mjs +6 -0
- package/dist/client/_-CAsCx-Ay.mjs.map +1 -0
- package/dist/client/_auth-SrDjHL6j.mjs +12 -0
- package/dist/client/_auth-SrDjHL6j.mjs.map +1 -0
- package/dist/client/_flavorId-9PcBBW52.mjs +231 -0
- package/dist/client/_flavorId-9PcBBW52.mjs.map +1 -0
- package/dist/client/{_flavorId-Zj7LNL-R.mjs → _flavorId-a9Gu66R1.mjs} +3 -9
- package/dist/client/_flavorId-a9Gu66R1.mjs.map +1 -0
- package/dist/client/_floatingIpId-AE9Fu8l6.mjs +210 -0
- package/dist/client/_floatingIpId-AE9Fu8l6.mjs.map +1 -0
- package/dist/client/{_floatingIpId-DCQQpNO-.mjs → _floatingIpId-AZ11Ksmu.mjs} +3 -9
- package/dist/client/_floatingIpId-AZ11Ksmu.mjs.map +1 -0
- package/dist/client/_imageId-BtAql2Kr.mjs +570 -0
- package/dist/client/_imageId-BtAql2Kr.mjs.map +1 -0
- package/dist/client/_imageId-D76BxvFY.mjs +39 -0
- package/dist/client/_imageId-D76BxvFY.mjs.map +1 -0
- package/dist/client/_projectId-7Nl1MQTJ.mjs +99 -0
- package/dist/client/_projectId-7Nl1MQTJ.mjs.map +1 -0
- package/dist/client/_projectId-B3wmSala.mjs +281 -0
- package/dist/client/_projectId-B3wmSala.mjs.map +1 -0
- package/dist/client/_projectId-DPzv0CCp.mjs +77 -0
- package/dist/client/_projectId-DPzv0CCp.mjs.map +1 -0
- package/dist/client/_projectId-DfeVJy0G.mjs +30 -0
- package/dist/client/_projectId-DfeVJy0G.mjs.map +1 -0
- package/dist/client/_securityGroupId-C5huJNfO.mjs +1810 -0
- package/dist/client/_securityGroupId-C5huJNfO.mjs.map +1 -0
- package/dist/client/{_securityGroupId-Mj8NJT2-.mjs → _securityGroupId-D85mSigA.mjs} +3 -9
- package/dist/client/_securityGroupId-D85mSigA.mjs.map +1 -0
- package/dist/client/_serviceType-DS8DxsrP.mjs +20 -0
- package/dist/client/_serviceType-DS8DxsrP.mjs.map +1 -0
- package/dist/client/_serviceType-M8d9rOT6.mjs +6 -0
- package/dist/client/_serviceType-M8d9rOT6.mjs.map +1 -0
- package/dist/client/_storageType-BRWWJtow.mjs +14 -0
- package/dist/client/_storageType-BRWWJtow.mjs.map +1 -0
- package/dist/client/_storageType-CzZ4u9x_.mjs +12 -0
- package/dist/client/_storageType-CzZ4u9x_.mjs.map +1 -0
- package/dist/client/_storageType-Dy9uCVXr.mjs +845 -0
- package/dist/client/_storageType-Dy9uCVXr.mjs.map +1 -0
- package/dist/client/_storageType-zeSZe--V.mjs.map +1 -1
- package/dist/client/{about-WLyShNgE.mjs → about-BmQTyLWc.mjs} +2 -2
- package/dist/client/{about-WLyShNgE.mjs.map → about-BmQTyLWc.mjs.map} +1 -1
- package/dist/client/assets/{objectDownload.worker-BXFQIIU_.js.map → objectDownload.worker-CWWLPDyb.js.map} +1 -1
- package/dist/client/assets/{objectDownload.worker-ECvFtmOF.js.map → objectDownload.worker-kZlQuo3F.js.map} +1 -1
- package/dist/client/{aurora-IMO9HhqJ.mjs → aurora-CIml-f2f.mjs} +2 -2
- package/dist/client/{aurora-IMO9HhqJ.mjs.map → aurora-CIml-f2f.mjs.map} +1 -1
- package/dist/client/{build-DnD-T35u.mjs → build-WuxXRAqf.mjs} +2335 -2667
- package/dist/client/{build-DnD-T35u.mjs.map → build-WuxXRAqf.mjs.map} +1 -1
- package/dist/client/components/Breadcrumbs.d.ts +1 -0
- package/dist/client/components/ListToolbar/SortInput.d.ts +3 -0
- package/dist/client/context/BreadcrumbExtensionContext.d.ts +9 -0
- package/dist/client/context/DynamicBreadcrumbContext.d.ts +9 -0
- package/dist/client/{flavors-Cp0LEGOH.mjs → flavors-B0rbqffG.mjs} +3 -5
- package/dist/client/flavors-B0rbqffG.mjs.map +1 -0
- package/dist/client/flavors-DWMZ6TuJ.mjs.map +1 -1
- package/dist/client/flavors-Rl20bxVU.mjs +628 -0
- package/dist/client/flavors-Rl20bxVU.mjs.map +1 -0
- package/dist/client/floatingips-Cz9k80cc.mjs +8 -0
- package/dist/client/floatingips-Cz9k80cc.mjs.map +1 -0
- package/dist/client/floatingips-xbO_mu4f.mjs +576 -0
- package/dist/client/floatingips-xbO_mu4f.mjs.map +1 -0
- package/dist/client/hooks/useBreadcrumbs.d.ts +16 -0
- package/dist/client/hooks/usePushBreadcrumbs.d.ts +10 -0
- package/dist/client/hooks/useSetBreadcrumb.d.ts +11 -0
- package/dist/client/{hooks-CrriowRk.mjs → hooks-D0yKIumu.mjs} +2 -2
- package/dist/client/{hooks-CrriowRk.mjs.map → hooks-D0yKIumu.mjs.map} +1 -1
- package/dist/client/images-BGQv9kKT.mjs +1983 -0
- package/dist/client/images-BGQv9kKT.mjs.map +1 -0
- package/dist/client/{images-DWiM_72I.mjs → images-CPmMa4SQ.mjs} +3 -5
- package/dist/client/images-CPmMa4SQ.mjs.map +1 -0
- package/dist/client/images-NBf2bV43.mjs.map +1 -1
- package/dist/client/index.d.ts +9 -2
- package/dist/client/index.js +567 -695
- package/dist/client/index.js.map +1 -1
- package/dist/client/{md-DNzcRhmz.mjs → md-kvaGCNAK.mjs} +4 -22
- package/dist/client/{md-DNzcRhmz.mjs.map → md-kvaGCNAK.mjs.map} +1 -1
- package/dist/client/objects-BE_u5yRt.mjs +12950 -0
- package/dist/client/objects-BE_u5yRt.mjs.map +1 -0
- package/dist/client/objects-BN-59Th0.mjs +66 -0
- package/dist/client/objects-BN-59Th0.mjs.map +1 -0
- package/dist/client/objects-D9Luf9KB.mjs +66 -0
- package/dist/client/objects-D9Luf9KB.mjs.map +1 -0
- package/dist/client/projects-yiK0HGSA.mjs.map +1 -1
- package/dist/client/routeInfo-DP3v74Wg.mjs +19 -0
- package/dist/client/routeInfo-DP3v74Wg.mjs.map +1 -0
- package/dist/client/router.d.ts +2 -1
- package/dist/client/{routes-B05u5bk4.mjs → routes-CJj7SR_K.mjs} +2 -2
- package/dist/client/routes-CJj7SR_K.mjs.map +1 -0
- package/dist/client/routes-xofA3ksU.mjs +110 -0
- package/dist/client/routes-xofA3ksU.mjs.map +1 -0
- package/dist/client/securitygroups-BjhgLBHm.mjs +620 -0
- package/dist/client/securitygroups-BjhgLBHm.mjs.map +1 -0
- package/dist/client/securitygroups-CtKne8UQ.mjs +8 -0
- package/dist/client/securitygroups-CtKne8UQ.mjs.map +1 -0
- package/dist/client/{securitygroups-_7SYN2jN.mjs → securitygroups-DEJQBcxm.mjs} +3 -5
- package/dist/client/securitygroups-DEJQBcxm.mjs.map +1 -0
- package/dist/client/services-D1PbooD1.mjs +6 -0
- package/dist/client/services-D1PbooD1.mjs.map +1 -0
- package/dist/client/services-DEMVtFyn.mjs +9 -0
- package/dist/client/services-DEMVtFyn.mjs.map +1 -0
- package/dist/client/trpcClient.d.ts +153 -370
- package/dist/client/useBreadcrumbs-ha3IlaxX.mjs +54 -0
- package/dist/client/useBreadcrumbs-ha3IlaxX.mjs.map +1 -0
- package/dist/client/useModalTracking-BcOKTYRN.mjs +33 -0
- package/dist/client/useModalTracking-BcOKTYRN.mjs.map +1 -0
- package/dist/client/{useSecurityGroupPermissions-qPwm4mFt.mjs → useSecurityGroupPermissions-BOyLQLdC.mjs} +78 -12
- package/dist/client/useSecurityGroupPermissions-BOyLQLdC.mjs.map +1 -0
- package/dist/client/useSetBreadcrumb-tn7lBaQV.mjs +19 -0
- package/dist/client/useSetBreadcrumb-tn7lBaQV.mjs.map +1 -0
- package/dist/client/utils/formatSwiftDate.d.ts +30 -0
- package/dist/server/index.d.ts +179 -373
- package/dist/server/index.js +910 -530
- package/package.json +37 -38
- package/dist/client/AuthProvider-5TyZKZkx.mjs.map +0 -1
- package/dist/client/DeleteFlavorModal-C2K43ABZ.mjs +0 -732
- package/dist/client/DeleteFlavorModal-C2K43ABZ.mjs.map +0 -1
- package/dist/client/DeletePcaModal-D9v8E0Ki.mjs +0 -92
- package/dist/client/DeletePcaModal-D9v8E0Ki.mjs.map +0 -1
- package/dist/client/DetailsInfo-h7rPJ4Jf.mjs +0 -61
- package/dist/client/DetailsInfo-h7rPJ4Jf.mjs.map +0 -1
- package/dist/client/FloatingIpActionModals-BfEDfYg9.mjs +0 -417
- package/dist/client/FloatingIpActionModals-BfEDfYg9.mjs.map +0 -1
- package/dist/client/ImageToastNotifications-C0Tluzq-.mjs +0 -1125
- package/dist/client/ImageToastNotifications-C0Tluzq-.mjs.map +0 -1
- package/dist/client/RouteError-B-NPGIv7.mjs +0 -25
- package/dist/client/RouteError-B-NPGIv7.mjs.map +0 -1
- package/dist/client/SortInput-DysAXpB3.mjs.map +0 -1
- package/dist/client/StatusError-DX-GvLjq.mjs +0 -39
- package/dist/client/StatusError-DX-GvLjq.mjs.map +0 -1
- package/dist/client/_auth-R5H2yKFf.mjs +0 -11
- package/dist/client/_auth-R5H2yKFf.mjs.map +0 -1
- package/dist/client/_flavorId-Dit5mM8I.mjs +0 -210
- package/dist/client/_flavorId-Dit5mM8I.mjs.map +0 -1
- package/dist/client/_flavorId-Zj7LNL-R.mjs.map +0 -1
- package/dist/client/_floatingIpId-B0MCoqE3.mjs +0 -215
- package/dist/client/_floatingIpId-B0MCoqE3.mjs.map +0 -1
- package/dist/client/_floatingIpId-DCQQpNO-.mjs.map +0 -1
- package/dist/client/_imageId-CZYzBAVx.mjs +0 -558
- package/dist/client/_imageId-CZYzBAVx.mjs.map +0 -1
- package/dist/client/_pcaId-CHRRsWmO.mjs +0 -605
- package/dist/client/_pcaId-CHRRsWmO.mjs.map +0 -1
- package/dist/client/_projectId-B8wWSxPu.mjs +0 -98
- package/dist/client/_projectId-B8wWSxPu.mjs.map +0 -1
- package/dist/client/_projectId-C5DUYIjt.mjs +0 -291
- package/dist/client/_projectId-C5DUYIjt.mjs.map +0 -1
- package/dist/client/_projectId-D2pFfYIs.mjs +0 -46
- package/dist/client/_projectId-D2pFfYIs.mjs.map +0 -1
- package/dist/client/_projectId-DhSWowQo.mjs +0 -29
- package/dist/client/_projectId-DhSWowQo.mjs.map +0 -1
- package/dist/client/_securityGroupId-DZ4D4WwB.mjs +0 -1801
- package/dist/client/_securityGroupId-DZ4D4WwB.mjs.map +0 -1
- package/dist/client/_securityGroupId-Mj8NJT2-.mjs.map +0 -1
- package/dist/client/_storageType-C-9bNkmZ.mjs +0 -2211
- package/dist/client/_storageType-C-9bNkmZ.mjs.map +0 -1
- package/dist/client/components/Error/StatusError.d.ts +0 -11
- package/dist/client/components/ProjectView/ProjectInfoBox.d.ts +0 -12
- package/dist/client/flavors-Cp0LEGOH.mjs.map +0 -1
- package/dist/client/flavors-CwMbDRHm2.mjs +0 -650
- package/dist/client/flavors-CwMbDRHm2.mjs.map +0 -1
- package/dist/client/floatingips-ICwo-rV_.mjs +0 -591
- package/dist/client/floatingips-ICwo-rV_.mjs.map +0 -1
- package/dist/client/images-DOGZmr3D.mjs +0 -1937
- package/dist/client/images-DOGZmr3D.mjs.map +0 -1
- package/dist/client/images-DWiM_72I.mjs.map +0 -1
- package/dist/client/objects-D2MKUCxc.mjs +0 -56
- package/dist/client/objects-D2MKUCxc.mjs.map +0 -1
- package/dist/client/objects-DI1-tnKr.mjs +0 -56
- package/dist/client/objects-DI1-tnKr.mjs.map +0 -1
- package/dist/client/objects-DeK2WD5K.mjs +0 -10078
- package/dist/client/objects-DeK2WD5K.mjs.map +0 -1
- package/dist/client/pca-BokFv4Gz.mjs +0 -239
- package/dist/client/pca-BokFv4Gz.mjs.map +0 -1
- package/dist/client/pca-D5jHAl0b.mjs +0 -26
- package/dist/client/pca-D5jHAl0b.mjs.map +0 -1
- package/dist/client/pcaAccess-Br4kVjLQ.mjs +0 -9
- package/dist/client/pcaAccess-Br4kVjLQ.mjs.map +0 -1
- package/dist/client/routeInfo-CdTRlSxv.mjs +0 -32
- package/dist/client/routeInfo-CdTRlSxv.mjs.map +0 -1
- package/dist/client/routes-B05u5bk4.mjs.map +0 -1
- package/dist/client/routes-DOJr5onJ.mjs +0 -115
- package/dist/client/routes-DOJr5onJ.mjs.map +0 -1
- package/dist/client/securitygroups-Be2Qgmew.mjs +0 -595
- package/dist/client/securitygroups-Be2Qgmew.mjs.map +0 -1
- package/dist/client/securitygroups-_7SYN2jN.mjs.map +0 -1
- package/dist/client/useSecurityGroupPermissions-qPwm4mFt.mjs.map +0 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useEffect as e, useRef as t } from "react";
|
|
2
|
+
import { useRouteContext as n } from "@tanstack/react-router";
|
|
3
|
+
//#region src/client/hooks/useModalTracking.ts
|
|
4
|
+
var r = ({ isOpen: r, actionPrefix: i }) => {
|
|
5
|
+
let { onTrackEvent: a } = n({ strict: !1 }), o = t(!1), s = t(!1);
|
|
6
|
+
return e(() => {
|
|
7
|
+
r && !o.current && (a?.({
|
|
8
|
+
source: "modal",
|
|
9
|
+
action: `${i}.open`
|
|
10
|
+
}), o.current = !0);
|
|
11
|
+
}, [
|
|
12
|
+
r,
|
|
13
|
+
a,
|
|
14
|
+
i
|
|
15
|
+
]), {
|
|
16
|
+
trackClose: () => {
|
|
17
|
+
r && !s.current && a?.({
|
|
18
|
+
source: "modal",
|
|
19
|
+
action: `${i}.close`
|
|
20
|
+
});
|
|
21
|
+
},
|
|
22
|
+
markSubmitted: () => {
|
|
23
|
+
s.current = !0;
|
|
24
|
+
},
|
|
25
|
+
resetTracking: () => {
|
|
26
|
+
s.current = !1, o.current = !1;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
//#endregion
|
|
31
|
+
export { r as t };
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=useModalTracking-BcOKTYRN.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useModalTracking-BcOKTYRN.mjs","names":["useEffect","useRef","useRouteContext","useModalTracking","isOpen","actionPrefix","onTrackEvent","strict","hasTrackedOpen","hasSubmitted","current","source","action","trackClose","markSubmitted","resetTracking"],"sources":["../../src/client/hooks/useModalTracking.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\"\nimport { useRouteContext } from \"@tanstack/react-router\"\n\ninterface UseModalTrackingOptions {\n isOpen: boolean\n actionPrefix: string // e.g., \"storage.ceph.bucket.create\"\n}\n\ninterface UseModalTrackingReturn {\n trackClose: () => void\n markSubmitted: () => void\n resetTracking: () => void\n}\n\n/**\n * Custom hook to handle modal open/close analytics tracking.\n *\n * Tracks:\n * - `.open` event when modal opens (once per modal open)\n * - `.close` event when modal closes without submission (cancelled)\n *\n * @example\n * const { trackClose, markSubmitted, resetTracking } = useModalTracking({\n * isOpen,\n * actionPrefix: \"storage.ceph.bucket.create\"\n * })\n *\n * // In handleClose:\n * trackClose()\n *\n * // In handleSubmit:\n * markSubmitted()\n *\n * // In cleanup/reset:\n * resetTracking()\n */\nexport const useModalTracking = ({ isOpen, actionPrefix }: UseModalTrackingOptions): UseModalTrackingReturn => {\n const { onTrackEvent } = useRouteContext({ strict: false })\n const hasTrackedOpen = useRef(false)\n // Use useRef instead of useState to avoid timing race with synchronous close paths\n // See: https://github.com/... - setState doesn't apply until next render, so trackClose()\n // could read stale hasSubmitted === false even after markSubmitted() was called\n const hasSubmitted = useRef(false)\n\n // Track when user opens the modal (once per modal open)\n useEffect(() => {\n if (isOpen && !hasTrackedOpen.current) {\n onTrackEvent?.({\n source: \"modal\",\n action: `${actionPrefix}.open`,\n })\n hasTrackedOpen.current = true\n }\n }, [isOpen, onTrackEvent, actionPrefix])\n\n /**\n * Track close event if user didn't submit.\n * Call this at the start of your handleClose function.\n */\n const trackClose = () => {\n if (isOpen && !hasSubmitted.current) {\n onTrackEvent?.({\n source: \"modal\",\n action: `${actionPrefix}.close`,\n })\n }\n }\n\n /**\n * Mark that the user submitted the form.\n * Call this in your handleSubmit function before the mutation.\n */\n const markSubmitted = () => {\n hasSubmitted.current = true\n }\n\n /**\n * Reset tracking state.\n * Call this in handleClose after tracking close event.\n */\n const resetTracking = () => {\n hasSubmitted.current = false\n hasTrackedOpen.current = false\n }\n\n return {\n trackClose,\n markSubmitted,\n resetTracking,\n }\n}\n"],"mappings":";;;AAoCA,IAAaG,KAAoB,EAAEC,WAAQC,sBAAuC;CAChF,IAAM,EAAEC,oBAAiBJ,EAAgB,EAAEK,QAAQ,GAAM,CAAA,GACnDC,IAAiBP,EAAO,EAAA,GAIxBQ,IAAeR,EAAO,EAAA;CA2C5B,OAxCAD,QAAU;EACR,AAAII,KAAU,CAACI,EAAeE,YAC5BJ,IAAe;GACbK,QAAQ;GACRC,QAAQ,GAAGP,EAAa;EAC1B,CAAA,GACAG,EAAeE,UAAU;CAE7B,GAAG;EAACN;EAAQE;EAAcD;CAAa,CAAA,GAgChC;EACLQ,kBA3BiB;GACjB,AAAIT,KAAU,CAACK,EAAaC,WAC1BJ,IAAe;IACbK,QAAQ;IACRC,QAAQ,GAAGP,EAAa;GAC1B,CAAA;EAEJ;EAqBES,qBAfoB;GACpBL,EAAaC,UAAU;EACzB;EAcEK,qBARoB;GAEpBP,AADAC,EAAaC,UAAU,IACvBF,EAAeE,UAAU;EAC3B;CAMA;AACF"}
|
|
@@ -1,10 +1,76 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { K as e, L as t, M as n, P as r, X as i, ft as a, h as o, i as s, lt as c, m as l, p as u } from "./build-WuxXRAqf.mjs";
|
|
2
2
|
import { a as d } from "./trpcClient-D7gpR7YG.mjs";
|
|
3
3
|
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
4
4
|
import { useEffect as m, useState as h } from "react";
|
|
5
5
|
import { Trans as g, useLingui as _ } from "@lingui/react";
|
|
6
|
-
//#region src/client/routes/_auth/projects/$projectId/network/securitygroups/-components
|
|
7
|
-
var v = (
|
|
6
|
+
//#region src/client/routes/_auth/projects/$projectId/network/securitygroups/-components/SecurityGroupToastNotifications.tsx
|
|
7
|
+
var v = (e) => ({
|
|
8
|
+
message: /*#__PURE__*/ f(g, { id: "FT6BiH" }),
|
|
9
|
+
description: /*#__PURE__*/ f(g, {
|
|
10
|
+
id: "+rAGXM",
|
|
11
|
+
values: { name: e }
|
|
12
|
+
})
|
|
13
|
+
}), y = (e) => ({
|
|
14
|
+
message: /*#__PURE__*/ f(g, { id: "xc8SHc" }),
|
|
15
|
+
description: /*#__PURE__*/ f(g, {
|
|
16
|
+
id: "K4twCt",
|
|
17
|
+
values: { errorMessage: e }
|
|
18
|
+
})
|
|
19
|
+
}), b = (e) => ({
|
|
20
|
+
message: /*#__PURE__*/ f(g, { id: "pySxXV" }),
|
|
21
|
+
description: /*#__PURE__*/ f(g, {
|
|
22
|
+
id: "/GSSFQ",
|
|
23
|
+
values: { name: e }
|
|
24
|
+
})
|
|
25
|
+
}), x = (e) => ({
|
|
26
|
+
message: /*#__PURE__*/ f(g, { id: "9PnW2j" }),
|
|
27
|
+
description: /*#__PURE__*/ f(g, {
|
|
28
|
+
id: "6x1HCw",
|
|
29
|
+
values: { errorMessage: e }
|
|
30
|
+
})
|
|
31
|
+
}), S = () => ({
|
|
32
|
+
message: /*#__PURE__*/ f(g, { id: "3qYWKy" }),
|
|
33
|
+
description: /*#__PURE__*/ f(g, { id: "8Xn6tg" })
|
|
34
|
+
}), C = (e) => ({
|
|
35
|
+
message: /*#__PURE__*/ f(g, { id: "3cksfP" }),
|
|
36
|
+
description: /*#__PURE__*/ f(g, {
|
|
37
|
+
id: "nqaM9R",
|
|
38
|
+
values: { errorMessage: e }
|
|
39
|
+
})
|
|
40
|
+
}), w = () => ({
|
|
41
|
+
message: /*#__PURE__*/ f(g, { id: "ygiW4d" }),
|
|
42
|
+
description: /*#__PURE__*/ f(g, { id: "lbxRVC" })
|
|
43
|
+
}), T = (e) => ({
|
|
44
|
+
message: /*#__PURE__*/ f(g, { id: "qToFUF" }),
|
|
45
|
+
description: /*#__PURE__*/ f(g, {
|
|
46
|
+
id: "/9TcRw",
|
|
47
|
+
values: { errorMessage: e }
|
|
48
|
+
})
|
|
49
|
+
}), E = (e) => ({
|
|
50
|
+
message: /*#__PURE__*/ f(g, { id: "CpPgKl" }),
|
|
51
|
+
description: /*#__PURE__*/ f(g, {
|
|
52
|
+
id: "3Gviib",
|
|
53
|
+
values: { targetTenant: e }
|
|
54
|
+
})
|
|
55
|
+
}), D = (e) => ({
|
|
56
|
+
message: /*#__PURE__*/ f(g, { id: "7xCEph" }),
|
|
57
|
+
description: /*#__PURE__*/ f(g, {
|
|
58
|
+
id: "tXYQKw",
|
|
59
|
+
values: { errorMessage: e }
|
|
60
|
+
})
|
|
61
|
+
}), O = (e) => ({
|
|
62
|
+
message: /*#__PURE__*/ f(g, { id: "+lwzZX" }),
|
|
63
|
+
description: /*#__PURE__*/ f(g, {
|
|
64
|
+
id: "+W6219",
|
|
65
|
+
values: { targetTenant: e }
|
|
66
|
+
})
|
|
67
|
+
}), k = (e) => ({
|
|
68
|
+
message: /*#__PURE__*/ f(g, { id: "YmvhrF" }),
|
|
69
|
+
description: /*#__PURE__*/ f(g, {
|
|
70
|
+
id: "Pc3uze",
|
|
71
|
+
values: { errorMessage: e }
|
|
72
|
+
})
|
|
73
|
+
}), A = ({ securityGroup: d, open: v, onClose: y, onUpdate: b, isLoading: x = !1, error: S = null }) => {
|
|
8
74
|
let { i18n: C, _: w } = _(), [T, E] = h({
|
|
9
75
|
name: d.name || "",
|
|
10
76
|
description: d.description || ""
|
|
@@ -45,12 +111,12 @@ var v = ({ securityGroup: d, open: v, onClose: y, onUpdate: b, isLoading: x = !1
|
|
|
45
111
|
title: C._({ id: "yu9G3x" }),
|
|
46
112
|
modalFooter: /*#__PURE__*/ f(r, {
|
|
47
113
|
className: "flex justify-end",
|
|
48
|
-
children: /*#__PURE__*/ p(n, { children: [/*#__PURE__*/ f(
|
|
114
|
+
children: /*#__PURE__*/ p(n, { children: [/*#__PURE__*/ f(s, {
|
|
49
115
|
variant: "default",
|
|
50
116
|
onClick: M,
|
|
51
117
|
disabled: x,
|
|
52
118
|
children: /*#__PURE__*/ f(g, { id: "dEgA5A" })
|
|
53
|
-
}), /*#__PURE__*/ f(
|
|
119
|
+
}), /*#__PURE__*/ f(s, {
|
|
54
120
|
variant: "primary",
|
|
55
121
|
onClick: (e) => {
|
|
56
122
|
j(e);
|
|
@@ -74,11 +140,11 @@ var v = ({ securityGroup: d, open: v, onClose: y, onUpdate: b, isLoading: x = !1
|
|
|
74
140
|
children: /*#__PURE__*/ f(g, { id: "V804LY" })
|
|
75
141
|
})]
|
|
76
142
|
}),
|
|
77
|
-
!x && /*#__PURE__*/ f(
|
|
143
|
+
!x && /*#__PURE__*/ f(a, {
|
|
78
144
|
className: "mb-6",
|
|
79
145
|
children: /*#__PURE__*/ p(u, {
|
|
80
146
|
className: "mb-6",
|
|
81
|
-
children: [/*#__PURE__*/ f(
|
|
147
|
+
children: [/*#__PURE__*/ f(o, {
|
|
82
148
|
className: "mb-6",
|
|
83
149
|
children: /*#__PURE__*/ f(l, {
|
|
84
150
|
id: "name",
|
|
@@ -91,9 +157,9 @@ var v = ({ securityGroup: d, open: v, onClose: y, onUpdate: b, isLoading: x = !1
|
|
|
91
157
|
placeholder: C._({ id: "Ac6dy9" }),
|
|
92
158
|
disabled: x
|
|
93
159
|
})
|
|
94
|
-
}), /*#__PURE__*/ f(
|
|
160
|
+
}), /*#__PURE__*/ f(o, {
|
|
95
161
|
className: "mb-6",
|
|
96
|
-
children: /*#__PURE__*/ f(
|
|
162
|
+
children: /*#__PURE__*/ f(c, {
|
|
97
163
|
id: "description",
|
|
98
164
|
name: "description",
|
|
99
165
|
label: C._({ id: "Nu4oKW" }),
|
|
@@ -111,7 +177,7 @@ var v = ({ securityGroup: d, open: v, onClose: y, onUpdate: b, isLoading: x = !1
|
|
|
111
177
|
};
|
|
112
178
|
//#endregion
|
|
113
179
|
//#region src/client/routes/_auth/projects/$projectId/network/securitygroups/-hooks/useSecurityGroupPermissions.ts
|
|
114
|
-
function
|
|
180
|
+
function j(e) {
|
|
115
181
|
let { data: t = {
|
|
116
182
|
canView: !1,
|
|
117
183
|
canCreate: !1,
|
|
@@ -156,6 +222,6 @@ function y(e) {
|
|
|
156
222
|
};
|
|
157
223
|
}
|
|
158
224
|
//#endregion
|
|
159
|
-
export { v as n, y as t };
|
|
225
|
+
export { k as a, v as c, T as d, w as f, E as i, C as l, b as m, A as n, O as o, x as p, D as r, y as s, j as t, S as u };
|
|
160
226
|
|
|
161
|
-
//# sourceMappingURL=useSecurityGroupPermissions-
|
|
227
|
+
//# sourceMappingURL=useSecurityGroupPermissions-BOyLQLdC.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSecurityGroupPermissions-BOyLQLdC.mjs","names":["getSecurityGroupDeletedToast","name","message","description","getSecurityGroupDeleteErrorToast","errorMessage","getSecurityGroupUpdatedToast","getSecurityGroupUpdateErrorToast","getSecurityGroupRuleCreatedToast","getSecurityGroupRuleCreateErrorToast","getSecurityGroupRuleDeletedToast","getSecurityGroupRuleDeleteErrorToast","getRBACPolicyAddedToast","targetTenant","getRBACPolicyAddErrorToast","getRBACPolicyDeletedToast","getRBACPolicyDeleteErrorToast","React","useState","useEffect","Modal","Form","FormRow","FormSection","TextInput","Button","ButtonRow","Spinner","ModalFooter","Textarea","Message","EditSecurityGroupModal","securityGroup","open","onClose","onUpdate","isLoading","error","useLingui","properties","setProperties","name","description","errors","setErrors","handleInputChange","e","value","type","target","checked","prev","newErrors","validateForm","trim","t","Object","keys","length","handleSubmit","preventDefault","updateData","undefined","id","handleClose","onCancel","size","title","modalFooter","className","variant","onClick","disabled","data-testid","dismissible","div","span","label","onChange","required","errortext","placeholder","rows","trpcReact","useSecurityGroupPermissions","projectId","data","permissions","canView","canCreate","canUpdate","canDelete","canCreateRule","canDeleteRule","canManageAccess","canViewRBAC","isLoading","isError","network","canUser","useQuery","project_id","permission","enabled","Boolean","select","canCreateRBAC","canDeleteRBAC","staleTime","Infinity","gcTime"],"sources":["../../src/client/routes/_auth/projects/$projectId/network/securitygroups/-components/SecurityGroupToastNotifications.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/-components/-modals/EditSecurityGroupModal.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/-hooks/useSecurityGroupPermissions.ts"],"sourcesContent":["import { ReactNode } from \"react\"\nimport { NotificationOptions } from \"@cloudoperators/juno-ui-components\"\nimport { Trans } from \"@lingui/react/macro\"\n\ntype ToastReturnType = { message: ReactNode } & NotificationOptions\n\n// ── Security Group operations ──────────────────────────────────────────────\n\nexport const getSecurityGroupDeletedToast = (name: string): ToastReturnType => ({\n message: <Trans>Security Group Deleted</Trans>,\n description: <Trans>Security group \"{name}\" was successfully deleted.</Trans>,\n})\n\nexport const getSecurityGroupDeleteErrorToast = (errorMessage: string): ToastReturnType => ({\n message: <Trans>Failed to Delete Security Group</Trans>,\n description: <Trans>Could not delete security group: {errorMessage}</Trans>,\n})\n\nexport const getSecurityGroupUpdatedToast = (name: string): ToastReturnType => ({\n message: <Trans>Security Group Updated</Trans>,\n description: <Trans>Security group \"{name}\" was successfully updated.</Trans>,\n})\n\nexport const getSecurityGroupUpdateErrorToast = (errorMessage: string): ToastReturnType => ({\n message: <Trans>Failed to Update Security Group</Trans>,\n description: <Trans>Could not update security group: {errorMessage}</Trans>,\n})\n\n// ── Rule operations ────────────────────────────────────────────────────────\n\nexport const getSecurityGroupRuleCreatedToast = (): ToastReturnType => ({\n message: <Trans>Rule Created</Trans>,\n description: <Trans>Security group rule was successfully created.</Trans>,\n})\n\nexport const getSecurityGroupRuleCreateErrorToast = (errorMessage: string): ToastReturnType => ({\n message: <Trans>Failed to Create Rule</Trans>,\n description: <Trans>Could not create security group rule: {errorMessage}</Trans>,\n})\n\nexport const getSecurityGroupRuleDeletedToast = (): ToastReturnType => ({\n message: <Trans>Rule Deleted</Trans>,\n description: <Trans>Security group rule was successfully deleted.</Trans>,\n})\n\nexport const getSecurityGroupRuleDeleteErrorToast = (errorMessage: string): ToastReturnType => ({\n message: <Trans>Failed to Delete Rule</Trans>,\n description: <Trans>Could not delete security group rule: {errorMessage}</Trans>,\n})\n\n// ── RBAC Policy operations ─────────────────────────────────────────────────\n\nexport const getRBACPolicyAddedToast = (targetTenant: string): ToastReturnType => ({\n message: <Trans>Security Group Shared</Trans>,\n description: <Trans>Security group was successfully shared with project \"{targetTenant}\".</Trans>,\n})\n\nexport const getRBACPolicyAddErrorToast = (errorMessage: string): ToastReturnType => ({\n message: <Trans>Failed to Share Security Group</Trans>,\n description: <Trans>Could not share security group: {errorMessage}</Trans>,\n})\n\nexport const getRBACPolicyDeletedToast = (targetTenant: string): ToastReturnType => ({\n message: <Trans>Access Revoked</Trans>,\n description: <Trans>Access for project \"{targetTenant}\" was successfully revoked.</Trans>,\n})\n\nexport const getRBACPolicyDeleteErrorToast = (errorMessage: string): ToastReturnType => ({\n message: <Trans>Failed to Revoke Access</Trans>,\n description: <Trans>Could not revoke access: {errorMessage}</Trans>,\n})\n","import React, { useState, useEffect } from \"react\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport {\n Modal,\n Form,\n FormRow,\n FormSection,\n TextInput,\n Button,\n ButtonRow,\n Spinner,\n ModalFooter,\n Textarea,\n Message,\n} from \"@cloudoperators/juno-ui-components\"\nimport type { SecurityGroup } from \"@/server/Network/types/securityGroup\"\nimport { UpdateSecurityGroupInput } from \"@/server/Network/types/securityGroup\"\n\ninterface EditSecurityGroupModalProps {\n securityGroup: SecurityGroup\n open: boolean\n onClose: () => void\n onUpdate?: (\n securityGroupId: string,\n data: Omit<UpdateSecurityGroupInput, \"securityGroupId\" | \"project_id\">\n ) => Promise<void>\n isLoading?: boolean\n error?: string | null\n}\n\ninterface SecurityGroupProperties {\n name: string\n description: string\n}\n\nexport const EditSecurityGroupModal: React.FC<EditSecurityGroupModalProps> = ({\n securityGroup,\n open,\n onClose,\n onUpdate,\n isLoading = false,\n error = null,\n}) => {\n const { t } = useLingui()\n\n const [properties, setProperties] = useState<SecurityGroupProperties>({\n name: securityGroup.name || \"\",\n description: securityGroup.description || \"\",\n })\n const [errors, setErrors] = useState<{ [key: string]: string }>({})\n\n // Update properties when securityGroup changes\n useEffect(() => {\n setProperties({\n name: securityGroup.name || \"\",\n description: securityGroup.description || \"\",\n })\n }, [securityGroup])\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n const { name, value, type } = e.target\n const checked = (e.target as HTMLInputElement).checked\n\n setProperties((prev) => ({\n ...prev,\n [name]: type === \"checkbox\" ? checked : value,\n }))\n\n if (errors[name]) {\n setErrors((prev) => {\n const newErrors = { ...prev }\n delete newErrors[name]\n return newErrors\n })\n }\n }\n\n const validateForm = (): boolean => {\n const newErrors: { [key: string]: string } = {}\n\n if (!properties.name || properties.name.trim() === \"\") {\n newErrors.name = t`Security group name is required`\n }\n\n setErrors(newErrors)\n return Object.keys(newErrors).length === 0\n }\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n\n if (!validateForm()) {\n return\n }\n\n if (onUpdate) {\n // Prepare base update data without stateful\n const updateData: Omit<UpdateSecurityGroupInput, \"securityGroupId\" | \"project_id\"> = {\n name: properties.name.trim(),\n description: properties.description.trim() || undefined,\n }\n\n // Note: We deliberately do NOT include 'stateful' field here\n // because it requires special 'update_security_group:stateful' permission\n // which needs cloud admin role. Regular users can only update name/description.\n\n await onUpdate(securityGroup.id, updateData)\n }\n }\n\n const handleClose = () => {\n setErrors({})\n onClose()\n }\n\n return (\n <Modal\n open={open}\n onCancel={handleClose}\n size=\"large\"\n title={t`Edit Security Group`}\n modalFooter={\n <ModalFooter className=\"flex justify-end\">\n <ButtonRow>\n <Button variant=\"default\" onClick={handleClose} disabled={isLoading}>\n <Trans>Cancel</Trans>\n </Button>\n <Button\n variant=\"primary\"\n onClick={(e) => {\n handleSubmit(e)\n }}\n disabled={isLoading}\n data-testid=\"update-security-group-button\"\n >\n {isLoading ? <Spinner size=\"small\" /> : <Trans>Update Security Group</Trans>}\n </Button>\n </ButtonRow>\n </ModalFooter>\n }\n >\n {/* Error Message */}\n {error && (\n <Message dismissible={false} variant=\"error\" className=\"mb-4\">\n {error}\n </Message>\n )}\n\n {isLoading && (\n <div className=\"mb-4 flex items-center justify-center gap-2\">\n <Spinner variant=\"primary\" />\n <span className=\"text-theme-high text-sm\">\n <Trans>Updating security group...</Trans>\n </span>\n </div>\n )}\n\n {!isLoading && (\n <Form className=\"mb-6\">\n <FormSection className=\"mb-6\">\n <FormRow className=\"mb-6\">\n <TextInput\n id=\"name\"\n name=\"name\"\n label={t`Name`}\n value={properties.name}\n onChange={handleInputChange}\n required\n errortext={errors.name}\n placeholder={t`Type name`}\n disabled={isLoading}\n />\n </FormRow>\n\n <FormRow className=\"mb-6\">\n <Textarea\n id=\"description\"\n name=\"description\"\n label={t`Description`}\n value={properties.description}\n onChange={handleInputChange}\n placeholder={t`Description`}\n disabled={isLoading}\n rows={3}\n />\n </FormRow>\n {/* Note: Stateful checkbox is not shown here because it requires 'update_security_group:stateful' permission (cloud admin only) */}\n </FormSection>\n </Form>\n )}\n </Modal>\n )\n}\n","import { trpcReact } from \"@/client/trpcClient\"\n\nexport interface SecurityGroupPermissions {\n canView: boolean\n canCreate: boolean\n canUpdate: boolean\n canDelete: boolean\n canCreateRule: boolean\n canDeleteRule: boolean\n canManageAccess: boolean\n canViewRBAC: boolean\n}\n\n/**\n * Hook to fetch security group permissions for the current user\n * Uses React Query with infinite cache since permissions don't change during session\n */\nexport function useSecurityGroupPermissions(projectId: string) {\n const {\n data: permissions = {\n canView: false,\n canCreate: false,\n canUpdate: false,\n canDelete: false,\n canCreateRule: false,\n canDeleteRule: false,\n canManageAccess: false,\n canViewRBAC: false,\n },\n isLoading,\n isError,\n } = trpcReact.network.canUser.useQuery(\n {\n project_id: projectId || \"\",\n permission: [\n \"network:security_groups:read\",\n \"network:security_groups:create\",\n \"network:security_groups:update\",\n \"network:security_groups:delete\",\n \"network:security_group_rules:create\",\n \"network:security_group_rules:delete\",\n \"network:rbac_policies:create\",\n \"network:rbac_policies:delete\",\n \"network:rbac_policies:read\",\n ],\n },\n {\n enabled: Boolean(projectId), // Only fetch if we have a project ID\n select: ([\n canView,\n canCreate,\n canUpdate,\n canDelete,\n canCreateRule,\n canDeleteRule,\n canCreateRBAC,\n canDeleteRBAC,\n canViewRBAC,\n ]) => ({\n canView,\n canCreate,\n canUpdate,\n canDelete,\n canCreateRule,\n canDeleteRule,\n canManageAccess: canCreateRBAC && canDeleteRBAC,\n canViewRBAC,\n }),\n staleTime: Infinity, // Permissions don't change during session\n gcTime: Infinity, // Keep in cache forever (previously cacheTime)\n }\n )\n\n return {\n permissions,\n isLoading,\n isError,\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { t as e } from "./DynamicBreadcrumbContext-CVcUQFou.mjs";
|
|
2
|
+
import { useContext as t, useLayoutEffect as n } from "react";
|
|
3
|
+
//#region src/client/hooks/useSetBreadcrumb.ts
|
|
4
|
+
function r(r, i, a) {
|
|
5
|
+
let { setCrumb: o } = t(e), s = a?.to;
|
|
6
|
+
n(() => (i ? o(r, {
|
|
7
|
+
text: i,
|
|
8
|
+
to: s
|
|
9
|
+
}) : o(r, null), () => o(r, null)), [
|
|
10
|
+
r,
|
|
11
|
+
i,
|
|
12
|
+
s,
|
|
13
|
+
o
|
|
14
|
+
]);
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { r as t };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=useSetBreadcrumb-tn7lBaQV.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSetBreadcrumb-tn7lBaQV.mjs","names":["useContext","useLayoutEffect","DynamicBreadcrumbContext","useSetBreadcrumb","routeId","text","options","setCrumb","to"],"sources":["../../src/client/hooks/useSetBreadcrumb.ts"],"sourcesContent":["import { useContext, useLayoutEffect } from \"react\"\nimport { DynamicBreadcrumbContext } from \"@/client/context/DynamicBreadcrumbContext\"\n\n/**\n * Registers a dynamic breadcrumb for a route. Call inside a route component, passing Route.id.\n * The entry is added when text is defined and removed when text becomes undefined or the component unmounts.\n *\n * Requirements:\n * - Must be rendered inside `DynamicBreadcrumbProvider` (mounted at `_auth.tsx`)\n * - Pass `Route.id` as routeId so `useBreadcrumbs` can correlate it with the correct match\n */\nexport function useSetBreadcrumb(routeId: string, text: string | undefined, options?: { to?: string }) {\n const { setCrumb } = useContext(DynamicBreadcrumbContext)\n const to = options?.to\n\n useLayoutEffect(() => {\n if (text) {\n setCrumb(routeId, { text, to })\n } else {\n setCrumb(routeId, null)\n }\n return () => setCrumb(routeId, null)\n }, [routeId, text, to, setCrumb])\n}\n"],"mappings":";;;AAWA,SAAgBG,EAAiBC,GAAiBC,GAA0BC,GAAyB;CACnG,IAAM,EAAEC,gBAAaP,EAAWE,CAAAA,GAC1BM,IAAKF,GAASE;CAEpBP,SACMI,IACFE,EAASH,GAAS;EAAEC;EAAMG;CAAG,CAAA,IAE7BD,EAASH,GAAS,IAAA,SAEPG,EAASH,GAAS,IAAA,IAC9B;EAACA;EAASC;EAAMG;EAAID;CAAS,CAAA;AAClC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Swift timestamp helpers.
|
|
3
|
+
*
|
|
4
|
+
* Swift returns `last_modified` in container and object listings as an ISO 8601
|
|
5
|
+
* timestamp that is UTC but carries NO zone designator — e.g.
|
|
6
|
+
* "2024-03-01T08:00:00.000000" (see OpenStack Swift bug #1169287: dates in the
|
|
7
|
+
* JSON listings are UTC without a trailing "Z"). Per ISO 8601, a date-time with
|
|
8
|
+
* no zone is interpreted as LOCAL time, so `new Date("...T08:00:00")` treats the
|
|
9
|
+
* value as local and the rendered time ends up shifted by the viewer's UTC
|
|
10
|
+
* offset (#1236).
|
|
11
|
+
*
|
|
12
|
+
* These helpers treat a zone-less timestamp as UTC (by appending "Z" before
|
|
13
|
+
* parsing) so it converts correctly to the viewer's local time. Timestamps that
|
|
14
|
+
* already carry a zone — a trailing "Z" or an explicit ±hh:mm offset, as Ceph
|
|
15
|
+
* returns — are left untouched.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Parse a Swift timestamp into a Date, treating a zone-less value as UTC.
|
|
19
|
+
* Returns null for empty or unparseable input.
|
|
20
|
+
*/
|
|
21
|
+
export declare const parseSwiftDate: (value: string | null | undefined) => Date | null;
|
|
22
|
+
/**
|
|
23
|
+
* Format a Swift timestamp, defaulting to the viewer's local timezone (unless
|
|
24
|
+
* overridden via `options.timeZone`).
|
|
25
|
+
*
|
|
26
|
+
* Returns null for empty/invalid input so callers can supply their own fallback
|
|
27
|
+
* (e.g. a translated "N/A"). `locales`/`options` are passed straight through to
|
|
28
|
+
* `Date.prototype.toLocaleString`.
|
|
29
|
+
*/
|
|
30
|
+
export declare const formatSwiftDate: (value: string | null | undefined, locales?: Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions) => string | null;
|