@cobaltcore-dev/aurora 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -25
- package/dist/client/AuroraApp.d.ts +9 -2
- package/dist/client/context/AppConfigContext.d.ts +44 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +41221 -845
- package/dist/client/index.js.map +1 -1
- package/dist/client/trpcClient.d.ts +314 -0
- package/dist/client/utils/appConfigGating.d.ts +21 -0
- package/dist/server/index.d.ts +694 -3
- package/dist/server/index.js +1748 -722
- package/package.json +3 -3
- package/dist/client/AuthProvider-CVSAwW9f.mjs +0 -83
- package/dist/client/AuthProvider-CVSAwW9f.mjs.map +0 -1
- package/dist/client/ContentHeader-fKKZVu-o.mjs +0 -116
- package/dist/client/ContentHeader-fKKZVu-o.mjs.map +0 -1
- package/dist/client/DeleteFlavorModal-C4nAi7gY.mjs +0 -724
- package/dist/client/DeleteFlavorModal-C4nAi7gY.mjs.map +0 -1
- package/dist/client/DynamicBreadcrumbContext-CVcUQFou.mjs +0 -26
- package/dist/client/DynamicBreadcrumbContext-CVcUQFou.mjs.map +0 -1
- package/dist/client/FiltersInput-Becwxo_J.mjs +0 -85
- package/dist/client/FiltersInput-Becwxo_J.mjs.map +0 -1
- package/dist/client/FloatingIpActionModals-Cq10WljB.mjs +0 -466
- package/dist/client/FloatingIpActionModals-Cq10WljB.mjs.map +0 -1
- package/dist/client/RouteIdLevelDefaultError-DPF_x2tG.mjs +0 -26
- package/dist/client/RouteIdLevelDefaultError-DPF_x2tG.mjs.map +0 -1
- package/dist/client/Slot-CWb612-_.mjs +0 -28
- package/dist/client/Slot-CWb612-_.mjs.map +0 -1
- package/dist/client/SortInput-4g7nSTHW.mjs +0 -34
- package/dist/client/SortInput-4g7nSTHW.mjs.map +0 -1
- package/dist/client/StorageNotFound-B-zVinVD.mjs +0 -30
- package/dist/client/StorageNotFound-B-zVinVD.mjs.map +0 -1
- package/dist/client/TwoColumnDescriptionList-DKS42RKa.mjs +0 -28
- package/dist/client/TwoColumnDescriptionList-DKS42RKa.mjs.map +0 -1
- package/dist/client/_-CAsCx-Ay.mjs +0 -6
- package/dist/client/_-CAsCx-Ay.mjs.map +0 -1
- package/dist/client/_auth-SrDjHL6j.mjs +0 -12
- package/dist/client/_auth-SrDjHL6j.mjs.map +0 -1
- package/dist/client/_flavorId-BPvssEzn.mjs +0 -277
- package/dist/client/_flavorId-BPvssEzn.mjs.map +0 -1
- package/dist/client/_flavorId-CFUBcU-l.mjs +0 -27
- package/dist/client/_flavorId-CFUBcU-l.mjs.map +0 -1
- package/dist/client/_flavorId-CZcIp0Ih.mjs +0 -22
- package/dist/client/_flavorId-CZcIp0Ih.mjs.map +0 -1
- package/dist/client/_floatingIpId-B8r64AL9.mjs +0 -196
- package/dist/client/_floatingIpId-B8r64AL9.mjs.map +0 -1
- package/dist/client/_floatingIpId-lEobpOER.mjs +0 -26
- package/dist/client/_floatingIpId-lEobpOER.mjs.map +0 -1
- package/dist/client/_imageId-BAezmV0Y.mjs +0 -526
- package/dist/client/_imageId-BAezmV0Y.mjs.map +0 -1
- package/dist/client/_imageId-D-jqz3e3.mjs +0 -40
- package/dist/client/_imageId-D-jqz3e3.mjs.map +0 -1
- package/dist/client/_imageId-gMdrdnVt.mjs +0 -22
- package/dist/client/_imageId-gMdrdnVt.mjs.map +0 -1
- package/dist/client/_projectId-BYccdAtX.mjs +0 -77
- package/dist/client/_projectId-BYccdAtX.mjs.map +0 -1
- package/dist/client/_projectId-CBjZC1tv.mjs +0 -283
- package/dist/client/_projectId-CBjZC1tv.mjs.map +0 -1
- package/dist/client/_projectId-CLEa1zgw.mjs +0 -30
- package/dist/client/_projectId-CLEa1zgw.mjs.map +0 -1
- package/dist/client/_projectId-D3VOH5lN.mjs +0 -94
- package/dist/client/_projectId-D3VOH5lN.mjs.map +0 -1
- package/dist/client/_securityGroupId-BwgZnoiR.mjs +0 -29
- package/dist/client/_securityGroupId-BwgZnoiR.mjs.map +0 -1
- package/dist/client/_securityGroupId-Cz2NUHdB.mjs +0 -1819
- package/dist/client/_securityGroupId-Cz2NUHdB.mjs.map +0 -1
- package/dist/client/_serviceType-DS8DxsrP.mjs +0 -20
- package/dist/client/_serviceType-DS8DxsrP.mjs.map +0 -1
- package/dist/client/_serviceType-M8d9rOT6.mjs +0 -6
- package/dist/client/_serviceType-M8d9rOT6.mjs.map +0 -1
- package/dist/client/_storageType-BNpP1A2N.mjs +0 -13
- package/dist/client/_storageType-BNpP1A2N.mjs.map +0 -1
- package/dist/client/_storageType-BxSGKhAI.mjs +0 -15
- package/dist/client/_storageType-BxSGKhAI.mjs.map +0 -1
- package/dist/client/_storageType-DZYCmiLt.mjs +0 -30
- package/dist/client/_storageType-DZYCmiLt.mjs.map +0 -1
- package/dist/client/_storageType-UqAMP-8d.mjs +0 -859
- package/dist/client/_storageType-UqAMP-8d.mjs.map +0 -1
- package/dist/client/_storageType-u51_7OwJ.mjs +0 -7
- package/dist/client/_storageType-u51_7OwJ.mjs.map +0 -1
- package/dist/client/about-BmQTyLWc.mjs +0 -92
- package/dist/client/about-BmQTyLWc.mjs.map +0 -1
- package/dist/client/assets/__mocks__/svgMock.d.ts +0 -3
- package/dist/client/aurora-CIml-f2f.mjs +0 -19
- package/dist/client/aurora-CIml-f2f.mjs.map +0 -1
- package/dist/client/build-WuxXRAqf.mjs +0 -14530
- package/dist/client/build-WuxXRAqf.mjs.map +0 -1
- package/dist/client/cn-DM4Cy3jv.mjs +0 -10
- package/dist/client/cn-DM4Cy3jv.mjs.map +0 -1
- package/dist/client/flavors-CJVSNz6R.mjs +0 -15
- package/dist/client/flavors-CJVSNz6R.mjs.map +0 -1
- package/dist/client/flavors-CflJDIEH.mjs +0 -667
- package/dist/client/flavors-CflJDIEH.mjs.map +0 -1
- package/dist/client/flavors-DWMZ6TuJ.mjs +0 -8
- package/dist/client/flavors-DWMZ6TuJ.mjs.map +0 -1
- package/dist/client/floatingips-Cz9k80cc.mjs +0 -8
- package/dist/client/floatingips-Cz9k80cc.mjs.map +0 -1
- package/dist/client/floatingips-DXnRlLvV.mjs +0 -551
- package/dist/client/floatingips-DXnRlLvV.mjs.map +0 -1
- package/dist/client/floatingips-HRbuLxiN.mjs +0 -22
- package/dist/client/floatingips-HRbuLxiN.mjs.map +0 -1
- package/dist/client/floatingips-nN1kQmsu.mjs +0 -14
- package/dist/client/floatingips-nN1kQmsu.mjs.map +0 -1
- package/dist/client/formatBytes-CZv_XyCY.mjs +0 -38
- package/dist/client/formatBytes-CZv_XyCY.mjs.map +0 -1
- package/dist/client/helpers-1PpYf-fC.mjs +0 -6
- package/dist/client/helpers-1PpYf-fC.mjs.map +0 -1
- package/dist/client/hooks-D0yKIumu.mjs +0 -22
- package/dist/client/hooks-D0yKIumu.mjs.map +0 -1
- package/dist/client/imageHelpers-DBhL2ebL.mjs +0 -1272
- package/dist/client/imageHelpers-DBhL2ebL.mjs.map +0 -1
- package/dist/client/images-BsylWUiH.mjs +0 -2011
- package/dist/client/images-BsylWUiH.mjs.map +0 -1
- package/dist/client/images-NBf2bV43.mjs +0 -8
- package/dist/client/images-NBf2bV43.mjs.map +0 -1
- package/dist/client/images-zQq1nSVv.mjs +0 -15
- package/dist/client/images-zQq1nSVv.mjs.map +0 -1
- package/dist/client/md-kvaGCNAK.mjs +0 -336
- package/dist/client/md-kvaGCNAK.mjs.map +0 -1
- package/dist/client/network-DuZm76BZ.mjs +0 -8
- package/dist/client/network-DuZm76BZ.mjs.map +0 -1
- package/dist/client/objects-BudUAfWY.mjs +0 -12909
- package/dist/client/objects-BudUAfWY.mjs.map +0 -1
- package/dist/client/objects-Dc7sKUr8.mjs +0 -67
- package/dist/client/objects-Dc7sKUr8.mjs.map +0 -1
- package/dist/client/objects-Dw7oeTq2.mjs +0 -80
- package/dist/client/objects-Dw7oeTq2.mjs.map +0 -1
- package/dist/client/objects-_g7nGIn5.mjs +0 -25
- package/dist/client/objects-_g7nGIn5.mjs.map +0 -1
- package/dist/client/objects-eBxvY6_n.mjs +0 -78
- package/dist/client/objects-eBxvY6_n.mjs.map +0 -1
- package/dist/client/projects-yiK0HGSA.mjs +0 -7
- package/dist/client/projects-yiK0HGSA.mjs.map +0 -1
- package/dist/client/routeInfo-DP3v74Wg.mjs +0 -19
- package/dist/client/routeInfo-DP3v74Wg.mjs.map +0 -1
- package/dist/client/routes-CJj7SR_K.mjs +0 -10
- package/dist/client/routes-CJj7SR_K.mjs.map +0 -1
- package/dist/client/routes-xofA3ksU.mjs +0 -110
- package/dist/client/routes-xofA3ksU.mjs.map +0 -1
- package/dist/client/securitygroups-CSmsBzUb.mjs +0 -581
- package/dist/client/securitygroups-CSmsBzUb.mjs.map +0 -1
- package/dist/client/securitygroups-CtKne8UQ.mjs +0 -8
- package/dist/client/securitygroups-CtKne8UQ.mjs.map +0 -1
- package/dist/client/securitygroups-T7kaNFEp.mjs +0 -15
- package/dist/client/securitygroups-T7kaNFEp.mjs.map +0 -1
- package/dist/client/securitygroups-WLB1_IM6.mjs +0 -22
- package/dist/client/securitygroups-WLB1_IM6.mjs.map +0 -1
- package/dist/client/securitygroups-o0IXZM6S.mjs +0 -14
- package/dist/client/securitygroups-o0IXZM6S.mjs.map +0 -1
- package/dist/client/serviceCatalog-B3lKWC9V.mjs +0 -6
- package/dist/client/serviceCatalog-B3lKWC9V.mjs.map +0 -1
- package/dist/client/services-D1PbooD1.mjs +0 -6
- package/dist/client/services-D1PbooD1.mjs.map +0 -1
- package/dist/client/services-DEMVtFyn.mjs +0 -9
- package/dist/client/services-DEMVtFyn.mjs.map +0 -1
- package/dist/client/storageProviders-CJ5rOh13.mjs +0 -15
- package/dist/client/storageProviders-CJ5rOh13.mjs.map +0 -1
- package/dist/client/trpcClient-D7gpR7YG.mjs +0 -71
- package/dist/client/trpcClient-D7gpR7YG.mjs.map +0 -1
- package/dist/client/useBreadcrumbs-ha3IlaxX.mjs +0 -54
- package/dist/client/useBreadcrumbs-ha3IlaxX.mjs.map +0 -1
- package/dist/client/useErrorTranslation-Dc0eE8Zt.mjs +0 -83
- package/dist/client/useErrorTranslation-Dc0eE8Zt.mjs.map +0 -1
- package/dist/client/useModal-DCs1OJh7.mjs +0 -12
- package/dist/client/useModal-DCs1OJh7.mjs.map +0 -1
- package/dist/client/useModalTracking-BYd37pXm.mjs +0 -37
- package/dist/client/useModalTracking-BYd37pXm.mjs.map +0 -1
- package/dist/client/useProjectId-DBc5lpoU.mjs +0 -11
- package/dist/client/useProjectId-DBc5lpoU.mjs.map +0 -1
- package/dist/client/useSecurityGroupPermissions--hK4aR8Y.mjs +0 -294
- package/dist/client/useSecurityGroupPermissions--hK4aR8Y.mjs.map +0 -1
- package/dist/client/useSetBreadcrumb-tn7lBaQV.mjs +0 -19
- package/dist/client/useSetBreadcrumb-tn7lBaQV.mjs.map +0 -1
- package/dist/client/utils/trpcErrors.d.ts +0 -13
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { F as e, Q as t, R as n, it as r } from "./build-WuxXRAqf.mjs";
|
|
2
|
-
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
3
|
-
import { useLingui as o } from "@lingui/react";
|
|
4
|
-
//#region src/client/components/ListToolbar/SortInput.tsx
|
|
5
|
-
var s = ({ sortBy: s, onSortByChange: c, sortDirection: l, onSortDirectionChange: u, options: d, selectClassName: f, selectWidth: p }) => {
|
|
6
|
-
let { i18n: m, _: h } = o(), g = () => ({
|
|
7
|
-
className: f,
|
|
8
|
-
width: p,
|
|
9
|
-
onChange: c,
|
|
10
|
-
value: s,
|
|
11
|
-
"data-testid": "sort-select",
|
|
12
|
-
label: m._({ id: "/HgF9q" })
|
|
13
|
-
}), _ = () => ({
|
|
14
|
-
"data-testid": "direction-toggle",
|
|
15
|
-
order: l,
|
|
16
|
-
onChange: u
|
|
17
|
-
});
|
|
18
|
-
return /*#__PURE__*/ a(t, {
|
|
19
|
-
gap: "0.5",
|
|
20
|
-
alignment: "end",
|
|
21
|
-
className: "w-full sm:w-auto",
|
|
22
|
-
children: [/*#__PURE__*/ i(r, {
|
|
23
|
-
...g(),
|
|
24
|
-
children: d.map((e) => /*#__PURE__*/ i(n, {
|
|
25
|
-
value: e.value,
|
|
26
|
-
children: e.label
|
|
27
|
-
}, e.value))
|
|
28
|
-
}), /*#__PURE__*/ i(e, { ..._() })]
|
|
29
|
-
});
|
|
30
|
-
};
|
|
31
|
-
//#endregion
|
|
32
|
-
export { s as t };
|
|
33
|
-
|
|
34
|
-
//# sourceMappingURL=SortInput-4g7nSTHW.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SortInput-4g7nSTHW.mjs","names":["React","Select","SelectOption","SortButton","Stack","SortInput","sortBy","onSortByChange","sortDirection","onSortDirectionChange","options","selectClassName","selectWidth","useLingui","getSelectProps","className","width","onChange","value","label","t","getSortButtonProps","order","gap","alignment","map","option"],"sources":["../../src/client/components/ListToolbar/SortInput.tsx"],"sourcesContent":["import React from \"react\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { Select, SelectOption, SortButton, Stack, SelectProps, ButtonProps } from \"@cloudoperators/juno-ui-components\"\nimport { SortOption } from \"./types\"\n\nexport interface SortInputProps {\n sortBy?: string | number | string[]\n onSortByChange: (param?: string | number | string[]) => void\n sortDirection: \"asc\" | \"desc\"\n onSortDirectionChange: (direction: \"asc\" | \"desc\") => void\n options: SortOption[]\n selectClassName?: string\n /** Passed through to the underlying Select. \"auto\" sizes the toggle to its content (use with a `min-w-*` selectClassName floor) instead of the default \"full\" width. */\n selectWidth?: SelectProps[\"width\"]\n}\n\nexport const SortInput: React.FC<SortInputProps> = ({\n sortBy,\n onSortByChange,\n sortDirection,\n onSortDirectionChange,\n options,\n selectClassName,\n selectWidth,\n}) => {\n const { t } = useLingui()\n\n const getSelectProps = (): SelectProps & { \"data-testid\"?: string } => ({\n className: selectClassName,\n width: selectWidth,\n onChange: onSortByChange,\n value: sortBy,\n \"data-testid\": \"sort-select\",\n label: t`Sort by`,\n })\n\n const getSortButtonProps = (): Omit<ButtonProps, \"onChange\"> & {\n \"data-testid\"?: string\n order: \"asc\" | \"desc\"\n onChange: (order: \"asc\" | \"desc\") => void\n } => ({\n \"data-testid\": \"direction-toggle\",\n order: sortDirection,\n onChange: onSortDirectionChange,\n })\n\n return (\n <Stack gap=\"0.5\" alignment=\"end\" className=\"w-full sm:w-auto\">\n <Select {...getSelectProps()}>\n {options.map((option) => (\n <SelectOption key={option.value} value={option.value}>\n {option.label}\n </SelectOption>\n ))}\n </Select>\n <SortButton {...getSortButtonProps()} />\n </Stack>\n )\n}\n"],"mappings":";;;;AAgBA,IAAaK,KAAuC,EAClDC,WACAC,mBACAC,kBACAC,0BACAC,YACAC,oBACAC,qBACD;CACC,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQC,EAAAA,GAERC,WAAkE;EACtEC,WAAWJ;EACXK,OAAOJ;EACPK,UAAUV;EACVW,OAAOZ;EACP,eAAe;EACfa,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAQ,CAAA;CAClB,IAEMC,WAIA;EACJ,eAAe;EACfC,OAAOd;EACPS,UAAUR;CACZ;CAEA,OACE,gBAACL,GAAAA;EAAMmB,KAAI;EAAMC,WAAU;EAAMT,WAAU;EACzC,UAAA,CAAA,gBAACd,GAAAA;GAAQ,GAAGa,EAAAA;GACTJ,UAAAA,EAAQe,KAAKC,MACZ,gBAACxB,GAAAA;IAAgCgB,OAAOQ,EAAOR;IAC5CQ,UAAAA,EAAOP;GADSO,GAAAA,EAAOR,KAAK,CAAA;EAKnC,CAAA,GAAA,gBAACf,GAAAA,EAAY,GAAGkB,EAAAA,EAAAA,CAAAA,CAAAA;;AAGtB"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { i as e, rt as t } from "./build-WuxXRAqf.mjs";
|
|
2
|
-
import { jsx as n } from "react/jsx-runtime";
|
|
3
|
-
import { useNavigate as r, useParams as i } from "@tanstack/react-router";
|
|
4
|
-
import { Trans as a, useLingui as o } from "@lingui/react";
|
|
5
|
-
//#region src/client/routes/_auth/projects/$projectId/storage/-components/StorageNotFound.tsx
|
|
6
|
-
function s({ data: s }) {
|
|
7
|
-
let { i18n: c, _: l } = o(), u = r(), { projectId: d } = i({ strict: !1 }), f = s?.reason === "storage-type-mismatch";
|
|
8
|
-
return /*#__PURE__*/ n(t, {
|
|
9
|
-
status: "error",
|
|
10
|
-
code: 404,
|
|
11
|
-
title: f ? c._({ id: "boJlGf" }) : c._({ id: "Zu31u6" }),
|
|
12
|
-
body: f ? c._({ id: "cyMmud" }) : c._({ id: "E4WmGR" }),
|
|
13
|
-
action: d ? /*#__PURE__*/ n(e, {
|
|
14
|
-
variant: "primary",
|
|
15
|
-
onClick: () => u({
|
|
16
|
-
to: "/projects/$projectId",
|
|
17
|
-
params: { projectId: d }
|
|
18
|
-
}),
|
|
19
|
-
children: /*#__PURE__*/ n(a, { id: "AGco1A" })
|
|
20
|
-
}) : /*#__PURE__*/ n(e, {
|
|
21
|
-
variant: "primary",
|
|
22
|
-
onClick: () => u({ to: "/projects" }),
|
|
23
|
-
children: /*#__PURE__*/ n(a, { id: "aKznJS" })
|
|
24
|
-
})
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
//#endregion
|
|
28
|
-
export { s as t };
|
|
29
|
-
|
|
30
|
-
//# sourceMappingURL=StorageNotFound-B-zVinVD.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"StorageNotFound-B-zVinVD.mjs","names":["Status","Button","useNavigate","useParams","StorageNotFound","data","useLingui","navigate","projectId","strict","isBadUrl","reason","status","code","title","t","body","action","variant","onClick","to","params"],"sources":["../../src/client/routes/_auth/projects/$projectId/storage/-components/StorageNotFound.tsx"],"sourcesContent":["import { Status, Button } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui, Trans } from \"@lingui/react/macro\"\nimport { useNavigate, useParams } from \"@tanstack/react-router\"\nimport type { StorageNotFoundReason } from \"./utils/serviceAvailability\"\n\ninterface StorageNotFoundProps {\n data?: { reason?: StorageNotFoundReason }\n}\n\nexport function StorageNotFound({ data }: StorageNotFoundProps) {\n const { t } = useLingui()\n const navigate = useNavigate()\n const { projectId } = useParams({ strict: false })\n\n const isBadUrl = data?.reason === \"storage-type-mismatch\"\n\n return (\n <Status\n status=\"error\"\n code={404}\n title={isBadUrl ? t`Page Not Found` : t`Object Storage Not Found`}\n body={\n isBadUrl\n ? t`This address is not valid for this object storage service.`\n : t`This object storage service does not exist or is not available for this project.`\n }\n action={\n projectId ? (\n <Button variant=\"primary\" onClick={() => navigate({ to: \"/projects/$projectId\", params: { projectId } })}>\n <Trans>Go to Project</Trans>\n </Button>\n ) : (\n <Button variant=\"primary\" onClick={() => navigate({ to: \"/projects\" })}>\n <Trans>Go to Projects</Trans>\n </Button>\n )\n }\n />\n )\n}\n"],"mappings":";;;;;AASA,SAAgBI,EAAgB,EAAEC,WAA4B;CAC5D,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQC,EAAAA,GACRC,IAAWL,EAAAA,GACX,EAAEM,iBAAcL,EAAU,EAAEM,QAAQ,GAAM,CAAA,GAE1CC,IAAWL,GAAMM,WAAW;CAElC,OACE,gBAACX,GAAAA;EACCY,QAAO;EACPC,MAAM;EACNC,OAAOJ,IAAWK,EAAAA,EAAC,EAAA,IAAA,SAAe,CAAA,IAAIA,EAAAA,EAAC,EAAA,IAAA,SAAyB,CAAA;EAChEC,MACEN,IACIK,EAAAA,EAAC,EAAA,IAAA,SAA2D,CAAA,IAC5DA,EAAAA,EAAC,EAAA,IAAA,SAAiF,CAAA;EAExFE,QACET,IACE,gBAACP,GAAAA;GAAOiB,SAAQ;GAAUC,eAAeZ,EAAS;IAAEa,IAAI;IAAwBC,QAAQ,EAAEb,aAAU;GAAE,CAAA;GACpG,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;EAGF,CAAA,IAAA,gBAACP,GAAAA;GAAOiB,SAAQ;GAAUC,eAAeZ,EAAS,EAAEa,IAAI,YAAY,CAAA;GAClE,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;;;AAMZ"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { E as e, Q as t, n, s as r } from "./build-WuxXRAqf.mjs";
|
|
2
|
-
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
3
|
-
import { Fragment as o } from "react";
|
|
4
|
-
//#region src/client/components/TwoColumnDescriptionList.tsx
|
|
5
|
-
var s = ({ items: s }) => {
|
|
6
|
-
let c = Math.ceil(s.length / 2), l = s.slice(0, c), u = s.slice(c);
|
|
7
|
-
return /*#__PURE__*/ a(t, {
|
|
8
|
-
gap: "6",
|
|
9
|
-
className: "grid grid-cols-2",
|
|
10
|
-
children: [/*#__PURE__*/ i(r, {
|
|
11
|
-
alignTerms: "right",
|
|
12
|
-
children: l.map(({ id: t, label: r, value: s }, c) => /*#__PURE__*/ a(o, { children: [/*#__PURE__*/ i(n, { children: r }), /*#__PURE__*/ i(e, { children: /*#__PURE__*/ i("div", {
|
|
13
|
-
className: "truncate",
|
|
14
|
-
children: s
|
|
15
|
-
}) })] }, t ?? `left-${c}`))
|
|
16
|
-
}), /*#__PURE__*/ i(r, {
|
|
17
|
-
alignTerms: "right",
|
|
18
|
-
children: u.map(({ id: t, label: r, value: s }, c) => /*#__PURE__*/ a(o, { children: [/*#__PURE__*/ i(n, { children: r }), /*#__PURE__*/ i(e, { children: /*#__PURE__*/ i("div", {
|
|
19
|
-
className: "truncate",
|
|
20
|
-
children: s
|
|
21
|
-
}) })] }, t ?? `right-${c}`))
|
|
22
|
-
})]
|
|
23
|
-
});
|
|
24
|
-
};
|
|
25
|
-
//#endregion
|
|
26
|
-
export { s as t };
|
|
27
|
-
|
|
28
|
-
//# sourceMappingURL=TwoColumnDescriptionList-DKS42RKa.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TwoColumnDescriptionList-DKS42RKa.mjs","names":["Fragment","DescriptionDefinition","DescriptionList","DescriptionTerm","Stack","TwoColumnDescriptionList","items","mid","Math","ceil","length","firstColumn","slice","secondColumn","gap","className","alignTerms","map","id","label","value","index","div"],"sources":["../../src/client/components/TwoColumnDescriptionList.tsx"],"sourcesContent":["import { Fragment, type ReactNode } from \"react\"\nimport { DescriptionDefinition, DescriptionList, DescriptionTerm, Stack } from \"@cloudoperators/juno-ui-components\"\n\nexport type DetailListItem = {\n id?: string\n label: string | ReactNode\n value: string | number | ReactNode | undefined\n}\n\ninterface TwoColumnDescriptionListProps {\n items: DetailListItem[]\n}\n\nexport const TwoColumnDescriptionList = ({ items }: TwoColumnDescriptionListProps) => {\n const mid = Math.ceil(items.length / 2)\n const firstColumn = items.slice(0, mid)\n const secondColumn = items.slice(mid)\n\n return (\n <Stack gap=\"6\" className=\"grid grid-cols-2\">\n <DescriptionList alignTerms=\"right\">\n {firstColumn.map(({ id, label, value }, index) => (\n <Fragment key={id ?? `left-${index}`}>\n <DescriptionTerm>{label}</DescriptionTerm>\n <DescriptionDefinition>\n <div className=\"truncate\">{value}</div>\n </DescriptionDefinition>\n </Fragment>\n ))}\n </DescriptionList>\n\n <DescriptionList alignTerms=\"right\">\n {secondColumn.map(({ id, label, value }, index) => (\n <Fragment key={id ?? `right-${index}`}>\n <DescriptionTerm>{label}</DescriptionTerm>\n <DescriptionDefinition>\n <div className=\"truncate\">{value}</div>\n </DescriptionDefinition>\n </Fragment>\n ))}\n </DescriptionList>\n </Stack>\n )\n}\n"],"mappings":";;;;AAaA,IAAaK,KAA4B,EAAEC,eAAsC;CAC/E,IAAMC,IAAMC,KAAKC,KAAKH,EAAMI,SAAS,CAAA,GAC/BC,IAAcL,EAAMM,MAAM,GAAGL,CAAAA,GAC7BM,IAAeP,EAAMM,MAAML,CAAAA;CAEjC,OACE,gBAACH,GAAAA;EAAMU,KAAI;EAAIC,WAAU;EACvB,UAAA,CAAA,gBAACb,GAAAA;GAAgBc,YAAW;GACzBL,UAAAA,EAAYM,KAAK,EAAEC,OAAIC,UAAOC,YAASC,MACtC,gBAACrB,GAAAA,EAAAA,UAAAA,CACC,gBAACG,GAAAA,EAAiBgB,UAAAA,EAAAA,CAAAA,GAClB,gBAAClB,GAAAA,EACC,UAAA,gBAACqB,OAAAA;IAAIP,WAAU;IAAYK,UAAAA;GAHhBF,CAAAA,EAAAA,CAAAA,CAAAA,EAAAA,GAAAA,KAAM,QAAQG,GAAO,CAAA;EASxC,CAAA,GAAA,gBAACnB,GAAAA;GAAgBc,YAAW;GACzBH,UAAAA,EAAaI,KAAK,EAAEC,OAAIC,UAAOC,YAASC,MACvC,gBAACrB,GAAAA,EAAAA,UAAAA,CACC,gBAACG,GAAAA,EAAiBgB,UAAAA,EAAAA,CAAAA,GAClB,gBAAClB,GAAAA,EACC,UAAA,gBAACqB,OAAAA;IAAIP,WAAU;IAAYK,UAAAA;GAHhBF,CAAAA,EAAAA,CAAAA,CAAAA,EAAAA,GAAAA,KAAM,SAASG,GAAO,CAAA;;;AAU/C"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_-CAsCx-Ay.mjs","names":["SplitComponent","component"],"sources":["../../src/client/routes/_auth/projects/$projectId/services/$serviceType/$.tsx?tsr-split=component"],"sourcesContent":["import { createFileRoute } from \"@tanstack/react-router\"\n\n// Catch-all so deep links under /services/$serviceType/** match (no 404). The extension mount\n// is rendered by the parent layout route ($serviceType.tsx) so it persists across navigation;\n// the extension's own router handles everything below the base path.\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/services/$serviceType/$\")({\n component: () => null,\n})\n"],"mappings":";AAIA,IAAAA,UAEmB"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { n as e } from "./AuthProvider-CVSAwW9f.mjs";
|
|
2
|
-
import { n as t } from "./DynamicBreadcrumbContext-CVcUQFou.mjs";
|
|
3
|
-
import { jsx as n } from "react/jsx-runtime";
|
|
4
|
-
import { Outlet as r } from "@tanstack/react-router";
|
|
5
|
-
//#region src/client/routes/_auth.tsx?tsr-split=component
|
|
6
|
-
function i() {
|
|
7
|
-
return e(), /*#__PURE__*/ n(t, { children: /*#__PURE__*/ n(r, {}) });
|
|
8
|
-
}
|
|
9
|
-
//#endregion
|
|
10
|
-
export { i as component };
|
|
11
|
-
|
|
12
|
-
//# sourceMappingURL=_auth-SrDjHL6j.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_auth-SrDjHL6j.mjs","names":["Outlet","useAuth","DynamicBreadcrumbProvider","RouteComponent","component"],"sources":["../../src/client/routes/_auth.tsx?tsr-split=component"],"sourcesContent":["import { createFileRoute, Outlet, redirect } from \"@tanstack/react-router\"\nimport { useAuth } from \"../store/AuthProvider\"\nimport { DynamicBreadcrumbProvider } from \"@/client/context/DynamicBreadcrumbContext\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { msg } from \"@lingui/core/macro\"\n\nexport const Route = createFileRoute(\"/_auth\")({\n staticData: {\n crumb: { text: msg`Home`, icon: \"home\", to: \"/projects\" },\n } satisfies RouteInfo,\n component: RouteComponent,\n beforeLoad: async ({ context, location }) => {\n if (!context.auth?.isAuthenticated) {\n const redirectPath = `${location.pathname}${location.searchStr || \"\"}${location.hash || \"\"}`\n\n throw redirect({\n to: \"/\",\n search: { redirect: redirectPath },\n })\n }\n },\n})\n\nfunction RouteComponent() {\n useAuth()\n\n return (\n <DynamicBreadcrumbProvider>\n <Outlet />\n </DynamicBreadcrumbProvider>\n )\n}\n"],"mappings":";;;;;AAuBA,SAASG,IAAAA;CAGP,OAFAF,EAAAA,GAGE,gBAAC,GAAA,EACC,UAAA,gBAAC,GAAA,CAAA,CAAA,EAAA,CAAA;AAGP"}
|
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
import { A as e, D as t, E as n, M as r, Q as i, c as a, g as o, i as s, n as c, r as l, rt as u, s as d, x as f } from "./build-WuxXRAqf.mjs";
|
|
2
|
-
import { a as p } from "./trpcClient-D7gpR7YG.mjs";
|
|
3
|
-
import { t as m } from "./_flavorId-CFUBcU-l.mjs";
|
|
4
|
-
import { t as h } from "./useProjectId-DBc5lpoU.mjs";
|
|
5
|
-
import { n as g, t as _ } from "./ContentHeader-fKKZVu-o.mjs";
|
|
6
|
-
import { t as v } from "./useSetBreadcrumb-tn7lBaQV.mjs";
|
|
7
|
-
import { t as y } from "./useErrorTranslation-Dc0eE8Zt.mjs";
|
|
8
|
-
import { a as b, n as x, t as S } from "./DeleteFlavorModal-C4nAi7gY.mjs";
|
|
9
|
-
import { t as C } from "./useModal-DCs1OJh7.mjs";
|
|
10
|
-
import { Fragment as w, jsx as T, jsxs as E } from "react/jsx-runtime";
|
|
11
|
-
import { Fragment as D } from "react";
|
|
12
|
-
import { useNavigate as O, useParams as ee } from "@tanstack/react-router";
|
|
13
|
-
import { Trans as k, useLingui as A } from "@lingui/react";
|
|
14
|
-
//#region src/client/routes/_auth/projects/$projectId/compute/flavors/-components/FlavorDetailsView.tsx
|
|
15
|
-
function te({ flavor: e, canListSpecs: t = !1 }) {
|
|
16
|
-
let { i18n: r, _: a } = A(), o = h(), s = (e, t) => `${e} ${t}`, { data: l, isLoading: f, isError: m } = p.compute.getExtraSpecs.useQuery({
|
|
17
|
-
project_id: o,
|
|
18
|
-
flavorId: e.id
|
|
19
|
-
}, { enabled: !!o && !!e.id && t }), _ = [
|
|
20
|
-
{
|
|
21
|
-
label: r._({ id: "S0kLOH" }),
|
|
22
|
-
value: /*#__PURE__*/ T(g, { text: e.id })
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
label: r._({ id: "6YtxFj" }),
|
|
26
|
-
value: e.name
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
label: r._({ id: "Nu4oKW" }),
|
|
30
|
-
value: e?.description ?? ""
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
label: r._({ id: "7d1a0d" }),
|
|
34
|
-
value: e["os-flavor-access:is_public"] ? /*#__PURE__*/ T(k, { id: "l75CjT" }) : /*#__PURE__*/ T(k, { id: "1UzENP" })
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
label: r._({ id: "E/QGRL" }),
|
|
38
|
-
value: e["OS-FLV-DISABLED:disabled"] ? /*#__PURE__*/ T(k, { id: "l75CjT" }) : /*#__PURE__*/ T(k, { id: "1UzENP" })
|
|
39
|
-
}
|
|
40
|
-
], v = [
|
|
41
|
-
{
|
|
42
|
-
label: r._({ id: "MZGbkp" }),
|
|
43
|
-
value: e.vcpus
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
label: r._({ id: "RGhYAo" }),
|
|
47
|
-
value: s(e.ram, "MiB")
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
label: r._({ id: "cJDQIO" }),
|
|
51
|
-
value: s(e.disk, "GiB")
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
label: r._({ id: "r9Aac8" }),
|
|
55
|
-
value: s(e["OS-FLV-EXT-DATA:ephemeral"] || 0, "GiB")
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
label: r._({ id: "vH2C/2" }),
|
|
59
|
-
value: e.swap === 0 || e.swap === "" ? /*#__PURE__*/ T(k, { id: "EdQY6l" }) : s(Number(e.swap), "MiB")
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
label: r._({ id: "u5HztT" }),
|
|
63
|
-
value: e.rxtx_factor ?? ""
|
|
64
|
-
}
|
|
65
|
-
], y = l ? Object.entries(l).map(([e, t]) => ({
|
|
66
|
-
label: e,
|
|
67
|
-
value: t
|
|
68
|
-
})) : [];
|
|
69
|
-
return /*#__PURE__*/ E(i, {
|
|
70
|
-
direction: "vertical",
|
|
71
|
-
gap: "6",
|
|
72
|
-
className: "mt-6",
|
|
73
|
-
children: [/*#__PURE__*/ E(i, {
|
|
74
|
-
direction: "horizontal",
|
|
75
|
-
gap: "6",
|
|
76
|
-
className: "grid grid-cols-2",
|
|
77
|
-
children: [/*#__PURE__*/ E(i, {
|
|
78
|
-
direction: "vertical",
|
|
79
|
-
gap: "2",
|
|
80
|
-
children: [/*#__PURE__*/ T("h2", { children: /*#__PURE__*/ T(k, { id: "JlSgnX" }) }), /*#__PURE__*/ T(d, {
|
|
81
|
-
alignTerms: "right",
|
|
82
|
-
children: _.map(({ label: e, value: t }, r) => /*#__PURE__*/ E(D, { children: [/*#__PURE__*/ T(c, { children: e }), /*#__PURE__*/ T(n, { children: /*#__PURE__*/ T("div", {
|
|
83
|
-
className: "truncate",
|
|
84
|
-
children: t
|
|
85
|
-
}) })] }, `basic-${r}`))
|
|
86
|
-
})]
|
|
87
|
-
}), /*#__PURE__*/ E(i, {
|
|
88
|
-
direction: "vertical",
|
|
89
|
-
gap: "2",
|
|
90
|
-
children: [/*#__PURE__*/ T("h2", { children: /*#__PURE__*/ T(k, { id: "qQ1QBh" }) }), /*#__PURE__*/ T(d, {
|
|
91
|
-
alignTerms: "right",
|
|
92
|
-
children: v.map(({ label: e, value: t }, r) => /*#__PURE__*/ E(D, { children: [/*#__PURE__*/ T(c, { children: e }), /*#__PURE__*/ T(n, { children: /*#__PURE__*/ T("div", {
|
|
93
|
-
className: "truncate",
|
|
94
|
-
children: t
|
|
95
|
-
}) })] }, `hardware-${r}`))
|
|
96
|
-
})]
|
|
97
|
-
})]
|
|
98
|
-
}), t && /*#__PURE__*/ E(i, {
|
|
99
|
-
direction: "vertical",
|
|
100
|
-
gap: "2",
|
|
101
|
-
children: [/*#__PURE__*/ T("h2", { children: /*#__PURE__*/ T(k, { id: "6GBt0m" }) }), f ? /*#__PURE__*/ T(u, { status: "progress" }) : m ? /*#__PURE__*/ T(u, {
|
|
102
|
-
status: "error",
|
|
103
|
-
title: r._({ id: "mXHHga" })
|
|
104
|
-
}) : l && Object.keys(l).length > 0 ? /*#__PURE__*/ T(d, {
|
|
105
|
-
alignTerms: "right",
|
|
106
|
-
className: "grid-cols-2",
|
|
107
|
-
children: y.map(({ label: e, value: t }, r) => /*#__PURE__*/ E(D, { children: [/*#__PURE__*/ T(c, {
|
|
108
|
-
className: "col-span-1 break-all",
|
|
109
|
-
children: e
|
|
110
|
-
}), /*#__PURE__*/ T(n, {
|
|
111
|
-
className: "col-span-1",
|
|
112
|
-
children: /*#__PURE__*/ T("div", {
|
|
113
|
-
className: "break-all",
|
|
114
|
-
children: t
|
|
115
|
-
})
|
|
116
|
-
})] }, `extra-${r}`))
|
|
117
|
-
}) : /*#__PURE__*/ T(u, {
|
|
118
|
-
status: "empty",
|
|
119
|
-
title: r._({ id: "qTRcSX" })
|
|
120
|
-
})]
|
|
121
|
-
})]
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
//#endregion
|
|
125
|
-
//#region src/client/routes/_auth/projects/$projectId/compute/flavors/$flavorId.tsx?tsr-split=component
|
|
126
|
-
function j() {
|
|
127
|
-
let { projectId: n, flavorId: c } = ee({ from: "/_auth/projects/$projectId/compute/flavors/$flavorId" }), { trpcClient: d } = m.useRouteContext(), h = O(), { i18n: g, _: D } = A(), { translateError: j, isRetryableError: M } = y(), N = p.useUtils(), { data: P, status: F, error: I, refetch: L } = p.compute.getFlavorById.useQuery({
|
|
128
|
-
project_id: n,
|
|
129
|
-
flavorId: c
|
|
130
|
-
});
|
|
131
|
-
v(m.id, P?.name);
|
|
132
|
-
let { data: R } = p.compute.canUser.useQuery({
|
|
133
|
-
project_id: n,
|
|
134
|
-
permission: [
|
|
135
|
-
"flavors:delete",
|
|
136
|
-
"flavors:add_project",
|
|
137
|
-
"flavors:remove_project",
|
|
138
|
-
"flavor_specs:list",
|
|
139
|
-
"flavor_specs:create",
|
|
140
|
-
"flavor_specs:delete"
|
|
141
|
-
]
|
|
142
|
-
}), z = R?.[0] ?? !1, B = (R?.[1] ?? !1) || (R?.[2] ?? !1), V = R?.[3] ?? !1, ne = (R?.[4] ?? !1) || (R?.[5] ?? !1), [H, U] = C(), [W, G] = C(), [K, q] = C(), J = () => {
|
|
143
|
-
U(), N.compute.getExtraSpecs.invalidate({
|
|
144
|
-
project_id: n,
|
|
145
|
-
flavorId: c
|
|
146
|
-
});
|
|
147
|
-
}, Y = () => {
|
|
148
|
-
h({
|
|
149
|
-
to: "/projects/$projectId/compute/flavors",
|
|
150
|
-
params: { projectId: n }
|
|
151
|
-
});
|
|
152
|
-
}, X = () => {
|
|
153
|
-
h({
|
|
154
|
-
to: "/projects/$projectId",
|
|
155
|
-
params: { projectId: n }
|
|
156
|
-
});
|
|
157
|
-
}, re = () => {
|
|
158
|
-
L();
|
|
159
|
-
};
|
|
160
|
-
if (F === "pending") return /*#__PURE__*/ T(u, {
|
|
161
|
-
status: "progress",
|
|
162
|
-
title: g._({ id: "YNgcgc" })
|
|
163
|
-
});
|
|
164
|
-
if (F === "error") {
|
|
165
|
-
let t = I?.message || "UNKNOWN_ERROR", n = j(t), i = M(t);
|
|
166
|
-
return /*#__PURE__*/ T(e, {
|
|
167
|
-
className: "py-8",
|
|
168
|
-
children: /*#__PURE__*/ T(u, {
|
|
169
|
-
status: "error",
|
|
170
|
-
code: ((e) => {
|
|
171
|
-
if (e.includes("UNAUTHORIZED")) return 401;
|
|
172
|
-
if (e.includes("FORBIDDEN")) return 403;
|
|
173
|
-
if (e.includes("NOT_FOUND")) return 404;
|
|
174
|
-
if (e.includes("SERVER_ERROR")) return 500;
|
|
175
|
-
})(t),
|
|
176
|
-
title: g._({ id: "FjONW3" }),
|
|
177
|
-
body: n,
|
|
178
|
-
action: /*#__PURE__*/ E(r, { children: [
|
|
179
|
-
/*#__PURE__*/ T(s, {
|
|
180
|
-
variant: "primary",
|
|
181
|
-
onClick: Y,
|
|
182
|
-
children: /*#__PURE__*/ T(k, { id: "iH8pgl" })
|
|
183
|
-
}),
|
|
184
|
-
/*#__PURE__*/ T(s, {
|
|
185
|
-
onClick: X,
|
|
186
|
-
children: /*#__PURE__*/ T(k, { id: "i0qMbr" })
|
|
187
|
-
}),
|
|
188
|
-
i && /*#__PURE__*/ T(s, {
|
|
189
|
-
onClick: re,
|
|
190
|
-
children: /*#__PURE__*/ T(k, { id: "qJb6G2" })
|
|
191
|
-
})
|
|
192
|
-
] })
|
|
193
|
-
})
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
if (!P) return /*#__PURE__*/ T(e, {
|
|
197
|
-
className: "py-8",
|
|
198
|
-
children: /*#__PURE__*/ T(u, {
|
|
199
|
-
status: "error",
|
|
200
|
-
code: 404,
|
|
201
|
-
title: g._({ id: "bpme7e" }),
|
|
202
|
-
body: g._({ id: "y0u86k" }),
|
|
203
|
-
action: /*#__PURE__*/ E(r, { children: [/*#__PURE__*/ T(s, {
|
|
204
|
-
variant: "primary",
|
|
205
|
-
onClick: Y,
|
|
206
|
-
children: /*#__PURE__*/ T(k, { id: "iH8pgl" })
|
|
207
|
-
}), /*#__PURE__*/ T(s, {
|
|
208
|
-
onClick: X,
|
|
209
|
-
children: /*#__PURE__*/ T(k, { id: "i0qMbr" })
|
|
210
|
-
})] })
|
|
211
|
-
})
|
|
212
|
-
});
|
|
213
|
-
let Z = P["os-flavor-access:is_public"] !== !1, Q = B && !Z || z, $ = ne && V, ie = Q || $ ? /*#__PURE__*/ E(i, {
|
|
214
|
-
gap: "0.5",
|
|
215
|
-
alignment: "center",
|
|
216
|
-
children: [Q && /*#__PURE__*/ E(t, { children: [/*#__PURE__*/ T(a, {
|
|
217
|
-
as: "div",
|
|
218
|
-
children: /*#__PURE__*/ T(s, {
|
|
219
|
-
icon: "moreVert",
|
|
220
|
-
title: g._({ id: "PgNNGl" }),
|
|
221
|
-
"aria-label": g._({ id: "PgNNGl" })
|
|
222
|
-
})
|
|
223
|
-
}), /*#__PURE__*/ E(o, { children: [B && !Z && /*#__PURE__*/ T(f, {
|
|
224
|
-
label: g._({ id: "cWbW6w" }),
|
|
225
|
-
onClick: G
|
|
226
|
-
}), z && /*#__PURE__*/ E(w, { children: [/*#__PURE__*/ T(l, {}), /*#__PURE__*/ T(f, {
|
|
227
|
-
label: g._({ id: "JT3I1g" }),
|
|
228
|
-
onClick: q
|
|
229
|
-
})] })] })] }), $ && /*#__PURE__*/ T(s, {
|
|
230
|
-
variant: "primary",
|
|
231
|
-
onClick: U,
|
|
232
|
-
children: /*#__PURE__*/ T(k, { id: "SIfYq6" })
|
|
233
|
-
})]
|
|
234
|
-
}) : void 0;
|
|
235
|
-
return /*#__PURE__*/ E(w, { children: [
|
|
236
|
-
/*#__PURE__*/ T(_, {
|
|
237
|
-
title: P.name,
|
|
238
|
-
projectId: n,
|
|
239
|
-
actions: ie
|
|
240
|
-
}),
|
|
241
|
-
/*#__PURE__*/ T(i, {
|
|
242
|
-
direction: "vertical",
|
|
243
|
-
children: /*#__PURE__*/ T(te, {
|
|
244
|
-
flavor: P,
|
|
245
|
-
canListSpecs: V
|
|
246
|
-
})
|
|
247
|
-
}),
|
|
248
|
-
d && /*#__PURE__*/ E(w, { children: [
|
|
249
|
-
H && /*#__PURE__*/ T(b, {
|
|
250
|
-
client: d,
|
|
251
|
-
isOpen: H,
|
|
252
|
-
onClose: J,
|
|
253
|
-
project: n,
|
|
254
|
-
flavor: P
|
|
255
|
-
}),
|
|
256
|
-
W && /*#__PURE__*/ T(x, {
|
|
257
|
-
client: d,
|
|
258
|
-
isOpen: W,
|
|
259
|
-
onClose: G,
|
|
260
|
-
project: n,
|
|
261
|
-
flavor: P
|
|
262
|
-
}),
|
|
263
|
-
K && /*#__PURE__*/ T(S, {
|
|
264
|
-
client: d,
|
|
265
|
-
isOpen: K,
|
|
266
|
-
onClose: q,
|
|
267
|
-
project: n,
|
|
268
|
-
flavor: P,
|
|
269
|
-
onSuccess: Y
|
|
270
|
-
})
|
|
271
|
-
] })
|
|
272
|
-
] });
|
|
273
|
-
}
|
|
274
|
-
//#endregion
|
|
275
|
-
export { j as component };
|
|
276
|
-
|
|
277
|
-
//# sourceMappingURL=_flavorId-BPvssEzn.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_flavorId-BPvssEzn.mjs","names":["Stack","DescriptionList","DescriptionTerm","DescriptionDefinition","Status","Fragment","ClipboardText","trpcReact","useProjectId","FlavorDetailsView","flavor","canListSpecs","useLingui","projectId","formatWithUnit","value","unit","data","extraSpecs","isLoading","isError","compute","getExtraSpecs","useQuery","project_id","flavorId","id","enabled","basicInfoItems","label","t","text","name","description","hardwareSpecItems","vcpus","ram","disk","swap","Number","rxtx_factor","extraSpecItems","Object","entries","map","key","direction","gap","className","h2","alignTerms","index","div","status","title","keys","length","Button","ButtonRow","Stack","PopupMenu","PopupMenuToggle","PopupMenuOptions","PopupMenuItem","PopupMenuSectionSeparator","Container","Status","useNavigate","useParams","Trans","useLingui","trpcReact","useSetBreadcrumb","FlavorDetailsView","useErrorTranslation","EditSpecModal","ManageAccessModal","DeleteFlavorModal","useModal","ContentHeader","Route","RouteComponent","projectId","flavorId","from","trpcClient","useRouteContext","navigate","t","translateError","isRetryableError","utils","useUtils","data","flavor","status","error","refetch","compute","getFlavorById","useQuery","project_id","id","name","permissionsData","canUser","permission","canDeleteFlavor","canManageAccess","canListSpecs","canManageSpecs","specModalOpen","toggleSpecModal","accessModalOpen","toggleAccessModal","deleteModalOpen","toggleDeleteModal","handleSpecModalClose","getExtraSpecs","invalidate","handleBack","to","params","handleHome","handleRetry","errorCode","message","translatedError","canRetry","getStatusCode","code","includes","undefined","isPublicFlavor","hasPopupMenuItems","canEditMetadata","hasMoreActions","headerActions","component"],"sources":["../../src/client/routes/_auth/projects/$projectId/compute/flavors/-components/FlavorDetailsView.tsx","../../src/client/routes/_auth/projects/$projectId/compute/flavors/$flavorId.tsx?tsr-split=component"],"sourcesContent":["import {\n Stack,\n DescriptionList,\n DescriptionTerm,\n DescriptionDefinition,\n Status,\n} from \"@cloudoperators/juno-ui-components/index\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { Fragment } from \"react\"\nimport type { Flavor } from \"@/server/Compute/types/flavor\"\nimport ClipboardText from \"@/client/components/ClipboardText\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useProjectId } from \"@/client/hooks/useProjectId\"\n\ninterface FlavorDetailsViewProps {\n flavor: Flavor\n canListSpecs?: boolean\n}\n\nexport function FlavorDetailsView({ flavor, canListSpecs = false }: FlavorDetailsViewProps) {\n const { t } = useLingui()\n const projectId = useProjectId()\n const formatWithUnit = (value: number, unit: string) => `${value} ${unit}`\n\n const {\n data: extraSpecs,\n isLoading,\n isError,\n } = trpcReact.compute.getExtraSpecs.useQuery(\n {\n project_id: projectId,\n flavorId: flavor.id,\n },\n {\n enabled: !!projectId && !!flavor.id && canListSpecs,\n }\n )\n\n const basicInfoItems = [\n { label: t`ID`, value: <ClipboardText text={flavor.id} /> },\n { label: t`Name`, value: flavor.name },\n { label: t`Description`, value: flavor?.description ?? \"\" },\n {\n label: t`Public`,\n value: flavor[\"os-flavor-access:is_public\"] ? <Trans>Yes</Trans> : <Trans>No</Trans>,\n },\n {\n label: t`Disabled`,\n value: flavor[\"OS-FLV-DISABLED:disabled\"] ? <Trans>Yes</Trans> : <Trans>No</Trans>,\n },\n ]\n\n const hardwareSpecItems = [\n { label: t`VCPUs`, value: flavor.vcpus },\n { label: t`RAM`, value: formatWithUnit(flavor.ram, \"MiB\") },\n { label: t`Root Disk`, value: formatWithUnit(flavor.disk, \"GiB\") },\n {\n label: t`Ephemeral Disk`,\n value: formatWithUnit(flavor[\"OS-FLV-EXT-DATA:ephemeral\"] || 0, \"GiB\"),\n },\n {\n label: t`Swap`,\n value: flavor.swap === 0 || flavor.swap === \"\" ? <Trans>None</Trans> : formatWithUnit(Number(flavor.swap), \"MiB\"),\n },\n { label: t`RX/TX Factor`, value: flavor.rxtx_factor ?? \"\" },\n ]\n\n const extraSpecItems = extraSpecs ? Object.entries(extraSpecs).map(([key, value]) => ({ label: key, value })) : []\n\n return (\n <Stack direction=\"vertical\" gap=\"6\" className=\"mt-6\">\n <Stack direction=\"horizontal\" gap=\"6\" className=\"grid grid-cols-2\">\n <Stack direction=\"vertical\" gap=\"2\">\n <h2>\n <Trans>Flavor Information</Trans>\n </h2>\n <DescriptionList alignTerms=\"right\">\n {basicInfoItems.map(({ label, value }, index) => (\n <Fragment key={`basic-${index}`}>\n <DescriptionTerm>{label}</DescriptionTerm>\n <DescriptionDefinition>\n <div className=\"truncate\">{value}</div>\n </DescriptionDefinition>\n </Fragment>\n ))}\n </DescriptionList>\n </Stack>\n\n <Stack direction=\"vertical\" gap=\"2\">\n <h2>\n <Trans>Hardware Specifications</Trans>\n </h2>\n <DescriptionList alignTerms=\"right\">\n {hardwareSpecItems.map(({ label, value }, index) => (\n <Fragment key={`hardware-${index}`}>\n <DescriptionTerm>{label}</DescriptionTerm>\n <DescriptionDefinition>\n <div className=\"truncate\">{value}</div>\n </DescriptionDefinition>\n </Fragment>\n ))}\n </DescriptionList>\n </Stack>\n </Stack>\n\n {canListSpecs && (\n <Stack direction=\"vertical\" gap=\"2\">\n <h2>\n <Trans>Metadata</Trans>\n </h2>\n {isLoading ? (\n <Status status=\"progress\" />\n ) : isError ? (\n <Status status=\"error\" title={t`Failed to Load Metadata`} />\n ) : extraSpecs && Object.keys(extraSpecs).length > 0 ? (\n <DescriptionList alignTerms=\"right\" className=\"grid-cols-2\">\n {extraSpecItems.map(({ label, value }, index) => (\n <Fragment key={`extra-${index}`}>\n <DescriptionTerm className=\"col-span-1 break-all\">{label}</DescriptionTerm>\n <DescriptionDefinition className=\"col-span-1\">\n <div className=\"break-all\">{value}</div>\n </DescriptionDefinition>\n </Fragment>\n ))}\n </DescriptionList>\n ) : (\n <Status status=\"empty\" title={t`No Metadata Properties Found`} />\n )}\n </Stack>\n )}\n </Stack>\n )\n}\n","import {\n Button,\n ButtonRow,\n Stack,\n PopupMenu,\n PopupMenuToggle,\n PopupMenuOptions,\n PopupMenuItem,\n PopupMenuSectionSeparator,\n Container,\n Status,\n} from \"@cloudoperators/juno-ui-components/index\"\nimport { createFileRoute, redirect, useNavigate, useParams } from \"@tanstack/react-router\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useSetBreadcrumb } from \"@/client/hooks/useSetBreadcrumb\"\nimport { FlavorDetailsView } from \"./-components/FlavorDetailsView\"\nimport { useErrorTranslation } from \"@/client/utils/useErrorTranslation\"\nimport { EditSpecModal } from \"./-components/EditSpecModal\"\nimport { ManageAccessModal } from \"./-components/ManageAccessModal\"\nimport { DeleteFlavorModal } from \"./-components/DeleteFlavorModal\"\nimport { useModal } from \"@/client/utils/useModal\"\nimport { ContentHeader } from \"@/client/components/ContentHeader/ContentHeader\"\nimport { RouteIdLevelDefaultError } from \"@/client/components/Errors/RouteIdLevelDefaultError\"\n\nfunction FlavorErrorComponent() {\n const { t } = useLingui()\n const navigate = useNavigate()\n const { projectId } = Route.useParams()\n\n return (\n <RouteIdLevelDefaultError\n action={\n <Button\n variant=\"primary\"\n onClick={() => navigate({ to: \"/projects/$projectId/compute/flavors\", params: { projectId } })}\n >\n {t`Back to Flavors`}\n </Button>\n }\n />\n )\n}\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/compute/flavors/$flavorId\")({\n staticData: {\n section: \"compute\",\n service: \"flavors\",\n analytics: {\n name: \"compute.flavors.detail\",\n },\n } satisfies RouteInfo,\n loader: async ({ context, params }) => {\n const flavor = await context.trpcClient?.compute.getFlavorById.query({\n project_id: params.projectId,\n flavorId: params.flavorId,\n })\n return { flavorName: flavor?.name ?? null }\n },\n head: ({ loaderData }) => ({\n meta: [{ title: loaderData?.flavorName ?? \"Flavor Details\" }],\n }),\n component: RouteComponent,\n beforeLoad: async ({ context, params }) => {\n const { trpcClient } = context\n const { projectId } = params\n\n const availableServices = (await trpcClient?.auth.getAvailableServices.query()) || []\n\n const serviceIndex = getServiceIndex(availableServices)\n\n if (!serviceIndex[\"flavor\"] && !serviceIndex[\"compute\"]) {\n throw redirect({\n to: \"/projects/$projectId\",\n params: { projectId },\n })\n }\n },\n errorComponent: FlavorErrorComponent,\n})\n\nfunction RouteComponent() {\n const { projectId, flavorId } = useParams({\n from: \"/_auth/projects/$projectId/compute/flavors/$flavorId\",\n })\n const { trpcClient } = Route.useRouteContext()\n const navigate = useNavigate()\n const { t } = useLingui()\n const { translateError, isRetryableError } = useErrorTranslation()\n const utils = trpcReact.useUtils()\n\n const {\n data: flavor,\n status,\n error,\n refetch,\n } = trpcReact.compute.getFlavorById.useQuery({\n project_id: projectId,\n flavorId,\n })\n\n useSetBreadcrumb(Route.id, flavor?.name)\n\n const { data: permissionsData } = trpcReact.compute.canUser.useQuery({\n project_id: projectId,\n permission: [\n \"flavors:delete\",\n \"flavors:add_project\",\n \"flavors:remove_project\",\n \"flavor_specs:list\",\n \"flavor_specs:create\",\n \"flavor_specs:delete\",\n ],\n })\n\n const canDeleteFlavor = permissionsData?.[0] ?? false\n const canManageAccess = (permissionsData?.[1] ?? false) || (permissionsData?.[2] ?? false)\n const canListSpecs = permissionsData?.[3] ?? false\n const canManageSpecs = (permissionsData?.[4] ?? false) || (permissionsData?.[5] ?? false)\n\n const [specModalOpen, toggleSpecModal] = useModal()\n const [accessModalOpen, toggleAccessModal] = useModal()\n const [deleteModalOpen, toggleDeleteModal] = useModal()\n\n const handleSpecModalClose = () => {\n toggleSpecModal()\n utils.compute.getExtraSpecs.invalidate({ project_id: projectId, flavorId })\n }\n\n const handleBack = () => {\n navigate({\n to: \"/projects/$projectId/compute/flavors\",\n params: { projectId },\n })\n }\n\n const handleHome = () => {\n navigate({\n to: \"/projects/$projectId\",\n params: { projectId },\n })\n }\n\n const handleRetry = () => {\n refetch()\n }\n\n if (status === \"pending\") {\n return <Status status=\"progress\" title={t`Loading Flavor Details...`} />\n }\n\n if (status === \"error\") {\n const errorCode = error?.message || \"UNKNOWN_ERROR\"\n const translatedError = translateError(errorCode)\n const canRetry = isRetryableError(errorCode)\n\n const getStatusCode = (code: string): number | undefined => {\n if (code.includes(\"UNAUTHORIZED\")) return 401\n if (code.includes(\"FORBIDDEN\")) return 403\n if (code.includes(\"NOT_FOUND\")) return 404\n if (code.includes(\"SERVER_ERROR\")) return 500\n return undefined\n }\n\n return (\n <Container className=\"py-8\">\n <Status\n status=\"error\"\n code={getStatusCode(errorCode)}\n title={t`Error Loading Flavor`}\n body={translatedError}\n action={\n <ButtonRow>\n <Button variant=\"primary\" onClick={handleBack}>\n <Trans>Back</Trans>\n </Button>\n <Button onClick={handleHome}>\n <Trans>Home</Trans>\n </Button>\n {canRetry && (\n <Button onClick={handleRetry}>\n <Trans>Try Again</Trans>\n </Button>\n )}\n </ButtonRow>\n }\n />\n </Container>\n )\n }\n\n if (!flavor) {\n return (\n <Container className=\"py-8\">\n <Status\n status=\"error\"\n code={404}\n title={t`Flavor Not Found`}\n body={t`The requested flavor could not be found. It may have been deleted or you may not have access to it.`}\n action={\n <ButtonRow>\n <Button variant=\"primary\" onClick={handleBack}>\n <Trans>Back</Trans>\n </Button>\n <Button onClick={handleHome}>\n <Trans>Home</Trans>\n </Button>\n </ButtonRow>\n }\n />\n </Container>\n )\n }\n\n const isPublicFlavor = flavor[\"os-flavor-access:is_public\"] !== false\n const hasPopupMenuItems = (canManageAccess && !isPublicFlavor) || canDeleteFlavor\n const canEditMetadata = canManageSpecs && canListSpecs\n const hasMoreActions = hasPopupMenuItems || canEditMetadata\n\n const headerActions = hasMoreActions ? (\n <Stack gap=\"0.5\" alignment=\"center\">\n {hasPopupMenuItems && (\n <PopupMenu>\n <PopupMenuToggle as=\"div\">\n <Button icon=\"moreVert\" title={t`More Actions`} aria-label={t`More Actions`} />\n </PopupMenuToggle>\n <PopupMenuOptions>\n {canManageAccess && !isPublicFlavor && (\n <PopupMenuItem label={t`Manage Access`} onClick={toggleAccessModal} />\n )}\n {canDeleteFlavor && (\n <>\n <PopupMenuSectionSeparator />\n <PopupMenuItem label={t`Delete Flavor`} onClick={toggleDeleteModal} />\n </>\n )}\n </PopupMenuOptions>\n </PopupMenu>\n )}\n {canEditMetadata && (\n <Button variant=\"primary\" onClick={toggleSpecModal}>\n <Trans>Edit Metadata</Trans>\n </Button>\n )}\n </Stack>\n ) : undefined\n\n return (\n <>\n <ContentHeader title={flavor.name} projectId={projectId} actions={headerActions} />\n <Stack direction=\"vertical\">\n <FlavorDetailsView flavor={flavor} canListSpecs={canListSpecs} />\n </Stack>\n\n {trpcClient && (\n <>\n {specModalOpen && (\n <EditSpecModal\n client={trpcClient}\n isOpen={specModalOpen}\n onClose={handleSpecModalClose}\n project={projectId}\n flavor={flavor}\n />\n )}\n\n {accessModalOpen && (\n <ManageAccessModal\n client={trpcClient}\n isOpen={accessModalOpen}\n onClose={toggleAccessModal}\n project={projectId}\n flavor={flavor}\n />\n )}\n\n {deleteModalOpen && (\n <DeleteFlavorModal\n client={trpcClient}\n isOpen={deleteModalOpen}\n onClose={toggleDeleteModal}\n project={projectId}\n flavor={flavor}\n onSuccess={handleBack}\n />\n )}\n </>\n )}\n </>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;AAmBA,SAAgBS,GAAkB,EAAEC,WAAQC,kBAAe,MAA+B;CACxF,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQC,EAAAA,GACRC,IAAYL,EAAAA,GACZM,KAAkBC,GAAeC,MAAiB,GAAGD,EAAM,GAAGC,KAE9D,EACJC,MAAMC,GACNC,cACAC,eACEb,EAAUc,QAAQC,cAAcC,SAClC;EACEC,YAAYX;EACZY,UAAUf,EAAOgB;CACnB,GACA,EACEC,SAAS,CAAC,CAACd,KAAa,CAAC,CAACH,EAAOgB,MAAMf,EACzC,CAAA,GAGIiB,IAAiB;EACrB;GAAEC,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAG,CAAA;GAAGf,OAAO,gBAACT,GAAAA,EAAcyB,MAAMrB,EAAOgB,GAAAA,CAAAA;EAAO;EAC1D;GAAEG,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAK,CAAA;GAAGf,OAAOL,EAAOsB;EAAK;EACrC;GAAEH,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAY,CAAA;GAAGf,OAAOL,GAAQuB,eAAe;EAAG;EAC1D;GACEJ,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAO,CAAA;GACff,OAAOL,EAAO,gCAAgC,gBAAA,GAAA,EAAA,IAAA,SAAqB,CAAA,IAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;EACrE;EACA;GACEmB,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAS,CAAA;GACjBf,OAAOL,EAAO,8BAA8B,gBAAA,GAAA,EAAA,IAAA,SAAqB,CAAA,IAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;EACnE;CACD,GAEKwB,IAAoB;EACxB;GAAEL,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAM,CAAA;GAAGf,OAAOL,EAAOyB;EAAM;EACvC;GAAEN,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAI,CAAA;GAAGf,OAAOD,EAAeJ,EAAO0B,KAAK,KAAA;EAAO;EAC1D;GAAEP,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAU,CAAA;GAAGf,OAAOD,EAAeJ,EAAO2B,MAAM,KAAA;EAAO;EACjE;GACER,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAe,CAAA;GACvBf,OAAOD,EAAeJ,EAAO,gCAAgC,GAAG,KAAA;EAClE;EACA;GACEmB,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAK,CAAA;GACbf,OAAOL,EAAO4B,SAAS,KAAK5B,EAAO4B,SAAS,KAAK,gBAAA,GAAA,EAAA,IAAA,SAAsBxB,CAAAA,IAAAA,EAAeyB,OAAO7B,EAAO4B,IAAI,GAAG,KAAA;EAC7G;EACA;GAAET,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAa,CAAA;GAAGf,OAAOL,EAAO8B,eAAe;EAAG;CAC3D,GAEKC,IAAiBvB,IAAawB,OAAOC,QAAQzB,CAAAA,CAAAA,CAAY0B,KAAK,CAACC,GAAK9B,QAAY;EAAEc,OAAOgB;EAAK9B;CAAM,EAAA,IAAM,CAAA;CAEhH,OACE,gBAACf,GAAAA;EAAM8C,WAAU;EAAWC,KAAI;EAAIC,WAAU;EAC5C,UAAA,CAAA,gBAAChD,GAAAA;GAAM8C,WAAU;GAAaC,KAAI;GAAIC,WAAU;GAC9C,UAAA,CAAA,gBAAChD,GAAAA;IAAM8C,WAAU;IAAWC,KAAI;IAC9B,UAAA,CAAA,gBAACE,MAAAA,EACC,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA,EAAA,CAAA,GAEF,gBAAChD,GAAAA;KAAgBiD,YAAW;KACzBtB,UAAAA,EAAegB,KAAK,EAAEf,UAAOd,YAASoC,MACrC,gBAAC9C,GAAAA,EAAAA,UAAAA,CACC,gBAACH,GAAAA,EAAiB2B,UAAAA,EAAAA,CAAAA,GAClB,gBAAC1B,GAAAA,EACC,UAAA,gBAACiD,OAAAA;MAAIJ,WAAU;MAAYjC,UAAAA;KAHhB,CAAA,EAAA,CAAA,CAAA,EAAA,GAAA,SAASoC,GAAO,CAAA;;GAUrC,CAAA,GAAA,gBAACnD,GAAAA;IAAM8C,WAAU;IAAWC,KAAI;IAC9B,UAAA,CAAA,gBAACE,MAAAA,EACC,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA,EAAA,CAAA,GAEF,gBAAChD,GAAAA;KAAgBiD,YAAW;KACzBhB,UAAAA,EAAkBU,KAAK,EAAEf,UAAOd,YAASoC,MACxC,gBAAC9C,GAAAA,EAAAA,UAAAA,CACC,gBAACH,GAAAA,EAAiB2B,UAAAA,EAAAA,CAAAA,GAClB,gBAAC1B,GAAAA,EACC,UAAA,gBAACiD,OAAAA;MAAIJ,WAAU;MAAYjC,UAAAA;KAHhB,CAAA,EAAA,CAAA,CAAA,EAAA,GAAA,YAAYoC,GAAO,CAAA;;;EAWzCxC,CAAAA,GAAAA,KACC,gBAACX,GAAAA;GAAM8C,WAAU;GAAWC,KAAI;GAC9B,UAAA,CAAA,gBAACE,MAAAA,EACC,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA,EAAA,CAAA,GAED9B,IACC,gBAACf,GAAAA,EAAOiD,QAAO,WACbjC,CAAAA,IAAAA,IACF,gBAAChB,GAAAA;IAAOiD,QAAO;IAAQC,OAAOxB,EAAAA,EAAC,EAAA,IAAA,SAAwB,CAAA;GACrDZ,CAAAA,IAAAA,KAAcwB,OAAOa,KAAKrC,CAAAA,CAAAA,CAAYsC,SAAS,IACjD,gBAACvD,GAAAA;IAAgBiD,YAAW;IAAQF,WAAU;IAC3CP,UAAAA,EAAeG,KAAK,EAAEf,UAAOd,YAASoC,MACrC,gBAAC9C,GAAAA,EAAAA,UAAAA,CACC,gBAACH,GAAAA;KAAgB8C,WAAU;KAAwBnB,UAAAA;IACnD,CAAA,GAAA,gBAAC1B,GAAAA;KAAsB6C,WAAU;KAC/B,UAAA,gBAACI,OAAAA;MAAIJ,WAAU;MAAajC,UAAAA;;IAHjB,CAAA,CAAA,EAAA,GAAA,SAASoC,GAAO,CAAA;GASnC,CAAA,IAAA,gBAAC/C,GAAAA;IAAOiD,QAAO;IAAQC,OAAOxB,EAAAA,EAAC,EAAA,IAAA,SAA6B,CAAA;;;;AAMxE;;;ACjDA,SAASmD,IAAAA;CACP,IAAM,EAAEC,cAAWC,gBAAaf,GAAU,EACxCgB,MAAM,uDACR,CAAA,GACM,EAAEC,kBAAeL,EAAMM,gBAAe,GACtCC,IAAWpB,EAAAA,GACX,EAAA,MAAA,GAAA,GAAA,MAAQG,EAAAA,GACR,EAAEmB,mBAAgBC,wBAAqBhB,EAAAA,GACvCiB,IAAQpB,EAAUqB,SAAQ,GAE1B,EACJC,MAAMC,GACNC,WACAC,UACAC,eACE1B,EAAU2B,QAAQC,cAAcC,SAAS;EAC3CC,YAAYnB;EACZC;CACF,CAAA;CAEAX,EAAiBQ,EAAMsB,IAAIR,GAAQS,IAAAA;CAEnC,IAAM,EAAEV,MAAMW,MAAoBjC,EAAU2B,QAAQO,QAAQL,SAAS;EACnEC,YAAYnB;EACZwB,YAAY;GACV;GACA;GACA;GACA;GACA;GACA;EAAqB;CAEzB,CAAA,GAEMC,IAAkBH,IAAkB,MAAM,IAC1CI,KAAmBJ,IAAkB,MAAM,QAAWA,IAAkB,MAAM,KAC9EK,IAAeL,IAAkB,MAAM,IACvCM,MAAkBN,IAAkB,MAAM,QAAWA,IAAkB,MAAM,KAE7E,CAACO,GAAeC,KAAmBlC,EAAAA,GACnC,CAACmC,GAAiBC,KAAqBpC,EAAAA,GACvC,CAACqC,GAAiBC,KAAqBtC,EAAAA,GAEvCuC,UAAuBA;EAE3B1B,AADAqB,EAAAA,GACArB,EAAMO,QAAQoB,cAAcC,WAAW;GAAElB,YAAYnB;GAAWC;EAAS,CAAA;CAC3E,GAEMqC,UAAaA;EACjBjC,EAAS;GACPkC,IAAI;GACJC,QAAQ,EAAExC,aAAU;EACtB,CAAA;CACF,GAEMyC,UAAaA;EACjBpC,EAAS;GACPkC,IAAI;GACJC,QAAQ,EAAExC,aAAU;EACtB,CAAA;CACF,GAEM0C,WAAcA;EAClB3B,EAAAA;CACF;CAEA,IAAIF,MAAW,WACb,OAAO,gBAAC,GAAA;EAAO,QAAO;EAAW,OAAOP,EAAAA,EAAC,EAAA,IAAA,SAAA,CAAA;;CAG3C,IAAIO,MAAW,SAAS;EACtB,IAAM8B,IAAY7B,GAAO8B,WAAW,iBAC9BC,IAAkBtC,EAAeoC,CAAAA,GACjCG,IAAWtC,EAAiBmC,CAAAA;EAUlC,OACE,gBAAC,GAAA;GAAU,WAAU;GACnB,UAAA,gBAAC,GAAA;IACC,QAAO;IACP,QAZiBK,MAAAA;KACrB,IAAIA,EAAKC,SAAS,cAAA,GAAiB,OAAO;KAC1C,IAAID,EAAKC,SAAS,WAAA,GAAc,OAAO;KACvC,IAAID,EAAKC,SAAS,WAAA,GAAc,OAAO;KACvC,IAAID,EAAKC,SAAS,cAAA,GAAiB,OAAO;IAE5C,EAMYF,CAAcJ,CAAAA;IACpB,OAAOrC,EAAAA,EAAC,EAAA,IAAA,SAAA,CAAA;IACR,MAAMuC;IACN,QACE,gBAAC,GAAA,EAAA,UAAA;KACC,gBAAC,GAAA;MAAO,SAAQ;MAAU,SAASP;MACjC,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;;KAEF,gBAAC,GAAA;MAAO,SAASG;MACf,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;;KAEDK,KACC,gBAAC,GAAA;MAAO,SAASJ;MACf,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;;;;;CAQhB;CAEA,IAAI,CAAC9B,GACH,OACE,gBAAC,GAAA;EAAU,WAAU;EACnB,UAAA,gBAAC,GAAA;GACC,QAAO;GACP,MAAM;GACN,OAAON,EAAAA,EAAC,EAAA,IAAA,SAAA,CAAA;GACR,MAAMA,EAAAA,EAAC,EAAA,IAAA,SAAA,CAAA;GACP,QACE,gBAAC,GAAA,EAAA,UAAA,CACC,gBAAC,GAAA;IAAO,SAAQ;IAAU,SAASgC;IACjC,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;GAEF,CAAA,GAAA,gBAAC,GAAA;IAAO,SAASG;IACf,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;;;;CASd,IAAMU,IAAiBvC,EAAO,kCAAkC,IAC1DwC,IAAqB1B,KAAmB,CAACyB,KAAmB1B,GAC5D4B,IAAkBzB,MAAkBD,GAGpC4B,KAFiBH,KAAqBC,IAG1C,gBAAC,GAAA;EAAM,KAAI;EAAM,WAAU;EACxBD,UAAAA,CAAAA,KACC,gBAAC,GAAA,EAAA,UAAA,CACC,gBAAC,GAAA;GAAgB,IAAG;GAClB,UAAA,gBAAC,GAAA;IAAO,MAAK;IAAW,OAAO9C,EAAAA,EAAC,EAAA,IAAA,SAAA,CAAA;IAAgB,cAAYA,EAAAA,EAAC,EAAA,IAAA,SAAA,CAAA;;EAE/D,CAAA,GAAA,gBAAC,GAAA,EAAA,UAAA,CACEoB,KAAmB,CAACyB,KACnB,gBAAC,GAAA;GAAc,OAAO7C,EAAAA,EAAC,EAAA,IAAA,SAAA,CAAA;GAAiB,SAAS0B;EAElDP,CAAAA,GAAAA,KACC,gBAAA,GAAA,EAAA,UAAA,CACE,gBAAC,GAAA,CAAA,CAAA,GACD,gBAAC,GAAA;GAAc,OAAOnB,EAAAA,EAAC,EAAA,IAAA,SAAA,CAAA;GAAiB,SAAS4B;EAM1DmB,CAAAA,CAAAA,EAAAA,CAAAA,CAAAA,EAAAA,CAAAA,CAAAA,EAAAA,CAAAA,GAAAA,KACC,gBAAC,GAAA;GAAO,SAAQ;GAAU,SAASvB;GACjC,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;;CAIJoB,CAAAA,IAAAA,KAAAA;CAEJ,OACE,gBAAA,GAAA,EAAA,UAAA;EACE,gBAAC,GAAA;GAAc,OAAOtC,EAAOS;GAAiBrB;GAAW,SAASuD;;EAClE,gBAAC,GAAA;GAAM,WAAU;GACf,UAAA,gBAAC,IAAA;IAA0B3C;IAAsBe;;;EAGlDxB,KACC,gBAAA,GAAA,EAAA,UAAA;GACG0B,KACC,gBAAC,GAAA;IACC,QAAQ1B;IACR,QAAQ0B;IACR,SAASM;IACT,SAASnC;IACDY;;GAIXmB,KACC,gBAAC,GAAA;IACC,QAAQ5B;IACR,QAAQ4B;IACR,SAASC;IACT,SAAShC;IACDY;;GAIXqB,KACC,gBAAC,GAAA;IACC,QAAQ9B;IACR,QAAQ8B;IACR,SAASC;IACT,SAASlC;IACDY;IACR,WAAW0B;;;;AAOzB"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { t as e } from "./helpers-1PpYf-fC.mjs";
|
|
2
|
-
import { createFileRoute as t, lazyRouteComponent as n, redirect as r } from "@tanstack/react-router";
|
|
3
|
-
var i = t("/_auth/projects/$projectId/compute/flavors/$flavorId")({
|
|
4
|
-
staticData: {
|
|
5
|
-
section: "compute",
|
|
6
|
-
service: "flavors",
|
|
7
|
-
analytics: { name: "compute.flavors.detail" }
|
|
8
|
-
},
|
|
9
|
-
loader: async ({ context: e, params: t }) => ({ flavorName: (await e.trpcClient?.compute.getFlavorById.query({
|
|
10
|
-
project_id: t.projectId,
|
|
11
|
-
flavorId: t.flavorId
|
|
12
|
-
}))?.name ?? null }),
|
|
13
|
-
head: ({ loaderData: e }) => ({ meta: [{ title: e?.flavorName ?? "Flavor Details" }] }),
|
|
14
|
-
component: n(() => import("./_flavorId-BPvssEzn.mjs"), "component"),
|
|
15
|
-
beforeLoad: async ({ context: t, params: n }) => {
|
|
16
|
-
let { trpcClient: i } = t, { projectId: a } = n, o = await i?.auth.getAvailableServices.query() || [], s = e(o);
|
|
17
|
-
if (!s.flavor && !s.compute) throw r({
|
|
18
|
-
to: "/projects/$projectId",
|
|
19
|
-
params: { projectId: a }
|
|
20
|
-
});
|
|
21
|
-
},
|
|
22
|
-
errorComponent: n(() => import("./_flavorId-CZcIp0Ih.mjs"), "errorComponent")
|
|
23
|
-
});
|
|
24
|
-
//#endregion
|
|
25
|
-
export { i as t };
|
|
26
|
-
|
|
27
|
-
//# sourceMappingURL=_flavorId-CFUBcU-l.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_flavorId-CFUBcU-l.mjs","names":["createFileRoute","redirect","getServiceIndex","Route","staticData","section","service","analytics","name","RouteInfo","loader","context","params","flavor","trpcClient","compute","getFlavorById","query","project_id","projectId","flavorId","flavorName","head","loaderData","meta","title","component","lazyRouteComponent","$$splitComponentImporter","beforeLoad","availableServices","auth","getAvailableServices","serviceIndex","to","errorComponent","$$splitErrorComponentImporter"],"sources":["../../src/client/routes/_auth/projects/$projectId/compute/flavors/$flavorId.tsx"],"sourcesContent":["import {\n Button,\n ButtonRow,\n Stack,\n PopupMenu,\n PopupMenuToggle,\n PopupMenuOptions,\n PopupMenuItem,\n PopupMenuSectionSeparator,\n Container,\n Status,\n} from \"@cloudoperators/juno-ui-components/index\"\nimport { createFileRoute, redirect, useNavigate, useParams } from \"@tanstack/react-router\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useSetBreadcrumb } from \"@/client/hooks/useSetBreadcrumb\"\nimport { FlavorDetailsView } from \"./-components/FlavorDetailsView\"\nimport { useErrorTranslation } from \"@/client/utils/useErrorTranslation\"\nimport { EditSpecModal } from \"./-components/EditSpecModal\"\nimport { ManageAccessModal } from \"./-components/ManageAccessModal\"\nimport { DeleteFlavorModal } from \"./-components/DeleteFlavorModal\"\nimport { useModal } from \"@/client/utils/useModal\"\nimport { ContentHeader } from \"@/client/components/ContentHeader/ContentHeader\"\nimport { RouteIdLevelDefaultError } from \"@/client/components/Errors/RouteIdLevelDefaultError\"\n\nfunction FlavorErrorComponent() {\n const { t } = useLingui()\n const navigate = useNavigate()\n const { projectId } = Route.useParams()\n\n return (\n <RouteIdLevelDefaultError\n action={\n <Button\n variant=\"primary\"\n onClick={() => navigate({ to: \"/projects/$projectId/compute/flavors\", params: { projectId } })}\n >\n {t`Back to Flavors`}\n </Button>\n }\n />\n )\n}\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/compute/flavors/$flavorId\")({\n staticData: {\n section: \"compute\",\n service: \"flavors\",\n analytics: {\n name: \"compute.flavors.detail\",\n },\n } satisfies RouteInfo,\n loader: async ({ context, params }) => {\n const flavor = await context.trpcClient?.compute.getFlavorById.query({\n project_id: params.projectId,\n flavorId: params.flavorId,\n })\n return { flavorName: flavor?.name ?? null }\n },\n head: ({ loaderData }) => ({\n meta: [{ title: loaderData?.flavorName ?? \"Flavor Details\" }],\n }),\n component: RouteComponent,\n beforeLoad: async ({ context, params }) => {\n const { trpcClient } = context\n const { projectId } = params\n\n const availableServices = (await trpcClient?.auth.getAvailableServices.query()) || []\n\n const serviceIndex = getServiceIndex(availableServices)\n\n if (!serviceIndex[\"flavor\"] && !serviceIndex[\"compute\"]) {\n throw redirect({\n to: \"/projects/$projectId\",\n params: { projectId },\n })\n }\n },\n errorComponent: FlavorErrorComponent,\n})\n\nfunction RouteComponent() {\n const { projectId, flavorId } = useParams({\n from: \"/_auth/projects/$projectId/compute/flavors/$flavorId\",\n })\n const { trpcClient } = Route.useRouteContext()\n const navigate = useNavigate()\n const { t } = useLingui()\n const { translateError, isRetryableError } = useErrorTranslation()\n const utils = trpcReact.useUtils()\n\n const {\n data: flavor,\n status,\n error,\n refetch,\n } = trpcReact.compute.getFlavorById.useQuery({\n project_id: projectId,\n flavorId,\n })\n\n useSetBreadcrumb(Route.id, flavor?.name)\n\n const { data: permissionsData } = trpcReact.compute.canUser.useQuery({\n project_id: projectId,\n permission: [\n \"flavors:delete\",\n \"flavors:add_project\",\n \"flavors:remove_project\",\n \"flavor_specs:list\",\n \"flavor_specs:create\",\n \"flavor_specs:delete\",\n ],\n })\n\n const canDeleteFlavor = permissionsData?.[0] ?? false\n const canManageAccess = (permissionsData?.[1] ?? false) || (permissionsData?.[2] ?? false)\n const canListSpecs = permissionsData?.[3] ?? false\n const canManageSpecs = (permissionsData?.[4] ?? false) || (permissionsData?.[5] ?? false)\n\n const [specModalOpen, toggleSpecModal] = useModal()\n const [accessModalOpen, toggleAccessModal] = useModal()\n const [deleteModalOpen, toggleDeleteModal] = useModal()\n\n const handleSpecModalClose = () => {\n toggleSpecModal()\n utils.compute.getExtraSpecs.invalidate({ project_id: projectId, flavorId })\n }\n\n const handleBack = () => {\n navigate({\n to: \"/projects/$projectId/compute/flavors\",\n params: { projectId },\n })\n }\n\n const handleHome = () => {\n navigate({\n to: \"/projects/$projectId\",\n params: { projectId },\n })\n }\n\n const handleRetry = () => {\n refetch()\n }\n\n if (status === \"pending\") {\n return <Status status=\"progress\" title={t`Loading Flavor Details...`} />\n }\n\n if (status === \"error\") {\n const errorCode = error?.message || \"UNKNOWN_ERROR\"\n const translatedError = translateError(errorCode)\n const canRetry = isRetryableError(errorCode)\n\n const getStatusCode = (code: string): number | undefined => {\n if (code.includes(\"UNAUTHORIZED\")) return 401\n if (code.includes(\"FORBIDDEN\")) return 403\n if (code.includes(\"NOT_FOUND\")) return 404\n if (code.includes(\"SERVER_ERROR\")) return 500\n return undefined\n }\n\n return (\n <Container className=\"py-8\">\n <Status\n status=\"error\"\n code={getStatusCode(errorCode)}\n title={t`Error Loading Flavor`}\n body={translatedError}\n action={\n <ButtonRow>\n <Button variant=\"primary\" onClick={handleBack}>\n <Trans>Back</Trans>\n </Button>\n <Button onClick={handleHome}>\n <Trans>Home</Trans>\n </Button>\n {canRetry && (\n <Button onClick={handleRetry}>\n <Trans>Try Again</Trans>\n </Button>\n )}\n </ButtonRow>\n }\n />\n </Container>\n )\n }\n\n if (!flavor) {\n return (\n <Container className=\"py-8\">\n <Status\n status=\"error\"\n code={404}\n title={t`Flavor Not Found`}\n body={t`The requested flavor could not be found. It may have been deleted or you may not have access to it.`}\n action={\n <ButtonRow>\n <Button variant=\"primary\" onClick={handleBack}>\n <Trans>Back</Trans>\n </Button>\n <Button onClick={handleHome}>\n <Trans>Home</Trans>\n </Button>\n </ButtonRow>\n }\n />\n </Container>\n )\n }\n\n const isPublicFlavor = flavor[\"os-flavor-access:is_public\"] !== false\n const hasPopupMenuItems = (canManageAccess && !isPublicFlavor) || canDeleteFlavor\n const canEditMetadata = canManageSpecs && canListSpecs\n const hasMoreActions = hasPopupMenuItems || canEditMetadata\n\n const headerActions = hasMoreActions ? (\n <Stack gap=\"0.5\" alignment=\"center\">\n {hasPopupMenuItems && (\n <PopupMenu>\n <PopupMenuToggle as=\"div\">\n <Button icon=\"moreVert\" title={t`More Actions`} aria-label={t`More Actions`} />\n </PopupMenuToggle>\n <PopupMenuOptions>\n {canManageAccess && !isPublicFlavor && (\n <PopupMenuItem label={t`Manage Access`} onClick={toggleAccessModal} />\n )}\n {canDeleteFlavor && (\n <>\n <PopupMenuSectionSeparator />\n <PopupMenuItem label={t`Delete Flavor`} onClick={toggleDeleteModal} />\n </>\n )}\n </PopupMenuOptions>\n </PopupMenu>\n )}\n {canEditMetadata && (\n <Button variant=\"primary\" onClick={toggleSpecModal}>\n <Trans>Edit Metadata</Trans>\n </Button>\n )}\n </Stack>\n ) : undefined\n\n return (\n <>\n <ContentHeader title={flavor.name} projectId={projectId} actions={headerActions} />\n <Stack direction=\"vertical\">\n <FlavorDetailsView flavor={flavor} canListSpecs={canListSpecs} />\n </Stack>\n\n {trpcClient && (\n <>\n {specModalOpen && (\n <EditSpecModal\n client={trpcClient}\n isOpen={specModalOpen}\n onClose={handleSpecModalClose}\n project={projectId}\n flavor={flavor}\n />\n )}\n\n {accessModalOpen && (\n <ManageAccessModal\n client={trpcClient}\n isOpen={accessModalOpen}\n onClose={toggleAccessModal}\n project={projectId}\n flavor={flavor}\n />\n )}\n\n {deleteModalOpen && (\n <DeleteFlavorModal\n client={trpcClient}\n isOpen={deleteModalOpen}\n onClose={toggleDeleteModal}\n project={projectId}\n flavor={flavor}\n onSuccess={handleBack}\n />\n )}\n </>\n )}\n </>\n )\n}\n"],"mappings":";;AA8CA,IAAaG,IAAQH,EAAgB,sDAAA,CAAA,CAAwD;CAC3FI,YAAY;EACVC,SAAS;EACTC,SAAS;EACTC,WAAW,EACTC,MAAM,yBACR;CACF;CACAE,QAAQ,OAAO,EAAEC,YAASC,iBAKjB,EAAES,aAAYR,MAJAF,EAAQG,YAAYC,QAAQC,cAAcC,MAAM;EACnEC,YAAYN,EAAOO;EACnBC,UAAUR,EAAOQ;CACnB,CAAA,EAAA,EAC6BZ,QAAQ,KAAK;CAE5Cc,OAAO,EAAEC,qBAAkB,EACzBC,MAAM,CAAC,EAAEC,OAAOF,GAAYF,cAAc,iBAAiB,CAAC,EAC9D;CACAK,WAASC,4CAAA,WAAA;CACTE,YAAY,OAAO,EAAElB,YAASC,gBAAQ;EACpC,IAAM,EAAEE,kBAAeH,GACjB,EAAEQ,iBAAcP,GAEhBkB,IAAoB,MAAOhB,GAAYiB,KAAKC,qBAAqBf,MAAAA,KAAY,CAAA,GAE7EgB,IAAe/B,EAAgB4B,CAAAA;EAErC,IAAI,CAACG,EAAa,UAAa,CAACA,EAAa,SAC3C,MAAMhC,EAAS;GACbiC,IAAI;GACJtB,QAAQ,EAAEO,aAAU;EACtB,CAAA;CAEJ;CACAgB,gBAAcR,4CAAA,gBAAA;AAChB,CAAA"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { i as e } from "./build-WuxXRAqf.mjs";
|
|
2
|
-
import { t } from "./_flavorId-CFUBcU-l.mjs";
|
|
3
|
-
import { t as n } from "./RouteIdLevelDefaultError-DPF_x2tG.mjs";
|
|
4
|
-
import { jsx as r } from "react/jsx-runtime";
|
|
5
|
-
import { useNavigate as i } from "@tanstack/react-router";
|
|
6
|
-
import { useLingui as a } from "@lingui/react";
|
|
7
|
-
//#region src/client/routes/_auth/projects/$projectId/compute/flavors/$flavorId.tsx?tsr-split=errorComponent
|
|
8
|
-
function o() {
|
|
9
|
-
let { i18n: o, _: s } = a(), c = i(), { projectId: l } = t.useParams();
|
|
10
|
-
return /*#__PURE__*/ r(n, { action: /*#__PURE__*/ r(e, {
|
|
11
|
-
variant: "primary",
|
|
12
|
-
onClick: () => c({
|
|
13
|
-
to: "/projects/$projectId/compute/flavors",
|
|
14
|
-
params: { projectId: l }
|
|
15
|
-
}),
|
|
16
|
-
children: o._({ id: "ergacm" })
|
|
17
|
-
}) });
|
|
18
|
-
}
|
|
19
|
-
//#endregion
|
|
20
|
-
export { o as errorComponent };
|
|
21
|
-
|
|
22
|
-
//# sourceMappingURL=_flavorId-CZcIp0Ih.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_flavorId-CZcIp0Ih.mjs","names":["Button","useNavigate","useLingui","RouteIdLevelDefaultError","FlavorErrorComponent","t","navigate","projectId","Route","useParams","to","params","errorComponent"],"sources":["../../src/client/routes/_auth/projects/$projectId/compute/flavors/$flavorId.tsx?tsr-split=errorComponent"],"sourcesContent":["import {\n Button,\n ButtonRow,\n Stack,\n PopupMenu,\n PopupMenuToggle,\n PopupMenuOptions,\n PopupMenuItem,\n PopupMenuSectionSeparator,\n Container,\n Status,\n} from \"@cloudoperators/juno-ui-components/index\"\nimport { createFileRoute, redirect, useNavigate, useParams } from \"@tanstack/react-router\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useSetBreadcrumb } from \"@/client/hooks/useSetBreadcrumb\"\nimport { FlavorDetailsView } from \"./-components/FlavorDetailsView\"\nimport { useErrorTranslation } from \"@/client/utils/useErrorTranslation\"\nimport { EditSpecModal } from \"./-components/EditSpecModal\"\nimport { ManageAccessModal } from \"./-components/ManageAccessModal\"\nimport { DeleteFlavorModal } from \"./-components/DeleteFlavorModal\"\nimport { useModal } from \"@/client/utils/useModal\"\nimport { ContentHeader } from \"@/client/components/ContentHeader/ContentHeader\"\nimport { RouteIdLevelDefaultError } from \"@/client/components/Errors/RouteIdLevelDefaultError\"\n\nfunction FlavorErrorComponent() {\n const { t } = useLingui()\n const navigate = useNavigate()\n const { projectId } = Route.useParams()\n\n return (\n <RouteIdLevelDefaultError\n action={\n <Button\n variant=\"primary\"\n onClick={() => navigate({ to: \"/projects/$projectId/compute/flavors\", params: { projectId } })}\n >\n {t`Back to Flavors`}\n </Button>\n }\n />\n )\n}\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/compute/flavors/$flavorId\")({\n staticData: {\n section: \"compute\",\n service: \"flavors\",\n analytics: {\n name: \"compute.flavors.detail\",\n },\n } satisfies RouteInfo,\n loader: async ({ context, params }) => {\n const flavor = await context.trpcClient?.compute.getFlavorById.query({\n project_id: params.projectId,\n flavorId: params.flavorId,\n })\n return { flavorName: flavor?.name ?? null }\n },\n head: ({ loaderData }) => ({\n meta: [{ title: loaderData?.flavorName ?? \"Flavor Details\" }],\n }),\n component: RouteComponent,\n beforeLoad: async ({ context, params }) => {\n const { trpcClient } = context\n const { projectId } = params\n\n const availableServices = (await trpcClient?.auth.getAvailableServices.query()) || []\n\n const serviceIndex = getServiceIndex(availableServices)\n\n if (!serviceIndex[\"flavor\"] && !serviceIndex[\"compute\"]) {\n throw redirect({\n to: \"/projects/$projectId\",\n params: { projectId },\n })\n }\n },\n errorComponent: FlavorErrorComponent,\n})\n\nfunction RouteComponent() {\n const { projectId, flavorId } = useParams({\n from: \"/_auth/projects/$projectId/compute/flavors/$flavorId\",\n })\n const { trpcClient } = Route.useRouteContext()\n const navigate = useNavigate()\n const { t } = useLingui()\n const { translateError, isRetryableError } = useErrorTranslation()\n const utils = trpcReact.useUtils()\n\n const {\n data: flavor,\n status,\n error,\n refetch,\n } = trpcReact.compute.getFlavorById.useQuery({\n project_id: projectId,\n flavorId,\n })\n\n useSetBreadcrumb(Route.id, flavor?.name)\n\n const { data: permissionsData } = trpcReact.compute.canUser.useQuery({\n project_id: projectId,\n permission: [\n \"flavors:delete\",\n \"flavors:add_project\",\n \"flavors:remove_project\",\n \"flavor_specs:list\",\n \"flavor_specs:create\",\n \"flavor_specs:delete\",\n ],\n })\n\n const canDeleteFlavor = permissionsData?.[0] ?? false\n const canManageAccess = (permissionsData?.[1] ?? false) || (permissionsData?.[2] ?? false)\n const canListSpecs = permissionsData?.[3] ?? false\n const canManageSpecs = (permissionsData?.[4] ?? false) || (permissionsData?.[5] ?? false)\n\n const [specModalOpen, toggleSpecModal] = useModal()\n const [accessModalOpen, toggleAccessModal] = useModal()\n const [deleteModalOpen, toggleDeleteModal] = useModal()\n\n const handleSpecModalClose = () => {\n toggleSpecModal()\n utils.compute.getExtraSpecs.invalidate({ project_id: projectId, flavorId })\n }\n\n const handleBack = () => {\n navigate({\n to: \"/projects/$projectId/compute/flavors\",\n params: { projectId },\n })\n }\n\n const handleHome = () => {\n navigate({\n to: \"/projects/$projectId\",\n params: { projectId },\n })\n }\n\n const handleRetry = () => {\n refetch()\n }\n\n if (status === \"pending\") {\n return <Status status=\"progress\" title={t`Loading Flavor Details...`} />\n }\n\n if (status === \"error\") {\n const errorCode = error?.message || \"UNKNOWN_ERROR\"\n const translatedError = translateError(errorCode)\n const canRetry = isRetryableError(errorCode)\n\n const getStatusCode = (code: string): number | undefined => {\n if (code.includes(\"UNAUTHORIZED\")) return 401\n if (code.includes(\"FORBIDDEN\")) return 403\n if (code.includes(\"NOT_FOUND\")) return 404\n if (code.includes(\"SERVER_ERROR\")) return 500\n return undefined\n }\n\n return (\n <Container className=\"py-8\">\n <Status\n status=\"error\"\n code={getStatusCode(errorCode)}\n title={t`Error Loading Flavor`}\n body={translatedError}\n action={\n <ButtonRow>\n <Button variant=\"primary\" onClick={handleBack}>\n <Trans>Back</Trans>\n </Button>\n <Button onClick={handleHome}>\n <Trans>Home</Trans>\n </Button>\n {canRetry && (\n <Button onClick={handleRetry}>\n <Trans>Try Again</Trans>\n </Button>\n )}\n </ButtonRow>\n }\n />\n </Container>\n )\n }\n\n if (!flavor) {\n return (\n <Container className=\"py-8\">\n <Status\n status=\"error\"\n code={404}\n title={t`Flavor Not Found`}\n body={t`The requested flavor could not be found. It may have been deleted or you may not have access to it.`}\n action={\n <ButtonRow>\n <Button variant=\"primary\" onClick={handleBack}>\n <Trans>Back</Trans>\n </Button>\n <Button onClick={handleHome}>\n <Trans>Home</Trans>\n </Button>\n </ButtonRow>\n }\n />\n </Container>\n )\n }\n\n const isPublicFlavor = flavor[\"os-flavor-access:is_public\"] !== false\n const hasPopupMenuItems = (canManageAccess && !isPublicFlavor) || canDeleteFlavor\n const canEditMetadata = canManageSpecs && canListSpecs\n const hasMoreActions = hasPopupMenuItems || canEditMetadata\n\n const headerActions = hasMoreActions ? (\n <Stack gap=\"0.5\" alignment=\"center\">\n {hasPopupMenuItems && (\n <PopupMenu>\n <PopupMenuToggle as=\"div\">\n <Button icon=\"moreVert\" title={t`More Actions`} aria-label={t`More Actions`} />\n </PopupMenuToggle>\n <PopupMenuOptions>\n {canManageAccess && !isPublicFlavor && (\n <PopupMenuItem label={t`Manage Access`} onClick={toggleAccessModal} />\n )}\n {canDeleteFlavor && (\n <>\n <PopupMenuSectionSeparator />\n <PopupMenuItem label={t`Delete Flavor`} onClick={toggleDeleteModal} />\n </>\n )}\n </PopupMenuOptions>\n </PopupMenu>\n )}\n {canEditMetadata && (\n <Button variant=\"primary\" onClick={toggleSpecModal}>\n <Trans>Edit Metadata</Trans>\n </Button>\n )}\n </Stack>\n ) : undefined\n\n return (\n <>\n <ContentHeader title={flavor.name} projectId={projectId} actions={headerActions} />\n <Stack direction=\"vertical\">\n <FlavorDetailsView flavor={flavor} canListSpecs={canListSpecs} />\n </Stack>\n\n {trpcClient && (\n <>\n {specModalOpen && (\n <EditSpecModal\n client={trpcClient}\n isOpen={specModalOpen}\n onClose={handleSpecModalClose}\n project={projectId}\n flavor={flavor}\n />\n )}\n\n {accessModalOpen && (\n <ManageAccessModal\n client={trpcClient}\n isOpen={accessModalOpen}\n onClose={toggleAccessModal}\n project={projectId}\n flavor={flavor}\n />\n )}\n\n {deleteModalOpen && (\n <DeleteFlavorModal\n client={trpcClient}\n isOpen={deleteModalOpen}\n onClose={toggleDeleteModal}\n project={projectId}\n flavor={flavor}\n onSuccess={handleBack}\n />\n )}\n </>\n )}\n </>\n )\n}\n"],"mappings":";;;;;;;AA2BA,SAASI,IAAAA;CACP,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQF,EAAAA,GACRI,IAAWL,EAAAA,GACX,EAAEM,iBAAcC,EAAMC,UAAS;CAErC,OACE,gBAAC,GAAA,EACC,QACE,gBAAC,GAAA;EACC,SAAQ;EACR,eAAeH,EAAS;GAAEI,IAAI;GAAwCC,QAAQ,EAAEJ,aAAU;EAAE,CAAA;EAE3FF,UAAAA,EAAAA,EAAC,EAAA,IAAA,SAAA,CAAA;;AAKZ"}
|