@cobaltcore-dev/aurora 1.3.0 → 2.0.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 (122) hide show
  1. package/dist/client/DeleteFlavorModal-C2MqUgGR.mjs +801 -0
  2. package/dist/client/DeleteFlavorModal-C2MqUgGR.mjs.map +1 -0
  3. package/dist/client/{FiltersInput-CKI6zWnm.mjs → FiltersInput-Becwxo_J.mjs} +36 -33
  4. package/dist/client/FiltersInput-Becwxo_J.mjs.map +1 -0
  5. package/dist/client/{FloatingIpActionModals-Ch8uozH9.mjs → FloatingIpActionModals-Cq10WljB.mjs} +2 -2
  6. package/dist/client/{FloatingIpActionModals-Ch8uozH9.mjs.map → FloatingIpActionModals-Cq10WljB.mjs.map} +1 -1
  7. package/dist/client/ImageToastNotifications-BWfzOUMc.mjs +1135 -0
  8. package/dist/client/ImageToastNotifications-BWfzOUMc.mjs.map +1 -0
  9. package/dist/client/RouteIdLevelDefaultError-CSseJ1yG.mjs +26 -0
  10. package/dist/client/RouteIdLevelDefaultError-CSseJ1yG.mjs.map +1 -0
  11. package/dist/client/{_flavorId-Dg7MS0Af.mjs → _flavorId-CaA4-Pnf.mjs} +4 -3
  12. package/dist/client/_flavorId-CaA4-Pnf.mjs.map +1 -0
  13. package/dist/client/_flavorId-DYv_StX22.mjs +276 -0
  14. package/dist/client/_flavorId-DYv_StX22.mjs.map +1 -0
  15. package/dist/client/_flavorId-YV3jCS5g.mjs +22 -0
  16. package/dist/client/_flavorId-YV3jCS5g.mjs.map +1 -0
  17. package/dist/client/{_floatingIpId-C9xfRWot.mjs → _floatingIpId-BeYElanB.mjs} +2 -2
  18. package/dist/client/{_floatingIpId-C9xfRWot.mjs.map → _floatingIpId-BeYElanB.mjs.map} +1 -1
  19. package/dist/client/{_floatingIpId-DNn6ABCB.mjs → _floatingIpId-Dpsc7GU4.mjs} +5 -5
  20. package/dist/client/{_floatingIpId-DNn6ABCB.mjs.map → _floatingIpId-Dpsc7GU4.mjs.map} +1 -1
  21. package/dist/client/_imageId-mfKp3JHn.mjs +558 -0
  22. package/dist/client/_imageId-mfKp3JHn.mjs.map +1 -0
  23. package/dist/client/_imageId-mpXUMCh_.mjs +22 -0
  24. package/dist/client/_imageId-mpXUMCh_.mjs.map +1 -0
  25. package/dist/client/{_imageId-8JIbFmGB.mjs → _imageId-pBSS0YcC.mjs} +4 -3
  26. package/dist/client/_imageId-pBSS0YcC.mjs.map +1 -0
  27. package/dist/client/{_projectId-B3wmSala.mjs → _projectId-AjgJX6Gl.mjs} +2 -2
  28. package/dist/client/_projectId-AjgJX6Gl.mjs.map +1 -0
  29. package/dist/client/{_projectId-DPzv0CCp.mjs → _projectId-BnTBxKfp.mjs} +4 -4
  30. package/dist/client/_projectId-BnTBxKfp.mjs.map +1 -0
  31. package/dist/client/{_projectId-DfeVJy0G.mjs → _projectId-CVrdJ52s.mjs} +2 -2
  32. package/dist/client/_projectId-CVrdJ52s.mjs.map +1 -0
  33. package/dist/client/_projectId-DgciZslU.mjs +92 -0
  34. package/dist/client/_projectId-DgciZslU.mjs.map +1 -0
  35. package/dist/client/{_securityGroupId-C6eHmrx_.mjs → _securityGroupId-AO3wnH8g.mjs} +2 -2
  36. package/dist/client/_securityGroupId-AO3wnH8g.mjs.map +1 -0
  37. package/dist/client/{_securityGroupId-DmplhDgt.mjs → _securityGroupId-Bq0ZyG6z.mjs} +750 -741
  38. package/dist/client/_securityGroupId-Bq0ZyG6z.mjs.map +1 -0
  39. package/dist/client/_storageType-c-DAu8qr.mjs +858 -0
  40. package/dist/client/_storageType-c-DAu8qr.mjs.map +1 -0
  41. package/dist/client/components/{Error → Errors}/RouteError.d.ts +5 -0
  42. package/dist/client/components/Errors/RouteIdLevelDefaultError.d.ts +17 -0
  43. package/dist/client/components/Errors/ServiceLevelDefaultError.d.ts +9 -0
  44. package/dist/client/components/ListToolbar/SelectedFilters.d.ts +7 -2
  45. package/dist/client/components/ListToolbar/types.d.ts +6 -0
  46. package/dist/client/components/ListToolbar/valueLabels.d.ts +11 -0
  47. package/dist/client/flavors-Bgq3KZmx.mjs +659 -0
  48. package/dist/client/flavors-Bgq3KZmx.mjs.map +1 -0
  49. package/dist/client/{flavors-B1SDOPDu.mjs → flavors-ZudiAiTU.mjs} +2 -2
  50. package/dist/client/{flavors-B1SDOPDu.mjs.map → flavors-ZudiAiTU.mjs.map} +1 -1
  51. package/dist/client/{floatingips-DrCvtXtT.mjs → floatingips-B1oLH8z6.mjs} +6 -6
  52. package/dist/client/{floatingips-DrCvtXtT.mjs.map → floatingips-B1oLH8z6.mjs.map} +1 -1
  53. package/dist/client/floatingips-BeQEkVH8.mjs +14 -0
  54. package/dist/client/floatingips-BeQEkVH8.mjs.map +1 -0
  55. package/dist/client/floatingips-BtLg3yEQ.mjs +22 -0
  56. package/dist/client/floatingips-BtLg3yEQ.mjs.map +1 -0
  57. package/dist/client/floatingips-Cz9k80cc.mjs.map +1 -1
  58. package/dist/client/{images-BGQv9kKT.mjs → images-CnTW3bpy.mjs} +810 -770
  59. package/dist/client/images-CnTW3bpy.mjs.map +1 -0
  60. package/dist/client/{images-CPmMa4SQ.mjs → images-DZHDYDQu.mjs} +2 -2
  61. package/dist/client/{images-CPmMa4SQ.mjs.map → images-DZHDYDQu.mjs.map} +1 -1
  62. package/dist/client/index.js +412 -409
  63. package/dist/client/index.js.map +1 -1
  64. package/dist/client/{objects-DVccbrL1.mjs → objects-25xsh4Ia.mjs} +2 -2
  65. package/dist/client/objects-25xsh4Ia.mjs.map +1 -0
  66. package/dist/client/objects-KXY6dgwq.mjs +82 -0
  67. package/dist/client/objects-KXY6dgwq.mjs.map +1 -0
  68. package/dist/client/objects-QryuClU3.mjs +82 -0
  69. package/dist/client/objects-QryuClU3.mjs.map +1 -0
  70. package/dist/client/{objects-BR3eeSNH.mjs → objects-jYQBFzwg.mjs} +4668 -4699
  71. package/dist/client/objects-jYQBFzwg.mjs.map +1 -0
  72. package/dist/client/projects-yiK0HGSA.mjs.map +1 -1
  73. package/dist/client/securitygroups--0PS2wbM.mjs +580 -0
  74. package/dist/client/securitygroups--0PS2wbM.mjs.map +1 -0
  75. package/dist/client/{securitygroups-DEJQBcxm.mjs → securitygroups-BRndk7wh.mjs} +2 -2
  76. package/dist/client/{securitygroups-DEJQBcxm.mjs.map → securitygroups-BRndk7wh.mjs.map} +1 -1
  77. package/dist/client/securitygroups-CdN4yAAw.mjs +14 -0
  78. package/dist/client/securitygroups-CdN4yAAw.mjs.map +1 -0
  79. package/dist/client/securitygroups-Cs2Op-tu.mjs +22 -0
  80. package/dist/client/securitygroups-Cs2Op-tu.mjs.map +1 -0
  81. package/dist/client/securitygroups-CtKne8UQ.mjs.map +1 -1
  82. package/dist/client/trpcClient.d.ts +6 -1
  83. package/dist/client/useModalTracking-BYd37pXm.mjs +37 -0
  84. package/dist/client/useModalTracking-BYd37pXm.mjs.map +1 -0
  85. package/dist/client/useSecurityGroupPermissions--hK4aR8Y.mjs +294 -0
  86. package/dist/client/useSecurityGroupPermissions--hK4aR8Y.mjs.map +1 -0
  87. package/dist/server/index.d.ts +6 -1
  88. package/dist/server/index.js +96 -30
  89. package/package.json +4 -4
  90. package/dist/client/DeleteFlavorModal-V44QCJBd.mjs +0 -773
  91. package/dist/client/DeleteFlavorModal-V44QCJBd.mjs.map +0 -1
  92. package/dist/client/FiltersInput-CKI6zWnm.mjs.map +0 -1
  93. package/dist/client/ImageToastNotifications-m6c3tVPb.mjs +0 -1152
  94. package/dist/client/ImageToastNotifications-m6c3tVPb.mjs.map +0 -1
  95. package/dist/client/_flavorId-Dg7MS0Af.mjs.map +0 -1
  96. package/dist/client/_flavorId-kHl-b8rI.mjs +0 -232
  97. package/dist/client/_flavorId-kHl-b8rI.mjs.map +0 -1
  98. package/dist/client/_imageId-8JIbFmGB.mjs.map +0 -1
  99. package/dist/client/_imageId-BBAlRioC.mjs +0 -574
  100. package/dist/client/_imageId-BBAlRioC.mjs.map +0 -1
  101. package/dist/client/_projectId-7Nl1MQTJ.mjs +0 -99
  102. package/dist/client/_projectId-7Nl1MQTJ.mjs.map +0 -1
  103. package/dist/client/_projectId-B3wmSala.mjs.map +0 -1
  104. package/dist/client/_projectId-DPzv0CCp.mjs.map +0 -1
  105. package/dist/client/_projectId-DfeVJy0G.mjs.map +0 -1
  106. package/dist/client/_securityGroupId-C6eHmrx_.mjs.map +0 -1
  107. package/dist/client/_securityGroupId-DmplhDgt.mjs.map +0 -1
  108. package/dist/client/_storageType-C5gS9eut.mjs +0 -845
  109. package/dist/client/_storageType-C5gS9eut.mjs.map +0 -1
  110. package/dist/client/flavors-D8_PzQUB.mjs +0 -628
  111. package/dist/client/flavors-D8_PzQUB.mjs.map +0 -1
  112. package/dist/client/images-BGQv9kKT.mjs.map +0 -1
  113. package/dist/client/objects-AERkhfiM.mjs +0 -66
  114. package/dist/client/objects-AERkhfiM.mjs.map +0 -1
  115. package/dist/client/objects-BR3eeSNH.mjs.map +0 -1
  116. package/dist/client/objects-DVccbrL1.mjs.map +0 -1
  117. package/dist/client/securitygroups-BjhgLBHm.mjs +0 -620
  118. package/dist/client/securitygroups-BjhgLBHm.mjs.map +0 -1
  119. package/dist/client/useModalTracking-BcOKTYRN.mjs +0 -33
  120. package/dist/client/useModalTracking-BcOKTYRN.mjs.map +0 -1
  121. package/dist/client/useSecurityGroupPermissions-BOyLQLdC.mjs +0 -227
  122. package/dist/client/useSecurityGroupPermissions-BOyLQLdC.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_flavorId-DYv_StX22.mjs","names":["Stack","ContentHeading","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","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 ContentHeading,\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 <ContentHeading>\n <Trans>Flavor Information</Trans>\n </ContentHeading>\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 <ContentHeading>\n <Trans>Hardware Specifications</Trans>\n </ContentHeading>\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 <ContentHeading>\n <Trans>Metadata</Trans>\n </ContentHeading>\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":"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"}
