@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,32 +1,32 @@
1
1
  import { C as e, D as t, L as n, Q as r, S as i, T as a, V as o, X as s, ft as c, g as l, h as u, i as d, l as f, m as p, o as m, ot as h, p as g, r as _, rt as v, st as y, t as b, x } from "./build-WuxXRAqf.mjs";
2
- import { t as S } from "./flavors-ZudiAiTU.mjs";
2
+ import { t as S } from "./flavors-Ce3J-cFa.mjs";
3
3
  import { t as C } from "./SortInput-4g7nSTHW.mjs";
4
- import { t as w } from "./ContentHeader-CPJbgYWn.mjs";
5
- import { a as T, i as E, n as D, o as O, r as k, t as A } from "./DeleteFlavorModal-C2MqUgGR.mjs";
4
+ import { t as w } from "./ContentHeader-fKKZVu-o.mjs";
5
+ import { a as T, i as E, n as D, o as O, r as k, t as A } from "./DeleteFlavorModal-Be2GFiB_.mjs";
6
6
  import { Fragment as j, jsx as M, jsxs as N } from "react/jsx-runtime";
7
- import { Suspense as P, startTransition as F, use as I, useCallback as L, useEffect as R, useRef as z, useState as B } from "react";
8
- import { useNavigate as V, useParams as H, useSearch as U } from "@tanstack/react-router";
7
+ import P, { Suspense as F, startTransition as I, use as L, useCallback as R, useEffect as z, useRef as B, useState as V } from "react";
8
+ import { useNavigate as H, useParams as ee, useSearch as U } from "@tanstack/react-router";
9
9
  import { TRPCClientError as W } from "@trpc/client";
10
10
  import { Trans as G, useLingui as K } from "@lingui/react";
11
11
  import { ErrorBoundary as q } from "react-error-boundary";
12
12
  //#region src/client/routes/_auth/projects/$projectId/compute/flavors/-components/FlavorListContainer.tsx
13
13
  var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c, canDeleteFlavor: u, canMangageAccess: d, canManageSpecs: f, currentPage: p = 1, totalPages: h = 1, onPageChange: g }) => {
14
- let { i18n: y, _: S } = K(), C = V(), [w, E] = B(!1), [O, k] = B(!1), [P, F] = B(!1), [I, L] = B(null), [z, U] = B(p.toString());
15
- R(() => {
16
- U(p.toString());
14
+ let { i18n: y, _: S } = K(), C = H(), [w, E] = V(!1), [O, k] = V(!1), [P, F] = V(!1), [I, L] = V(null), [R, B] = V(p.toString());
15
+ z(() => {
16
+ B(p.toString());
17
17
  }, [p]);
18
- let { projectId: W } = H({ from: "/_auth/projects/$projectId/compute/flavors/" }), q = (e) => {
18
+ let { projectId: U } = ee({ from: "/_auth/projects/$projectId/compute/flavors/" }), W = (e) => {
19
19
  L(e), E(!0);
20
- }, J = (e) => {
20
+ }, q = (e) => {
21
21
  L(e), k(!0);
22
- }, Y = (e) => {
22
+ }, J = (e) => {
23
23
  L(e), F(!0);
24
- }, X = () => {
24
+ }, Y = () => {
25
25
  E(!1), L(null);
26
- }, Z = () => {
27
- I && c && c(I.name || ""), X();
28
- }, Q = (e) => {
29
- e >= 1 && e <= h && (g?.(e), U(e.toString()));
26
+ }, X = () => {
27
+ I && c && c(I.name || ""), Y();
28
+ }, Z = (e) => {
29
+ e >= 1 && e <= h && (g?.(e), B(e.toString()));
30
30
  };
31
31
  return n ? /*#__PURE__*/ M(v, {
32
32
  status: "progress",
@@ -50,7 +50,7 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
50
50
  onClick: () => C({
51
51
  to: "/projects/$projectId/compute/flavors/$flavorId",
52
52
  params: {
53
- projectId: W,
53
+ projectId: U,
54
54
  flavorId: e.id
55
55
  }
56
56
  }),
@@ -66,25 +66,25 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
66
66
  children: /*#__PURE__*/ M(t, { children: /*#__PURE__*/ N(l, { children: [
67
67
  f && /*#__PURE__*/ M(x, {
68
68
  label: y._({ id: "SIfYq6" }),
69
- onClick: () => J(e)
69
+ onClick: () => q(e)
70
70
  }),
71
71
  d && e["os-flavor-access:is_public"] === !1 && /*#__PURE__*/ M(x, {
72
72
  label: y._({ id: "cWbW6w" }),
73
- onClick: () => Y(e)
73
+ onClick: () => J(e)
74
74
  }),
75
75
  /*#__PURE__*/ M(x, {
76
76
  label: y._({ id: "v0hPHE" }),
77
77
  onClick: () => C({
78
78
  to: "/projects/$projectId/compute/flavors/$flavorId",
79
79
  params: {
80
- projectId: W,
80
+ projectId: U,
81
81
  flavorId: e.id
82
82
  }
83
83
  })
84
84
  }),
85
85
  u && /*#__PURE__*/ N(j, { children: [/*#__PURE__*/ M(_, {}), /*#__PURE__*/ M(x, {
86
86
  label: y._({ id: "JT3I1g" }),
87
- onClick: () => q(e)
87
+ onClick: () => W(e)
88
88
  })] })
89
89
  ] }) })
90
90
  })
@@ -104,18 +104,18 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
104
104
  variant: "input",
105
105
  currentPage: p,
106
106
  pages: h,
107
- onPressPrevious: () => Q(Math.max(p - 1, 1)),
108
- onPressNext: () => Q(Math.min(p + 1, h)),
107
+ onPressPrevious: () => Z(Math.max(p - 1, 1)),
108
+ onPressNext: () => Z(Math.min(p + 1, h)),
109
109
  onSelectChange: (e) => {
110
- Q(e);
110
+ Z(e);
111
111
  },
112
112
  onInputChange: (e) => {
113
- U(e === void 0 ? "" : String(e));
113
+ B(e === void 0 ? "" : String(e));
114
114
  },
115
115
  onKeyDown: (e) => {
116
- if (e.key === "Enter" && z !== "") {
117
- let e = parseInt(z, 10);
118
- !isNaN(e) && e >= 1 && e <= h && Q(e);
116
+ if (e.key === "Enter" && R !== "") {
117
+ let e = parseInt(R, 10);
118
+ !isNaN(e) && e >= 1 && e <= h && Z(e);
119
119
  }
120
120
  }
121
121
  })
@@ -123,10 +123,10 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
123
123
  /*#__PURE__*/ M(A, {
124
124
  client: r,
125
125
  isOpen: w,
126
- onClose: X,
126
+ onClose: Y,
127
127
  project: s,
128
128
  flavor: I,
129
- onSuccess: Z
129
+ onSuccess: X
130
130
  }),
131
131
  /*#__PURE__*/ M(T, {
132
132
  client: r,
@@ -194,7 +194,15 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
194
194
  }, n = (e) => e != null && e !== "" && String(e).trim() !== "", r = (e) => e != null && e !== "" && String(e).trim() !== "" && !isNaN(Number(e));
195
195
  return n(e.id) && (t.id = String(e.id).trim()), n(e.description) && (t.description = String(e.description).trim()), r(e.swap) && (t.swap = Number(e.swap)), r(e.rxtx_factor) && (t.rxtx_factor = Number(e.rxtx_factor)), r(e["OS-FLV-EXT-DATA:ephemeral"]) && (t["OS-FLV-EXT-DATA:ephemeral"] = Number(e["OS-FLV-EXT-DATA:ephemeral"])), e["os-flavor-access:is_public"] !== void 0 && (t["os-flavor-access:is_public"] = !!e["os-flavor-access:is_public"]), t;
196
196
  }, Z = ({ client: e, isOpen: t, onClose: r, project: i, onSuccess: a }) => {
197
- let { i18n: o, _: l } = K(), { translateError: d } = O(), [f, m] = B({ "os-flavor-access:is_public": !0 }), [h, _] = B({}), [b, x] = B(!1), [S, C] = B(null), w = (e) => {
197
+ let { i18n: o, _: l } = K(), { translateError: d } = O(), [f, m] = V({ "os-flavor-access:is_public": !0 }), [h, _] = V({}), [b, x] = V(!1), [S, C] = V(null), [w, T] = V(!1);
198
+ P.useEffect(() => {
199
+ t && e.compute.getComputeApiVersion.query({ project_id: i }).then((e) => T(e.supportsDescription)).catch(() => T(!1));
200
+ }, [
201
+ t,
202
+ e,
203
+ i
204
+ ]);
205
+ let E = (e) => {
198
206
  let { name: t, value: n, type: r, checked: i } = e.target;
199
207
  m((e) => ({
200
208
  ...e,
@@ -203,7 +211,7 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
203
211
  ...e,
204
212
  [t]: void 0
205
213
  })), S && C(null);
206
- }, T = (e, t) => {
214
+ }, D = (e, t) => {
207
215
  m((n) => ({
208
216
  ...n,
209
217
  [e]: t
@@ -211,13 +219,13 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
211
219
  ...t,
212
220
  [e]: void 0
213
221
  })), S && C(null);
214
- }, E = (e) => {
222
+ }, k = (e) => {
215
223
  let { name: t, value: n } = e.target, r = Y(t, n, l);
216
224
  _((e) => ({
217
225
  ...e,
218
226
  [t]: r
219
227
  }));
220
- }, D = async (t) => {
228
+ }, A = async (t) => {
221
229
  t.preventDefault(), C(null);
222
230
  let n = {};
223
231
  if ([
@@ -251,22 +259,22 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
251
259
  await e.compute.createFlavor.mutate({
252
260
  project_id: i,
253
261
  flavor: t
254
- }), a(t.name), k();
262
+ }), a(t.name), j();
255
263
  } catch (e) {
256
264
  let t = e?.message ? d(e.message) : o._({ id: "OxDN2m" });
257
265
  C(t);
258
266
  } finally {
259
267
  x(!1);
260
268
  }
261
- }, k = () => {
269
+ }, j = () => {
262
270
  m({ "os-flavor-access:is_public": !0 }), _({}), C(null), r();
263
271
  };
264
272
  return /*#__PURE__*/ N(s, {
265
- onCancel: k,
273
+ onCancel: j,
266
274
  size: "large",
267
275
  title: o._({ id: "Rlp5zj" }),
268
276
  open: t,
269
- onConfirm: D,
277
+ onConfirm: A,
270
278
  cancelButtonLabel: o._({ id: "dEgA5A" }),
271
279
  confirmButtonLabel: o._({ id: "wEfZld" }),
272
280
  disableConfirmButton: !(() => {
@@ -313,8 +321,8 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
313
321
  name: "id",
314
322
  label: o._({ id: "s2ubkU" }),
315
323
  value: f.id || "",
316
- onChange: w,
317
- onBlur: E,
324
+ onChange: E,
325
+ onBlur: k,
318
326
  errortext: h.id,
319
327
  helptext: o._({ id: "hv2CnP" })
320
328
  }) }),
@@ -323,19 +331,19 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
323
331
  name: "name",
324
332
  label: o._({ id: "lWxDDh" }),
325
333
  value: f.name || "",
326
- onChange: w,
327
- onBlur: E,
334
+ onChange: E,
335
+ onBlur: k,
328
336
  errortext: h.name,
329
337
  helptext: o._({ id: "nq24is" }),
330
338
  required: !0
331
339
  }) }),
