@cobaltcore-dev/aurora 0.9.0 → 0.11.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 +2 -1
- package/dist/client/AuroraApp.d.ts +2 -0
- package/dist/client/AuthProvider-DZqOvceF.mjs +64 -0
- package/dist/client/AuthProvider-DZqOvceF.mjs.map +1 -0
- package/dist/client/ContentHeader-DsuZD8fa.mjs +110 -0
- package/dist/client/ContentHeader-DsuZD8fa.mjs.map +1 -0
- package/dist/client/{DeleteFlavorModal-C3m7bQJu.mjs → DeleteFlavorModal-RnbspW_2.mjs} +135 -135
- package/dist/client/{DeleteFlavorModal-C3m7bQJu.mjs.map → DeleteFlavorModal-RnbspW_2.mjs.map} +1 -1
- package/dist/client/DeleteVersionsModal-CsBJzXoW.mjs +331 -0
- package/dist/client/DeleteVersionsModal-CsBJzXoW.mjs.map +1 -0
- package/dist/client/{EditSecurityGroupModal-DKusxfta.mjs → EditSecurityGroupModal-BPv3d7am.mjs} +15 -15
- package/dist/client/{EditSecurityGroupModal-DKusxfta.mjs.map → EditSecurityGroupModal-BPv3d7am.mjs.map} +1 -1
- package/dist/client/{FiltersInput-GzR4D0q6.mjs → FiltersInput-CViamP59.mjs} +2 -2
- package/dist/client/{FiltersInput-GzR4D0q6.mjs.map → FiltersInput-CViamP59.mjs.map} +1 -1
- package/dist/client/{FloatingIpActionModals-CRvROJ3H.mjs → FloatingIpActionModals-DTn3HFei.mjs} +45 -45
- package/dist/client/{FloatingIpActionModals-CRvROJ3H.mjs.map → FloatingIpActionModals-DTn3HFei.mjs.map} +1 -1
- package/dist/client/{ImageToastNotifications-BuDXpTkl.mjs → ImageToastNotifications-CFKQZTgf.mjs} +261 -261
- package/dist/client/{ImageToastNotifications-BuDXpTkl.mjs.map → ImageToastNotifications-CFKQZTgf.mjs.map} +1 -1
- package/dist/client/{RouteError-DVAiT0mT.mjs → RouteError-BebIhFpQ.mjs} +2 -2
- package/dist/client/{RouteError-DVAiT0mT.mjs.map → RouteError-BebIhFpQ.mjs.map} +1 -1
- package/dist/client/{SortInput-VK7IYqQv.mjs → SortInput-D0Vb864D.mjs} +9 -9
- package/dist/client/SortInput-D0Vb864D.mjs.map +1 -0
- package/dist/client/{_auth-DXJkv9QO.mjs → _auth-DnImOqR-.mjs} +2 -2
- package/dist/client/_auth-DnImOqR-.mjs.map +1 -0
- package/dist/client/{_flavorId-Dy7EYQum.mjs → _flavorId-C9SZd1jL.mjs} +8 -8
- package/dist/client/{_flavorId-Dy7EYQum.mjs.map → _flavorId-C9SZd1jL.mjs.map} +1 -1
- package/dist/client/{_flavorId-DsD2VTKA.mjs → _flavorId-DINgWoeV.mjs} +38 -38
- package/dist/client/{_flavorId-DsD2VTKA.mjs.map → _flavorId-DINgWoeV.mjs.map} +1 -1
- package/dist/client/{_floatingIpId-j17rCQqG2.mjs → _floatingIpId-BACLbMzi2.mjs} +32 -32
- package/dist/client/{_floatingIpId-j17rCQqG2.mjs.map → _floatingIpId-BACLbMzi2.mjs.map} +1 -1
- package/dist/client/{_floatingIpId-BjVbeNw_.mjs → _floatingIpId-BzVMOv97.mjs} +2 -2
- package/dist/client/{_floatingIpId-BjVbeNw_.mjs.map → _floatingIpId-BzVMOv97.mjs.map} +1 -1
- package/dist/client/_imageId-DCvaU7-S.mjs +534 -0
- package/dist/client/_imageId-DCvaU7-S.mjs.map +1 -0
- package/dist/client/{_pcaId-BwTvJJgh.mjs → _pcaId-B3PqECyO.mjs} +115 -115
- package/dist/client/{_pcaId-BwTvJJgh.mjs.map → _pcaId-B3PqECyO.mjs.map} +1 -1
- package/dist/client/{_pcaId-DUHQd0rB.mjs → _pcaId-DAJEt3ZI.mjs} +2 -2
- package/dist/client/{_pcaId-DUHQd0rB.mjs.map → _pcaId-DAJEt3ZI.mjs.map} +1 -1
- package/dist/client/{_projectId-CARHuZTU.mjs → _projectId-B2hG5peP.mjs} +3 -3
- package/dist/client/_projectId-B2hG5peP.mjs.map +1 -0
- package/dist/client/{_projectId-DR_2U10f.mjs → _projectId-BnWXWTBR.mjs} +3 -3
- package/dist/client/_projectId-BnWXWTBR.mjs.map +1 -0
- package/dist/client/{_projectId-BaqZ4W50.mjs → _projectId-DRr9rLST.mjs} +103 -109
- package/dist/client/_projectId-DRr9rLST.mjs.map +1 -0
- package/dist/client/{_projectId-B_2sZKk-.mjs → _projectId-DU8qRiZk.mjs} +2 -2
- package/dist/client/_projectId-DU8qRiZk.mjs.map +1 -0
- package/dist/client/{_securityGroupId-fhK1CuZh.mjs → _securityGroupId-Cj9IotMJ.mjs} +2 -2
- package/dist/client/{_securityGroupId-fhK1CuZh.mjs.map → _securityGroupId-Cj9IotMJ.mjs.map} +1 -1
- package/dist/client/{_securityGroupId-DYxmXUOP.mjs → _securityGroupId-ClJiFh4R.mjs} +267 -267
- package/dist/client/{_securityGroupId-DYxmXUOP.mjs.map → _securityGroupId-ClJiFh4R.mjs.map} +1 -1
- package/dist/client/_storageType-BrHDa2bD.mjs +3005 -0
- package/dist/client/_storageType-BrHDa2bD.mjs.map +1 -0
- package/dist/client/{_storageType-D7-_Xwwl.mjs → _storageType-CSLH93js.mjs} +2 -2
- package/dist/client/{_storageType-D7-_Xwwl.mjs.map → _storageType-CSLH93js.mjs.map} +1 -1
- package/dist/client/_storageType-zeSZe--V.mjs.map +1 -1
- package/dist/client/{about-Nsxkyh9U.mjs → about-BnU297yB.mjs} +2 -2
- package/dist/client/about-BnU297yB.mjs.map +1 -0
- package/dist/client/{aurora-DDzsst74.mjs → aurora-6RsAZtnz.mjs} +2 -2
- package/dist/client/aurora-6RsAZtnz.mjs.map +1 -0
- package/dist/client/{build-BdRRmNf5.mjs → build-DF7MTyXG.mjs} +3582 -3114
- package/dist/client/{build-BdRRmNf5.mjs.map → build-DF7MTyXG.mjs.map} +1 -1
- package/dist/client/{constants-J5nm9hbP.mjs → constants-BskfpGYY.mjs} +17 -17
- package/dist/client/{constants-J5nm9hbP.mjs.map → constants-BskfpGYY.mjs.map} +1 -1
- package/dist/client/{flavors-C-gY4XeQ.mjs → flavors-DAbtRoep.mjs} +151 -151
- package/dist/client/{flavors-C-gY4XeQ.mjs.map → flavors-DAbtRoep.mjs.map} +1 -1
- package/dist/client/{flavors-Dwy1ID_f.mjs → flavors-DODudzrA.mjs} +2 -2
- package/dist/client/{flavors-Dwy1ID_f.mjs.map → flavors-DODudzrA.mjs.map} +1 -1
- package/dist/client/flavors-DWMZ6TuJ.mjs.map +1 -1
- package/dist/client/{floatingips-Dq4DXQYb.mjs → floatingips-DJW9ftN_.mjs} +84 -84
- package/dist/client/floatingips-DJW9ftN_.mjs.map +1 -0
- package/dist/client/{hooks-dSArr2Ca.mjs → hooks-CMgoYcDG.mjs} +1 -1
- package/dist/client/{images-bG-MZZ7V.mjs → images-BbLnuYrL.mjs} +2 -2
- package/dist/client/{images-bG-MZZ7V.mjs.map → images-BbLnuYrL.mjs.map} +1 -1
- package/dist/client/{images-Dbjo4yKn.mjs → images-C3JyPwer.mjs} +2 -2
- package/dist/client/images-C3JyPwer.mjs.map +1 -0
- package/dist/client/{images-HG7TneK0.mjs → images-Cp6V1nF5.mjs} +455 -455
- package/dist/client/{images-HG7TneK0.mjs.map → images-Cp6V1nF5.mjs.map} +1 -1
- package/dist/client/images-NBf2bV43.mjs.map +1 -1
- package/dist/client/index.js +270 -266
- package/dist/client/index.js.map +1 -1
- package/dist/client/{md-CYTrL5dq.mjs → md-CyCflQee.mjs} +10 -28
- package/dist/client/{md-CYTrL5dq.mjs.map → md-CyCflQee.mjs.map} +1 -1
- package/dist/client/network-DuZm76BZ.mjs.map +1 -1
- package/dist/client/{objects-DKWp9RtR.mjs → objects-Bw96WXOs.mjs} +4 -3
- package/dist/client/objects-Bw96WXOs.mjs.map +1 -0
- package/dist/client/objects-DUmK3WgA.mjs +5998 -0
- package/dist/client/objects-DUmK3WgA.mjs.map +1 -0
- package/dist/client/objects-o2Cj_ndZ.mjs.map +1 -1
- package/dist/client/{pca-D7DF_BZZ.mjs → pca-DKeGzbww.mjs} +2 -2
- package/dist/client/{pca-D7DF_BZZ.mjs.map → pca-DKeGzbww.mjs.map} +1 -1
- package/dist/client/{pca-BBxPCAH0.mjs → pca-Dc_tdh4-.mjs} +47 -47
- package/dist/client/{pca-BBxPCAH0.mjs.map → pca-Dc_tdh4-.mjs.map} +1 -1
- package/dist/client/{projects-DNd3UTas.mjs → projects-CRL37ftA.mjs} +16 -16
- package/dist/client/{projects-DNd3UTas.mjs.map → projects-CRL37ftA.mjs.map} +1 -1
- package/dist/client/{projects-B5topuei.mjs → projects-DUWOgB3m.mjs} +2 -2
- package/dist/client/{projects-B5topuei.mjs.map → projects-DUWOgB3m.mjs.map} +1 -1
- package/dist/client/{projects-CHYn7L5e.mjs → projects-DpXQYfKc.mjs} +2 -2
- package/dist/client/projects-DpXQYfKc.mjs.map +1 -0
- package/dist/client/{securitygroups-CNFLu9zS.mjs → securitygroups-CWWFSjjj.mjs} +94 -94
- package/dist/client/securitygroups-CWWFSjjj.mjs.map +1 -0
- package/dist/client/{useListWithFiltering-v2A0-SZb.mjs → useListWithFiltering-C9k7xWqz.mjs} +7 -7
- package/dist/client/{useListWithFiltering-v2A0-SZb.mjs.map → useListWithFiltering-C9k7xWqz.mjs.map} +1 -1
- package/dist/server/index.js +979 -454
- package/package.json +3 -3
- package/dist/client/AuthProvider-Co4d0WzB.mjs +0 -100
- package/dist/client/AuthProvider-Co4d0WzB.mjs.map +0 -1
- package/dist/client/ContentHeader-D4jlOG-9.mjs +0 -96
- package/dist/client/ContentHeader-D4jlOG-9.mjs.map +0 -1
- package/dist/client/SortInput-VK7IYqQv.mjs.map +0 -1
- package/dist/client/_auth-DXJkv9QO.mjs.map +0 -1
- package/dist/client/_imageId-BjfhqAje.mjs +0 -534
- package/dist/client/_imageId-BjfhqAje.mjs.map +0 -1
- package/dist/client/_projectId-B_2sZKk-.mjs.map +0 -1
- package/dist/client/_projectId-BaqZ4W50.mjs.map +0 -1
- package/dist/client/_projectId-CARHuZTU.mjs.map +0 -1
- package/dist/client/_projectId-DR_2U10f.mjs.map +0 -1
- package/dist/client/_storageType-B0eJODiQ.mjs +0 -3244
- package/dist/client/_storageType-B0eJODiQ.mjs.map +0 -1
- package/dist/client/about-Nsxkyh9U.mjs.map +0 -1
- package/dist/client/aurora-DDzsst74.mjs.map +0 -1
- package/dist/client/floatingips-Dq4DXQYb.mjs.map +0 -1
- package/dist/client/images-Dbjo4yKn.mjs.map +0 -1
- package/dist/client/objects-DKWp9RtR.mjs.map +0 -1
- package/dist/client/objects-DaCuy_CB.mjs +0 -5708
- package/dist/client/objects-DaCuy_CB.mjs.map +0 -1
- package/dist/client/projects-CHYn7L5e.mjs.map +0 -1
- package/dist/client/securitygroups-CNFLu9zS.mjs.map +0 -1
|
@@ -1,76 +1,66 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { G as e, M as t, O as n, P as r, V as i, X as a, Z as o, a as s, lt as c, y as l } from "./build-DF7MTyXG.mjs";
|
|
2
2
|
import { t as u } from "./Slot-CWb612-_.mjs";
|
|
3
|
-
import { t as d } from "./_projectId-
|
|
3
|
+
import { t as d } from "./_projectId-BnWXWTBR.mjs";
|
|
4
4
|
import { t as f } from "./helpers-1PpYf-fC.mjs";
|
|
5
5
|
import { t as p } from "./routeInfo-Dy9l-wFB.mjs";
|
|
6
6
|
import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
7
|
-
import { useEffect as _, useMemo as v,
|
|
8
|
-
import { Outlet as
|
|
9
|
-
import { useLingui as
|
|
10
|
-
import { i18n as
|
|
7
|
+
import { useEffect as _, useMemo as v, useState as y } from "react";
|
|
8
|
+
import { Outlet as b, useLoaderData as x, useMatches as S, useNavigate as C, useParams as w, useRouteContext as T } from "@tanstack/react-router";
|
|
9
|
+
import { useLingui as E } from "@lingui/react";
|
|
10
|
+
import { i18n as D } from "@lingui/core";
|
|
11
11
|
//#region src/client/routes/_auth/projects/-components/SideNavBar.tsx
|
|
12
|
-
var
|
|
13
|
-
let o =
|
|
12
|
+
var O = ({ projectId: e, projectName: n, domainName: r, sections: a }) => {
|
|
13
|
+
let o = C(), d = S(), { provider: f } = w({ strict: !1 }), { slots: v } = T({ strict: !1 }), b = (e) => v?.serviceBadge ? /*#__PURE__*/ h(u, {
|
|
14
14
|
component: v.serviceBadge,
|
|
15
15
|
useShadowDOM: !1,
|
|
16
16
|
currentService: e
|
|
17
|
-
}) : null,
|
|
17
|
+
}) : null, x = [...d].reverse().find((e) => p(e.staticData)), E = x && p(x.staticData) ? x.staticData : void 0, D = E?.section ?? null, O = E?.service ?? null, [k, A] = y(() => Object.fromEntries(a.map((e) => [e.section, 0])));
|
|
18
18
|
return _(() => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
...e,
|
|
25
|
-
[O]: !1
|
|
26
|
-
}));
|
|
27
|
-
let e = O;
|
|
28
|
-
setTimeout(() => j((t) => ({
|
|
29
|
-
...t,
|
|
30
|
-
[e]: !0
|
|
31
|
-
})), 0);
|
|
32
|
-
}
|
|
33
|
-
}, [O]), /*#__PURE__*/ h(t, {
|
|
19
|
+
D && A((e) => ({
|
|
20
|
+
...e,
|
|
21
|
+
[D]: (e[D] || 0) + 1
|
|
22
|
+
}));
|
|
23
|
+
}, [D]), /*#__PURE__*/ h(t, {
|
|
34
24
|
ariaLabel: "Project Side Navigation",
|
|
35
|
-
children: /*#__PURE__*/ g(m, { children: [/*#__PURE__*/ h(
|
|
25
|
+
children: /*#__PURE__*/ g(m, { children: [/*#__PURE__*/ h(i, { children: /*#__PURE__*/ g(m, { children: [
|
|
36
26
|
/*#__PURE__*/ h(s, {
|
|
37
27
|
onClick: () => o({
|
|
38
28
|
to: "/projects/$projectId",
|
|
39
|
-
params: { projectId:
|
|
29
|
+
params: { projectId: e }
|
|
40
30
|
}),
|
|
41
|
-
label: /*#__PURE__*/ g(m, { children: [
|
|
31
|
+
label: /*#__PURE__*/ g(m, { children: [r && /*#__PURE__*/ g("p", {
|
|
42
32
|
className: "text-theme-light text-xs leading-4 font-bold",
|
|
43
|
-
children: [
|
|
33
|
+
children: [r, " /"]
|
|
44
34
|
}), /*#__PURE__*/ h("p", {
|
|
45
35
|
className: "leading-5 font-normal",
|
|
46
|
-
children:
|
|
36
|
+
children: n
|
|
47
37
|
})] })
|
|
48
38
|
}),
|
|
49
39
|
/*#__PURE__*/ h(c, { spacing: "1" }),
|
|
50
40
|
a.map(({ section: e, label: t, services: n }) => /*#__PURE__*/ h(l, {
|
|
51
41
|
label: t,
|
|
52
|
-
open:
|
|
42
|
+
open: !0,
|
|
53
43
|
children: n.map((t) => {
|
|
54
|
-
let n =
|
|
44
|
+
let n = D === e && (D === "storage" && O === "containers" ? t.params.provider === f : O === t.service);
|
|
55
45
|
return /*#__PURE__*/ h(s, {
|
|
56
46
|
onClick: () => t.navigate(o),
|
|
57
47
|
label: /*#__PURE__*/ g("span", {
|
|
58
48
|
className: "flex items-start gap-2",
|
|
59
|
-
children: [t.label,
|
|
49
|
+
children: [t.label, b(t.service)]
|
|
60
50
|
}),
|
|
61
51
|
selected: n
|
|
62
52
|
}, t.service);
|
|
63
53
|
})
|
|
64
|
-
}, e))
|
|
54
|
+
}, `${e}-${k[e]}`))
|
|
65
55
|
] }) }), v?.sideNavBanner && /*#__PURE__*/ h(u, { component: v.sideNavBanner })] })
|
|
66
56
|
});
|
|
67
57
|
};
|
|
68
58
|
//#endregion
|
|
69
59
|
//#region src/client/routes/_auth/projects/-components/buildNavSections.ts
|
|
70
|
-
function
|
|
60
|
+
function k(e, t, n) {
|
|
71
61
|
let r = f(t), i = (e) => !n || n.includes(e), a = [...r.image?.glance && i("images") ? [{
|
|
72
62
|
service: "images",
|
|
73
|
-
label:
|
|
63
|
+
label: D._({ id: "an5hVd" }),
|
|
74
64
|
navigate: (t) => t({
|
|
75
65
|
to: "/projects/$projectId/compute/images",
|
|
76
66
|
params: { projectId: e }
|
|
@@ -78,7 +68,7 @@ function A(e, t, n) {
|
|
|
78
68
|
params: { projectId: e }
|
|
79
69
|
}] : [], ...r?.compute?.nova && i("flavors") ? [{
|
|
80
70
|
service: "flavors",
|
|
81
|
-
label:
|
|
71
|
+
label: D._({ id: "neiJm0" }),
|
|
82
72
|
navigate: (t) => t({
|
|
83
73
|
to: "/projects/$projectId/compute/flavors",
|
|
84
74
|
params: { projectId: e }
|
|
@@ -86,7 +76,7 @@ function A(e, t, n) {
|
|
|
86
76
|
params: { projectId: e }
|
|
87
77
|
}] : []], o = r.network ? [...i("securitygroups") ? [{
|
|
88
78
|
service: "securitygroups",
|
|
89
|
-
label:
|
|
79
|
+
label: D._({ id: "4opp4r" }),
|
|
90
80
|
navigate: (t) => t({
|
|
91
81
|
to: "/projects/$projectId/network/securitygroups",
|
|
92
82
|
params: { projectId: e }
|
|
@@ -94,7 +84,7 @@ function A(e, t, n) {
|
|
|
94
84
|
params: { projectId: e }
|
|
95
85
|
}] : [], ...i("floatingips") ? [{
|
|
96
86
|
service: "floatingips",
|
|
97
|
-
label:
|
|
87
|
+
label: D._({ id: "u77/s4" }),
|
|
98
88
|
navigate: (t) => t({
|
|
99
89
|
to: "/projects/$projectId/network/floatingips",
|
|
100
90
|
params: { projectId: e }
|
|
@@ -102,7 +92,7 @@ function A(e, t, n) {
|
|
|
102
92
|
params: { projectId: e }
|
|
103
93
|
}] : []] : [], s = [...r?.["object-store"]?.swift && i("containers") ? [{
|
|
104
94
|
service: "containers",
|
|
105
|
-
label:
|
|
95
|
+
label: D._({ id: "+OEi73" }),
|
|
106
96
|
navigate: (t) => t({
|
|
107
97
|
to: "/projects/$projectId/storage/$provider/$storageType",
|
|
108
98
|
params: {
|
|
@@ -118,7 +108,7 @@ function A(e, t, n) {
|
|
|
118
108
|
}
|
|
119
109
|
}] : [], ...i("ceph-containers") ? [{
|
|
120
110
|
service: "ceph-containers",
|
|
121
|
-
label:
|
|
111
|
+
label: D._({ id: "KhNDX4" }),
|
|
122
112
|
navigate: (t) => t({
|
|
123
113
|
to: "/projects/$projectId/storage/$provider/$storageType",
|
|
124
114
|
params: {
|
|
@@ -134,7 +124,7 @@ function A(e, t, n) {
|
|
|
134
124
|
}
|
|
135
125
|
}] : []], c = (r.pca?.["clavis-beta"] || r.pca?.["clavis-dev"]) && i("pca") ? [{
|
|
136
126
|
service: "pca",
|
|
137
|
-
label:
|
|
127
|
+
label: D._({ id: "miy5mb" }),
|
|
138
128
|
navigate: (t) => t({
|
|
139
129
|
to: "/projects/$projectId/services/pca",
|
|
140
130
|
params: { projectId: e }
|
|
@@ -144,100 +134,100 @@ function A(e, t, n) {
|
|
|
144
134
|
return [
|
|
145
135
|
{
|
|
146
136
|
section: "compute",
|
|
147
|
-
label:
|
|
137
|
+
label: D._({ id: "rp0Bd0" }),
|
|
148
138
|
services: a
|
|
149
139
|
},
|
|
150
140
|
{
|
|
151
141
|
section: "network",
|
|
152
|
-
label:
|
|
142
|
+
label: D._({ id: "OR475H" }),
|
|
153
143
|
services: o
|
|
154
144
|
},
|
|
155
145
|
{
|
|
156
146
|
section: "storage",
|
|
157
|
-
label:
|
|
147
|
+
label: D._({ id: "BrrIs8" }),
|
|
158
148
|
services: s
|
|
159
149
|
},
|
|
160
150
|
{
|
|
161
151
|
section: "services",
|
|
162
|
-
label:
|
|
152
|
+
label: D._({ id: "MILoeL" }),
|
|
163
153
|
services: c
|
|
164
154
|
}
|
|
165
155
|
].filter((e) => e.services.length > 0);
|
|
166
156
|
}
|
|
167
157
|
//#endregion
|
|
168
158
|
//#region src/client/components/ProjectView/ProjectInfoBox.tsx
|
|
169
|
-
function
|
|
170
|
-
let { i18n:
|
|
171
|
-
return /*#__PURE__*/ h(
|
|
159
|
+
function A({ projectInfo: t }) {
|
|
160
|
+
let { i18n: n, _: r } = E(), i = C(), a = S(), { projectId: s } = w({ strict: !1 });
|
|
161
|
+
return /*#__PURE__*/ h(o, {
|
|
172
162
|
className: "relative z-1 mt-8 mb-4",
|
|
173
163
|
children: v(() => {
|
|
174
|
-
let
|
|
175
|
-
Compute:
|
|
176
|
-
Network:
|
|
177
|
-
Storage:
|
|
178
|
-
Services:
|
|
179
|
-
Images:
|
|
180
|
-
Flavors:
|
|
181
|
-
"Security Groups":
|
|
182
|
-
"Floating IPs":
|
|
183
|
-
"PCA (Clavis)":
|
|
184
|
-
},
|
|
185
|
-
|
|
164
|
+
let e = {
|
|
165
|
+
Compute: n._({ id: "rp0Bd0" }),
|
|
166
|
+
Network: n._({ id: "OR475H" }),
|
|
167
|
+
Storage: n._({ id: "BrrIs8" }),
|
|
168
|
+
Services: n._({ id: "MILoeL" }),
|
|
169
|
+
Images: n._({ id: "an5hVd" }),
|
|
170
|
+
Flavors: n._({ id: "neiJm0" }),
|
|
171
|
+
"Security Groups": n._({ id: "4opp4r" }),
|
|
172
|
+
"Floating IPs": n._({ id: "u77/s4" }),
|
|
173
|
+
"PCA (Clavis)": n._({ id: "miy5mb" })
|
|
174
|
+
}, r = (e) => e === "swift" ? n._({ id: "+OEi73" }) : e === "ceph" ? n._({ id: "KhNDX4" }) : n._({ id: "BrrIs8" }), o = [];
|
|
175
|
+
o.push({
|
|
186
176
|
icon: "home",
|
|
187
|
-
label:
|
|
188
|
-
onClick: () =>
|
|
189
|
-
}),
|
|
190
|
-
let c =
|
|
191
|
-
if (!l || !u) return
|
|
192
|
-
label:
|
|
177
|
+
label: n._({ id: "i0qMbr" }),
|
|
178
|
+
onClick: () => i({ to: "/projects" })
|
|
179
|
+
}), t.domain?.name && o.push({ label: t.domain.name });
|
|
180
|
+
let c = a.filter((e) => e.routeId !== "/_auth/projects/$projectId" && e.routeId.startsWith("/_auth/projects/$projectId")), l = c[c.length - 1], u = l && p(l.staticData) ? l.staticData : void 0;
|
|
181
|
+
if (!l || !u) return o.push({
|
|
182
|
+
label: t.name,
|
|
193
183
|
active: !0
|
|
194
|
-
}),
|
|
195
|
-
|
|
196
|
-
label:
|
|
197
|
-
onClick: () =>
|
|
184
|
+
}), o;
|
|
185
|
+
o.push({
|
|
186
|
+
label: t.name,
|
|
187
|
+
onClick: () => i({
|
|
198
188
|
to: "/projects/$projectId",
|
|
199
189
|
params: { projectId: s }
|
|
200
190
|
})
|
|
201
191
|
});
|
|
202
192
|
let d = l.params;
|
|
203
193
|
if (u.sectionCrumb?.to) {
|
|
204
|
-
let { labelKey:
|
|
205
|
-
|
|
206
|
-
label:
|
|
207
|
-
onClick: () =>
|
|
208
|
-
to:
|
|
194
|
+
let { labelKey: t, to: n } = u.sectionCrumb, r = t ? e[t] : void 0;
|
|
195
|
+
o.push({
|
|
196
|
+
label: r,
|
|
197
|
+
onClick: () => i({
|
|
198
|
+
to: n,
|
|
209
199
|
params: d
|
|
210
200
|
})
|
|
211
201
|
});
|
|
212
202
|
}
|
|
213
203
|
if (u.crumb) {
|
|
214
|
-
let { labelKey:
|
|
204
|
+
let { labelKey: t, to: n, useParamAsLabel: a } = u.crumb, s = a ? r(d[a]) : t ? e[t] : void 0;
|
|
215
205
|
if (u.isDetail) {
|
|
216
|
-
if (
|
|
206
|
+
if (o.push({
|
|
217
207
|
label: s,
|
|
218
|
-
onClick: () =>
|
|
219
|
-
to:
|
|
208
|
+
onClick: () => i({
|
|
209
|
+
to: n,
|
|
220
210
|
params: d
|
|
221
211
|
})
|
|
222
212
|
}), u.intermediateCrumb) {
|
|
223
|
-
let { to: e, useParamAsLabel: t, useParentTitleAsLabel: n } = u.intermediateCrumb,
|
|
224
|
-
|
|
225
|
-
label:
|
|
226
|
-
onClick: () =>
|
|
213
|
+
let { to: e, useParamAsLabel: t, useParentTitleAsLabel: n } = u.intermediateCrumb, r = c[c.length - 2]?.meta?.find((e) => e != null && "title" in e)?.title, a = n ? r ?? (t ? d[t] : void 0) : t ? d[t] : void 0;
|
|
214
|
+
o.push(e ? {
|
|
215
|
+
label: a,
|
|
216
|
+
onClick: () => i({
|
|
227
217
|
to: e,
|
|
228
218
|
params: d
|
|
229
219
|
})
|
|
230
|
-
} : { label:
|
|
220
|
+
} : { label: a });
|
|
231
221
|
}
|
|
232
222
|
let e = l.meta?.find((e) => e != null && "title" in e)?.title;
|
|
233
|
-
e &&
|
|
223
|
+
e && o.push({
|
|
234
224
|
label: e,
|
|
235
225
|
active: !0
|
|
236
226
|
});
|
|
237
|
-
} else
|
|
227
|
+
} else o.push(n ? {
|
|
238
228
|
label: s,
|
|
239
|
-
onClick: () =>
|
|
240
|
-
to:
|
|
229
|
+
onClick: () => i({
|
|
230
|
+
to: n,
|
|
241
231
|
params: d
|
|
242
232
|
})
|
|
243
233
|
} : {
|
|
@@ -245,35 +235,39 @@ function j({ projectInfo: e }) {
|
|
|
245
235
|
active: !0
|
|
246
236
|
});
|
|
247
237
|
}
|
|
248
|
-
return
|
|
238
|
+
return o;
|
|
249
239
|
}, [
|
|
250
|
-
|
|
251
|
-
|
|
240
|
+
a,
|
|
241
|
+
t,
|
|
252
242
|
s,
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
]).map((
|
|
256
|
-
label:
|
|
257
|
-
icon:
|
|
258
|
-
onClick:
|
|
259
|
-
active:
|
|
260
|
-
},
|
|
243
|
+
i,
|
|
244
|
+
r
|
|
245
|
+
]).map((t, n) => /*#__PURE__*/ h(e, {
|
|
246
|
+
label: t.label,
|
|
247
|
+
icon: t.icon,
|
|
248
|
+
onClick: t.onClick,
|
|
249
|
+
active: t.active
|
|
250
|
+
}, n))
|
|
261
251
|
});
|
|
262
252
|
}
|
|
263
253
|
//#endregion
|
|
264
254
|
//#region src/client/routes/_auth/projects/$projectId.tsx?tsr-split=component
|
|
265
|
-
function
|
|
266
|
-
let { availableServices: e, projectId: t, crumbProject: i, crumbDomain:
|
|
255
|
+
function j() {
|
|
256
|
+
let { availableServices: e, projectId: t, crumbProject: i, crumbDomain: o } = x({ from: d.id }), { enabledServices: s } = T({ strict: !1 });
|
|
267
257
|
return /*#__PURE__*/ h(r, {
|
|
268
258
|
embedded: !0,
|
|
269
|
-
sideNavigation: /*#__PURE__*/ h(
|
|
270
|
-
sections:
|
|
259
|
+
sideNavigation: /*#__PURE__*/ h(O, {
|
|
260
|
+
sections: v(() => k(t, e, s), [
|
|
261
|
+
t,
|
|
262
|
+
e,
|
|
263
|
+
s
|
|
264
|
+
]),
|
|
271
265
|
projectId: t,
|
|
272
266
|
projectName: i?.name || t,
|
|
273
|
-
domainName:
|
|
267
|
+
domainName: o?.name
|
|
274
268
|
}),
|
|
275
269
|
className: "h-min-screen",
|
|
276
|
-
children: /*#__PURE__*/ h(n, { children: /*#__PURE__*/ h(
|
|
270
|
+
children: /*#__PURE__*/ h(n, { children: /*#__PURE__*/ h(a, {
|
|
277
271
|
direction: "vertical",
|
|
278
272
|
distribution: "start",
|
|
279
273
|
alignment: "stretch",
|
|
@@ -281,16 +275,16 @@ function M() {
|
|
|
281
275
|
gap: "6",
|
|
282
276
|
children: /*#__PURE__*/ g("div", {
|
|
283
277
|
className: "min-w-0 flex-1",
|
|
284
|
-
children: [/*#__PURE__*/ h(
|
|
278
|
+
children: [/*#__PURE__*/ h(A, { projectInfo: {
|
|
285
279
|
id: t,
|
|
286
280
|
name: i?.name || t,
|
|
287
281
|
domain: i?.domain
|
|
288
|
-
} }), /*#__PURE__*/ h(
|
|
282
|
+
} }), /*#__PURE__*/ h(b, {})]
|
|
289
283
|
})
|
|
290
284
|
}) })
|
|
291
285
|
});
|
|
292
286
|
}
|
|
293
287
|
//#endregion
|
|
294
|
-
export {
|
|
288
|
+
export { j as component };
|
|
295
289
|
|
|
296
|
-
//# sourceMappingURL=_projectId-
|
|
290
|
+
//# sourceMappingURL=_projectId-DRr9rLST.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_projectId-DRr9rLST.mjs","names":["useNavigate","useMatches","useParams","useRouteContext","useState","useEffect","SideNavigation","SideNavigationList","SideNavigationGroup","SideNavigationItem","Divider","isRouteInfo","Slot","SideNavBar","projectId","projectName","domainName","sections","navigate","matches","provider","strict","slots","navBadge","service","serviceBadge","component","useShadowDOM","currentService","activeMatch","reverse","find","m","staticData","activeRouteInfo","undefined","activeSection","section","activeService","forceOpenCounter","setForceOpenCounter","Object","fromEntries","map","s","prev","ariaLabel","onClick","to","params","label","p","className","spacing","services","open","item","isStorageContainers","isSelected","span","selected","sideNavBanner","getServiceIndex","buildNavSections","projectId","availableServices","enabledServices","serviceIndex","isEnabled","service","includes","computeServices","label","t","navigate","nav","to","params","networkServices","storageServices","provider","storageType","pcaServices","clavisServices","section","services","filter","s","length","Breadcrumb","BreadcrumbItem","useMatches","useNavigate","useParams","useMemo","isRouteInfo","ProjectInfoBox","projectInfo","useLingui","navigate","matches","projectId","strict","breadcrumbs","crumbLabels","Compute","t","Network","Storage","Services","Images","Flavors","resolveProviderLabel","provider","items","push","icon","label","onClick","to","domain","name","projectMatches","filter","m","routeId","startsWith","deepest","length","info","staticData","undefined","active","params","sectionCrumb","labelKey","crumb","useParamAsLabel","resolvedLabel","isDetail","intermediateCrumb","iTo","iParam","useParentTitleAsLabel","parentMatch","parentTitle","meta","find","title","iLabel","className","map","item","index","Outlet","useLoaderData","useRouteContext","AppShell","Container","Stack","SideNavBar","buildNavSections","ProjectInfoBox","useMemo","Route","RouteComponent","availableServices","projectId","crumbProject","crumbDomain","from","id","enabledServices","strict","sections","name","domain","component"],"sources":["../../src/client/routes/_auth/projects/-components/SideNavBar.tsx","../../src/client/routes/_auth/projects/-components/buildNavSections.ts","../../src/client/components/ProjectView/ProjectInfoBox.tsx","../../src/client/routes/_auth/projects/$projectId.tsx?tsr-split=component"],"sourcesContent":["import { useNavigate, useMatches, useParams, useRouteContext } from \"@tanstack/react-router\"\nimport { useState, useEffect } from \"react\"\nimport {\n SideNavigation,\n SideNavigationList,\n SideNavigationGroup,\n SideNavigationItem,\n Divider,\n} from \"@cloudoperators/juno-ui-components/index\"\nimport { isRouteInfo } from \"@/client/routes/routeInfo\"\nimport { Slot } from \"@/client/components/Slot\"\nimport type { NavSection } from \"./buildNavSections\"\n\ninterface SideNavBarProps {\n projectId: string\n projectName: string\n domainName?: string\n sections: NavSection[]\n}\n\nexport const SideNavBar = ({ projectId, projectName, domainName, sections }: SideNavBarProps) => {\n const navigate = useNavigate()\n const matches = useMatches()\n const { provider } = useParams({ strict: false }) as { provider?: string }\n const { slots } = useRouteContext({ strict: false })\n\n const navBadge = (service: string) => {\n if (!slots?.serviceBadge) return null\n return <Slot component={slots.serviceBadge} useShadowDOM={false} currentService={service} />\n }\n\n // Read active section/service from the deepest match that has valid RouteInfo staticData\n const activeMatch = [...matches].reverse().find((m) => isRouteInfo(m.staticData))\n const activeRouteInfo = activeMatch && isRouteInfo(activeMatch.staticData) ? activeMatch.staticData : undefined\n const activeSection = activeRouteInfo?.section ?? null\n const activeService = activeRouteInfo?.service ?? null\n\n // Track which sections should be forced open by incrementing a counter\n // This forces a remount of SideNavigationGroup since it doesn't expose onToggle\n const [forceOpenCounter, setForceOpenCounter] = useState<Record<string, number>>(() =>\n Object.fromEntries(sections.map((s) => [s.section, 0]))\n )\n\n // When navigating to a section, force it to expand by remounting\n useEffect(() => {\n if (activeSection) {\n setForceOpenCounter((prev) => ({ ...prev, [activeSection]: (prev[activeSection] || 0) + 1 }))\n }\n }, [activeSection])\n\n return (\n <SideNavigation ariaLabel=\"Project Side Navigation\">\n <>\n <SideNavigationList>\n <>\n <SideNavigationItem\n onClick={() => navigate({ to: \"/projects/$projectId\", params: { projectId } })}\n label={\n <>\n {domainName && <p className=\"text-theme-light text-xs leading-4 font-bold\">{domainName} /</p>}\n <p className=\"leading-5 font-normal\">{projectName}</p>\n </>\n }\n />\n <Divider spacing=\"1\" />\n {sections.map(({ section, label, services }) => (\n <SideNavigationGroup key={`${section}-${forceOpenCounter[section]}`} label={label} open={true}>\n {services.map((item) => {\n const isStorageContainers = activeSection === \"storage\" && activeService === \"containers\"\n const isSelected =\n activeSection === section &&\n (isStorageContainers ? item.params.provider === provider : activeService === item.service)\n\n return (\n <SideNavigationItem\n key={item.service}\n onClick={() => item.navigate(navigate)}\n label={\n <span className=\"flex items-start gap-2\">\n {item.label}\n {navBadge(item.service)}\n </span>\n }\n selected={isSelected}\n />\n )\n })}\n </SideNavigationGroup>\n ))}\n </>\n </SideNavigationList>\n {slots?.sideNavBanner && <Slot component={slots.sideNavBanner} />}\n </>\n </SideNavigation>\n )\n}\n","import { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport { t } from \"@lingui/core/macro\"\nimport type { NavigateFn } from \"@tanstack/react-router\"\n\nexport type NavItem = {\n service: string\n label: string\n navigate: (navigateFn: NavigateFn) => void\n params: Record<string, string>\n}\n\nexport type NavSection = {\n section: string\n label: string\n services: NavItem[]\n}\n\nexport function buildNavSections(\n projectId: string,\n availableServices: { type: string; name: string }[],\n enabledServices?: string[]\n): NavSection[] {\n const serviceIndex = getServiceIndex(availableServices)\n const isEnabled = (service: string) => !enabledServices || enabledServices.includes(service)\n\n const computeServices: NavItem[] = [\n ...(serviceIndex[\"image\"]?.[\"glance\"] && isEnabled(\"images\")\n ? [\n {\n service: \"images\",\n label: t`Images`,\n navigate: (nav: NavigateFn) => nav({ to: \"/projects/$projectId/compute/images\", params: { projectId } }),\n params: { projectId },\n },\n ]\n : []),\n ...(serviceIndex?.[\"compute\"]?.[\"nova\"] && isEnabled(\"flavors\")\n ? [\n {\n service: \"flavors\",\n label: t`Flavors`,\n navigate: (nav: NavigateFn) => nav({ to: \"/projects/$projectId/compute/flavors\", params: { projectId } }),\n params: { projectId },\n },\n ]\n : []),\n ]\n\n const networkServices: NavItem[] = serviceIndex[\"network\"]\n ? [\n ...(isEnabled(\"securitygroups\")\n ? [\n {\n service: \"securitygroups\",\n label: t`Security Groups`,\n navigate: (nav: NavigateFn) =>\n nav({ to: \"/projects/$projectId/network/securitygroups\", params: { projectId } }),\n params: { projectId },\n },\n ]\n : []),\n ...(isEnabled(\"floatingips\")\n ? [\n {\n service: \"floatingips\",\n label: t`Floating IPs`,\n navigate: (nav: NavigateFn) =>\n nav({ to: \"/projects/$projectId/network/floatingips\", params: { projectId } }),\n params: { projectId },\n },\n ]\n : []),\n ]\n : []\n\n const storageServices: NavItem[] = [\n ...(serviceIndex?.[\"object-store\"]?.[\"swift\"] && isEnabled(\"containers\")\n ? [\n {\n service: \"containers\",\n label: t`Object Storage (Swift)`,\n navigate: (nav: NavigateFn) =>\n nav({\n to: \"/projects/$projectId/storage/$provider/$storageType\",\n params: { projectId, provider: \"swift\", storageType: \"containers\" },\n }),\n params: { projectId, provider: \"swift\", storageType: \"containers\" },\n },\n ]\n : []),\n ...(isEnabled(\"ceph-containers\")\n ? [\n {\n service: \"ceph-containers\",\n label: t`Object Storage (Ceph)`,\n navigate: (nav: NavigateFn) =>\n nav({\n to: \"/projects/$projectId/storage/$provider/$storageType\",\n params: { projectId, provider: \"ceph\", storageType: \"buckets\" },\n }),\n params: { projectId, provider: \"ceph\", storageType: \"buckets\" },\n },\n ]\n : []),\n ]\n\n // temporary as clavis is not fully GA, after GA replace with [\"pca\"]?.[\"clavis\"]\n const pcaServices = serviceIndex[\"pca\"]?.[\"clavis-beta\"] || serviceIndex[\"pca\"]?.[\"clavis-dev\"]\n const clavisServices: NavItem[] =\n pcaServices && isEnabled(\"pca\")\n ? [\n {\n service: \"pca\",\n label: t`PCA (Clavis)`,\n navigate: (nav: NavigateFn) => nav({ to: \"/projects/$projectId/services/pca\", params: { projectId } }),\n params: { projectId },\n },\n ]\n : []\n\n return [\n { section: \"compute\", label: t`Compute`, services: computeServices },\n { section: \"network\", label: t`Network`, services: networkServices },\n { section: \"storage\", label: t`Storage`, services: storageServices },\n { section: \"services\", label: t`Services`, services: clavisServices },\n ].filter((s) => s.services.length > 0)\n}\n","import { Breadcrumb, BreadcrumbItem, KnownIcons } from \"@cloudoperators/juno-ui-components\"\nimport { useMatches, useNavigate, useParams } from \"@tanstack/react-router\"\nimport { useMemo } from \"react\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { isRouteInfo, CrumbLabelKey } from \"@/client/routes/routeInfo\"\n\ninterface ProjectInfoBoxProps {\n projectInfo: {\n id: string\n name: string\n description?: string\n domain?: {\n name?: string\n }\n }\n}\n\nexport function ProjectInfoBox({ projectInfo }: ProjectInfoBoxProps) {\n const { t } = useLingui()\n const navigate = useNavigate()\n const matches = useMatches()\n const { projectId } = useParams({ strict: false }) as { projectId: string }\n\n const breadcrumbs = useMemo(() => {\n const crumbLabels: Record<CrumbLabelKey, string> = {\n Compute: t`Compute`,\n Network: t`Network`,\n Storage: t`Storage`,\n Services: t`Services`,\n Images: t`Images`,\n Flavors: t`Flavors`,\n \"Security Groups\": t`Security Groups`,\n \"Floating IPs\": t`Floating IPs`,\n \"PCA (Clavis)\": t`PCA (Clavis)`,\n }\n\n const resolveProviderLabel = (provider: string | undefined) => {\n if (provider === \"swift\") return t`Object Storage (Swift)`\n if (provider === \"ceph\") return t`Object Storage (Ceph)`\n return t`Storage`\n }\n\n const items: Array<{ label?: string; icon?: KnownIcons; onClick?: () => void; active?: boolean }> = []\n\n items.push({ icon: \"home\", label: t`Home`, onClick: () => navigate({ to: \"/projects\" }) })\n\n if (projectInfo.domain?.name) {\n items.push({ label: projectInfo.domain.name })\n }\n\n const projectMatches = matches.filter(\n (m) => m.routeId !== \"/_auth/projects/$projectId\" && m.routeId.startsWith(\"/_auth/projects/$projectId\")\n )\n const deepest = projectMatches[projectMatches.length - 1]\n\n const info = deepest ? (isRouteInfo(deepest.staticData) ? deepest.staticData : undefined) : undefined\n\n if (!deepest || !info) {\n items.push({ label: projectInfo.name, active: true })\n return items\n }\n\n items.push({\n label: projectInfo.name,\n onClick: () => navigate({ to: \"/projects/$projectId\", params: { projectId } }),\n })\n\n const params = deepest.params as Record<string, string>\n\n if (info.sectionCrumb?.to) {\n const { labelKey, to } = info.sectionCrumb\n const label = labelKey ? crumbLabels[labelKey] : undefined\n items.push({ label, onClick: () => navigate({ to: to as never, params: params as never }) })\n }\n\n if (info.crumb) {\n const { labelKey, to, useParamAsLabel } = info.crumb\n const resolvedLabel = useParamAsLabel\n ? resolveProviderLabel(params[useParamAsLabel])\n : labelKey\n ? crumbLabels[labelKey]\n : undefined\n\n if (info.isDetail) {\n items.push({ label: resolvedLabel, onClick: () => navigate({ to: to as never, params: params as never }) })\n\n if (info.intermediateCrumb) {\n const { to: iTo, useParamAsLabel: iParam, useParentTitleAsLabel } = info.intermediateCrumb\n const parentMatch = projectMatches[projectMatches.length - 2]\n const parentTitle = parentMatch?.meta?.find((m) => m != null && \"title\" in m)?.title as string | undefined\n const iLabel = useParentTitleAsLabel\n ? (parentTitle ?? (iParam ? params[iParam] : undefined))\n : iParam\n ? params[iParam]\n : undefined\n items.push(\n iTo\n ? { label: iLabel, onClick: () => navigate({ to: iTo as never, params: params as never }) }\n : { label: iLabel }\n )\n }\n\n const title = deepest.meta?.find((m) => m != null && \"title\" in m)?.title as string | undefined\n if (title) items.push({ label: title, active: true })\n } else {\n items.push(\n to\n ? { label: resolvedLabel, onClick: () => navigate({ to: to as never, params: params as never }) }\n : { label: resolvedLabel, active: true }\n )\n }\n }\n\n return items\n }, [matches, projectInfo, projectId, navigate, t])\n\n return (\n <Breadcrumb className=\"relative z-1 mt-8 mb-4\">\n {breadcrumbs.map((item, index) => (\n <BreadcrumbItem key={index} label={item.label} icon={item.icon} onClick={item.onClick} active={item.active} />\n ))}\n </Breadcrumb>\n )\n}\n","import { createFileRoute, Outlet, useLoaderData, useRouteContext } from \"@tanstack/react-router\"\nimport { AppShell, Container, Stack } from \"@cloudoperators/juno-ui-components\"\nimport { SideNavBar } from \"@/client/routes/_auth/projects/-components/SideNavBar\"\nimport { buildNavSections } from \"@/client/routes/_auth/projects/-components/buildNavSections\"\nimport { ProjectInfoBox } from \"@/client/components/ProjectView/ProjectInfoBox\"\nimport { RouteError } from \"@/client/components/Error/RouteError\"\nimport { useMemo } from \"react\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId\")({\n component: RouteComponent,\n errorComponent: ({ error }) => {\n return <RouteError error={error} />\n },\n loader: async (options) => {\n const { context, params } = options\n const data = await context.trpcClient?.auth.setCurrentScope.mutate({\n type: \"project\",\n projectId: params.projectId || \"\",\n })\n\n const [availableServices, projects] = await Promise.all([\n context.trpcClient?.auth.getAvailableServices.query(),\n context.trpcClient?.project.getAuthProjects.query().catch(() => null),\n ])\n\n const accountId = data?.domain?.id || \"\"\n const description = projects?.find((p) => p.id === params.projectId)?.description ?? null\n\n return {\n trpcClient: context.trpcClient,\n crumbDomain: { path: `/projects`, name: data?.domain?.name },\n crumbProject: data?.project,\n availableServices,\n accountId,\n projectId: params.projectId,\n description,\n }\n },\n})\n\nfunction RouteComponent() {\n const { availableServices, projectId, crumbProject, crumbDomain } = useLoaderData({ from: Route.id })\n const { enabledServices } = useRouteContext({ strict: false })\n\n const sections = useMemo(\n () => buildNavSections(projectId, availableServices!, enabledServices),\n [projectId, availableServices, enabledServices]\n )\n\n return (\n <AppShell\n embedded\n sideNavigation={\n <SideNavBar\n sections={sections}\n projectId={projectId}\n projectName={crumbProject?.name || projectId}\n domainName={crumbDomain?.name}\n />\n }\n className=\"h-min-screen\"\n >\n <Container>\n <Stack direction=\"vertical\" distribution=\"start\" alignment=\"stretch\" className=\"xl:flex-row\" gap=\"6\">\n {/* Main content area */}\n <div className=\"min-w-0 flex-1\">\n <ProjectInfoBox\n projectInfo={{\n id: projectId,\n name: crumbProject?.name || projectId,\n domain: crumbProject?.domain,\n }}\n />\n <Outlet />\n </div>\n </Stack>\n </Container>\n </AppShell>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as e } from "./RouteError-
|
|
1
|
+
import { t as e } from "./RouteError-BebIhFpQ.mjs";
|
|
2
2
|
import { jsx as t } from "react/jsx-runtime";
|
|
3
3
|
//#region src/client/routes/_auth/projects/$projectId.tsx?tsr-split=errorComponent
|
|
4
4
|
var n = ({ error: n }) => /*#__PURE__*/ t(e, { error: n });
|
|
5
5
|
//#endregion
|
|
6
6
|
export { n as errorComponent };
|
|
7
7
|
|
|
8
|
-
//# sourceMappingURL=_projectId-
|
|
8
|
+
//# sourceMappingURL=_projectId-DU8qRiZk.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_projectId-DU8qRiZk.mjs","names":["RouteError","Route","SplitErrorComponent","error","errorComponent"],"sources":["../../src/client/routes/_auth/projects/$projectId.tsx?tsr-split=errorComponent"],"sourcesContent":["import { createFileRoute, Outlet, useLoaderData, useRouteContext } from \"@tanstack/react-router\"\nimport { AppShell, Container, Stack } from \"@cloudoperators/juno-ui-components\"\nimport { SideNavBar } from \"@/client/routes/_auth/projects/-components/SideNavBar\"\nimport { buildNavSections } from \"@/client/routes/_auth/projects/-components/buildNavSections\"\nimport { ProjectInfoBox } from \"@/client/components/ProjectView/ProjectInfoBox\"\nimport { RouteError } from \"@/client/components/Error/RouteError\"\nimport { useMemo } from \"react\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId\")({\n component: RouteComponent,\n errorComponent: ({ error }) => {\n return <RouteError error={error} />\n },\n loader: async (options) => {\n const { context, params } = options\n const data = await context.trpcClient?.auth.setCurrentScope.mutate({\n type: \"project\",\n projectId: params.projectId || \"\",\n })\n\n const [availableServices, projects] = await Promise.all([\n context.trpcClient?.auth.getAvailableServices.query(),\n context.trpcClient?.project.getAuthProjects.query().catch(() => null),\n ])\n\n const accountId = data?.domain?.id || \"\"\n const description = projects?.find((p) => p.id === params.projectId)?.description ?? null\n\n return {\n trpcClient: context.trpcClient,\n crumbDomain: { path: `/projects`, name: data?.domain?.name },\n crumbProject: data?.project,\n availableServices,\n accountId,\n projectId: params.projectId,\n description,\n }\n },\n})\n\nfunction RouteComponent() {\n const { availableServices, projectId, crumbProject, crumbDomain } = useLoaderData({ from: Route.id })\n const { enabledServices } = useRouteContext({ strict: false })\n\n const sections = useMemo(\n () => buildNavSections(projectId, availableServices!, enabledServices),\n [projectId, availableServices, enabledServices]\n )\n\n return (\n <AppShell\n embedded\n sideNavigation={\n <SideNavBar\n sections={sections}\n projectId={projectId}\n projectName={crumbProject?.name || projectId}\n domainName={crumbDomain?.name}\n />\n }\n className=\"h-min-screen\"\n >\n <Container>\n <Stack direction=\"vertical\" distribution=\"start\" alignment=\"stretch\" className=\"xl:flex-row\" gap=\"6\">\n {/* Main content area */}\n <div className=\"min-w-0 flex-1\">\n <ProjectInfoBox\n projectInfo={{\n id: projectId,\n name: crumbProject?.name || projectId,\n domain: crumbProject?.domain,\n }}\n />\n <Outlet />\n </div>\n </Stack>\n </Container>\n </AppShell>\n )\n}\n"],"mappings":";;;AAKiE,IAAAE,KAK9C,EAAEC,eACV,gBAAC,GAAA,EAAkBA,SAAAA,CAAAA"}
|
|
@@ -19,7 +19,7 @@ var i = t("/_auth/projects/$projectId/network/securitygroups/$securityGroupId/")
|
|
|
19
19
|
return { sgTitle: n?.name || n?.id || null };
|
|
20
20
|
},
|
|
21
21
|
head: ({ loaderData: e }) => ({ meta: [{ title: e?.sgTitle ?? "Security Group" }] }),
|
|
22
|
-
component: n(() => import("./_securityGroupId-
|
|
22
|
+
component: n(() => import("./_securityGroupId-ClJiFh4R.mjs"), "component"),
|
|
23
23
|
beforeLoad: async ({ context: t, params: n }) => {
|
|
24
24
|
let { trpcClient: i } = t, a = e(await i?.auth.getAvailableServices.query() || []);
|
|
25
25
|
if (!a.network || !a.network.neutron) throw r({
|
|
@@ -31,4 +31,4 @@ var i = t("/_auth/projects/$projectId/network/securitygroups/$securityGroupId/")
|
|
|
31
31
|
//#endregion
|
|
32
32
|
export { i as t };
|
|
33
33
|
|
|
34
|
-
//# sourceMappingURL=_securityGroupId-
|
|
34
|
+
//# sourceMappingURL=_securityGroupId-Cj9IotMJ.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_securityGroupId-
|
|
1
|
+
{"version":3,"file":"_securityGroupId-Cj9IotMJ.mjs","names":["createFileRoute","redirect","getServiceIndex","Route","staticData","section","service","isDetail","sectionCrumb","labelKey","crumb","to","RouteInfo","loader","context","params","sg","trpcClient","network","securityGroup","getById","query","project_id","projectId","securityGroupId","sgTitle","name","id","head","loaderData","meta","title","component","lazyRouteComponent","$$splitComponentImporter","beforeLoad","availableServices","auth","getAvailableServices","serviceIndex"],"sources":["../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/index.tsx"],"sourcesContent":["import {\n Breadcrumb,\n BreadcrumbItem,\n Button,\n ContentHeading,\n Stack,\n Spinner,\n} from \"@cloudoperators/juno-ui-components/index\"\nimport { createFileRoute, redirect, useNavigate } from \"@tanstack/react-router\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { useMemo } from \"react\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport { useProjectId } from \"@/client/hooks\"\nimport { SecurityGroupDetailsView } from \"./-components/SecurityGroupDetailsView\"\nimport { EditSecurityGroupModal } from \"../-components/-modals/EditSecurityGroupModal\"\nimport { useSecurityGroupDetails } from \"./-hooks/useSecurityGroupDetails\"\nimport { useListWithFiltering } from \"@/client/utils/useListWithFiltering\"\nimport { trpcReact } from \"@/client/trpcClient\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/network/securitygroups/$securityGroupId/\")({\n staticData: {\n section: \"network\",\n service: \"securitygroups\",\n isDetail: true,\n sectionCrumb: { labelKey: \"Network\" },\n crumb: { labelKey: \"Security Groups\", to: \"/projects/$projectId/network/securitygroups\" },\n } satisfies RouteInfo,\n loader: async ({ context, params }) => {\n const sg = await context.trpcClient?.network.securityGroup.getById.query({\n project_id: params.projectId,\n securityGroupId: params.securityGroupId,\n })\n return { sgTitle: sg?.name || sg?.id || null }\n },\n head: ({ loaderData }) => ({\n meta: [{ title: loaderData?.sgTitle ?? \"Security Group\" }],\n }),\n component: RouteComponent,\n beforeLoad: async ({ context, params }) => {\n const { trpcClient } = context\n\n const availableServices = (await trpcClient?.auth.getAvailableServices.query()) || []\n\n const serviceIndex = getServiceIndex(availableServices)\n\n // Redirect to the \"Projects Overview\" page if network service not available\n if (!serviceIndex[\"network\"]) {\n throw redirect({\n to: \"/projects/$projectId/network/securitygroups\",\n params: { projectId: params.projectId },\n })\n }\n\n if (!serviceIndex[\"network\"][\"neutron\"]) {\n // Redirect to the \"Network Services Overview\" page if the \"Neutron\" service is not available\n throw redirect({\n to: \"/projects/$projectId/network/securitygroups\",\n params: { projectId: params.projectId },\n })\n }\n },\n})\n\nfunction RouteComponent() {\n const { securityGroupId } = Route.useParams()\n const projectId = useProjectId()\n const navigate = useNavigate()\n const { t } = useLingui()\n\n // Rules filtering using the same pattern as List page\n const {\n searchTerm: rulesSearchTerm,\n sortSettings,\n filterSettings,\n handleSearchChange,\n handleSortChange,\n handleFilterChange,\n } = useListWithFiltering<\"direction\" | \"protocol\" | \"description\">({\n defaultSortKey: \"direction\",\n defaultSortDir: \"asc\",\n sortOptions: [\n { label: t`Direction`, value: \"direction\" },\n { label: t`Protocol`, value: \"protocol\" },\n { label: t`Description`, value: \"description\" },\n ],\n filterSettings: {\n filters: [\n {\n displayName: t`Direction`,\n filterName: \"direction\",\n values: [\"ingress\", \"egress\"],\n supportsMultiValue: false,\n },\n {\n displayName: t`Ethertype`,\n filterName: \"ethertype\",\n values: [\"IPv4\", \"IPv6\"],\n supportsMultiValue: false,\n },\n {\n displayName: t`Protocol`,\n filterName: \"protocol\",\n values: [\"tcp\", \"udp\", \"icmp\", \"ipv6-icmp\"],\n supportsMultiValue: false,\n },\n ],\n },\n })\n\n // Group filter controls for the hook\n const filterControls = {\n searchTerm: rulesSearchTerm,\n onSearchChange: handleSearchChange,\n sortSettings,\n onSortChange: handleSortChange,\n filterSettings,\n onFilterChange: handleFilterChange,\n }\n\n // Use custom hook for logic (now includes filtering/sorting)\n const {\n securityGroup,\n filteredAndSortedRules,\n isLoading,\n isError,\n error,\n isUpdating,\n updateError,\n isDeletingRule,\n deleteRuleError,\n isCreatingRule,\n createRuleError,\n editModalOpen,\n handleEdit,\n handleCloseEditModal,\n handleUpdate,\n handleDeleteRule,\n handleCreateRule,\n } = useSecurityGroupDetails({\n securityGroupId,\n filterControls,\n })\n\n // Fetch available security groups for the Add Rule dropdown\n const { data: securityGroups } = trpcReact.network.securityGroup.list.useQuery({ project_id: projectId })\n const availableSecurityGroups = useMemo(() => {\n return (securityGroups || [])\n .filter((sg) => sg.id !== securityGroupId) // Exclude current group\n .map((sg) => ({\n id: sg.id,\n name: sg.name || sg.id,\n }))\n }, [securityGroups, securityGroupId])\n\n const handleBack = () => {\n navigate({\n to: \"/projects/$projectId/network/securitygroups\",\n params: { projectId },\n })\n }\n\n // Handle loading state\n if (isLoading) {\n return (\n <Stack className=\"fixed inset-0\" distribution=\"center\" alignment=\"center\" direction=\"vertical\">\n <Spinner variant=\"primary\" size=\"large\" className=\"mb-2\" />\n <Trans>Loading Security Group Details...</Trans>\n </Stack>\n )\n }\n\n // Handle error state\n if (isError) {\n const errorMessage = error?.message || \"Unknown error\"\n\n return (\n <Stack className=\"fixed inset-0\" distribution=\"center\" alignment=\"center\" direction=\"vertical\" gap=\"5\">\n <p className=\"text-theme-error font-semibold\">\n <Trans>Error loading security group</Trans>\n </p>\n <p className=\"text-theme-highest\">{errorMessage}</p>\n <Button onClick={handleBack} variant=\"primary\">\n <Trans>Back to Security Groups</Trans>\n </Button>\n </Stack>\n )\n }\n\n // Handle no data state\n if (!securityGroup) {\n return (\n <Stack className=\"fixed inset-0\" distribution=\"center\" alignment=\"center\" direction=\"vertical\" gap=\"5\">\n <p className=\"text-theme-secondary\">\n <Trans>Security group not found</Trans>\n </p>\n <Button onClick={handleBack} variant=\"primary\">\n <Trans>Back to Security Groups</Trans>\n </Button>\n </Stack>\n )\n }\n\n // Render success state\n return (\n <Stack direction=\"vertical\">\n <ContentHeading>{securityGroup.name || securityGroup.id}</ContentHeading>\n <Breadcrumb className=\"my-6\">\n <BreadcrumbItem onClick={handleBack} label={t`Security Groups`} />\n <BreadcrumbItem active label={securityGroup.id} />\n </Breadcrumb>\n\n <SecurityGroupDetailsView\n securityGroup={securityGroup}\n filteredAndSortedRules={filteredAndSortedRules}\n onEdit={handleEdit}\n onDeleteRule={handleDeleteRule}\n isDeletingRule={isDeletingRule}\n deleteRuleError={deleteRuleError}\n filterControls={filterControls}\n onCreateRule={handleCreateRule}\n isCreatingRule={isCreatingRule}\n createRuleError={createRuleError}\n availableSecurityGroups={availableSecurityGroups}\n currentProjectId={projectId}\n />\n\n <EditSecurityGroupModal\n securityGroup={securityGroup}\n open={editModalOpen}\n onClose={handleCloseEditModal}\n onUpdate={handleUpdate}\n isLoading={isUpdating}\n error={updateError}\n />\n </Stack>\n )\n}\n"],"mappings":";;AAoBA,IAAaG,IAAQH,EAAgB,qEAAA,EAAuE;CAC1GI,YAAY;EACVC,SAAS;EACTC,SAAS;EACTC,UAAU;EACVC,cAAc,EAAEC,UAAU,UAAU;EACpCC,OAAO;GAAED,UAAU;GAAmBE,IAAI;EAA8C;CAC1F;CACAE,QAAQ,OAAO,EAAEC,YAASC,gBAAQ;EAChC,IAAMC,IAAK,MAAMF,EAAQG,YAAYC,QAAQC,cAAcC,QAAQC,MAAM;GACvEC,YAAYP,EAAOQ;GACnBC,iBAAiBT,EAAOS;EAC1B,CAAA;EACA,OAAO,EAAEC,SAAST,GAAIU,QAAQV,GAAIW,MAAM,KAAK;CAC/C;CACAC,OAAO,EAAEC,qBAAkB,EACzBC,MAAM,CAAC,EAAEC,OAAOF,GAAYJ,WAAW,iBAAiB,CAAA,EAC1D;CACAO,WAASC,mDAAA,WAAA;CACTE,YAAY,OAAO,EAAErB,YAASC,gBAAQ;EACpC,IAAM,EAAEE,kBAAeH,GAIjByB,IAAerC,EAFK,MAAOe,GAAYoB,KAAKC,qBAAqBjB,MAAAA,KAAY,CAAA,CAE9Ce;EAUrC,IAPI,CAACG,EAAa,WAOd,CAACA,EAAa,QAAW,SAE3B,MAAMtC,EAAS;GACbU,IAAI;GACJI,QAAQ,EAAEQ,WAAWR,EAAOQ,UAAU;EACxC,CAAA;CAEJ;AACF,CAAA"}
|