@@ -0,0 +1,22 @@
1
+ import { i as e } from "./build-WuxXRAqf.mjs";
2
+ import { t } from "./_flavorId-CaA4-Pnf.mjs";
3
+ import { t as n } from "./RouteIdLevelDefaultError-CSseJ1yG.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-YV3jCS5g.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_flavorId-YV3jCS5g.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"}
@@ -11,7 +11,7 @@ var i = t("/_auth/projects/$projectId/network/floatingips/$floatingIpId/")({
11
11
  floatingip_id: t.floatingIpId
12
12
  }))?.floating_ip_address ?? null }),
13
13
  head: ({ loaderData: e }) => ({ meta: [{ title: e?.floatingIpAddress ?? "Floating IP" }] }),
14
- component: n(() => import("./_floatingIpId-DNn6ABCB.mjs"), "component"),
14
+ component: n(() => import("./_floatingIpId-Dpsc7GU4.mjs"), "component"),
15
15
  beforeLoad: async ({ context: t, params: n }) => {
16
16
  let { trpcClient: i } = t, a = await i?.auth.getAvailableServices.query() || [], o = e(a);
17
17
  if (!o.network || !o.network.neutron) throw r({
@@ -23,4 +23,4 @@ var i = t("/_auth/projects/$projectId/network/floatingips/$floatingIpId/")({
23
23
  //#endregion
24
24
  export { i as t };
25
25
 
26
- //# sourceMappingURL=_floatingIpId-C9xfRWot.mjs.map
26
+ //# sourceMappingURL=_floatingIpId-BeYElanB.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"_floatingIpId-C9xfRWot.mjs","names":["createFileRoute","redirect","getServiceIndex","Route","staticData","section","service","analytics","name","RouteInfo","loader","context","params","floatingIp","trpcClient","network","getById","query","project_id","projectId","floatingip_id","floatingIpId","floatingIpAddress","floating_ip_address","head","loaderData","meta","title","component","lazyRouteComponent","$$splitComponentImporter","beforeLoad","availableServices","auth","getAvailableServices","serviceIndex","to"],"sources":["../../src/client/routes/_auth/projects/$projectId/network/floatingips/$floatingIpId/index.tsx"],"sourcesContent":["import { createFileRoute, redirect, useNavigate } from \"@tanstack/react-router\"\nimport { Button, Status } from \"@cloudoperators/juno-ui-components\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { useProjectId } from \"@/client/hooks\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useSetBreadcrumb } from \"@/client/hooks/useSetBreadcrumb\"\nimport { FloatingIpDetailsView } from \"./-components/-details/FloatingIpDetailsView\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/network/floatingips/$floatingIpId/\")({\n staticData: {\n section: \"network\",\n service: \"floatingips\",\n analytics: {\n name: \"network.floatingips.detail\",\n },\n } satisfies RouteInfo,\n loader: async ({ context, params }) => {\n const floatingIp = await context.trpcClient?.network.floatingIp.getById.query({\n project_id: params.projectId,\n floatingip_id: params.floatingIpId,\n })\n return { floatingIpAddress: floatingIp?.floating_ip_address ?? null }\n },\n head: ({ loaderData }) => ({\n meta: [{ title: loaderData?.floatingIpAddress ?? \"Floating IP\" }],\n }),\n component: RouteComponent,\n beforeLoad: async ({ context, params }) => {\n const { trpcClient } = context\n\n const availableServices = (await trpcClient?.auth.getAvailableServices.query()) || []\n const serviceIndex = getServiceIndex(availableServices)\n\n // Redirect if network service not available\n if (!serviceIndex[\"network\"]) {\n throw redirect({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId: params.projectId },\n })\n }\n\n if (!serviceIndex[\"network\"][\"neutron\"]) {\n throw redirect({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId: params.projectId },\n })\n }\n },\n})\n\nfunction RouteComponent() {\n const { floatingIpId } = Route.useParams()\n const projectId = useProjectId()\n const navigate = useNavigate()\n const { t } = useLingui()\n\n // Fetch floating IP details\n const {\n data: floatingIp,\n isLoading,\n isError,\n error,\n } = trpcReact.network.floatingIp.getById.useQuery({\n project_id: projectId,\n floatingip_id: floatingIpId,\n })\n\n useSetBreadcrumb(Route.id, floatingIp?.floating_ip_address)\n\n const handleBack = () => {\n navigate({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId },\n })\n }\n\n // Loading state\n if (isLoading) {\n return <Status status=\"progress\" title={t`Loading Floating IP Details...`} />\n }\n\n // Error state\n if (isError || !floatingIp) {\n const errorMessage = error?.message || t`Error loading floating IP`\n return (\n <Status\n status=\"error\"\n title={isError ? errorMessage : t`Floating IP not found`}\n action={\n <Button onClick={handleBack} variant=\"primary\">\n <Trans>Back to Floating IPs</Trans>\n </Button>\n }\n />\n )\n }\n\n return <FloatingIpDetailsView floatingIp={floatingIp} />\n}\n"],"mappings":";;AAUA,IAAaG,IAAQH,EAAgB,+DAAA,CAAA,CAAiE;CACpGI,YAAY;EACVC,SAAS;EACTC,SAAS;EACTC,WAAW,EACTC,MAAM,6BACR;CACF;CACAE,QAAQ,OAAO,EAAEC,YAASC,iBAKjB,EAAEU,oBAAmBT,MAJHF,EAAQG,YAAYC,QAAQF,WAAWG,QAAQC,MAAM;EAC5EC,YAAYN,EAAOO;EACnBC,eAAeR,EAAOS;CACxB,CAAA,EAAA,EACwCE,uBAAuB,KAAK;CAEtEC,OAAO,EAAEC,qBAAkB,EACzBC,MAAM,CAAC,EAAEC,OAAOF,GAAYH,qBAAqB,cAAc,CAAC,EAClE;CACAM,WAASC,gDAAA,WAAA;CACTE,YAAY,OAAO,EAAEpB,YAASC,gBAAQ;EACpC,IAAM,EAAEE,kBAAeH,GAEjBqB,IAAoB,MAAOlB,GAAYmB,KAAKC,qBAAqBjB,MAAAA,KAAY,CAAA,GAC7EkB,IAAejC,EAAgB8B,CAAAA;EAUrC,IAPI,CAACG,EAAa,WAOd,CAACA,EAAa,QAAW,SAC3B,MAAMlC,EAAS;GACbmC,IAAI;GACJxB,QAAQ,EAAEO,WAAWP,EAAOO,UAAU;EACxC,CAAA;CAEJ;AACF,CAAA"}
1
+ {"version":3,"file":"_floatingIpId-BeYElanB.mjs","names":["createFileRoute","redirect","getServiceIndex","Route","staticData","section","service","analytics","name","RouteInfo","loader","context","params","floatingIp","trpcClient","network","getById","query","project_id","projectId","floatingip_id","floatingIpId","floatingIpAddress","floating_ip_address","head","loaderData","meta","title","component","lazyRouteComponent","$$splitComponentImporter","beforeLoad","availableServices","auth","getAvailableServices","serviceIndex","to"],"sources":["../../src/client/routes/_auth/projects/$projectId/network/floatingips/$floatingIpId/index.tsx"],"sourcesContent":["import { createFileRoute, redirect, useNavigate } from \"@tanstack/react-router\"\nimport { Button, Status } from \"@cloudoperators/juno-ui-components\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { useProjectId } from \"@/client/hooks\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useSetBreadcrumb } from \"@/client/hooks/useSetBreadcrumb\"\nimport { FloatingIpDetailsView } from \"./-components/-details/FloatingIpDetailsView\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/network/floatingips/$floatingIpId/\")({\n staticData: {\n section: \"network\",\n service: \"floatingips\",\n analytics: {\n name: \"network.floatingips.detail\",\n },\n } satisfies RouteInfo,\n loader: async ({ context, params }) => {\n const floatingIp = await context.trpcClient?.network.floatingIp.getById.query({\n project_id: params.projectId,\n floatingip_id: params.floatingIpId,\n })\n return { floatingIpAddress: floatingIp?.floating_ip_address ?? null }\n },\n head: ({ loaderData }) => ({\n meta: [{ title: loaderData?.floatingIpAddress ?? \"Floating IP\" }],\n }),\n component: RouteComponent,\n beforeLoad: async ({ context, params }) => {\n const { trpcClient } = context\n\n const availableServices = (await trpcClient?.auth.getAvailableServices.query()) || []\n const serviceIndex = getServiceIndex(availableServices)\n\n // Redirect if network service not available\n if (!serviceIndex[\"network\"]) {\n throw redirect({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId: params.projectId },\n })\n }\n\n if (!serviceIndex[\"network\"][\"neutron\"]) {\n throw redirect({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId: params.projectId },\n })\n }\n },\n})\n\nfunction RouteComponent() {\n const { floatingIpId } = Route.useParams()\n const projectId = useProjectId()\n const navigate = useNavigate()\n const { t } = useLingui()\n\n // Fetch floating IP details\n const {\n data: floatingIp,\n isLoading,\n isError,\n error,\n } = trpcReact.network.floatingIp.getById.useQuery({\n project_id: projectId,\n floatingip_id: floatingIpId,\n })\n\n useSetBreadcrumb(Route.id, floatingIp?.floating_ip_address)\n\n const handleBack = () => {\n navigate({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId },\n })\n }\n\n // Loading state\n if (isLoading) {\n return <Status status=\"progress\" title={t`Loading Floating IP Details...`} />\n }\n\n // Error state\n if (isError || !floatingIp) {\n const errorMessage = error?.message || t`Error Loading Floating IP`\n return (\n <Status\n status=\"error\"\n title={isError ? errorMessage : t`Floating IP Not Found`}\n action={\n <Button onClick={handleBack} variant=\"primary\">\n <Trans>Back to Floating IPs</Trans>\n </Button>\n }\n />\n )\n }\n\n return <FloatingIpDetailsView floatingIp={floatingIp} />\n}\n"],"mappings":";;AAUA,IAAaG,IAAQH,EAAgB,+DAAA,CAAA,CAAiE;CACpGI,YAAY;EACVC,SAAS;EACTC,SAAS;EACTC,WAAW,EACTC,MAAM,6BACR;CACF;CACAE,QAAQ,OAAO,EAAEC,YAASC,iBAKjB,EAAEU,oBAAmBT,MAJHF,EAAQG,YAAYC,QAAQF,WAAWG,QAAQC,MAAM;EAC5EC,YAAYN,EAAOO;EACnBC,eAAeR,EAAOS;CACxB,CAAA,EAAA,EACwCE,uBAAuB,KAAK;CAEtEC,OAAO,EAAEC,qBAAkB,EACzBC,MAAM,CAAC,EAAEC,OAAOF,GAAYH,qBAAqB,cAAc,CAAC,EAClE;CACAM,WAASC,gDAAA,WAAA;CACTE,YAAY,OAAO,EAAEpB,YAASC,gBAAQ;EACpC,IAAM,EAAEE,kBAAeH,GAEjBqB,IAAoB,MAAOlB,GAAYmB,KAAKC,qBAAqBjB,MAAAA,KAAY,CAAA,GAC7EkB,IAAejC,EAAgB8B,CAAAA;EAUrC,IAPI,CAACG,EAAa,WAOd,CAACA,EAAa,QAAW,SAC3B,MAAMlC,EAAS;GACbmC,IAAI;GACJxB,QAAQ,EAAEO,WAAWP,EAAOO,UAAU;EACxC,CAAA;CAEJ;AACF,CAAA"}
@@ -1,12 +1,12 @@
1
1
  import { D as e, Q as t, at as n, c as r, g as i, i as a, rt as o, x as s } from "./build-WuxXRAqf.mjs";
2
2
  import { a as c } from "./trpcClient-D7gpR7YG.mjs";
3
- import { t as l } from "./_floatingIpId-C9xfRWot.mjs";
3
+ import { t as l } from "./_floatingIpId-BeYElanB.mjs";
4
4
  import { t as u } from "./useProjectId-DBc5lpoU.mjs";
5
5
  import { t as d } from "./ContentHeader-CPJbgYWn.mjs";
6
6
  import { t as f } from "./useSetBreadcrumb-tn7lBaQV.mjs";
7
7
  import "./hooks-D0yKIumu.mjs";
8
8
  import { t as p } from "./TwoColumnDescriptionList-DKS42RKa.mjs";
9
- import { t as m } from "./FloatingIpActionModals-Ch8uozH9.mjs";
9
+ import { t as m } from "./FloatingIpActionModals-Cq10WljB.mjs";
10
10
  import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
11
11
  import { useNavigate as v } from "@tanstack/react-router";
12
12
  import { Trans as y, useLingui as b } from "@lingui/react";
@@ -177,10 +177,10 @@ function C() {
177
177
  title: r._({ id: "VLI9eO" })
178
178
  });
179
179
  if (p || !s) {
180
- let e = m?.message || r._({ id: "Smk7M2" });
180
+ let e = m?.message || r._({ id: "AjwnAt" });
181
181
  return /*#__PURE__*/ g(o, {
182
182
  status: "error",
183
- title: p ? e : r._({ id: "ChOuUj" }),
183
+ title: p ? e : r._({ id: "AZo+ca" }),
184
184
  action: /*#__PURE__*/ g(a, {
185
185
  onClick: h,
186
186
  variant: "primary",
@@ -193,4 +193,4 @@ function C() {
193
193
  //#endregion
194
194
  export { C as component };
195
195
 
196
- //# sourceMappingURL=_floatingIpId-DNn6ABCB.mjs.map
196
+ //# sourceMappingURL=_floatingIpId-Dpsc7GU4.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"_floatingIpId-DNn6ABCB.mjs","names":["formatFloatingIpStatus","status","charAt","slice","toLowerCase","Stack","Button","ContentHeading","PopupMenu","PopupMenuToggle","PopupMenuItem","PopupMenuOptions","formatFloatingIpStatus","TwoColumnDescriptionList","ContentHeader","FloatingIpActionModals","FloatingIpDetailsView","floatingIp","useLingui","basicInfoItems","label","t","value","id","description","project_id","status","created_at","Date","toLocaleString","updated_at","tags","join","networkRoutingItems","floating_ip_address","floating_network_id","fixed_ip_address","port_details","name","mac_address","network_id","device_owner","device_id","router_id","port_id","qos_policy_id","port_forwardings","map","port","dnsItems","dns_domain","dns_name","title","projectId","actions","toggleEditModal","toggleAttachModal","toggleDetachModal","toggleReleaseModal","gap","alignment","className","as","icon","onClick","variant","direction","items","useNavigate","Button","Status","Trans","useLingui","useProjectId","trpcReact","useSetBreadcrumb","FloatingIpDetailsView","Route","RouteComponent","floatingIpId","useParams","projectId","navigate","t","data","floatingIp","isLoading","isError","error","network","getById","useQuery","project_id","floatingip_id","id","floating_ip_address","handleBack","to","params","errorMessage","message","component"],"sources":["../../src/client/utils/formatFloatingIpStatus.ts","../../src/client/routes/_auth/projects/$projectId/network/floatingips/$floatingIpId/-components/-details/FloatingIpDetailsView.tsx","../../src/client/routes/_auth/projects/$projectId/network/floatingips/$floatingIpId/index.tsx?tsr-split=component"],"sourcesContent":["import type { FloatingIpStatus } from \"@/server/Network/types/floatingIp\"\n\n/**\n * Formats a floating IP status value from uppercase enum to title case.\n * Example: \"ACTIVE\" → \"Active\", \"DOWN\" → \"Down\", \"ERROR\" → \"Error\"\n */\nexport const formatFloatingIpStatus = (status: FloatingIpStatus) => {\n return status.charAt(0) + status.slice(1).toLowerCase()\n}\n","import { Trans, useLingui } from \"@lingui/react/macro\"\nimport {\n Stack,\n Button,\n ContentHeading,\n PopupMenu,\n PopupMenuToggle,\n PopupMenuItem,\n PopupMenuOptions,\n} from \"@cloudoperators/juno-ui-components\"\nimport type { FloatingIp } from \"@/server/Network/types/floatingIp\"\nimport { formatFloatingIpStatus } from \"@/client/utils/formatFloatingIpStatus\"\nimport type { DetailListItem } from \"@/client/components/TwoColumnDescriptionList\"\nimport { TwoColumnDescriptionList } from \"@/client/components/TwoColumnDescriptionList\"\nimport { ContentHeader } from \"@/client/components/ContentHeader/ContentHeader\"\nimport { FloatingIpActionModals } from \"../../../-components/-modals/FloatingIpActionModals\"\n\ninterface FloatingIpDetailsViewProps {\n floatingIp: FloatingIp\n}\n\nexport const FloatingIpDetailsView = ({ floatingIp }: FloatingIpDetailsViewProps) => {\n const { t } = useLingui()\n\n const basicInfoItems: DetailListItem[] = [\n { label: t`ID`, value: floatingIp.id },\n { label: t`Description`, value: floatingIp.description || `—` },\n { label: t`Project ID`, value: floatingIp.project_id || `—` },\n { label: t`Status`, value: formatFloatingIpStatus(floatingIp.status) },\n { label: t`Created At`, value: floatingIp.created_at ? new Date(floatingIp.created_at).toLocaleString() : `—` },\n { label: t`Updated At`, value: floatingIp.updated_at ? new Date(floatingIp.updated_at).toLocaleString() : `—` },\n { label: t`Tags`, value: floatingIp.tags?.join(\", \") || `—` },\n ]\n\n const networkRoutingItems: DetailListItem[] = [\n { label: t`Floating IP Address`, value: floatingIp.floating_ip_address || `—` },\n { label: t`Floating Network`, value: floatingIp.floating_network_id || `—` },\n { label: t`Fixed IP Address`, value: floatingIp.fixed_ip_address || `—` },\n { label: t`Port Name`, value: floatingIp.port_details?.name || `—` },\n { label: t`MAC Address`, value: floatingIp.port_details?.mac_address || `—` },\n { label: t`Network ID`, value: floatingIp.port_details?.network_id || `—` },\n { label: t`Device Owner`, value: floatingIp.port_details?.device_owner || `—` },\n { label: t`Device ID`, value: floatingIp.port_details?.device_id || `—` },\n { label: t`Router ID`, value: floatingIp.router_id || `—` },\n { label: t`Port ID`, value: floatingIp.port_id || `—` },\n { label: t`QoS Policy ID`, value: floatingIp.qos_policy_id || `—` },\n { label: t`Port Forwarding`, value: floatingIp.port_forwardings?.map((port) => port.id).join(\", \") || `—` },\n ]\n\n const dnsItems: DetailListItem[] = [\n { label: t`DNS Domain`, value: floatingIp.dns_domain || `—` },\n { label: t`DNS Name`, value: floatingIp.dns_name || `—` },\n ]\n\n return (\n <>\n <ContentHeader\n title={floatingIp.floating_ip_address ?? floatingIp.id}\n projectId={floatingIp.project_id}\n actions={\n <FloatingIpActionModals floatingIp={floatingIp}>\n {({ toggleEditModal, toggleAttachModal, toggleDetachModal, toggleReleaseModal }) => (\n <Stack gap=\"0.5\" alignment=\"center\">\n <PopupMenu className=\"flex items-center\">\n <PopupMenuToggle as=\"div\">\n <Button icon=\"moreVert\" title={t`Floating IP actions`} />\n </PopupMenuToggle>\n <PopupMenuOptions>\n <PopupMenuItem label={t`Edit Description`} onClick={toggleEditModal} />\n <PopupMenuItem label={t`Detach`} onClick={toggleDetachModal} />\n <PopupMenuItem label={t`Release`} onClick={toggleReleaseModal} />\n </PopupMenuOptions>\n </PopupMenu>\n <Button variant=\"primary\" className=\"whitespace-nowrap\" onClick={toggleAttachModal}>\n {t`Attach`}\n </Button>\n </Stack>\n )}\n </FloatingIpActionModals>\n }\n />\n\n <Stack direction=\"vertical\" gap=\"6\" className=\"my-6\">\n <Stack direction=\"vertical\" gap=\"2\">\n <ContentHeading>\n <Trans>Basic Info</Trans>\n </ContentHeading>\n <TwoColumnDescriptionList items={basicInfoItems} />\n </Stack>\n\n <Stack direction=\"vertical\" gap=\"2\">\n <ContentHeading>\n <Trans>Network & Routing</Trans>\n </ContentHeading>\n <TwoColumnDescriptionList items={networkRoutingItems} />\n </Stack>\n\n <Stack direction=\"vertical\" gap=\"2\">\n <ContentHeading>\n <Trans>DNS</Trans>\n </ContentHeading>\n <TwoColumnDescriptionList items={dnsItems} />\n </Stack>\n </Stack>\n </>\n )\n}\n","import { createFileRoute, redirect, useNavigate } from \"@tanstack/react-router\"\nimport { Button, Status } from \"@cloudoperators/juno-ui-components\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { useProjectId } from \"@/client/hooks\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useSetBreadcrumb } from \"@/client/hooks/useSetBreadcrumb\"\nimport { FloatingIpDetailsView } from \"./-components/-details/FloatingIpDetailsView\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/network/floatingips/$floatingIpId/\")({\n staticData: {\n section: \"network\",\n service: \"floatingips\",\n analytics: {\n name: \"network.floatingips.detail\",\n },\n } satisfies RouteInfo,\n loader: async ({ context, params }) => {\n const floatingIp = await context.trpcClient?.network.floatingIp.getById.query({\n project_id: params.projectId,\n floatingip_id: params.floatingIpId,\n })\n return { floatingIpAddress: floatingIp?.floating_ip_address ?? null }\n },\n head: ({ loaderData }) => ({\n meta: [{ title: loaderData?.floatingIpAddress ?? \"Floating IP\" }],\n }),\n component: RouteComponent,\n beforeLoad: async ({ context, params }) => {\n const { trpcClient } = context\n\n const availableServices = (await trpcClient?.auth.getAvailableServices.query()) || []\n const serviceIndex = getServiceIndex(availableServices)\n\n // Redirect if network service not available\n if (!serviceIndex[\"network\"]) {\n throw redirect({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId: params.projectId },\n })\n }\n\n if (!serviceIndex[\"network\"][\"neutron\"]) {\n throw redirect({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId: params.projectId },\n })\n }\n },\n})\n\nfunction RouteComponent() {\n const { floatingIpId } = Route.useParams()\n const projectId = useProjectId()\n const navigate = useNavigate()\n const { t } = useLingui()\n\n // Fetch floating IP details\n const {\n data: floatingIp,\n isLoading,\n isError,\n error,\n } = trpcReact.network.floatingIp.getById.useQuery({\n project_id: projectId,\n floatingip_id: floatingIpId,\n })\n\n useSetBreadcrumb(Route.id, floatingIp?.floating_ip_address)\n\n const handleBack = () => {\n navigate({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId },\n })\n }\n\n // Loading state\n if (isLoading) {\n return <Status status=\"progress\" title={t`Loading Floating IP Details...`} />\n }\n\n // Error state\n if (isError || !floatingIp) {\n const errorMessage = error?.message || t`Error loading floating IP`\n return (\n <Status\n status=\"error\"\n title={isError ? errorMessage : t`Floating IP not found`}\n action={\n <Button onClick={handleBack} variant=\"primary\">\n <Trans>Back to Floating IPs</Trans>\n </Button>\n }\n />\n )\n }\n\n return <FloatingIpDetailsView floatingIp={floatingIp} />\n}\n"],"mappings":";;;;;;;;;;;;;AAMA,IAAaA,KAA0BC,MAC9BA,EAAOC,OAAO,CAAA,IAAKD,EAAOE,MAAM,CAAA,CAAA,CAAGC,YAAW,GCc1CY,KAAyB,EAAEC,oBAAwC;CAC9E,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQC,EAAAA,GAERC,IAAmC;EACvC;GAAEC,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAG,CAAA;GAAGC,OAAOL,EAAWM;EAAG;EACrC;GAAEH,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAY,CAAA;GAAGC,OAAOL,EAAWO,eAAe;EAAI;EAC9D;GAAEJ,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAW,CAAA;GAAGC,OAAOL,EAAWQ,cAAc;EAAI;EAC5D;GAAEL,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAO,CAAA;GAAGC,OAAOV,EAAuBK,EAAWS,MAAM;EAAE;EACrE;GAAEN,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAW,CAAA;GAAGC,OAAOL,EAAWU,aAAa,IAAIC,KAAKX,EAAWU,UAAU,CAAA,CAAEE,eAAc,IAAK;EAAI;EAC9G;GAAET,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAW,CAAA;GAAGC,OAAOL,EAAWa,aAAa,IAAIF,KAAKX,EAAWa,UAAU,CAAA,CAAED,eAAc,IAAK;EAAI;EAC9G;GAAET,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAK,CAAA;GAAGC,OAAOL,EAAWc,MAAMC,KAAK,IAAA,KAAS;EAAI;CAC7D,GAEKC,IAAwC;EAC5C;GAAEb,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAoB,CAAA;GAAGC,OAAOL,EAAWiB,uBAAuB;EAAI;EAC9E;GAAEd,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAiB,CAAA;GAAGC,OAAOL,EAAWkB,uBAAuB;EAAI;EAC3E;GAAEf,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAiB,CAAA;GAAGC,OAAOL,EAAWmB,oBAAoB;EAAI;EACxE;GAAEhB,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAU,CAAA;GAAGC,OAAOL,EAAWoB,cAAcC,QAAQ;EAAI;EACnE;GAAElB,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAY,CAAA;GAAGC,OAAOL,EAAWoB,cAAcE,eAAe;EAAI;EAC5E;GAAEnB,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAW,CAAA;GAAGC,OAAOL,EAAWoB,cAAcG,cAAc;EAAI;EAC1E;GAAEpB,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAa,CAAA;GAAGC,OAAOL,EAAWoB,cAAcI,gBAAgB;EAAI;EAC9E;GAAErB,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAU,CAAA;GAAGC,OAAOL,EAAWoB,cAAcK,aAAa;EAAI;EACxE;GAAEtB,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAU,CAAA;GAAGC,OAAOL,EAAW0B,aAAa;EAAI;EAC1D;GAAEvB,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAQ,CAAA;GAAGC,OAAOL,EAAW2B,WAAW;EAAI;EACtD;GAAExB,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAc,CAAA;GAAGC,OAAOL,EAAW4B,iBAAiB;EAAI;EAClE;GAAEzB,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAgB,CAAA;GAAGC,OAAOL,EAAW6B,kBAAkBC,KAAKC,MAASA,EAAKzB,EAAE,CAAA,CAAES,KAAK,IAAA,KAAS;EAAI;CAC3G,GAEKiB,IAA6B,CACjC;EAAE7B,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAW,CAAA;EAAGC,OAAOL,EAAWiC,cAAc;CAAI,GAC5D;EAAE9B,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAS,CAAA;EAAGC,OAAOL,EAAWkC,YAAY;CAAI,CACzD;CAED,OACE,gBAAA,GAAA,EAAA,UAAA,CACE,gBAACrC,GAAAA;EACCsC,OAAOnC,EAAWiB,uBAAuBjB,EAAWM;EACpD8B,WAAWpC,EAAWQ;EACtB6B,SACE,gBAACvC,GAAAA;GAAmCE;GACjC,WAAC,EAAEsC,oBAAiBC,sBAAmBC,sBAAmBC,4BACzD,gBAACrD,GAAAA;IAAMsD,KAAI;IAAMC,WAAU;IACzB,UAAA,CAAA,gBAACpD,GAAAA;KAAUqD,WAAU;KACnB,UAAA,CAAA,gBAACpD,GAAAA;MAAgBqD,IAAG;MAClB,UAAA,gBAACxD,GAAAA;OAAOyD,MAAK;OAAWX,OAAO/B,EAAAA,EAAC,EAAA,IAAA,SAAoB,CAAA;;KAEtD,CAAA,GAAA,gBAACV,GAAAA,EAAAA,UAAAA;MACC,gBAACD,GAAAA;OAAcU,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAiB,CAAA;OAAG2C,SAAST;;MACpD,gBAAC7C,GAAAA;OAAcU,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAO,CAAA;OAAG2C,SAASP;;MAC1C,gBAAC/C,GAAAA;OAAcU,OAAOC,EAAAA,EAAC,EAAA,IAAA,SAAQ,CAAA;OAAG2C,SAASN;;;IAG/C,CAAA,GAAA,gBAACpD,GAAAA;KAAO2D,SAAQ;KAAUJ,WAAU;KAAoBG,SAASR;KAC9DnC,UAAAA,EAAAA,EAAC,EAAA,IAAA,SAAO,CAAA;;;;CAQrB,CAAA,GAAA,gBAAChB,GAAAA;EAAM6D,WAAU;EAAWP,KAAI;EAAIE,WAAU;;GAC5C,gBAACxD,GAAAA;IAAM6D,WAAU;IAAWP,KAAI;IAC9B,UAAA,CAAA,gBAACpD,GAAAA,EACC,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA,EAAA,CAAA,GAEF,gBAACM,GAAAA,EAAyBsD,OAAOhD,EAAAA,CAAAA,CAAAA;;GAGnC,gBAACd,GAAAA;IAAM6D,WAAU;IAAWP,KAAI;IAC9B,UAAA,CAAA,gBAACpD,GAAAA,EACC,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA,EAAA,CAAA,GAEF,gBAACM,GAAAA,EAAyBsD,OAAOlC,EAAAA,CAAAA,CAAAA;;GAGnC,gBAAC5B,GAAAA;IAAM6D,WAAU;IAAWP,KAAI;IAC9B,UAAA,CAAA,gBAACpD,GAAAA,EACC,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA,EAAA,CAAA,GAEF,gBAACM,GAAAA,EAAyBsD,OAAOlB,EAAAA,CAAAA,CAAAA;;;;AAK3C;;;ACtDA,SAAS6B,IAAAA;CACP,IAAM,EAAEC,oBAAiBF,EAAMG,UAAS,GAClCC,IAAYR,EAAAA,GACZS,IAAWd,EAAAA,GACX,EAAA,MAAA,GAAA,GAAA,MAAQI,EAAAA,GAGR,EACJY,MAAMC,GACNC,cACAC,YACAC,aACEd,EAAUe,QAAQJ,WAAWK,QAAQC,SAAS;EAChDC,YAAYX;EACZY,eAAed;CACjB,CAAA;CAEAJ,EAAiBE,EAAMiB,IAAIT,GAAYU,mBAAAA;CAEvC,IAAMC,UAAaA;EACjBd,EAAS;GACPe,IAAI;GACJC,QAAQ,EAAEjB,aAAU;EACtB,CAAA;CACF;CAGA,IAAIK,GACF,OAAO,gBAAC,GAAA;EAAO,QAAO;EAAW,OAAOH,EAAAA,EAAC,EAAA,IAAA,SAAA,CAAA;;CAI3C,IAAII,KAAW,CAACF,GAAY;EAC1B,IAAMc,IAAeX,GAAOY,WAAWjB,EAAAA,EAAC,EAAA,IAAA,SAAA,CAAA;EACxC,OACE,gBAAC,GAAA;GACC,QAAO;GACP,OAAOI,IAAUY,IAAehB,EAAAA,EAAC,EAAA,IAAA,SAAA,CAAA;GACjC,QACE,gBAAC,GAAA;IAAO,SAASa;IAAY,SAAQ;IACnC,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;;;CAKV;CAEA,OAAO,gBAAC,GAAA,EAAkCX,cAAAA,CAAAA;AAC5C"}
1
+ {"version":3,"file":"_floatingIpId-Dpsc7GU4.mjs","names":["formatFloatingIpStatus","status","charAt","slice","toLowerCase","Stack","Button","ContentHeading","PopupMenu","PopupMenuToggle","PopupMenuItem","PopupMenuOptions","formatFloatingIpStatus","TwoColumnDescriptionList","ContentHeader","FloatingIpActionModals","FloatingIpDetailsView","floatingIp","useLingui","basicInfoItems","label","t","value","id","description","project_id","status","created_at","Date","toLocaleString","updated_at","tags","join","networkRoutingItems","floating_ip_address","floating_network_id","fixed_ip_address","port_details","name","mac_address","network_id","device_owner","device_id","router_id","port_id","qos_policy_id","port_forwardings","map","port","dnsItems","dns_domain","dns_name","title","projectId","actions","toggleEditModal","toggleAttachModal","toggleDetachModal","toggleReleaseModal","gap","alignment","className","as","icon","onClick","variant","direction","items","useNavigate","Button","Status","Trans","useLingui","useProjectId","trpcReact","useSetBreadcrumb","FloatingIpDetailsView","Route","RouteComponent","floatingIpId","useParams","projectId","navigate","t","data","floatingIp","isLoading","isError","error","network","getById","useQuery","project_id","floatingip_id","id","floating_ip_address","handleBack","to","params","errorMessage","message","component"],"sources":["../../src/client/utils/formatFloatingIpStatus.ts","../../src/client/routes/_auth/projects/$projectId/network/floatingips/$floatingIpId/-components/-details/FloatingIpDetailsView.tsx","../../src/client/routes/_auth/projects/$projectId/network/floatingips/$floatingIpId/index.tsx?tsr-split=component"],"sourcesContent":["import type { FloatingIpStatus } from \"@/server/Network/types/floatingIp\"\n\n/**\n * Formats a floating IP status value from uppercase enum to title case.\n * Example: \"ACTIVE\" → \"Active\", \"DOWN\" → \"Down\", \"ERROR\" → \"Error\"\n */\nexport const formatFloatingIpStatus = (status: FloatingIpStatus) => {\n return status.charAt(0) + status.slice(1).toLowerCase()\n}\n","import { Trans, useLingui } from \"@lingui/react/macro\"\nimport {\n Stack,\n Button,\n ContentHeading,\n PopupMenu,\n PopupMenuToggle,\n PopupMenuItem,\n PopupMenuOptions,\n} from \"@cloudoperators/juno-ui-components\"\nimport type { FloatingIp } from \"@/server/Network/types/floatingIp\"\nimport { formatFloatingIpStatus } from \"@/client/utils/formatFloatingIpStatus\"\nimport type { DetailListItem } from \"@/client/components/TwoColumnDescriptionList\"\nimport { TwoColumnDescriptionList } from \"@/client/components/TwoColumnDescriptionList\"\nimport { ContentHeader } from \"@/client/components/ContentHeader/ContentHeader\"\nimport { FloatingIpActionModals } from \"../../../-components/-modals/FloatingIpActionModals\"\n\ninterface FloatingIpDetailsViewProps {\n floatingIp: FloatingIp\n}\n\nexport const FloatingIpDetailsView = ({ floatingIp }: FloatingIpDetailsViewProps) => {\n const { t } = useLingui()\n\n const basicInfoItems: DetailListItem[] = [\n { label: t`ID`, value: floatingIp.id },\n { label: t`Description`, value: floatingIp.description || `—` },\n { label: t`Project ID`, value: floatingIp.project_id || `—` },\n { label: t`Status`, value: formatFloatingIpStatus(floatingIp.status) },\n { label: t`Created At`, value: floatingIp.created_at ? new Date(floatingIp.created_at).toLocaleString() : `—` },\n { label: t`Updated At`, value: floatingIp.updated_at ? new Date(floatingIp.updated_at).toLocaleString() : `—` },\n { label: t`Tags`, value: floatingIp.tags?.join(\", \") || `—` },\n ]\n\n const networkRoutingItems: DetailListItem[] = [\n { label: t`Floating IP Address`, value: floatingIp.floating_ip_address || `—` },\n { label: t`Floating Network`, value: floatingIp.floating_network_id || `—` },\n { label: t`Fixed IP Address`, value: floatingIp.fixed_ip_address || `—` },\n { label: t`Port Name`, value: floatingIp.port_details?.name || `—` },\n { label: t`MAC Address`, value: floatingIp.port_details?.mac_address || `—` },\n { label: t`Network ID`, value: floatingIp.port_details?.network_id || `—` },\n { label: t`Device Owner`, value: floatingIp.port_details?.device_owner || `—` },\n { label: t`Device ID`, value: floatingIp.port_details?.device_id || `—` },\n { label: t`Router ID`, value: floatingIp.router_id || `—` },\n { label: t`Port ID`, value: floatingIp.port_id || `—` },\n { label: t`QoS Policy ID`, value: floatingIp.qos_policy_id || `—` },\n { label: t`Port Forwarding`, value: floatingIp.port_forwardings?.map((port) => port.id).join(\", \") || `—` },\n ]\n\n const dnsItems: DetailListItem[] = [\n { label: t`DNS Domain`, value: floatingIp.dns_domain || `—` },\n { label: t`DNS Name`, value: floatingIp.dns_name || `—` },\n ]\n\n return (\n <>\n <ContentHeader\n title={floatingIp.floating_ip_address ?? floatingIp.id}\n projectId={floatingIp.project_id}\n actions={\n <FloatingIpActionModals floatingIp={floatingIp}>\n {({ toggleEditModal, toggleAttachModal, toggleDetachModal, toggleReleaseModal }) => (\n <Stack gap=\"0.5\" alignment=\"center\">\n <PopupMenu className=\"flex items-center\">\n <PopupMenuToggle as=\"div\">\n <Button icon=\"moreVert\" title={t`Floating IP actions`} />\n </PopupMenuToggle>\n <PopupMenuOptions>\n <PopupMenuItem label={t`Edit Description`} onClick={toggleEditModal} />\n <PopupMenuItem label={t`Detach`} onClick={toggleDetachModal} />\n <PopupMenuItem label={t`Release`} onClick={toggleReleaseModal} />\n </PopupMenuOptions>\n </PopupMenu>\n <Button variant=\"primary\" className=\"whitespace-nowrap\" onClick={toggleAttachModal}>\n {t`Attach`}\n </Button>\n </Stack>\n )}\n </FloatingIpActionModals>\n }\n />\n\n <Stack direction=\"vertical\" gap=\"6\" className=\"my-6\">\n <Stack direction=\"vertical\" gap=\"2\">\n <ContentHeading>\n <Trans>Basic Info</Trans>\n </ContentHeading>\n <TwoColumnDescriptionList items={basicInfoItems} />\n </Stack>\n\n <Stack direction=\"vertical\" gap=\"2\">\n <ContentHeading>\n <Trans>Network & Routing</Trans>\n </ContentHeading>\n <TwoColumnDescriptionList items={networkRoutingItems} />\n </Stack>\n\n <Stack direction=\"vertical\" gap=\"2\">\n <ContentHeading>\n <Trans>DNS</Trans>\n </ContentHeading>\n <TwoColumnDescriptionList items={dnsItems} />\n </Stack>\n </Stack>\n </>\n )\n}\n","import { createFileRoute, redirect, useNavigate } from \"@tanstack/react-router\"\nimport { Button, Status } from \"@cloudoperators/juno-ui-components\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { useProjectId } from \"@/client/hooks\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useSetBreadcrumb } from \"@/client/hooks/useSetBreadcrumb\"\nimport { FloatingIpDetailsView } from \"./-components/-details/FloatingIpDetailsView\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/network/floatingips/$floatingIpId/\")({\n staticData: {\n section: \"network\",\n service: \"floatingips\",\n analytics: {\n name: \"network.floatingips.detail\",\n },\n } satisfies RouteInfo,\n loader: async ({ context, params }) => {\n const floatingIp = await context.trpcClient?.network.floatingIp.getById.query({\n project_id: params.projectId,\n floatingip_id: params.floatingIpId,\n })\n return { floatingIpAddress: floatingIp?.floating_ip_address ?? null }\n },\n head: ({ loaderData }) => ({\n meta: [{ title: loaderData?.floatingIpAddress ?? \"Floating IP\" }],\n }),\n component: RouteComponent,\n beforeLoad: async ({ context, params }) => {\n const { trpcClient } = context\n\n const availableServices = (await trpcClient?.auth.getAvailableServices.query()) || []\n const serviceIndex = getServiceIndex(availableServices)\n\n // Redirect if network service not available\n if (!serviceIndex[\"network\"]) {\n throw redirect({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId: params.projectId },\n })\n }\n\n if (!serviceIndex[\"network\"][\"neutron\"]) {\n throw redirect({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId: params.projectId },\n })\n }\n },\n})\n\nfunction RouteComponent() {\n const { floatingIpId } = Route.useParams()\n const projectId = useProjectId()\n const navigate = useNavigate()\n const { t } = useLingui()\n\n // Fetch floating IP details\n const {\n data: floatingIp,\n isLoading,\n isError,\n error,\n } = trpcReact.network.floatingIp.getById.useQuery({\n project_id: projectId,\n floatingip_id: floatingIpId,\n })\n\n useSetBreadcrumb(Route.id, floatingIp?.floating_ip_address)\n\n const handleBack = () => {\n navigate({\n to: \"/projects/$projectId/network/floatingips\",\n params: { projectId },\n })\n }\n\n // Loading state\n if (isLoading) {\n return <Status status=\"progress\" title={t`Loading Floating IP Details...`} />\n }\n\n // Error state\n if (isError || !floatingIp) {\n const errorMessage = error?.message || t`Error Loading Floating IP`\n return (\n <Status\n status=\"error\"\n title={isError ? errorMessage : t`Floating IP Not Found`}\n action={\n <Button onClick={handleBack} variant=\"primary\">\n <Trans>Back to Floating IPs</Trans>\n </Button>\n }\n />\n )\n }\n\n return <FloatingIpDetailsView floatingIp={floatingIp} />\n}\n"],"mappings":"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"}