332
- /*#__PURE__*/ M(u, { children: /*#__PURE__*/ M(p, {
340
+ w && /*#__PURE__*/ M(u, { children: /*#__PURE__*/ M(p, {
333
341
  id: "description",
334
342
  name: "description",
335
343
  label: o._({ id: "Nu4oKW" }),
336
344
  value: f.description || "",
337
- onChange: w,
338
- onBlur: E,
345
+ onChange: E,
346
+ onBlur: k,
339
347
  errortext: h.description
340
348
  }) }),
341
349
  /*#__PURE__*/ M(u, { children: /*#__PURE__*/ M(y, {
@@ -343,7 +351,7 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
343
351
  label: o._({ id: "vbajgL" }),
344
352
  helptext: o._({ id: "Y8TptA" }),
345
353
  checked: !!f["os-flavor-access:is_public"],
346
- onChange: w
354
+ onChange: E
347
355
  }) })
348
356
  ]
349
357
  }),
@@ -355,8 +363,8 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
355
363
  name: "vcpus",
356
364
  label: o._({ id: "k5nYwm" }),
357
365
  value: String(f.vcpus || ""),
358
- onChange: (e) => T("vcpus", Number(e.target.value)),
359
- onBlur: E,
366
+ onChange: (e) => D("vcpus", Number(e.target.value)),
367
+ onBlur: k,
360
368
  errortext: h.vcpus,
361
369
  type: "number",
362
370
  required: !0
@@ -366,8 +374,8 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
366
374
  name: "ram",
367
375
  label: o._({ id: "K+e/0e" }),
368
376
  value: String(f.ram || ""),
369
- onChange: (e) => T("ram", Number(e.target.value)),
370
- onBlur: E,
377
+ onChange: (e) => D("ram", Number(e.target.value)),
378
+ onBlur: k,
371
379
  errortext: h.ram,
372
380
  helptext: o._({ id: "9DrU1K" }),
373
381
  type: "number",
@@ -378,8 +386,8 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
378
386
  name: "disk",
379
387
  label: o._({ id: "n0ZttO" }),
380
388
  value: String(f.disk || ""),
381
- onChange: (e) => T("disk", Number(e.target.value)),
382
- onBlur: E,
389
+ onChange: (e) => D("disk", Number(e.target.value)),
390
+ onBlur: k,
383
391
  errortext: h.disk,
384
392
  type: "number",
385
393
  required: !0
@@ -389,8 +397,8 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
389
397
  name: "OS-FLV-EXT-DATA:ephemeral",
390
398
  label: o._({ id: "X2OnDx" }),
391
399
  value: String(f["OS-FLV-EXT-DATA:ephemeral"] || ""),
392
- onChange: (e) => T("OS-FLV-EXT-DATA:ephemeral", Number(e.target.value)),
393
- onBlur: E,
400
+ onChange: (e) => D("OS-FLV-EXT-DATA:ephemeral", Number(e.target.value)),
401
+ onBlur: k,
394
402
  errortext: h["OS-FLV-EXT-DATA:ephemeral"],
395
403
  type: "number"
396
404
  }) }),
@@ -399,8 +407,8 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
399
407
  name: "swap",
400
408
  label: o._({ id: "p4nMut" }),
401
409
  value: String(f.swap || ""),
402
- onChange: (e) => T("swap", e.target.value ? Number(e.target.value) : void 0),
403
- onBlur: E,
410
+ onChange: (e) => D("swap", e.target.value ? Number(e.target.value) : void 0),
411
+ onBlur: k,
404
412
  errortext: h.swap,
405
413
  type: "number"
406
414
  }) }),
@@ -408,10 +416,9 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
408
416
  id: "rxtx_factor",
409
417
  name: "rxtx_factor",
410
418
  label: o._({ id: "u5HztT" }),
411
- defaultValue: 1,
412
419
  value: String(f.rxtx_factor || ""),
413
- onChange: (e) => T("rxtx_factor", Number(e.target.value)),
414
- onBlur: E,
420
+ onChange: (e) => D("rxtx_factor", Number(e.target.value)),
421
+ onBlur: k,
415
422
  errortext: h.rxtx_factor,
416
423
  helptext: o._({ id: "IVw5fS" }),
417
424
  type: "number"
@@ -435,7 +442,7 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
435
442
  listError: e.message
436
443
  };
437
444
  throw e;
