@cobaltcore-dev/aurora 2.0.0 → 2.1.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.
Files changed (115) hide show
  1. package/dist/client/ContentHeader-fKKZVu-o.mjs +116 -0
  2. package/dist/client/ContentHeader-fKKZVu-o.mjs.map +1 -0
  3. package/dist/client/{DeleteFlavorModal-C2MqUgGR.mjs → DeleteFlavorModal-Be2GFiB_.mjs} +3 -2
  4. package/dist/client/DeleteFlavorModal-Be2GFiB_.mjs.map +1 -0
  5. package/dist/client/{RouteIdLevelDefaultError-CSseJ1yG.mjs → RouteIdLevelDefaultError-DPF_x2tG.mjs} +9 -9
  6. package/dist/client/RouteIdLevelDefaultError-DPF_x2tG.mjs.map +1 -0
  7. package/dist/client/StorageNotFound-B-zVinVD.mjs +30 -0
  8. package/dist/client/StorageNotFound-B-zVinVD.mjs.map +1 -0
  9. package/dist/client/{_flavorId-DYv_StX22.mjs → _flavorId-0PioWpEp.mjs} +4 -4
  10. package/dist/client/_flavorId-0PioWpEp.mjs.map +1 -0
  11. package/dist/client/{_flavorId-YV3jCS5g.mjs → _flavorId-B7fp6Nk8.mjs} +3 -3
  12. package/dist/client/{_flavorId-YV3jCS5g.mjs.map → _flavorId-B7fp6Nk8.mjs.map} +1 -1
  13. package/dist/client/{_flavorId-CaA4-Pnf.mjs → _flavorId-CgueqKTs.mjs} +3 -3
  14. package/dist/client/{_flavorId-CaA4-Pnf.mjs.map → _flavorId-CgueqKTs.mjs.map} +1 -1
  15. package/dist/client/{_floatingIpId-Dpsc7GU4.mjs → _floatingIpId-B8r64AL9.mjs} +3 -3
  16. package/dist/client/{_floatingIpId-Dpsc7GU4.mjs.map → _floatingIpId-B8r64AL9.mjs.map} +1 -1
  17. package/dist/client/{_floatingIpId-BeYElanB.mjs → _floatingIpId-lEobpOER.mjs} +2 -2
  18. package/dist/client/{_floatingIpId-BeYElanB.mjs.map → _floatingIpId-lEobpOER.mjs.map} +1 -1
  19. package/dist/client/{_imageId-pBSS0YcC.mjs → _imageId-Ccv8PedW.mjs} +3 -3
  20. package/dist/client/{_imageId-pBSS0YcC.mjs.map → _imageId-Ccv8PedW.mjs.map} +1 -1
  21. package/dist/client/_imageId-CiqEQB_J.mjs +558 -0
  22. package/dist/client/{_imageId-mfKp3JHn.mjs.map → _imageId-CiqEQB_J.mjs.map} +1 -1
  23. package/dist/client/{_imageId-mpXUMCh_.mjs → _imageId-D9LR-02T.mjs} +3 -3
  24. package/dist/client/{_imageId-mpXUMCh_.mjs.map → _imageId-D9LR-02T.mjs.map} +1 -1
  25. package/dist/client/{_projectId-BnTBxKfp.mjs → _projectId-BDARsteX.mjs} +3 -3
  26. package/dist/client/{_projectId-BnTBxKfp.mjs.map → _projectId-BDARsteX.mjs.map} +1 -1
  27. package/dist/client/{_projectId-CVrdJ52s.mjs → _projectId-CtyAHqhH.mjs} +2 -2
  28. package/dist/client/{_projectId-CVrdJ52s.mjs.map → _projectId-CtyAHqhH.mjs.map} +1 -1
  29. package/dist/client/_projectId-D3VOH5lN.mjs +94 -0
  30. package/dist/client/_projectId-D3VOH5lN.mjs.map +1 -0
  31. package/dist/client/{_projectId-AjgJX6Gl.mjs → _projectId-ZBk6vka0.mjs} +83 -81
  32. package/dist/client/_projectId-ZBk6vka0.mjs.map +1 -0
  33. package/dist/client/{_securityGroupId-AO3wnH8g.mjs → _securityGroupId-BwgZnoiR.mjs} +2 -2
  34. package/dist/client/{_securityGroupId-AO3wnH8g.mjs.map → _securityGroupId-BwgZnoiR.mjs.map} +1 -1
  35. package/dist/client/{_securityGroupId-Bq0ZyG6z.mjs → _securityGroupId-Cz2NUHdB.mjs} +3 -3
  36. package/dist/client/{_securityGroupId-Bq0ZyG6z.mjs.map → _securityGroupId-Cz2NUHdB.mjs.map} +1 -1
  37. package/dist/client/{_storageType-CzZ4u9x_.mjs → _storageType-BNpP1A2N.mjs} +3 -2
  38. package/dist/client/_storageType-BNpP1A2N.mjs.map +1 -0
  39. package/dist/client/_storageType-BxSGKhAI.mjs +15 -0
  40. package/dist/client/_storageType-BxSGKhAI.mjs.map +1 -0
  41. package/dist/client/_storageType-DZYCmiLt.mjs +30 -0
  42. package/dist/client/_storageType-DZYCmiLt.mjs.map +1 -0
  43. package/dist/client/{_storageType-c-DAu8qr.mjs → _storageType-UqAMP-8d.mjs} +286 -285
  44. package/dist/client/_storageType-UqAMP-8d.mjs.map +1 -0
  45. package/dist/client/_storageType-u51_7OwJ.mjs +7 -0
  46. package/dist/client/_storageType-u51_7OwJ.mjs.map +1 -0
  47. package/dist/client/components/Errors/RouteIdLevelDefaultError.d.ts +2 -1
  48. package/dist/client/{flavors-ZudiAiTU.mjs → flavors-Ce3J-cFa.mjs} +2 -2
  49. package/dist/client/{flavors-ZudiAiTU.mjs.map → flavors-Ce3J-cFa.mjs.map} +1 -1
  50. package/dist/client/{flavors-Bgq3KZmx.mjs → flavors-D5ThLaXO.mjs} +84 -77
  51. package/dist/client/flavors-D5ThLaXO.mjs.map +1 -0
  52. package/dist/client/{floatingips-B1oLH8z6.mjs → floatingips-DXnRlLvV.mjs} +2 -2
  53. package/dist/client/{floatingips-B1oLH8z6.mjs.map → floatingips-DXnRlLvV.mjs.map} +1 -1
  54. package/dist/client/{floatingips-BtLg3yEQ.mjs → floatingips-HRbuLxiN.mjs} +3 -3
  55. package/dist/client/{floatingips-BtLg3yEQ.mjs.map → floatingips-HRbuLxiN.mjs.map} +1 -1
  56. package/dist/client/{floatingips-BeQEkVH8.mjs → floatingips-nN1kQmsu.mjs} +2 -2
  57. package/dist/client/{floatingips-BeQEkVH8.mjs.map → floatingips-nN1kQmsu.mjs.map} +1 -1
  58. package/dist/client/{images-CnTW3bpy.mjs → images-C8M3ysWR.mjs} +3 -3
  59. package/dist/client/{images-CnTW3bpy.mjs.map → images-C8M3ysWR.mjs.map} +1 -1
  60. package/dist/client/{images-DZHDYDQu.mjs → images-Cf5R28NR.mjs} +2 -2
  61. package/dist/client/{images-DZHDYDQu.mjs.map → images-Cf5R28NR.mjs.map} +1 -1
  62. package/dist/client/index.js +198 -197
  63. package/dist/client/index.js.map +1 -1
  64. package/dist/client/{objects-jYQBFzwg.mjs → objects-BudUAfWY.mjs} +4265 -4275
  65. package/dist/client/objects-BudUAfWY.mjs.map +1 -0
  66. package/dist/client/objects-Dc7sKUr8.mjs +67 -0
  67. package/dist/client/objects-Dc7sKUr8.mjs.map +1 -0
  68. package/dist/client/objects-Dw7oeTq2.mjs +80 -0
  69. package/dist/client/objects-Dw7oeTq2.mjs.map +1 -0
  70. package/dist/client/objects-_g7nGIn5.mjs +25 -0
  71. package/dist/client/objects-_g7nGIn5.mjs.map +1 -0
  72. package/dist/client/objects-eBxvY6_n.mjs +78 -0
  73. package/dist/client/objects-eBxvY6_n.mjs.map +1 -0
  74. package/dist/client/projects-yiK0HGSA.mjs.map +1 -1
  75. package/dist/client/{securitygroups-BRndk7wh.mjs → securitygroups-67fFxiwt.mjs} +2 -2
  76. package/dist/client/{securitygroups-BRndk7wh.mjs.map → securitygroups-67fFxiwt.mjs.map} +1 -1
  77. package/dist/client/{securitygroups--0PS2wbM.mjs → securitygroups-DXrfyuVF.mjs} +3 -3
  78. package/dist/client/{securitygroups--0PS2wbM.mjs.map → securitygroups-DXrfyuVF.mjs.map} +1 -1
  79. package/dist/client/{securitygroups-Cs2Op-tu.mjs → securitygroups-WLB1_IM6.mjs} +3 -3
  80. package/dist/client/{securitygroups-Cs2Op-tu.mjs.map → securitygroups-WLB1_IM6.mjs.map} +1 -1
  81. package/dist/client/{securitygroups-CdN4yAAw.mjs → securitygroups-o0IXZM6S.mjs} +2 -2
  82. package/dist/client/{securitygroups-CdN4yAAw.mjs.map → securitygroups-o0IXZM6S.mjs.map} +1 -1
  83. package/dist/client/serviceCatalog-B3lKWC9V.mjs +6 -0
  84. package/dist/client/serviceCatalog-B3lKWC9V.mjs.map +1 -0
  85. package/dist/client/storageProviders-CJ5rOh13.mjs +15 -0
  86. package/dist/client/storageProviders-CJ5rOh13.mjs.map +1 -0
  87. package/dist/client/trpcClient.d.ts +96 -3
  88. package/dist/client/utils/serviceCatalog.d.ts +9 -0
  89. package/dist/client/utils/storageProviders.d.ts +44 -0
  90. package/dist/server/index.d.ts +96 -3
  91. package/dist/server/index.js +1224 -387
  92. package/package.json +1 -1
  93. package/dist/client/ContentHeader-CPJbgYWn.mjs +0 -115
  94. package/dist/client/ContentHeader-CPJbgYWn.mjs.map +0 -1
  95. package/dist/client/DeleteFlavorModal-C2MqUgGR.mjs.map +0 -1
  96. package/dist/client/RouteIdLevelDefaultError-CSseJ1yG.mjs.map +0 -1
  97. package/dist/client/_flavorId-DYv_StX22.mjs.map +0 -1
  98. package/dist/client/_imageId-mfKp3JHn.mjs +0 -558
  99. package/dist/client/_projectId-AjgJX6Gl.mjs.map +0 -1
  100. package/dist/client/_projectId-DgciZslU.mjs +0 -92
  101. package/dist/client/_projectId-DgciZslU.mjs.map +0 -1
  102. package/dist/client/_storageType-BRWWJtow.mjs +0 -14
  103. package/dist/client/_storageType-BRWWJtow.mjs.map +0 -1
  104. package/dist/client/_storageType-CzZ4u9x_.mjs.map +0 -1
  105. package/dist/client/_storageType-c-DAu8qr.mjs.map +0 -1
  106. package/dist/client/_storageType-zeSZe--V.mjs +0 -7
  107. package/dist/client/_storageType-zeSZe--V.mjs.map +0 -1
  108. package/dist/client/flavors-Bgq3KZmx.mjs.map +0 -1
  109. package/dist/client/objects-25xsh4Ia.mjs +0 -66
  110. package/dist/client/objects-25xsh4Ia.mjs.map +0 -1
  111. package/dist/client/objects-KXY6dgwq.mjs +0 -82
  112. package/dist/client/objects-KXY6dgwq.mjs.map +0 -1
  113. package/dist/client/objects-QryuClU3.mjs +0 -82
  114. package/dist/client/objects-QryuClU3.mjs.map +0 -1
  115. package/dist/client/objects-jYQBFzwg.mjs.map +0 -1