438
- }), ee = (e, t) => e.compute.canUser.query({
445
+ }), te = (e, t) => e.compute.canUser.query({
439
446
  project_id: t,
440
447
  permission: [
441
448
  "flavors:create",
@@ -451,11 +458,11 @@ var J = ({ flavors: e, isLoading: n, client: r, project: s, onFlavorDeleted: c,
451
458
  canManageAccess: n || r,
452
459
  canManageSpecs: i || a
453
460
  }));
454
- function te({ flavorsPromise: t, permissionsPromise: i, client: a, project: o, onFlavorDeleted: s, onFlavorCreated: c, searchTerm: l, setSearchTerm: u, sortSettings: p, handleSortChange: m, createModalOpen: h, setCreateModalOpen: g, currentPage: _, onPageChange: v }) {
455
- let { i18n: y, _: b } = K(), { flavors: x, privateFlavorError: S, listError: w } = I(t), T = I(i), [E, D] = B(l), O = z(void 0);
456
- if (R(() => () => clearTimeout(O.current), []), w) return /*#__PURE__*/ M("p", { children: w });
461
+ function ne({ flavorsPromise: t, permissionsPromise: i, client: a, project: o, onFlavorDeleted: s, onFlavorCreated: c, searchTerm: l, setSearchTerm: u, sortSettings: p, handleSortChange: m, createModalOpen: h, setCreateModalOpen: g, currentPage: _, onPageChange: v }) {
462
+ let { i18n: y, _: b } = K(), { flavors: x, privateFlavorError: S, listError: w } = L(t), T = L(i), [E, D] = V(l), O = B(void 0);
463
+ if (z(() => () => clearTimeout(O.current), []), w) return /*#__PURE__*/ M("p", { children: w });
457
464
  let k = Math.max(1, Math.ceil(x.length / Q)), A = Math.min(_, k), P = x.slice((A - 1) * Q, A * Q);
458
- return R(() => {
465
+ return z(() => {
459
466
  _ > k && v(1);
460
467
  }, [
461
468
  k,
@@ -537,8 +544,8 @@ function te({ flavorsPromise: t, permissionsPromise: i, client: a, project: o, o
537
544
  })
538
545
  ] });
539
546
  }
540
- var ne = ({ client: e, project: t }) => {
541
- let { i18n: n, _: r } = K(), i = V(), a = U({ strict: !1 }), [o, s] = B({
547
+ var re = ({ client: e, project: t }) => {
548
+ let { i18n: n, _: r } = K(), i = H(), a = U({ strict: !1 }), [o, s] = V({
542
549
  options: [
543
550
  {
544
551
  label: n._({ id: "6YtxFj" }),
@@ -563,8 +570,8 @@ var ne = ({ client: e, project: t }) => {
563
570
  ],
564
571
  sortBy: a.sortBy || "name",
565
572
  sortDirection: a.sortDirection || "asc"
566
- }), [c, l] = B(a.search || ""), u = a.page ?? 1, [d, f] = B(!1), [p, m] = B(() => $(e, t, o.sortBy, o.sortDirection, c)), [g] = B(() => ee(e, t)), _ = () => {
567
- F(() => {
573
+ }), [c, l] = V(a.search || ""), u = a.page ?? 1, [d, f] = V(!1), [p, m] = V(() => $(e, t, o.sortBy, o.sortDirection, c)), [g] = V(() => te(e, t)), _ = () => {
574
+ I(() => {
568
575
  m($(e, t, o.sortBy, o.sortDirection, c));
569
576
  });
570
577
  }, y = (e) => {
@@ -587,7 +594,7 @@ var ne = ({ client: e, project: t }) => {
587
594
  page: void 0
588
595
  }),
589
596
  replace: !0
590
- }), F(() => {
597
+ }), I(() => {
591
598
  m($(e, t, r.sortBy, r.sortDirection, c));
592
599
  });
593
600
  }, S = (n) => {
@@ -599,10 +606,10 @@ var ne = ({ client: e, project: t }) => {
599
606
  page: void 0
600
607
  }),
601
608
  replace: !0
602
- }), F(() => {
609
+ }), I(() => {
603
610
  m($(e, t, o.sortBy, o.sortDirection, r));
604
611
  });
605
- }, C = L((e) => {
612
+ }, C = R((e) => {
606
613
  i({ search: (t) => ({
607
614
  ...t,
608
615
  page: e === 1 ? void 0 : e
@@ -616,12 +623,12 @@ var ne = ({ client: e, project: t }) => {
616
623
  title: n._({ id: "ZllCCx" }),
617
624
  body: e instanceof Error ? e.message : n._({ id: "W5A0Ly" })
618
625
  }),
619
- children: /*#__PURE__*/ M(P, {
626
+ children: /*#__PURE__*/ M(F, {
620
627
  fallback: /*#__PURE__*/ M(v, {
621
628
  status: "progress",
622
629
  title: n._({ id: "EqSPkP" })
623
630
  }),
624
- children: /*#__PURE__*/ M(te, {
631
+ children: /*#__PURE__*/ M(ne, {
625
632
  flavorsPromise: p,
626
633
  permissionsPromise: g,
627
634
  client: e,
@@ -643,17 +650,17 @@ var ne = ({ client: e, project: t }) => {
643
650
  };
644
651
  //#endregion
645
652
  //#region src/client/routes/_auth/projects/$projectId/compute/flavors/index.tsx?tsr-split=component
646
- function re() {
653
+ function ie() {
647
654
  let { i18n: e, _: t } = K(), { projectId: n } = S.useParams(), { trpcClient: r } = S.useRouteContext();
648
655
  return /*#__PURE__*/ N(j, { children: [/*#__PURE__*/ M(w, {
649
656
  title: e._({ id: "neiJm0" }),
650
657
  projectId: n
651
- }), /*#__PURE__*/ M(ne, {
658
+ }), /*#__PURE__*/ M(re, {
652
659
  project: n,
653
660
  client: r
654
661
  })] });
655
662
  }
656
663
  //#endregion
657
- export { re as component };
664
+ export { ie as component };
658
665
 
659
- //# sourceMappingURL=flavors-Bgq3KZmx.mjs.map
666
+ //# sourceMappingURL=flavors-D5ThLaXO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flavors-D5ThLaXO.mjs","names":["DataGrid","DataGridHeadCell","DataGridRow","DataGridCell","PopupMenu","PopupMenuOptions","PopupMenuItem","PopupMenuSectionSeparator","Status","Pagination","DeleteFlavorModal","useEffect","useState","EditSpecModal","ManageAccessModal","useParams","useNavigate","FlavorListContainer","flavors","isLoading","client","project","onFlavorDeleted","canDeleteFlavor","canMangageAccess","canManageSpecs","currentPage","totalPages","onPageChange","useLingui","navigate","deleteModalOpen","setDeleteModalOpen","specModalOpen","setSpecModalOpen","accessModalOpen","setAccessModalOpen","selectedFlavor","setSelectedFlavor","inputPage","setInputPage","toString","projectId","from","openDeleteModal","flavor","openSpecModal","openAccessModal","closeDeleteModal","handleDeleteSuccess","name","updateCurrentPage","newPage","status","title","t","columns","minContentColumns","className","data-testid","length","map","id","onClick","to","params","flavorId","vcpus","ram","disk","swap","e","stopPropagation","label","colSpan","body","div","variant","pages","onPressPrevious","Math","max","onPressNext","min","onSelectChange","selectedPage","onInputChange","newInputPage","undefined","String","onKeyDown","key","parseInt","isNaN","isOpen","onClose","onSuccess","validateField","field","value","t","undefined","idStr","String","trim","idRegex","test","msg","nameStr","length","vcpus","Number","isNaN","ram","disk","swap","rxtx","str","ephemeral","cleanFlavorData","flavor","result","name","isValidValue","isValidNumber","id","description","rxtx_factor","Boolean","React","useState","Modal","Form","FormRow","FormSection","TextInput","Message","Status","Checkbox","validateField","cleanFlavorData","useErrorTranslation","CreateFlavorModal","client","isOpen","onClose","project","onSuccess","useLingui","translateError","newFlavor","setNewFlavor","errors","setErrors","isLoading","setIsLoading","generalError","setGeneralError","supportsDescription","setSupportsDescription","useEffect","compute","getComputeApiVersion","query","project_id","then","result","catch","handleInputChange","e","name","value","type","checked","target","prev","newState","undefined","handleNumericInputChange","handleBlur","error","handleSubmit","preventDefault","newErrors","requiredFields","forEach","key","optionalFields","Object","keys","length","t","flavorData","createFlavor","mutate","flavor","handleClose","errorMessage","message","dismissError","isFormValid","field","onCancel","size","title","open","onConfirm","cancelButtonLabel","confirmButtonLabel","disableConfirmButton","disableCancelButton","disableCloseButton","status","className","onDismiss","text","variant","id","label","onChange","onBlur","errortext","helptext","required","description","String","vcpus","Number","ram","disk","swap","rxtx_factor","use","Suspense","useState","useRef","startTransition","useEffect","useCallback","ErrorBoundary","useSearch","useNavigate","TRPCClientError","toast","Message","Button","Stack","DataGridToolbar","SearchInput","Status","SortInput","FlavorListContainer","CreateFlavorModal","getFlavorCreatedToast","getFlavorDeletedToast","PAGE_SIZE","createFlavorsPromise","client","project","sortBy","sortDirection","searchTerm","compute","getFlavorsByProjectId","query","project_id","then","res","listError","undefined","catch","err","data","code","flavors","privateFlavorError","message","createPermissionsPromise","canUser","permission","canCreate","canDelete","canAddProject","canRemoveProject","canCreateSpecs","canDeleteSpecs","canManageAccess","canManageSpecs","FlavorsContent","flavorsPromise","permissionsPromise","onFlavorDeleted","onFlavorCreated","setSearchTerm","sortSettings","handleSortChange","createModalOpen","setCreateModalOpen","currentPage","onPageChange","useLingui","permissions","localSearchTerm","setLocalSearchTerm","debounceTimer","clearTimeout","current","p","totalPages","Math","max","ceil","length","safePage","min","paginatedFlavors","slice","isOpen","onClose","onSuccess","className","text","t","variant","distribution","alignment","gap","options","selectClassName","selectWidth","onSortByChange","v","onSortDirectionChange","dir","label","onClick","placeholder","data-testid","value","onInput","e","currentTarget","window","setTimeout","onSearch","onClear","isLoading","canDeleteFlavor","canMangageAccess","Flavors","navigate","searchParams","strict","setSortSettings","search","page","setFlavorsPromise","refetchFlavors","handleFlavorDeleted","flavorName","success","handleFlavorCreated","newSortSettings","settings","toString","prev","replace","handleSearchChange","term","searchValue","handlePageChange","div","fallbackRender","error","status","title","body","Error","fallback","useLingui","Flavors","ContentHeader","Route","RouteComponent","t","projectId","useParams","trpcClient","useRouteContext","component"],"sources":["../../src/client/routes/_auth/projects/$projectId/compute/flavors/-components/FlavorListContainer.tsx","../../src/client/routes/_auth/projects/$projectId/compute/flavors/-components/flavorValidation.ts","../../src/client/routes/_auth/projects/$projectId/compute/flavors/-components/CreateFlavorModal.tsx","../../src/client/routes/_auth/projects/$projectId/compute/flavors/-components/List.tsx","../../src/client/routes/_auth/projects/$projectId/compute/flavors/index.tsx?tsr-split=component"],"sourcesContent":["import { Flavor } from \"@/server/Compute/types/flavor\"\nimport {\n DataGrid,\n DataGridHeadCell,\n DataGridRow,\n DataGridCell,\n PopupMenu,\n PopupMenuOptions,\n PopupMenuItem,\n PopupMenuSectionSeparator,\n Status,\n Pagination,\n} from \"@cloudoperators/juno-ui-components\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { DeleteFlavorModal } from \"./DeleteFlavorModal\"\nimport { useEffect, useState } from \"react\"\nimport { TrpcClient } from \"@/client/trpcClient\"\nimport { EditSpecModal } from \"./EditSpecModal\"\nimport { ManageAccessModal } from \"./ManageAccessModal\"\nimport { useParams, useNavigate } from \"@tanstack/react-router\"\n\ninterface FlavorListContainerProps {\n flavors?: Flavor[]\n isLoading: boolean\n client: TrpcClient\n project: string\n onFlavorDeleted?: (flavorName: string) => void\n canDeleteFlavor?: boolean\n canMangageAccess?: boolean\n canManageSpecs?: boolean\n currentPage?: number\n totalPages?: number\n onPageChange?: (page: number) => void\n}\n\nexport const FlavorListContainer = ({\n flavors,\n isLoading,\n client,\n project,\n onFlavorDeleted,\n canDeleteFlavor,\n canMangageAccess,\n canManageSpecs,\n currentPage = 1,\n totalPages = 1,\n onPageChange,\n}: FlavorListContainerProps) => {\n const { t } = useLingui()\n const navigate = useNavigate()\n const [deleteModalOpen, setDeleteModalOpen] = useState(false)\n const [specModalOpen, setSpecModalOpen] = useState(false)\n const [accessModalOpen, setAccessModalOpen] = useState(false)\n const [selectedFlavor, setSelectedFlavor] = useState<Flavor | null>(null)\n const [inputPage, setInputPage] = useState<string>(currentPage.toString())\n\n useEffect(() => {\n setInputPage(currentPage.toString())\n }, [currentPage])\n\n const { projectId } = useParams({\n from: \"/_auth/projects/$projectId/compute/flavors/\",\n })\n\n const openDeleteModal = (flavor: Flavor) => {\n setSelectedFlavor(flavor)\n setDeleteModalOpen(true)\n }\n\n const openSpecModal = (flavor: Flavor) => {\n setSelectedFlavor(flavor)\n setSpecModalOpen(true)\n }\n\n const openAccessModal = (flavor: Flavor) => {\n setSelectedFlavor(flavor)\n setAccessModalOpen(true)\n }\n\n const closeDeleteModal = () => {\n setDeleteModalOpen(false)\n setSelectedFlavor(null)\n }\n\n const handleDeleteSuccess = () => {\n if (selectedFlavor && onFlavorDeleted) {\n onFlavorDeleted(selectedFlavor.name || \"\")\n }\n closeDeleteModal()\n }\n\n const updateCurrentPage = (newPage: number) => {\n if (newPage >= 1 && newPage <= totalPages) {\n onPageChange?.(newPage)\n setInputPage(newPage.toString())\n }\n }\n\n if (isLoading) {\n return <Status status=\"progress\" title={t`Loading...`} />\n }\n\n return (\n <>\n <DataGrid columns={7} minContentColumns={[6]} className=\"flavors\" data-testid=\"flavors-table\">\n <DataGridRow>\n <DataGridHeadCell>\n <Trans>Name</Trans>\n </DataGridHeadCell>\n <DataGridHeadCell>\n <Trans>vCPU</Trans>\n </DataGridHeadCell>\n <DataGridHeadCell>\n <Trans>RAM (MiB)</Trans>\n </DataGridHeadCell>\n <DataGridHeadCell>\n <Trans>Root Disk (GiB)</Trans>\n </DataGridHeadCell>\n <DataGridHeadCell>\n <Trans>Swap (MiB)</Trans>\n </DataGridHeadCell>\n <DataGridHeadCell>\n <Trans>Access Type</Trans>\n </DataGridHeadCell>\n <DataGridHeadCell></DataGridHeadCell>\n </DataGridRow>\n\n {flavors && flavors.length > 0 ? (\n flavors.map((flavor) => (\n <DataGridRow\n key={flavor.id}\n data-testid={`flavor-row-${flavor.id}`}\n onClick={() =>\n navigate({\n to: \"/projects/$projectId/compute/flavors/$flavorId\",\n params: { projectId, flavorId: flavor.id },\n })\n }\n >\n <DataGridCell>{flavor.name || flavor.id}</DataGridCell>\n <DataGridCell>{flavor.vcpus || \"–\"}</DataGridCell>\n <DataGridCell>{flavor.ram || \"–\"}</DataGridCell>\n <DataGridCell>{flavor.disk || \"–\"}</DataGridCell>\n <DataGridCell>{flavor.swap || \"–\"}</DataGridCell>\n <DataGridCell>{flavor[\"os-flavor-access:is_public\"] === false ? t`Private` : t`Public`}</DataGridCell>\n <DataGridCell onClick={(e) => e.stopPropagation()}>\n <PopupMenu>\n <PopupMenuOptions>\n {canManageSpecs && <PopupMenuItem label={t`Edit Metadata`} onClick={() => openSpecModal(flavor)} />}\n {canMangageAccess && flavor[\"os-flavor-access:is_public\"] === false && (\n <PopupMenuItem label={t`Manage Access`} onClick={() => openAccessModal(flavor)} />\n )}\n <PopupMenuItem\n label={t`Show Details`}\n onClick={() =>\n navigate({\n to: \"/projects/$projectId/compute/flavors/$flavorId\",\n params: { projectId, flavorId: flavor.id },\n })\n }\n />\n {canDeleteFlavor && (\n <>\n <PopupMenuSectionSeparator />\n <PopupMenuItem label={t`Delete Flavor`} onClick={() => openDeleteModal(flavor)} />\n </>\n )}\n </PopupMenuOptions>\n </PopupMenu>\n </DataGridCell>\n </DataGridRow>\n ))\n ) : (\n <DataGridRow>\n <DataGridCell colSpan={7}>\n <Status\n status=\"empty\"\n title={t`No flavors found`}\n body={t`There are no flavors available for this project with the current filters applied. Try adjusting your filter criteria or create a new flavor.`}\n />\n </DataGridCell>\n </DataGridRow>\n )}\n </DataGrid>\n {totalPages > 1 && (\n <div className=\"flex justify-center py-4\">\n <Pagination\n variant=\"input\"\n currentPage={currentPage}\n pages={totalPages}\n onPressPrevious={() => updateCurrentPage(Math.max(currentPage - 1, 1))}\n onPressNext={() => updateCurrentPage(Math.min(currentPage + 1, totalPages))}\n onSelectChange={(selectedPage: number) => {\n updateCurrentPage(selectedPage)\n }}\n onInputChange={(newInputPage?: number) => {\n setInputPage(newInputPage === undefined ? \"\" : String(newInputPage))\n }}\n onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\" && inputPage !== \"\") {\n const newPage = parseInt(inputPage, 10)\n if (!isNaN(newPage) && newPage >= 1 && newPage <= totalPages) {\n updateCurrentPage(newPage)\n }\n }\n }}\n />\n </div>\n )}\n <DeleteFlavorModal\n client={client}\n isOpen={deleteModalOpen}\n onClose={closeDeleteModal}\n project={project}\n flavor={selectedFlavor}\n onSuccess={handleDeleteSuccess}\n />\n <EditSpecModal\n client={client}\n isOpen={specModalOpen}\n onClose={() => setSpecModalOpen(false)}\n project={project}\n flavor={selectedFlavor}\n />\n\n <ManageAccessModal\n client={client}\n isOpen={accessModalOpen}\n onClose={() => setAccessModalOpen(false)}\n project={project}\n flavor={selectedFlavor}\n />\n </>\n )\n}\n","import { msg } from \"@lingui/core/macro\"\nimport { MessageDescriptor } from \"@lingui/core\"\nimport { Flavor } from \"@/server/Compute/types/flavor\"\n\nexport const validateField = (\n field: FlavorFormField,\n value: string | number | boolean | null | undefined,\n t: (descriptor: MessageDescriptor) => string\n): string | undefined => {\n switch (field) {\n case \"id\":\n if (!value) return undefined\n {\n const idStr = String(value).trim()\n const idRegex = /^[a-zA-Z0-9.\\-_]*$/\n return idRegex.test(idStr)\n ? undefined\n : t(msg`ID must only contain alphanumeric characters, hyphens, underscores, and dots.`)\n }\n\n case \"name\": {\n const nameStr = String(value || \"\").trim()\n return nameStr.length >= 2 && nameStr.length <= 50 ? undefined : t(msg`Name must be 2-50 characters long.`)\n }\n\n case \"vcpus\": {\n const vcpus = Number(value)\n return !isNaN(vcpus) && vcpus >= 1 ? undefined : t(msg`VCPUs must be an integer ≥ 1.`)\n }\n\n case \"ram\": {\n const ram = Number(value)\n return !isNaN(ram) && ram >= 128 ? undefined : t(msg`RAM must be an integer ≥ 128 MB.`)\n }\n\n case \"disk\": {\n const disk = Number(value)\n return !isNaN(disk) && disk >= 0 ? undefined : t(msg`Root Disk must be an integer ≥ 0.`)\n }\n\n case \"swap\":\n if (value === \"\" || value === undefined || value === null) return undefined\n {\n const swap = Number(value)\n return !isNaN(swap) && swap >= 0 ? undefined : t(msg`Swap Disk must be an integer ≥ 0.`)\n }\n\n case \"rxtx_factor\": {\n const rxtx = Number(value)\n return !isNaN(rxtx) && rxtx >= 1 ? undefined : t(msg`RX/TX Factor must be an integer ≥ 1.`)\n }\n\n case \"description\":\n if (!value) return undefined\n {\n const str = String(value)\n return str.length < 65535 ? undefined : t(msg`Description must be less than 65535 characters.`)\n }\n\n case \"OS-FLV-EXT-DATA:ephemeral\": {\n const ephemeral = Number(value)\n return !isNaN(ephemeral) && ephemeral >= 0 ? undefined : t(msg`Ephemeral Disk must be an integer ≥ 0.`)\n }\n\n case \"os-flavor-access:is_public\": {\n if (value === undefined || value === null) {\n return undefined\n }\n if (typeof value === \"boolean\") {\n return undefined\n }\n if (typeof value === \"string\" && (value === \"true\" || value === \"false\")) {\n return undefined\n }\n return t(msg`Invalid value for public flavor setting.`)\n }\n\n default:\n return undefined\n }\n}\n\nexport type FlavorFormField =\n | \"id\"\n | \"name\"\n | \"vcpus\"\n | \"ram\"\n | \"disk\"\n | \"swap\"\n | \"description\"\n | \"rxtx_factor\"\n | \"OS-FLV-EXT-DATA:ephemeral\"\n | \"os-flavor-access:is_public\"\n\nexport interface FieldErrors {\n id?: string\n name?: string\n vcpus?: string\n ram?: string\n disk?: string\n swap?: string\n rxtx_factor?: string\n description?: string\n \"OS-FLV-EXT-DATA:ephemeral\"?: string\n \"os-flavor-access:is_public\"?: string\n}\n\nexport const cleanFlavorData = (flavor: Partial<Flavor>) => {\n const result: {\n name: string\n vcpus: number\n ram: number\n disk: number\n \"OS-FLV-EXT-DATA:ephemeral\"?: number\n id?: string\n swap?: number\n rxtx_factor?: number\n description?: string\n \"os-flavor-access:is_public\"?: boolean\n } = {\n name: String(flavor.name),\n vcpus: Number(flavor.vcpus),\n ram: Number(flavor.ram),\n disk: Number(flavor.disk),\n }\n\n const isValidValue = (value: string | undefined | null) => {\n return value !== undefined && value !== null && value !== \"\" && String(value).trim() !== \"\"\n }\n\n const isValidNumber = (value: string | number | undefined | null) => {\n return value !== undefined && value !== null && value !== \"\" && String(value).trim() !== \"\" && !isNaN(Number(value))\n }\n\n if (isValidValue(flavor.id)) {\n result.id = String(flavor.id).trim()\n }\n\n if (isValidValue(flavor.description)) {\n result.description = String(flavor.description).trim()\n }\n\n if (isValidNumber(flavor.swap)) {\n result.swap = Number(flavor.swap)\n }\n\n if (isValidNumber(flavor.rxtx_factor)) {\n result.rxtx_factor = Number(flavor.rxtx_factor)\n }\n\n if (isValidNumber(flavor[\"OS-FLV-EXT-DATA:ephemeral\"])) {\n result[\"OS-FLV-EXT-DATA:ephemeral\"] = Number(flavor[\"OS-FLV-EXT-DATA:ephemeral\"])\n }\n\n if (flavor[\"os-flavor-access:is_public\"] !== undefined) {\n result[\"os-flavor-access:is_public\"] = Boolean(flavor[\"os-flavor-access:is_public\"])\n }\n\n return result\n}\n","import React, { useState } from \"react\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { TrpcClient } from \"@/client/trpcClient\"\nimport {\n Modal,\n Form,\n FormRow,\n FormSection,\n TextInput,\n Message,\n Status,\n Checkbox,\n} from \"@cloudoperators/juno-ui-components\"\nimport { Flavor } from \"@/server/Compute/types/flavor\"\nimport { validateField, FlavorFormField, FieldErrors } from \"./flavorValidation\"\nimport { cleanFlavorData } from \"./flavorValidation\"\nimport { useErrorTranslation } from \"@/client/utils/useErrorTranslation\"\n\ninterface CreateFlavorModalProps {\n client: TrpcClient\n isOpen: boolean\n onClose: () => void\n project: string\n onSuccess: (name: string) => void\n}\n\nexport const CreateFlavorModal: React.FC<CreateFlavorModalProps> = ({\n client,\n isOpen,\n onClose,\n project,\n onSuccess,\n}) => {\n const { t } = useLingui()\n const { translateError } = useErrorTranslation()\n const [newFlavor, setNewFlavor] = useState<Partial<Flavor>>({\n \"os-flavor-access:is_public\": true,\n })\n const [errors, setErrors] = useState<FieldErrors>({})\n const [isLoading, setIsLoading] = useState(false)\n const [generalError, setGeneralError] = useState<string | null>(null)\n const [supportsDescription, setSupportsDescription] = useState(false)\n\n // Check if Nova API supports description field (microversion 2.55+)\n React.useEffect(() => {\n if (isOpen) {\n client.compute.getComputeApiVersion\n .query({ project_id: project })\n .then((result) => setSupportsDescription(result.supportsDescription))\n .catch(() => setSupportsDescription(false))\n }\n }, [isOpen, client, project])\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const { name, value, type, checked } = e.target\n\n setNewFlavor((prev) => {\n const newState = {\n ...prev,\n [name]: type === \"checkbox\" ? checked : value,\n }\n\n return newState\n })\n // Clear error for this field when user changes the value\n setErrors((prev) => ({\n ...prev,\n [name]: undefined,\n }))\n if (generalError) setGeneralError(null)\n }\n\n const handleNumericInputChange = (name: FlavorFormField, value: number | undefined) => {\n setNewFlavor((prev) => ({\n ...prev,\n [name]: value,\n }))\n // Clear error for this field when user changes the value\n setErrors((prev) => ({\n ...prev,\n [name]: undefined,\n }))\n if (generalError) setGeneralError(null)\n }\n\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n const { name, value } = e.target\n const error = validateField(name as FlavorFormField, value, t)\n setErrors((prev) => ({\n ...prev,\n [name]: error,\n }))\n }\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n setGeneralError(null)\n\n const newErrors: FieldErrors = {}\n\n const requiredFields: FlavorFormField[] = [\"name\", \"vcpus\", \"ram\", \"disk\"]\n requiredFields.forEach((key) => {\n const error = validateField(key, newFlavor[key], t)\n if (error) {\n newErrors[key] = error\n }\n })\n\n const optionalFields: FlavorFormField[] = [\n \"id\",\n \"swap\",\n \"OS-FLV-EXT-DATA:ephemeral\",\n \"rxtx_factor\",\n \"description\",\n \"os-flavor-access:is_public\",\n ]\n optionalFields.forEach((key) => {\n const value = newFlavor[key]\n\n if (value !== undefined && value !== \"\" && value !== null) {\n const error = validateField(key, value, t)\n if (error) {\n newErrors[key] = error\n }\n }\n })\n\n if (Object.keys(newErrors).length > 0) {\n setErrors(newErrors)\n setGeneralError(t`Please fix the validation errors below.`)\n return\n }\n\n try {\n setIsLoading(true)\n\n const flavorData = cleanFlavorData(newFlavor)\n\n await client.compute.createFlavor.mutate({\n project_id: project,\n flavor: flavorData,\n })\n\n onSuccess(flavorData.name)\n handleClose()\n } catch (error) {\n const errorMessage = (error as Error)?.message\n ? translateError((error as Error).message)\n : t`Failed to create flavor. Please try again.`\n setGeneralError(errorMessage)\n } finally {\n setIsLoading(false)\n }\n }\n\n const handleClose = () => {\n setNewFlavor({\n \"os-flavor-access:is_public\": true,\n })\n setErrors({})\n setGeneralError(null)\n onClose()\n }\n\n const dismissError = () => {\n setGeneralError(null)\n }\n\n const isFormValid = () => {\n // Check required fields are filled and have no errors\n const requiredFields: FlavorFormField[] = [\"name\", \"vcpus\", \"ram\", \"disk\"]\n\n for (const field of requiredFields) {\n const value = newFlavor[field]\n // Field must have a value\n if (value === undefined || value === \"\" || value === null) return false\n // Field must not have a validation error\n if (validateField(field, value, t)) return false\n }\n\n // Check optional fields for errors (if they have values)\n const optionalFields: FlavorFormField[] = [\"id\", \"swap\", \"OS-FLV-EXT-DATA:ephemeral\", \"rxtx_factor\", \"description\"]\n\n for (const field of optionalFields) {\n const value = newFlavor[field]\n // Skip empty optional fields\n if (value === undefined || value === \"\" || value === null) continue\n // Field must not have a validation error\n if (validateField(field, value, t)) return false\n }\n\n return true\n }\n\n return (\n <Modal\n onCancel={handleClose}\n size=\"large\"\n title={t`Create Flavor`}\n open={isOpen}\n onConfirm={handleSubmit}\n cancelButtonLabel={t`Cancel`}\n confirmButtonLabel={t`Create New Flavor`}\n disableConfirmButton={!isFormValid() || isLoading}\n disableCancelButton={isLoading}\n disableCloseButton={isLoading}\n >\n {isLoading && <Status status=\"progress\" title={t`Creating Flavor...`} className=\"mt-0\" />}\n {!isLoading && (\n <Form>\n {generalError && (\n <FormRow>\n <Message onDismiss={dismissError} text={generalError} variant=\"error\" />\n </FormRow>\n )}\n\n <FormSection title={t`Flavor Information`}>\n <FormRow>\n <TextInput\n id=\"id\"\n name=\"id\"\n label={t`Flavor ID`}\n value={newFlavor.id || \"\"}\n onChange={handleInputChange}\n onBlur={handleBlur}\n errortext={errors.id}\n helptext={t`Auto-generated if not provided. Only alphanumeric, hyphens, underscores, and dots allowed.`}\n />\n </FormRow>\n <FormRow>\n <TextInput\n id=\"name\"\n name=\"name\"\n label={t`Flavor Name`}\n value={newFlavor.name || \"\"}\n onChange={handleInputChange}\n onBlur={handleBlur}\n errortext={errors.name}\n helptext={t`2-50 characters.`}\n required\n />\n </FormRow>\n {supportsDescription && (\n <FormRow>\n <TextInput\n id=\"description\"\n name=\"description\"\n label={t`Description`}\n value={newFlavor.description || \"\"}\n onChange={handleInputChange}\n onBlur={handleBlur}\n errortext={errors.description}\n />\n </FormRow>\n )}\n <FormRow>\n <Checkbox\n name=\"os-flavor-access:is_public\"\n label={t`Public Flavor`}\n helptext={t`When checked, all tenants can use this flavor. Otherwise, grant access explicitly.`}\n checked={!!newFlavor[\"os-flavor-access:is_public\"]}\n onChange={handleInputChange}\n />\n </FormRow>\n </FormSection>\n\n <FormSection title={t`Hardware Specifications`}>\n <FormRow>\n <TextInput\n id=\"vcpus\"\n name=\"vcpus\"\n label={t`vCPU`}\n value={String(newFlavor.vcpus || \"\")}\n onChange={(e) => handleNumericInputChange(\"vcpus\", Number(e.target.value))}\n onBlur={handleBlur}\n errortext={errors.vcpus}\n type=\"number\"\n required\n />\n </FormRow>\n <FormRow>\n <TextInput\n id=\"ram\"\n name=\"ram\"\n label={t`RAM (MiB)`}\n value={String(newFlavor.ram || \"\")}\n onChange={(e) => handleNumericInputChange(\"ram\", Number(e.target.value))}\n onBlur={handleBlur}\n errortext={errors.ram}\n helptext={t`Minimum 128 MB.`}\n type=\"number\"\n required\n />\n </FormRow>\n <FormRow>\n <TextInput\n id=\"disk\"\n name=\"disk\"\n label={t`Root Disk (GiB)`}\n value={String(newFlavor.disk || \"\")}\n onChange={(e) => handleNumericInputChange(\"disk\", Number(e.target.value))}\n onBlur={handleBlur}\n errortext={errors.disk}\n type=\"number\"\n required\n />\n </FormRow>\n <FormRow>\n <TextInput\n id=\"OS-FLV-EXT-DATA:ephemeral\"\n name=\"OS-FLV-EXT-DATA:ephemeral\"\n label={t`Ephemeral Disk (GiB)`}\n value={String(newFlavor[\"OS-FLV-EXT-DATA:ephemeral\"] || \"\")}\n onChange={(e) => handleNumericInputChange(\"OS-FLV-EXT-DATA:ephemeral\", Number(e.target.value))}\n onBlur={handleBlur}\n errortext={errors[\"OS-FLV-EXT-DATA:ephemeral\"]}\n type=\"number\"\n />\n </FormRow>\n <FormRow>\n <TextInput\n id=\"swap\"\n name=\"swap\"\n label={t`Swap (MiB)`}\n value={String(newFlavor.swap || \"\")}\n onChange={(e) => handleNumericInputChange(\"swap\", e.target.value ? Number(e.target.value) : undefined)}\n onBlur={handleBlur}\n errortext={errors.swap}\n type=\"number\"\n />\n </FormRow>\n <FormRow>\n <TextInput\n id=\"rxtx_factor\"\n name=\"rxtx_factor\"\n label={t`RX/TX Factor`}\n value={String(newFlavor.rxtx_factor || \"\")}\n onChange={(e) => handleNumericInputChange(\"rxtx_factor\", Number(e.target.value))}\n onBlur={handleBlur}\n errortext={errors.rxtx_factor}\n helptext={t`Defaults to 1.`}\n type=\"number\"\n />\n </FormRow>\n </FormSection>\n </Form>\n )}\n </Modal>\n )\n}\n","import { use, Suspense, useState, useRef, startTransition, useEffect, useCallback } from \"react\"\nimport { ErrorBoundary } from \"react-error-boundary\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { useSearch, useNavigate } from \"@tanstack/react-router\"\nimport { TrpcClient } from \"@/client/trpcClient\"\nimport { Flavor } from \"@/server/Compute/types/flavor\"\nimport { TRPCClientError } from \"@trpc/client\"\nimport { toast, Message, Button, Stack, DataGridToolbar, SearchInput, Status } from \"@cloudoperators/juno-ui-components\"\nimport { SortInput } from \"@/client/components/ListToolbar/SortInput\"\nimport { SortSettings } from \"@/client/components/ListToolbar/types\"\nimport { FlavorListContainer } from \"./FlavorListContainer\"\nimport { CreateFlavorModal } from \"./CreateFlavorModal\"\nimport { getFlavorCreatedToast, getFlavorDeletedToast } from \"./FlavorToastNotifications\"\nimport type { FlavorsSearchParams } from \"@/client/routes/_auth/projects/$projectId/compute/flavors\"\n\nconst PAGE_SIZE = 50\n\ninterface FlavorsProps {\n client: TrpcClient\n project: string\n}\n\ntype RequiredSortSettings = {\n options: SortSettings[\"options\"]\n sortBy: string\n sortDirection: \"asc\" | \"desc\"\n}\n\nconst createFlavorsPromise = (\n client: TrpcClient,\n project: string,\n sortBy: string,\n sortDirection: string,\n searchTerm: string\n) => {\n return client.compute.getFlavorsByProjectId\n .query({ project_id: project, sortBy, sortDirection, searchTerm })\n .then((res) => ({ ...res, listError: undefined as string | undefined }))\n .catch((err: unknown) => {\n if (err instanceof TRPCClientError && err.data?.code === \"FORBIDDEN\") {\n return { flavors: [] as Flavor[], privateFlavorError: undefined, listError: err.message }\n }\n throw err\n })\n}\n\nconst createPermissionsPromise = (client: TrpcClient, project: string) => {\n return client.compute.canUser\n .query({\n project_id: project,\n permission: [\n \"flavors:create\",\n \"flavors:delete\",\n \"flavors:add_project\",\n \"flavors:remove_project\",\n \"flavor_specs:create\",\n \"flavor_specs:delete\",\n ],\n })\n .then(([canCreate, canDelete, canAddProject, canRemoveProject, canCreateSpecs, canDeleteSpecs]) => ({\n canCreate,\n canDelete,\n canManageAccess: canAddProject || canRemoveProject,\n canManageSpecs: canCreateSpecs || canDeleteSpecs,\n }))\n}\n\nfunction FlavorsContent({\n flavorsPromise,\n permissionsPromise,\n client,\n project,\n onFlavorDeleted,\n onFlavorCreated,\n searchTerm,\n setSearchTerm,\n sortSettings,\n handleSortChange,\n createModalOpen,\n setCreateModalOpen,\n currentPage,\n onPageChange,\n}: {\n flavorsPromise: Promise<{ flavors: Flavor[]; privateFlavorError?: string; listError?: string }>\n permissionsPromise: Promise<{\n canCreate: boolean\n canDelete: boolean\n canManageAccess: boolean\n canManageSpecs: boolean\n }>\n client: TrpcClient\n project: string\n onFlavorDeleted: (name: string) => void\n onFlavorCreated: (name: string) => void\n searchTerm: string\n setSearchTerm: (term: string) => void\n sortSettings: SortSettings\n handleSortChange: (settings: SortSettings) => void\n createModalOpen: boolean\n setCreateModalOpen: (open: boolean) => void\n currentPage: number\n onPageChange: (page: number) => void\n}) {\n const { t } = useLingui()\n const { flavors, privateFlavorError, listError } = use(flavorsPromise)\n const permissions = use(permissionsPromise)\n const [localSearchTerm, setLocalSearchTerm] = useState(searchTerm)\n const debounceTimer = useRef<number | undefined>(undefined)\n\n useEffect(() => () => clearTimeout(debounceTimer.current), [])\n\n if (listError) {\n return <p>{listError}</p>\n }\n\n const totalPages = Math.max(1, Math.ceil(flavors.length / PAGE_SIZE))\n const safePage = Math.min(currentPage, totalPages)\n const paginatedFlavors = flavors.slice((safePage - 1) * PAGE_SIZE, safePage * PAGE_SIZE)\n\n useEffect(() => {\n if (currentPage > totalPages) onPageChange(1)\n }, [totalPages, currentPage, onPageChange])\n\n return (\n <>\n <CreateFlavorModal\n client={client}\n isOpen={createModalOpen}\n project={project}\n onClose={() => setCreateModalOpen(false)}\n onSuccess={onFlavorCreated}\n />\n\n {privateFlavorError && (\n <Message\n className=\"mb-4\"\n text={t`Private flavors could not be loaded. You may be seeing an incomplete list.`}\n variant=\"warning\"\n />\n )}\n\n {/* Zone 1 — sort + create action, no background */}\n <Stack distribution=\"end\" alignment=\"center\" gap=\"2\" className=\"pb-2\">\n <Stack gap=\"2\">\n <SortInput\n options={sortSettings.options}\n sortBy={sortSettings.sortBy}\n sortDirection={sortSettings.sortDirection ?? \"asc\"}\n selectClassName=\"min-w-45\"\n selectWidth=\"auto\"\n onSortByChange={(v) =>\n handleSortChange({ ...sortSettings, sortBy: v, sortDirection: sortSettings.sortDirection })\n }\n onSortDirectionChange={(dir) => handleSortChange({ ...sortSettings, sortDirection: dir })}\n />\n {permissions.canCreate && (\n <Button variant=\"primary\" label={t`Create Flavor`} onClick={() => setCreateModalOpen(true)} />\n )}\n </Stack>\n </Stack>\n\n {/* Zone 2 — search bar */}\n <DataGridToolbar>\n <Stack distribution=\"end\" alignment=\"center\">\n <SearchInput\n placeholder={t`Search flavors...`}\n data-testid=\"searchbar\"\n value={localSearchTerm}\n onInput={(e: React.FormEvent<HTMLInputElement>) => {\n const v = e.currentTarget.value\n setLocalSearchTerm(v)\n clearTimeout(debounceTimer.current)\n debounceTimer.current = window.setTimeout(() => setSearchTerm(v), 500)\n }}\n onSearch={(v) => {\n clearTimeout(debounceTimer.current)\n setSearchTerm(typeof v === \"string\" ? v : \"\")\n }}\n onClear={() => {\n clearTimeout(debounceTimer.current)\n setLocalSearchTerm(\"\")\n setSearchTerm(\"\")\n }}\n />\n </Stack>\n </DataGridToolbar>\n\n <FlavorListContainer\n flavors={paginatedFlavors}\n isLoading={false}\n client={client}\n project={project}\n onFlavorDeleted={onFlavorDeleted}\n canDeleteFlavor={permissions.canDelete}\n canMangageAccess={permissions.canManageAccess}\n canManageSpecs={permissions.canManageSpecs}\n currentPage={safePage}\n totalPages={totalPages}\n onPageChange={onPageChange}\n />\n </>\n )\n}\nexport const Flavors = ({ client, project }: FlavorsProps) => {\n const { t } = useLingui()\n const navigate = useNavigate()\n const searchParams = useSearch({ strict: false }) as FlavorsSearchParams\n\n const [sortSettings, setSortSettings] = useState<RequiredSortSettings>({\n options: [\n { label: t`Name`, value: \"name\" },\n { label: t`vCPU`, value: \"vcpus\" },\n { label: t`RAM (MiB)`, value: \"ram\" },\n { label: t`Root Disk (GiB)`, value: \"disk\" },\n { label: t`Swap (MiB)`, value: \"swap\" },\n ],\n sortBy: searchParams.sortBy || \"name\",\n sortDirection: searchParams.sortDirection || \"asc\",\n })\n\n const [searchTerm, setSearchTerm] = useState(searchParams.search || \"\")\n const currentPage = searchParams.page ?? 1\n const [createModalOpen, setCreateModalOpen] = useState(false)\n\n const [flavorsPromise, setFlavorsPromise] = useState(() =>\n createFlavorsPromise(client, project, sortSettings.sortBy, sortSettings.sortDirection, searchTerm)\n )\n const [permissionsPromise] = useState(() => createPermissionsPromise(client, project))\n\n const refetchFlavors = () => {\n startTransition(() => {\n setFlavorsPromise(\n createFlavorsPromise(client, project, sortSettings.sortBy, sortSettings.sortDirection, searchTerm)\n )\n })\n }\n\n const handleFlavorDeleted = (flavorName: string) => {\n const { message, ...options } = getFlavorDeletedToast(flavorName)\n toast.success(message, options)\n refetchFlavors()\n }\n\n const handleFlavorCreated = (flavorName: string) => {\n const { message, ...options } = getFlavorCreatedToast(flavorName)\n toast.success(message, options)\n refetchFlavors()\n }\n\n const handleSortChange = (newSortSettings: SortSettings) => {\n const settings: RequiredSortSettings = {\n options: newSortSettings.options,\n sortBy: newSortSettings.sortBy?.toString() || \"name\",\n sortDirection: newSortSettings.sortDirection || \"asc\",\n }\n\n setSortSettings(settings)\n navigate({\n search: ((prev: FlavorsSearchParams) => ({\n ...prev,\n sortBy: settings.sortBy,\n sortDirection: settings.sortDirection,\n page: undefined,\n })) as unknown as true,\n replace: true,\n })\n startTransition(() => {\n setFlavorsPromise(createFlavorsPromise(client, project, settings.sortBy, settings.sortDirection, searchTerm))\n })\n }\n\n const handleSearchChange = (term: string | number | string[] | undefined) => {\n const searchValue = typeof term === \"string\" ? term : \"\"\n setSearchTerm(searchValue)\n\n navigate({\n search: ((prev: FlavorsSearchParams) => ({\n ...prev,\n search: searchValue || undefined,\n page: undefined,\n })) as unknown as true,\n replace: true,\n })\n startTransition(() => {\n setFlavorsPromise(\n createFlavorsPromise(client, project, sortSettings.sortBy, sortSettings.sortDirection, searchValue)\n )\n })\n }\n\n const handlePageChange = useCallback(\n (page: number) => {\n navigate({\n search: ((prev: FlavorsSearchParams) => ({\n ...prev,\n page: page === 1 ? undefined : page,\n })) as unknown as true,\n })\n },\n [navigate]\n )\n\n return (\n <div className=\"relative\">\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <Status\n status=\"error\"\n title={t`Failed to Load Flavors`}\n body={error instanceof Error ? error.message : t`An unexpected error occurred.`}\n />\n )}\n >\n <Suspense fallback={<Status status=\"progress\" title={t`Loading Flavors...`} />}>\n <FlavorsContent\n flavorsPromise={flavorsPromise}\n permissionsPromise={permissionsPromise}\n client={client}\n project={project}\n onFlavorDeleted={handleFlavorDeleted}\n onFlavorCreated={handleFlavorCreated}\n searchTerm={searchTerm}\n setSearchTerm={handleSearchChange}\n sortSettings={sortSettings}\n handleSortChange={handleSortChange}\n createModalOpen={createModalOpen}\n setCreateModalOpen={setCreateModalOpen}\n currentPage={currentPage}\n onPageChange={handlePageChange}\n />\n </Suspense>\n </ErrorBoundary>\n </div>\n )\n}\n","import { createFileRoute } from \"@tanstack/react-router\"\nimport { t } from \"@lingui/core/macro\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { Flavors } from \"./-components/List\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { ContentHeader } from \"@/client/components/ContentHeader/ContentHeader\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/compute/flavors/\")({\n staticData: {\n section: \"compute\",\n service: \"flavors\",\n analytics: {\n name: \"compute.flavors.list\",\n },\n } satisfies RouteInfo,\n head: () => ({ meta: [{ title: t`Flavors` }] }),\n component: RouteComponent,\n})\n\nfunction RouteComponent() {\n const { t } = useLingui()\n const { projectId } = Route.useParams()\n const { trpcClient } = Route.useRouteContext()\n return (\n <>\n <ContentHeader title={t`Flavors`} projectId={projectId} />\n <Flavors project={projectId} client={trpcClient!} />\n </>\n )\n}\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { a as b } from "./trpcClient-D7gpR7YG.mjs";
3
3
  import { t as x } from "./useProjectId-DBc5lpoU.mjs";
4
4
  import { t as S } from "./SortInput-4g7nSTHW.mjs";
5
5
  import { d as C, n as w, o as T } from "./md-kvaGCNAK.mjs";
6
- import { t as E } from "./ContentHeader-CPJbgYWn.mjs";
6
+ import { t as E } from "./ContentHeader-fKKZVu-o.mjs";
7
7
  import "./hooks-D0yKIumu.mjs";
8
8
  import { t as D } from "./useModal-DCs1OJh7.mjs";
9
9
  import { n as O, t as k } from "./FiltersInput-Becwxo_J.mjs";
@@ -548,4 +548,4 @@ function se() {
548
548
  //#endregion
549
549
  export { se as component };
550
550
 
551
- //# sourceMappingURL=floatingips-B1oLH8z6.mjs.map
551
+ //# sourceMappingURL=floatingips-DXnRlLvV.mjs.map