@@ -1,558 +0,0 @@
1
- import { A as e, B as t, D as n, E as r, L as i, M as a, Q as o, at as s, c, g as l, i as u, n as d, ot as f, r as p, rt as m, s as h, x as g } from "./build-WuxXRAqf.mjs";
2
- import { a as _ } from "./trpcClient-D7gpR7YG.mjs";
3
- import { t as v } from "./_imageId-pBSS0YcC.mjs";
4
- import { n as y, t as ee } from "./ContentHeader-CPJbgYWn.mjs";
5
- import { t as te } from "./useSetBreadcrumb-tn7lBaQV.mjs";
6
- import { t as b } from "./RouteIdLevelDefaultError-CSseJ1yG.mjs";
7
- import { A as x, C as ne, D as re, E as ie, F as S, I as C, N as ae, O as oe, P as w, S as se, T as ce, _ as le, d as ue, f as de, g as fe, k as pe, p as me, u as he, w as ge } from "./ImageToastNotifications-BWfzOUMc.mjs";
8
- import { t as T } from "./TwoColumnDescriptionList-DKS42RKa.mjs";
9
- import { Fragment as E, jsx as D, jsxs as O } from "react/jsx-runtime";
10
- import k, { useState as A } from "react";
11
- import { useNavigate as j, useParams as _e, useSearch as ve } from "@tanstack/react-router";
12
- import { Trans as M, useLingui as N } from "@lingui/react";
13
- //#region src/client/routes/_auth/projects/$projectId/compute/images/-components/ImageDetailsView.tsx
14
- var P = ({ image: e, myMemberData: n, canUpdateMember: r, onStatusChange: i, isLoading: o }) => {
15
- let { i18n: s, _: c } = N(), l = n.status === S.PENDING, d = n.status === S.REJECTED, f = n.created_at ? new Date(n.created_at).toLocaleString() : s._({ id: "fj5byd" }), p = n.updated_at ? new Date(n.updated_at).toLocaleString() : s._({ id: "fj5byd" }), m = e.owner ?? "";
16
- return /*#__PURE__*/ O(t, { children: [
17
- l && /*#__PURE__*/ D("p", {
18
- className: "text-theme-highest font-semibold",
19
- children: /*#__PURE__*/ D(M, { id: "/EcdUM" })
20
- }),
21
- /*#__PURE__*/ D("p", { children: /*#__PURE__*/ D(M, {
22
- id: "Uwo8Xw",
23
- values: {
24
- ownerProject: m,
25
- sharedAt: f
26
- },
27
- components: { 0: /*#__PURE__*/ D("span", { className: "font-semibold" }) }
28
- }) }),
29
- /*#__PURE__*/ O("ul", { children: [
30
- /*#__PURE__*/ O("li", { children: [
31
- /*#__PURE__*/ D("span", {
32
- className: "font-semibold",
33
- children: /*#__PURE__*/ D(M, { id: "azXlY+" })
34
- }),
35
- " ",
36
- n.status
37
- ] }),
38
- /*#__PURE__*/ O("li", { children: [
39
- /*#__PURE__*/ D("span", {
40
- className: "font-semibold",
41
- children: /*#__PURE__*/ D(M, { id: "G6AP+o" })
42
- }),
43
- " ",
44
- f
45
- ] }),
46
- /*#__PURE__*/ O("li", { children: [
47
- /*#__PURE__*/ D("span", {
48
- className: "font-semibold",
49
- children: /*#__PURE__*/ D(M, { id: "pFg+7w" })
50
- }),
51
- " ",
52
- p
53
- ] })
54
- ] }),
55
- r && (l || d) && /*#__PURE__*/ O(a, { children: [/*#__PURE__*/ D(u, {
56
- onClick: () => i(S.ACCEPTED),
57
- disabled: o,
58
- children: /*#__PURE__*/ D(M, { id: "g3UF2V" })
59
- }), l && /*#__PURE__*/ D(u, {
60
- onClick: () => i(S.REJECTED),
61
- disabled: o,
62
- children: /*#__PURE__*/ D(M, { id: "1t/NnN" })
63
- })] })
64
- ] });
65
- }, F = ({ image: t }) => {
66
- let { i18n: n, _: r } = N(), i = [
67
- {
68
- label: n._({ id: "S0kLOH" }),
69
- value: /*#__PURE__*/ D(y, { text: t.id })
70
- },
71
- {
72
- label: n._({ id: "6YtxFj" }),
73
- value: t.name
74
- },
75
- {
76
- label: n._({ id: "uAQUqI" }),
77
- value: t.status
78
- },
79
- {
80
- label: n._({ id: "Cj2Gtd" }),
81
- value: /*#__PURE__*/ D(C, { size: t.size })
82
- },
83
- {
84
- label: n._({ id: "Cxgv2U" }),
85
- value: `${t.min_disk} GB`
86
- },
87
- {
88
- label: n._({ id: "B2Czeb" }),
89
- value: `${t.min_ram} MB`
90
- },
91
- {
92
- label: n._({ id: "NopYGU" }),
93
- value: /*#__PURE__*/ D("span", {
94
- className: "uppercase",
95
- children: t.disk_format
96
- })
97
- },
98
- {
99
- label: n._({ id: "6/xipy" }),
100
- value: /*#__PURE__*/ D("span", {
101
- className: "uppercase",
102
- children: t.container_format
103
- })
104
- },
105
- {
106
- label: n._({ id: "88kg0+" }),
107
- value: t.created_at ? new Date(t.created_at).toLocaleDateString() : n._({ id: "fj5byd" })
108
- },
109
- {
110
- label: n._({ id: "Llcakz" }),
111
- value: t.updated_at ? new Date(t.updated_at).toLocaleDateString() : n._({ id: "fj5byd" })
112
- }
113
- ];
114
- return /*#__PURE__*/ O(e, {
115
- px: !1,
116
- py: !0,
117
- children: [/*#__PURE__*/ D(s, { children: n._({ id: "nW/hX9" }) }), /*#__PURE__*/ D(T, { items: i })]
118
- });
119
- }, I = ({ image: t, currentProjectId: n }) => {
120
- let { i18n: r, _: i } = N(), a = [
121
- {
122
- label: t.visibility === "shared" && t.owner !== void 0 && t.owner !== n ? r._({ id: "20axE5" }) : r._({ id: "YsrbQh" }),
123
- value: t.owner ? /*#__PURE__*/ D(y, { text: t.owner }) : ""
124
- },
125
- {
126
- label: r._({ id: "2q/Q7x" }),
127
- value: t.visibility
128
- },
129
- {
130
- label: r._({ id: "644xgx" }),
131
- value: t.protected ? r._({ id: "l75CjT" }) : r._({ id: "1UzENP" })
132
- },
133
- {
134
- label: r._({ id: "PzgYM9" }),
135
- value: t?.checksum ? t.checksum : ""
136
- }
137
- ];
138
- return /*#__PURE__*/ O(e, {
139
- px: !1,
140
- py: !0,
141
- children: [/*#__PURE__*/ D(s, { children: r._({ id: "a3LDKx" }) }), /*#__PURE__*/ D(T, { items: a })]
142
- });
143
- }, L = ({ image: t }) => {
144
- let { i18n: n, _: i } = N(), a = /* @__PURE__ */ new Set([
145
- "id",
146
- "name",
147
- "status",
148
- "visibility",
149
- "size",
150
- "disk_format",
151
- "container_format",
152
- "min_disk",
153
- "min_ram",
154
- "owner",
155
- "protected",
156
- "created_at",
157
- "updated_at",
158
- "checksum"
159
- ]), o = Object.entries(t).filter(([e]) => !a.has(e)).sort(([e], [t]) => e.localeCompare(t)), c = o.length > 0;
160
- return /*#__PURE__*/ O(e, {
161
- px: !1,
162
- py: !0,
163
- children: [/*#__PURE__*/ D(s, { children: n._({ id: "bc67JN" }) }), c ? /*#__PURE__*/ D(h, {
164
- alignTerms: "right",
165
- className: "grid-cols-4",
166
- children: o.map(([e, t]) => /*#__PURE__*/ O(k.Fragment, { children: [/*#__PURE__*/ D(d, {
167
- className: "col-span-1",
168
- children: e
169
- }), /*#__PURE__*/ D(r, {
170
- className: "col-span-1",
171
- children: t == null ? /*#__PURE__*/ D("span", { children: "null" }) : typeof t == "object" ? /*#__PURE__*/ D("span", {
172
- className: "break-all",
173
- children: JSON.stringify(t)
174
- }) : typeof t == "boolean" ? t ? n._({ id: "c+xCSz" }) : n._({ id: "ocUvR+" }) : /*#__PURE__*/ D("span", {
175
- className: "break-all",
176
- children: String(t)
177
- })
178
- })] }, e))
179
- }) : /*#__PURE__*/ D("p", {
180
- className: "text-theme-light",
181
- children: n._({ id: "9v5VLp" })
182
- })]
183
- });
184
- }, R = (e) => {
185
- let t = "px-6 py-3 font-semibold border-b-2 transition-colors";
186
- return e ? `${t} border-theme-accent text-theme-highest` : `${t} border-transparent text-theme-secondary hover:text-theme-high`;
187
- }, z = ({ image: t, permissions: n, currentProjectId: r }) => {
188
- let [a, o] = A(!1), [s, c] = A(null), { data: l, isLoading: u } = _.compute.listImageMembers.useQuery({
189
- project_id: r,
190
- imageId: t.id
191
- }, { enabled: !!t.id && !!r });
192
- return /*#__PURE__*/ O(e, {
193
- px: !1,
194
- py: !0,
195
- children: [s && /*#__PURE__*/ D(i, {
196
- text: s.text,
197
- variant: s.type,
198
- onDismiss: () => c(null),
199
- className: "mb-4"
200
- }), /*#__PURE__*/ D(x, {
201
- image: t,
202
- imageMembers: l,
203
- isMembersLoading: u,
204
- canAdd: n?.canCreateMember ?? !1,
205
- canRemove: n?.canDeleteMember ?? !1,
206
- isAddingMember: a,
207
- setIsAddingMember: o,
208
- setMessage: c,
209
- projectId: r
210
- })]
211
- });
212
- }, ye = ({ image: e, currentProjectId: t, activeTab: n = "details", onTabChange: r, permissions: i, myMemberData: a, onMemberStatusChange: s, isMemberStatusChanging: c, actions: l }) => {
213
- let { i18n: u, _: d } = N(), f = e.visibility === "shared" && e.owner !== void 0 && e.owner !== t, p = e.owner === t && e.visibility === "shared";
214
- return /*#__PURE__*/ O(o, {
215
- direction: "vertical",
216
- gap: "6",
217
- children: [
218
- f && a && s && /*#__PURE__*/ D(P, {
219
- image: e,
220
- myMemberData: a,
221
- canUpdateMember: i?.canUpdateMember ?? !1,
222
- onStatusChange: s,
223
- isLoading: c ?? !1
224
- }),
225
- p && /*#__PURE__*/ D("div", {
226
- className: "border-theme-background-lvl-3 border-b",
227
- children: /*#__PURE__*/ O(o, {
228
- direction: "horizontal",
229
- gap: "0",
230
- children: [/*#__PURE__*/ D("button", {
231
- className: R(n === "details"),
232
- onClick: () => r?.("details"),
233
- children: u._({ id: "URmyfc" })
234
- }), /*#__PURE__*/ D("button", {
235
- className: R(n === "sharing"),
236
- onClick: () => r?.("sharing"),
237
- children: u._({ id: "aG9OiI" })
238
- })]
239
- })
240
- }),
241
- (n === "details" || !p) && /*#__PURE__*/ O(E, { children: [
242
- l,
243
- /*#__PURE__*/ D(F, { image: e }),
244
- /*#__PURE__*/ D(I, {
245
- image: e,
246
- currentProjectId: t
247
- }),
248
- /*#__PURE__*/ D(L, { image: e })
249
- ] }),
250
- n === "sharing" && p && /*#__PURE__*/ D(z, {
251
- image: e,
252
- permissions: i
253
- })
254
- ]
255
- });
256
- };
257
- //#endregion
258
- //#region src/client/routes/_auth/projects/$projectId/compute/images/$imageId.tsx?tsr-split=component
259
- function be() {
260
- let { i18n: e, _: t } = N(), n = j(), { projectId: r } = v.useParams();
261
- return /*#__PURE__*/ D(b, { action: /*#__PURE__*/ D(u, {
262
- variant: "primary",
263
- onClick: () => n({
264
- to: "/projects/$projectId/compute/images",
265
- params: { projectId: r }
266
- }),
267
- children: e._({ id: "bnql/K" })
268
- }) });
269
- }
270
- function B() {
271
- let { projectId: e, imageId: t } = _e({ from: "/_auth/projects/$projectId/compute/images/$imageId" }), { tab: r } = ve({ from: "/_auth/projects/$projectId/compute/images/$imageId" }), i = j(), { i18n: a, _: s } = N(), { data: d, status: h, error: y } = _.compute.getImageById.useQuery({
272
- project_id: e,
273
- imageId: t
274
- });
275
- te(v.id, d?.name);
276
- let { data: x } = _.compute.canUser.useQuery({
277
- project_id: e,
278
- permission: [
279
- "images:delete",
280
- "images:update",
281
- "images:create_member",
282
- "images:delete_member",
283
- "images:update_member"
284
- ]
285
- }), S = {
286
- canDelete: x?.[0] ?? !1,
287
- canUpdate: x?.[1] ?? !1,
288
- canCreateMember: x?.[2] ?? !1,
289
- canDeleteMember: x?.[3] ?? !1,
290
- canUpdateMember: x?.[4] ?? !1
291
- }, C = _.useUtils(), [T, k] = A(!1), [P, F] = A(!1), [I, L] = A(!1), [R, z] = A(!1), [B, V] = A(!1), H = _.compute.updateImage.useMutation({ onSuccess: (n) => {
292
- C.compute.getImageById.setData({
293
- project_id: e,
294
- imageId: t
295
- }, n), C.compute.listImagesWithPagination.invalidate();
296
- } }), U = _.compute.deleteImage.useMutation({ onSuccess: () => {
297
- C.compute.listImagesWithPagination.invalidate();
298
- } }), W = _.compute.deactivateImage.useMutation({ onSuccess: () => {
299
- C.compute.getImageById.invalidate({
300
- project_id: e,
301
- imageId: t
302
- });
303
- } }), G = _.compute.reactivateImage.useMutation({ onSuccess: () => {
304
- C.compute.getImageById.invalidate({
305
- project_id: e,
306
- imageId: t
307
- });
308
- } }), K = _.compute.updateImageVisibility.useMutation({ onSuccess: (n) => {
309
- C.compute.getImageById.setData({
310
- project_id: e,
311
- imageId: t
312
- }, n);
313
- } }), q = d?.visibility === w.SHARED && d?.owner !== void 0 && d?.owner !== e, { data: J } = _.compute.getImageMember.useQuery({
314
- project_id: e,
315
- imageId: t,
316
- memberId: e
317
- }, { enabled: q && !!t && !!e }), Y = _.compute.updateImageMember.useMutation({ onSuccess: () => {
318
- C.compute.getImageMember.invalidate({
319
- project_id: e,
320
- imageId: t,
321
- memberId: e
322
- }), C.compute.listImageMembers.invalidate({
323
- project_id: e,
324
- imageId: t
325
- }), C.compute.listImagesWithPagination.invalidate(), C.compute.listSharedImagesByMemberStatus.invalidate();
326
- } }), X = async (n) => {
327
- try {
328
- await Y.mutateAsync({
329
- project_id: e,
330
- imageId: t,
331
- memberId: e,
332
- status: n
333
- });
334
- let { message: r, ...i } = ue(n);
335
- f.info(r, i);
336
- } catch (e) {
337
- let t = e?.message, { message: n, ...r } = he(t);
338
- f.error(n, r);
339
- }
340
- }, Z = () => {
341
- i({
342
- to: "/projects/$projectId/compute/images",
343
- params: { projectId: e }
344
- });
345
- }, Q = H.isPending || U.isPending || W.isPending || G.isPending || K.isPending, xe = (e, t) => {
346
- let n = [];
347
- return Object.entries(e).forEach(([e, r]) => {
348
- let i = `/${e}`;
349
- if (r == null) e in t && n.push({
350
- op: "remove",
351
- path: i
352
- });
353
- else {
354
- let a = e in t;
355
- n.push({
356
- op: a ? "replace" : "add",
357
- path: i,
358
- value: r
359
- });
360
- }
361
- }), n;
362
- }, Se = async (n) => {
363
- if (!d) return !1;
364
- let r = xe(n, d);
365
- try {
366
- await H.mutateAsync({
367
- project_id: e,
368
- imageId: t,
369
- operations: r
370
- }), k(!1);
371
- let { message: n, ...i } = se(String(d.name ?? d.id));
372
- return f.success(n, i), !0;
373
- } catch {
374
- return !1;
375
- }
376
- }, Ce = async (t) => {
377
- try {
378
- await U.mutateAsync({
379
- project_id: e,
380
- imageId: t.id
381
- }), L(!1), Z();
382
- } catch {
383
- L(!1);
384
- }
385
- }, we = async (t) => {
386
- try {
387
- await G.mutateAsync({
388
- project_id: e,
389
- imageId: t.id
390
- }), z(!1);
391
- let { message: n, ...r } = de(String(t.name ?? t.id));
392
- f.success(n, r);
393
- } catch (e) {
394
- z(!1);
395
- let { message: n, ...r } = me(t.id, e?.message ?? "");
396
- f.error(n, r);
397
- }
398
- }, Te = async (t) => {
399
- try {
400
- await W.mutateAsync({
401
- project_id: e,
402
- imageId: t.id
403
- }), V(!1);
404
- let { message: n, ...r } = fe(String(t.name ?? t.id));
405
- f.success(n, r);
406
- } catch (e) {
407
- V(!1);
408
- let { message: n, ...r } = le(t.id, e?.message ?? "");
409
- f.error(n, r);
410
- }
411
- }, Ee = async (t) => {
412
- if (d) try {
413
- await K.mutateAsync({
414
- project_id: e,
415
- imageId: d.id,
416
- visibility: t
417
- });
418
- let { message: n, ...r } = ge(String(d.name ?? d.id), t);
419
- f.success(n, r);
420
- } catch (e) {
421
- let { message: t, ...n } = ne(String(d.name ?? d.id), e?.message ?? "");
422
- f.error(t, n);
423
- }
424
- };
425
- if (h === "pending") return /*#__PURE__*/ D(m, {
426
- status: "progress",
427
- title: a._({ id: "hH3kDo" })
428
- });
429
- if (h === "error") {
430
- let e = y?.message || a._({ id: "LobdAW" });
431
- return /*#__PURE__*/ D(b, {
432
- errorTitle: a._({ id: "2bUZog" }),
433
- errorDescription: e,
434
- action: /*#__PURE__*/ D(u, {
435
- onClick: Z,
436
- variant: "primary",
437
- children: /*#__PURE__*/ D(M, { id: "bnql/K" })
438
- })
439
- });
440
- }
441
- if (!d) return /*#__PURE__*/ D(be, {});
442
- let De = d.status === ae.DEACTIVATED, Oe = d.visibility === w.PRIVATE, ke = J?.status === "accepted", Ae = d.owner === e, je = q && ke && S.canUpdateMember, Me = !q && S.canUpdate, Ne = !q && S.canDelete && !d.protected, Pe = !q && Ae && d.visibility === w.SHARED && (S.canCreateMember || S.canDeleteMember), $ = je || Me || Ne || Pe, Fe = ($ || !q && S.canUpdate) && /*#__PURE__*/ O(o, {
443
- gap: "0.5",
444
- alignment: "center",
445
- children: [($ || !q && S.canUpdate) && /*#__PURE__*/ O(n, {
446
- className: "flex items-center",
447
- children: [/*#__PURE__*/ D(c, {
448
- as: "div",
449
- children: /*#__PURE__*/ D(u, {
450
- icon: "moreVert",
451
- title: a._({ id: "PgNNGl" }),
452
- disabled: Q
453
- })
454
- }), /*#__PURE__*/ O(l, { children: [
455
- !q && S.canUpdate && /*#__PURE__*/ O(E, { children: [/*#__PURE__*/ D(g, {
456
- label: De ? a._({ id: "FQBaXG" }) : a._({ id: "5y3O+A" }),
457
- onClick: () => De ? z(!0) : V(!0)
458
- }), /*#__PURE__*/ D(g, {
459
- onClick: () => F(!0),
460
- label: a._({ id: "SIfYq6" }),
461
- disabled: Q
462
- })] }),
463
- !q && Ae && d.visibility === w.SHARED && (S.canCreateMember || S.canDeleteMember) && /*#__PURE__*/ D(g, {
464
- label: a._({ id: "cWbW6w" }),
465
- onClick: () => i({
466
- to: "/projects/$projectId/compute/images/$imageId",
467
- params: {
468
- projectId: e,
469
- imageId: d.id
470
- },
471
- search: { tab: "sharing" }
472
- })
473
- }),
474
- je && /*#__PURE__*/ D(g, {
475
- label: a._({ id: "1t/NnN" }),
476
- onClick: () => X("rejected")
477
- }),
478
- !q && S.canUpdate && Oe && /*#__PURE__*/ D(g, {
479
- label: a._({ id: "gMYsdZ" }),
480
- onClick: () => Ee("shared")
481
- }),
482
- !q && S.canDelete && !d.protected && /*#__PURE__*/ O(E, { children: [/*#__PURE__*/ D(p, {}), /*#__PURE__*/ D(g, {
483
- label: a._({ id: "cnGeoo" }),
484
- onClick: () => L(!0)
485
- })] })
486
- ] })]
487
- }), !q && S.canUpdate && /*#__PURE__*/ D(u, {
488
- onClick: () => k(!0),
489
- variant: "primary",
490
- disabled: Q,
491
- children: /*#__PURE__*/ D(M, { id: "Y1YKad" })
492
- })]
493
- });
494
- return /*#__PURE__*/ O(E, { children: [
495
- /*#__PURE__*/ D(ee, {
496
- title: String(d.name ?? d.id),
497
- projectId: e,
498
- actions: Fe
499
- }),
500
- /*#__PURE__*/ D("div", {
501
- className: "mt-3",
502
- children: /*#__PURE__*/ D(ye, {
503
- image: d,
504
- currentProjectId: e,
505
- activeTab: r ?? "details",
506
- onTabChange: (e) => i({ search: { tab: e === "details" ? void 0 : e } }),
507
- permissions: {
508
- canCreateMember: S.canCreateMember,
509
- canDeleteMember: S.canDeleteMember,
510
- canUpdateMember: S.canUpdateMember
511
- },
512
- myMemberData: J,
513
- onMemberStatusChange: X,
514
- isMemberStatusChanging: Y.isPending
515
- }, d.id)
516
- }),
517
- T && /*#__PURE__*/ D(pe, {
518
- image: d,
519
- isOpen: T,
520
- isLoading: H.isPending,
521
- onClose: () => k(!1),
522
- onSave: Se
523
- }),
524
- P && /*#__PURE__*/ D(oe, {
525
- image: d,
526
- isOpen: P,
527
- isLoading: H.isPending,
528
- onClose: () => F(!1),
529
- onSave: Se
530
- }),
531
- I && /*#__PURE__*/ D(re, {
532
- image: d,
533
- isOpen: I,
534
- isLoading: U.isPending,
535
- isDisabled: !!d.protected,
536
- onClose: () => L(!1),
537
- onDelete: Ce
538
- }),
539
- R && /*#__PURE__*/ D(ie, {
540
- image: d,
541
- isOpen: R,
542
- isLoading: G.isPending,
543
- onClose: () => z(!1),
544
- onActivate: we
545
- }),
546
- B && /*#__PURE__*/ D(ce, {
547
- image: d,
548
- isOpen: B,
549
- isLoading: W.isPending,
550
- onClose: () => V(!1),
551
- onDeactivate: Te
552
- })
553
- ] });
554
- }
555
- //#endregion
556
- export { B as component };
557
-
558
- //# sourceMappingURL=_imageId-mfKp3JHn.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_projectId-AjgJX6Gl.mjs","names":["useNavigate","useMatches","useParams","useRouteContext","useState","useEffect","SideNavigation","SideNavigationList","SideNavigationGroup","SideNavigationItem","Divider","isRouteInfo","Slot","SideNavBar","projectId","projectName","domainName","sections","navigate","matches","provider","serviceType","strict","slots","navBadge","service","serviceBadge","component","useShadowDOM","currentService","activeMatch","reverse","find","m","staticData","section","undefined","activeRouteInfo","activeSection","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","serviceExtensions","serviceIndex","isEnabled","service","includes","computeServices","label","t","navigate","nav","to","params","networkServices","storageServices","provider","storageType","sectionMap","Map","section","services","extension","serviceType","serviceName","get","push","values","filter","s","length","Breadcrumb","BreadcrumbItem","JunoBreadcrumbItem","useNavigate","useParams","useContext","useMemo","BreadcrumbExtensionContext","useBreadcrumbs","Breadcrumbs","navigate","projectId","strict","breadcrumbs","extensionCrumbs","allBreadcrumbs","length","slice","active","onClick","to","params","undefined","className","map","item","index","label","icon","Outlet","useLoaderData","useRouteContext","AppShell","Button","Container","Stack","Status","SideNavBar","buildNavSections","Breadcrumbs","RouteError","useMemo","useLingui","Trans","BreadcrumbExtensionProvider","useSetBreadcrumb","ScopeError","type","code","message","currentDomain","id","name","Route","RouteComponent","t","loaderData","from","navigate","useNavigate","enabledServices","serviceExtensions","strict","projectName","crumbProject","projectId","projectLabel","crumbDomain","scopeError","domainName","to","bodyText","Error","availableServices","sections","component"],"sources":["../../src/client/routes/_auth/projects/-components/SideNavBar.tsx","../../src/client/routes/_auth/projects/-components/buildNavSections.ts","../../src/client/components/Breadcrumbs.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, serviceType } = useParams({ strict: false }) as { provider?: string; serviceType?: 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 meaningful RouteInfo staticData.\n // isRouteInfo uses an all-optional schema, so an empty {} also passes — require at least section\n // or service to be set so that stub routes (index/splat) don't shadow their layout parent.\n const activeMatch = [...matches]\n .reverse()\n .find(\n (m) => isRouteInfo(m.staticData) && (m.staticData.section !== undefined || m.staticData.service !== undefined)\n )\n const activeRouteInfo = activeMatch && isRouteInfo(activeMatch.staticData) ? activeMatch.staticData : undefined\n const activeSection = activeRouteInfo?.section ?? null\n // Extension mount routes carry only staticData.section (no static `service`), so fall back to\n // the $serviceType URL param to identify the active service and highlight its nav item.\n const activeService = activeRouteInfo?.service ?? serviceType ?? 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\"\nimport type { ServiceExtension } from \"@/client/AuroraApp\"\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 serviceExtensions?: ServiceExtension[]\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 ...(serviceIndex?.[\"object-store-ceph\"]?.[\"ceph\"] && 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 // Seed the section map with built-in sections\n const sectionMap = new Map<string, NavSection>([\n [\"compute\", { section: \"compute\", label: t`Compute`, services: computeServices }],\n [\"network\", { section: \"network\", label: t`Network`, services: networkServices }],\n [\"storage\", { section: \"storage\", label: t`Storage`, services: storageServices }],\n [\"services\", { section: \"services\", label: t`Services`, services: [] }],\n ])\n\n // Merge service extensions: activate when the service exists in the project's catalog\n for (const extension of serviceExtensions ?? []) {\n if (!serviceIndex[extension.serviceType]?.[extension.serviceName]) continue\n if (enabledServices && !enabledServices.includes(extension.serviceType)) continue\n\n sectionMap.get(\"services\")?.services.push({\n service: extension.serviceType,\n label: extension.label,\n navigate: (nav: NavigateFn) =>\n nav({\n to: \"/projects/$projectId/services/$serviceType\",\n params: { projectId, serviceType: extension.serviceType },\n }),\n params: { projectId, serviceType: extension.serviceType },\n })\n }\n\n return [...sectionMap.values()].filter((s) => s.services.length > 0)\n}\n","import { Breadcrumb, BreadcrumbItem as JunoBreadcrumbItem } from \"@cloudoperators/juno-ui-components\"\nimport type { KnownIcons } from \"@cloudoperators/juno-ui-components\"\nimport { useNavigate, useParams } from \"@tanstack/react-router\"\nimport { useContext, useMemo } from \"react\"\nimport { BreadcrumbExtensionContext } from \"@/client/context/BreadcrumbExtensionContext\"\nimport { useBreadcrumbs, type BreadcrumbItem } from \"@/client/hooks/useBreadcrumbs\"\n\nexport function Breadcrumbs() {\n const navigate = useNavigate()\n const { projectId } = useParams({ strict: false }) as { projectId?: string }\n const { breadcrumbs: extensionCrumbs } = useContext(BreadcrumbExtensionContext)\n const breadcrumbs = useBreadcrumbs()\n\n const allBreadcrumbs = useMemo((): BreadcrumbItem[] => {\n if (extensionCrumbs.length === 0 || breadcrumbs.length === 0) return breadcrumbs\n\n // Extension crumbs present: deactivate the last OSS crumb (always the project crumb on\n // /services/* routes) and append the extension crumbs pushed by the sub-app.\n return [\n ...breadcrumbs.slice(0, -1),\n {\n ...breadcrumbs[breadcrumbs.length - 1],\n active: false,\n onClick: projectId\n ? () => navigate({ to: \"/projects/$projectId\" as never, params: { projectId } as never })\n : undefined,\n },\n ...extensionCrumbs,\n ]\n }, [breadcrumbs, extensionCrumbs, projectId, navigate])\n\n return (\n <Breadcrumb className=\"relative z-1 mt-8 mb-4\">\n {allBreadcrumbs.map((item, index) => (\n <JunoBreadcrumbItem\n key={index}\n label={item.label}\n icon={item.icon as KnownIcons | undefined}\n onClick={item.onClick}\n active={item.active}\n />\n ))}\n </Breadcrumb>\n )\n}\n","import { createFileRoute, Outlet, useLoaderData, useRouteContext } from \"@tanstack/react-router\"\nimport { AppShell, Button, Container, Stack, Status } from \"@cloudoperators/juno-ui-components\"\nimport { SideNavBar } from \"@/client/routes/_auth/projects/-components/SideNavBar\"\nimport { buildNavSections } from \"@/client/routes/_auth/projects/-components/buildNavSections\"\nimport { Breadcrumbs } from \"@/client/components/Breadcrumbs\"\nimport { RouteError } from \"@/client/components/Errors/RouteError\"\nimport { useMemo } from \"react\"\nimport { TRPCClientError } from \"@trpc/client\"\nimport { useLingui, Trans } from \"@lingui/react/macro\"\nimport { BreadcrumbExtensionProvider } from \"@/client/context/BreadcrumbExtensionContext\"\nimport { useSetBreadcrumb } from \"@/client/hooks/useSetBreadcrumb\"\n\n// Type for scope error that we catch and handle gracefully\ntype ScopeError = {\n type: \"scope_error\"\n code: string\n message: string\n currentDomain?: { id: string; name: string } | null\n}\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId\")({\n component: RouteComponent,\n errorComponent: ProjectErrorComponent,\n loader: async (options) => {\n const { context, params } = options\n\n // Catch rescope errors and return them as data instead of throwing\n // This allows the component to render a friendly error UI\n let scopeData\n let scopeError: ScopeError | undefined\n\n try {\n scopeData = await context.trpcClient?.auth.setCurrentScope.mutate({\n type: \"project\",\n projectId: params.projectId || \"\",\n })\n } catch (error) {\n if (error instanceof TRPCClientError) {\n // Try to get the current session's domain to show in the error message\n let currentDomain: { id: string; name: string } | null | undefined\n try {\n const currentScope = await context.trpcClient?.auth.getCurrentScope.query()\n if (currentScope?.domain?.id && currentScope?.domain?.name) {\n currentDomain = { id: currentScope.domain.id, name: currentScope.domain.name }\n }\n } catch {\n // Ignore errors fetching current scope\n }\n\n // Return error as data so the component can handle it\n scopeError = {\n type: \"scope_error\",\n code: error.data?.code || \"UNKNOWN\",\n message: error.message,\n currentDomain,\n }\n } else {\n // Unknown errors should still propagate\n throw error\n }\n }\n\n // If scope failed, return early with error state\n if (scopeError) {\n return {\n scopeError,\n projectId: params.projectId,\n // Provide minimal data for error rendering\n trpcClient: context.trpcClient,\n crumbDomain: undefined,\n crumbProject: undefined,\n availableServices: undefined,\n accountId: \"\",\n description: null,\n }\n }\n\n const [availableServices, project] = await Promise.all([\n context.trpcClient?.auth.getAvailableServices.query(),\n context.trpcClient?.project.getProject.query({ projectId: params.projectId }).catch(() => null),\n ])\n\n const accountId = scopeData?.domain?.id || \"\"\n const description = project?.description ?? null\n\n return {\n scopeError: undefined,\n trpcClient: context.trpcClient,\n crumbDomain: { path: `/projects`, name: scopeData?.domain?.name },\n crumbProject: scopeData?.project,\n availableServices,\n accountId,\n projectId: params.projectId,\n description,\n }\n },\n})\n\nfunction RouteComponent() {\n const { t } = useLingui()\n const loaderData = useLoaderData({ from: Route.id })\n const navigate = Route.useNavigate()\n const { enabledServices, serviceExtensions } = useRouteContext({ strict: false })\n\n const projectName = loaderData.crumbProject?.name || loaderData.projectId\n const projectLabel = loaderData.crumbDomain?.name ? `${loaderData.crumbDomain.name}/${projectName}` : projectName\n useSetBreadcrumb(Route.id, projectLabel)\n\n // Handle scope errors with a friendly UI using Juno's Status component\n if (loaderData.scopeError) {\n const { code, message, currentDomain } = loaderData.scopeError\n const domainName = currentDomain?.name\n\n if (code === \"UNAUTHORIZED\") {\n return (\n <Container className=\"py-8\">\n <Status\n status=\"error\"\n title={t`Session Expired`}\n body={t`Your session has expired. Please log in again. This may have occurred because you logged out or switched domains in another browser tab.`}\n action={\n <Button variant=\"primary\" onClick={() => navigate({ to: \"/\" })}>\n <Trans>Log In</Trans>\n </Button>\n }\n />\n </Container>\n )\n }\n\n if (code === \"NOT_FOUND\") {\n const bodyText = domainName\n ? t`This project doesn't exist or is not accessible from your current domain. Your current domain is ${domainName}. Please select a project from your current domain.`\n : t`This project doesn't exist or is not accessible from your current domain. Please select a project from your current domain.`\n\n return (\n <Container className=\"py-8\">\n <Status\n status=\"error\"\n code={404}\n title={t`Project Not Accessible`}\n body={bodyText}\n action={\n <Button variant=\"primary\" onClick={() => navigate({ to: \"/projects\" })}>\n <Trans>Go to Projects</Trans>\n </Button>\n }\n />\n </Container>\n )\n }\n\n if (code === \"FORBIDDEN\") {\n return (\n <Container className=\"py-8\">\n <Status\n status=\"error\"\n code={403}\n title={t`Access Denied`}\n body={t`You don't have permission to access this project.`}\n action={\n <Button variant=\"primary\" onClick={() => navigate({ to: \"/projects\" })}>\n <Trans>Go to Projects</Trans>\n </Button>\n }\n />\n </Container>\n )\n }\n\n // Fallback for other error codes\n return <RouteError error={new Error(message)} />\n }\n\n const { availableServices, projectId, crumbProject, crumbDomain } = loaderData\n\n const sections = useMemo(\n () => buildNavSections(projectId, availableServices!, enabledServices, serviceExtensions),\n [projectId, availableServices, enabledServices, serviceExtensions]\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 <BreadcrumbExtensionProvider>\n <Breadcrumbs />\n <Outlet />\n </BreadcrumbExtensionProvider>\n </div>\n </Stack>\n </Container>\n </AppShell>\n )\n}\n\nfunction ProjectErrorComponent({ error }: { error: Error & { statusCode?: number } }) {\n const { t } = useLingui()\n const navigate = Route.useNavigate()\n\n // Handle 404 errors with a custom UI\n if (error.statusCode === 404 || error.message === \"Project not found\") {\n return (\n <Container className=\"py-8\">\n <Status\n status=\"error\"\n code={404}\n title={t`Project Not Found`}\n body={t`The project you are looking for doesn't exist or you don't have access to it.`}\n action={\n <Button variant=\"primary\" onClick={() => navigate({ to: \"/projects\" })}>\n <Trans>Go to Projects</Trans>\n </Button>\n }\n />\n </Container>\n )\n }\n\n // For all other errors, use the default RouteError component\n return <RouteError error={error} safeErrorMessage={error instanceof TRPCClientError ? error.message : undefined} />\n}\n"],"mappings":"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"}