@cobaltcore-dev/aurora 1.1.0 → 1.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.
Files changed (183) hide show
  1. package/README.md +59 -9
  2. package/dist/client/App.d.ts +2 -2
  3. package/dist/client/AuroraApp.d.ts +33 -13
  4. package/dist/client/{AuthProvider-BS5OVv8n.mjs → AuthProvider-CVSAwW9f.mjs} +22 -8
  5. package/dist/client/AuthProvider-CVSAwW9f.mjs.map +1 -0
  6. package/dist/client/{ContentHeader-BHMUzd9H.mjs → ContentHeader-CPJbgYWn.mjs} +18 -18
  7. package/dist/client/{ContentHeader-BHMUzd9H.mjs.map → ContentHeader-CPJbgYWn.mjs.map} +1 -1
  8. package/dist/client/DeleteFlavorModal-V44QCJBd.mjs +773 -0
  9. package/dist/client/DeleteFlavorModal-V44QCJBd.mjs.map +1 -0
  10. package/dist/client/DynamicBreadcrumbContext-CVcUQFou.mjs +26 -0
  11. package/dist/client/DynamicBreadcrumbContext-CVcUQFou.mjs.map +1 -0
  12. package/dist/client/{FiltersInput-B8CNBg1L.mjs → FiltersInput-CKI6zWnm.mjs} +18 -18
  13. package/dist/client/{FiltersInput-B8CNBg1L.mjs.map → FiltersInput-CKI6zWnm.mjs.map} +1 -1
  14. package/dist/client/FloatingIpActionModals-CwEC5GR-.mjs +460 -0
  15. package/dist/client/FloatingIpActionModals-CwEC5GR-.mjs.map +1 -0
  16. package/dist/client/ImageToastNotifications-m6c3tVPb.mjs +1152 -0
  17. package/dist/client/ImageToastNotifications-m6c3tVPb.mjs.map +1 -0
  18. package/dist/client/SortInput-4g7nSTHW.mjs +34 -0
  19. package/dist/client/SortInput-4g7nSTHW.mjs.map +1 -0
  20. package/dist/client/{TwoColumnDescriptionList-DiDx3PnH.mjs → TwoColumnDescriptionList-NvgvErua.mjs} +2 -2
  21. package/dist/client/{TwoColumnDescriptionList-DiDx3PnH.mjs.map → TwoColumnDescriptionList-NvgvErua.mjs.map} +1 -1
  22. package/dist/client/_-CAsCx-Ay.mjs +6 -0
  23. package/dist/client/_-CAsCx-Ay.mjs.map +1 -0
  24. package/dist/client/_auth-SrDjHL6j.mjs +12 -0
  25. package/dist/client/_auth-SrDjHL6j.mjs.map +1 -0
  26. package/dist/client/_flavorId-9PcBBW52.mjs +231 -0
  27. package/dist/client/_flavorId-9PcBBW52.mjs.map +1 -0
  28. package/dist/client/{_flavorId-BN_qessZ.mjs → _flavorId-a9Gu66R1.mjs} +3 -9
  29. package/dist/client/_flavorId-a9Gu66R1.mjs.map +1 -0
  30. package/dist/client/_floatingIpId-AE9Fu8l6.mjs +210 -0
  31. package/dist/client/_floatingIpId-AE9Fu8l6.mjs.map +1 -0
  32. package/dist/client/{_floatingIpId-CwDGHkWm.mjs → _floatingIpId-AZ11Ksmu.mjs} +3 -9
  33. package/dist/client/_floatingIpId-AZ11Ksmu.mjs.map +1 -0
  34. package/dist/client/{_imageId-BtJ7GmYB.mjs → _imageId-BtAql2Kr.mjs} +104 -92
  35. package/dist/client/_imageId-BtAql2Kr.mjs.map +1 -0
  36. package/dist/client/_imageId-D76BxvFY.mjs +39 -0
  37. package/dist/client/_imageId-D76BxvFY.mjs.map +1 -0
  38. package/dist/client/{_projectId-Byt3GQDW.mjs → _projectId-7Nl1MQTJ.mjs} +5 -5
  39. package/dist/client/_projectId-7Nl1MQTJ.mjs.map +1 -0
  40. package/dist/client/_projectId-B3wmSala.mjs +281 -0
  41. package/dist/client/_projectId-B3wmSala.mjs.map +1 -0
  42. package/dist/client/_projectId-DPzv0CCp.mjs +77 -0
  43. package/dist/client/_projectId-DPzv0CCp.mjs.map +1 -0
  44. package/dist/client/_projectId-DfeVJy0G.mjs +30 -0
  45. package/dist/client/_projectId-DfeVJy0G.mjs.map +1 -0
  46. package/dist/client/_securityGroupId-C5huJNfO.mjs +1810 -0
  47. package/dist/client/_securityGroupId-C5huJNfO.mjs.map +1 -0
  48. package/dist/client/{_securityGroupId-BcbkRhsN.mjs → _securityGroupId-D85mSigA.mjs} +3 -9
  49. package/dist/client/_securityGroupId-D85mSigA.mjs.map +1 -0
  50. package/dist/client/_serviceType-DS8DxsrP.mjs +20 -0
  51. package/dist/client/_serviceType-DS8DxsrP.mjs.map +1 -0
  52. package/dist/client/_serviceType-M8d9rOT6.mjs +6 -0
  53. package/dist/client/_serviceType-M8d9rOT6.mjs.map +1 -0
  54. package/dist/client/_storageType-BRWWJtow.mjs +14 -0
  55. package/dist/client/_storageType-BRWWJtow.mjs.map +1 -0
  56. package/dist/client/_storageType-CzZ4u9x_.mjs +12 -0
  57. package/dist/client/_storageType-CzZ4u9x_.mjs.map +1 -0
  58. package/dist/client/_storageType-Dy9uCVXr.mjs +845 -0
  59. package/dist/client/_storageType-Dy9uCVXr.mjs.map +1 -0
  60. package/dist/client/_storageType-zeSZe--V.mjs.map +1 -1
  61. package/dist/client/{about-_73VmpTB.mjs → about-BmQTyLWc.mjs} +2 -2
  62. package/dist/client/{about-_73VmpTB.mjs.map → about-BmQTyLWc.mjs.map} +1 -1
  63. package/dist/client/{aurora-EbwGRLLf.mjs → aurora-CIml-f2f.mjs} +2 -2
  64. package/dist/client/{aurora-EbwGRLLf.mjs.map → aurora-CIml-f2f.mjs.map} +1 -1
  65. package/dist/client/{build-C_4vRMCq.mjs → build-WuxXRAqf.mjs} +121 -24
  66. package/dist/client/{build-C_4vRMCq.mjs.map → build-WuxXRAqf.mjs.map} +1 -1
  67. package/dist/client/components/Breadcrumbs.d.ts +1 -0
  68. package/dist/client/components/ListToolbar/SortInput.d.ts +3 -0
  69. package/dist/client/context/BreadcrumbExtensionContext.d.ts +9 -0
  70. package/dist/client/context/DynamicBreadcrumbContext.d.ts +9 -0
  71. package/dist/client/{flavors-CiHCYrtZ.mjs → flavors-B0rbqffG.mjs} +3 -5
  72. package/dist/client/flavors-B0rbqffG.mjs.map +1 -0
  73. package/dist/client/flavors-DWMZ6TuJ.mjs.map +1 -1
  74. package/dist/client/flavors-Rl20bxVU.mjs +628 -0
  75. package/dist/client/flavors-Rl20bxVU.mjs.map +1 -0
  76. package/dist/client/floatingips-Cz9k80cc.mjs +8 -0
  77. package/dist/client/floatingips-Cz9k80cc.mjs.map +1 -0
  78. package/dist/client/floatingips-xbO_mu4f.mjs +576 -0
  79. package/dist/client/floatingips-xbO_mu4f.mjs.map +1 -0
  80. package/dist/client/hooks/useBreadcrumbs.d.ts +16 -0
  81. package/dist/client/hooks/usePushBreadcrumbs.d.ts +10 -0
  82. package/dist/client/hooks/useSetBreadcrumb.d.ts +11 -0
  83. package/dist/client/{hooks-LutR2Yg3.mjs → hooks-D0yKIumu.mjs} +2 -2
  84. package/dist/client/{hooks-LutR2Yg3.mjs.map → hooks-D0yKIumu.mjs.map} +1 -1
  85. package/dist/client/images-BGQv9kKT.mjs +1983 -0
  86. package/dist/client/images-BGQv9kKT.mjs.map +1 -0
  87. package/dist/client/{images-CS4kZQyu.mjs → images-CPmMa4SQ.mjs} +3 -5
  88. package/dist/client/images-CPmMa4SQ.mjs.map +1 -0
  89. package/dist/client/images-NBf2bV43.mjs.map +1 -1
  90. package/dist/client/index.d.ts +7 -3
  91. package/dist/client/index.js +549 -535
  92. package/dist/client/index.js.map +1 -1
  93. package/dist/client/{objects-C3azvW8m.mjs → objects-BE_u5yRt.mjs} +7087 -4211
  94. package/dist/client/objects-BE_u5yRt.mjs.map +1 -0
  95. package/dist/client/objects-BN-59Th0.mjs +66 -0
  96. package/dist/client/objects-BN-59Th0.mjs.map +1 -0
  97. package/dist/client/objects-D9Luf9KB.mjs +66 -0
  98. package/dist/client/objects-D9Luf9KB.mjs.map +1 -0
  99. package/dist/client/projects-yiK0HGSA.mjs.map +1 -1
  100. package/dist/client/routeInfo-DP3v74Wg.mjs +19 -0
  101. package/dist/client/routeInfo-DP3v74Wg.mjs.map +1 -0
  102. package/dist/client/router.d.ts +2 -2
  103. package/dist/client/{routes-CdDm-hhO.mjs → routes-CJj7SR_K.mjs} +2 -2
  104. package/dist/client/routes-CJj7SR_K.mjs.map +1 -0
  105. package/dist/client/routes-xofA3ksU.mjs +110 -0
  106. package/dist/client/routes-xofA3ksU.mjs.map +1 -0
  107. package/dist/client/securitygroups-BjhgLBHm.mjs +620 -0
  108. package/dist/client/securitygroups-BjhgLBHm.mjs.map +1 -0
  109. package/dist/client/securitygroups-CtKne8UQ.mjs +8 -0
  110. package/dist/client/securitygroups-CtKne8UQ.mjs.map +1 -0
  111. package/dist/client/{securitygroups-Byte-iSp.mjs → securitygroups-DEJQBcxm.mjs} +3 -5
  112. package/dist/client/securitygroups-DEJQBcxm.mjs.map +1 -0
  113. package/dist/client/trpcClient.d.ts +135 -3
  114. package/dist/client/useBreadcrumbs-ha3IlaxX.mjs +54 -0
  115. package/dist/client/useBreadcrumbs-ha3IlaxX.mjs.map +1 -0
  116. package/dist/client/useModalTracking-BcOKTYRN.mjs +33 -0
  117. package/dist/client/useModalTracking-BcOKTYRN.mjs.map +1 -0
  118. package/dist/client/{useSecurityGroupPermissions-C29mzb3b.mjs → useSecurityGroupPermissions-BOyLQLdC.mjs} +85 -19
  119. package/dist/client/useSecurityGroupPermissions-BOyLQLdC.mjs.map +1 -0
  120. package/dist/client/useSetBreadcrumb-tn7lBaQV.mjs +19 -0
  121. package/dist/client/useSetBreadcrumb-tn7lBaQV.mjs.map +1 -0
  122. package/dist/client/utils/formatSwiftDate.d.ts +30 -0
  123. package/dist/server/index.d.ts +136 -4
  124. package/dist/server/index.js +845 -260
  125. package/package.json +37 -36
  126. package/dist/client/AuthProvider-BS5OVv8n.mjs.map +0 -1
  127. package/dist/client/DeleteFlavorModal-BP83t9zX.mjs +0 -721
  128. package/dist/client/DeleteFlavorModal-BP83t9zX.mjs.map +0 -1
  129. package/dist/client/FloatingIpActionModals-BraiJWBi.mjs +0 -417
  130. package/dist/client/FloatingIpActionModals-BraiJWBi.mjs.map +0 -1
  131. package/dist/client/ImageToastNotifications-BXMHJaIH.mjs +0 -1131
  132. package/dist/client/ImageToastNotifications-BXMHJaIH.mjs.map +0 -1
  133. package/dist/client/RouteError-hAF8_jbe.mjs +0 -25
  134. package/dist/client/RouteError-hAF8_jbe.mjs.map +0 -1
  135. package/dist/client/SortInput-Cqs2poV3.mjs +0 -34
  136. package/dist/client/SortInput-Cqs2poV3.mjs.map +0 -1
  137. package/dist/client/StatusError-C5KodQOq.mjs +0 -39
  138. package/dist/client/StatusError-C5KodQOq.mjs.map +0 -1
  139. package/dist/client/_auth-DJ9wHZaj.mjs +0 -11
  140. package/dist/client/_auth-DJ9wHZaj.mjs.map +0 -1
  141. package/dist/client/_flavorId-BN_qessZ.mjs.map +0 -1
  142. package/dist/client/_flavorId-CJjEB_Ao.mjs +0 -210
  143. package/dist/client/_flavorId-CJjEB_Ao.mjs.map +0 -1
  144. package/dist/client/_floatingIpId-CwDGHkWm.mjs.map +0 -1
  145. package/dist/client/_floatingIpId-foMIwbE4.mjs +0 -215
  146. package/dist/client/_floatingIpId-foMIwbE4.mjs.map +0 -1
  147. package/dist/client/_imageId-BtJ7GmYB.mjs.map +0 -1
  148. package/dist/client/_projectId-BmtCuzJu.mjs +0 -29
  149. package/dist/client/_projectId-BmtCuzJu.mjs.map +0 -1
  150. package/dist/client/_projectId-Byt3GQDW.mjs.map +0 -1
  151. package/dist/client/_projectId-NYk1IN_a.mjs +0 -291
  152. package/dist/client/_projectId-NYk1IN_a.mjs.map +0 -1
  153. package/dist/client/_projectId-QueiFczy.mjs +0 -46
  154. package/dist/client/_projectId-QueiFczy.mjs.map +0 -1
  155. package/dist/client/_securityGroupId-BcbkRhsN.mjs.map +0 -1
  156. package/dist/client/_securityGroupId-pPtJsCoe.mjs +0 -1797
  157. package/dist/client/_securityGroupId-pPtJsCoe.mjs.map +0 -1
  158. package/dist/client/_storageType-BmqrU06i.mjs +0 -2202
  159. package/dist/client/_storageType-BmqrU06i.mjs.map +0 -1
  160. package/dist/client/components/Error/StatusError.d.ts +0 -11
  161. package/dist/client/components/ProjectView/ProjectInfoBox.d.ts +0 -12
  162. package/dist/client/flavors-CiHCYrtZ.mjs.map +0 -1
  163. package/dist/client/flavors-DY-bDc8l.mjs +0 -650
  164. package/dist/client/flavors-DY-bDc8l.mjs.map +0 -1
  165. package/dist/client/floatingips-Ci4jHkaG.mjs +0 -591
  166. package/dist/client/floatingips-Ci4jHkaG.mjs.map +0 -1
  167. package/dist/client/images-91U7tr9Y2.mjs +0 -1976
  168. package/dist/client/images-91U7tr9Y2.mjs.map +0 -1
  169. package/dist/client/images-CS4kZQyu.mjs.map +0 -1
  170. package/dist/client/objects-C3azvW8m.mjs.map +0 -1
  171. package/dist/client/objects-CM265S6b.mjs +0 -56
  172. package/dist/client/objects-CM265S6b.mjs.map +0 -1
  173. package/dist/client/objects-EE9Cd1wI.mjs +0 -56
  174. package/dist/client/objects-EE9Cd1wI.mjs.map +0 -1
  175. package/dist/client/routeInfo-DXqB2HCf.mjs +0 -32
  176. package/dist/client/routeInfo-DXqB2HCf.mjs.map +0 -1
  177. package/dist/client/routes-CBd8CCuM.mjs +0 -115
  178. package/dist/client/routes-CBd8CCuM.mjs.map +0 -1
  179. package/dist/client/routes-CdDm-hhO.mjs.map +0 -1
  180. package/dist/client/securitygroups-Bd_uV4S9.mjs +0 -595
  181. package/dist/client/securitygroups-Bd_uV4S9.mjs.map +0 -1
  182. package/dist/client/securitygroups-Byte-iSp.mjs.map +0 -1
  183. package/dist/client/useSecurityGroupPermissions-C29mzb3b.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floatingips-xbO_mu4f.mjs","names":["MdError","MdRemoveCircle","MdCheckCircle","STATUS_CONFIG","ACTIVE","text","icon","size","color","fill","DOWN","ERROR","TABLE_COLUMNS","t","useNavigate","DataGridCell","DataGridRow","PopupMenu","PopupMenuItem","PopupMenuOptions","STATUS_CONFIG","FloatingIpActionModals","useProjectId","FloatingIpTableRow","floatingIp","useLingui","navigate","projectId","navigateToDetailsPage","to","params","floatingIpId","id","data-testid","onClick","div","className","status","icon","text","floating_ip_address","fixed_ip_address","floating_network_id","description","e","stopPropagation","toggleEditModal","toggleAttachModal","toggleDetachModal","toggleReleaseModal","label","t","DataGrid","DataGridHeadCell","DataGridRow","DataGridCell","Status","FloatingIpTableRow","TABLE_COLUMNS","FloatingIpListContainer","floatingIps","isLoading","isError","error","useLingui","columns","columnCount","length","status","title","t","message","minContentColumns","map","label","ip","floatingIp","id","colSpan","body","z","useForm","useStore","Modal","Form","FormSection","Spinner","Message","Textarea","TextInput","Select","SelectOption","toast","trpcReact","useProjectId","getFloatingIpAllocatedToast","ipv4Regex","ipv6Regex","isValidIpAddress","value","test","dnsNameRegex","AllocateFloatingIpModal","open","onClose","useLingui","projectId","utils","useUtils","isPending","createFloatingIpMutation","network","floatingIp","create","useMutation","onSettled","list","invalidate","data","externalNetworks","isLoading","isExternalNetworksLoading","error","externalNetworksError","listExternalNetworks","useQuery","project_id","dnsDomains","isDnsDomainsLoading","dnsDomainsError","listDnsDomains","availablePorts","isPortsLoading","portsError","listAvailablePorts","formSchema","object","floating_network_id","string","dns_domain","dns_name","trim","max","t","refine","message","description","floating_ip_address","port_id","fixed_ip_address","form","defaultValues","validators","onSubmit","created","mutateAsync","options","id","success","handleClose","reset","currentPortId","store","state","values","currentFloatingNetworkId","selectedPort","find","port","portFixedIps","fixed_ips","formErrorMessage","size","title","onCancel","cancelButtonLabel","confirmButtonLabel","onConfirm","handleSubmit","disableConfirmButton","dismissible","variant","className","div","span","e","preventDefault","Field","name","children","field","onChange","handleChange","label","helptext","placeholder","disabled","required","loading","map","onBlur","handleBlur","target","errortext","meta","errors","join","portId","p","ips","setFieldValue","length","ip_address","parseFiltersFromUrl","searchParams","filters","status","push","name","value","buildFilterParams","selectedFilters","filterDefinitions","params","length","filterGroups","filter","sf","inactive","reduce","acc","Object","entries","forEach","filterName","values","filterDef","find","f","supportsMultiValue","join","applyFilterSelection","current","selected","alreadySelected","some","supportsMulti","buildUrlSearchParams","baseParams","newParams","search","sortBy","sortDirection","useState","useRef","useEffect","useNavigate","useSearch","Button","Stack","DataGridToolbar","SearchInput","Message","Status","SortInput","SelectedFilters","FiltersInput","ContentHeader","trpcReact","useModal","useProjectId","FloatingIpListContainer","AllocateFloatingIpModal","parseFiltersFromUrl","buildFilterParams","buildUrlSearchParams","applyFilterSelection","DEFAULT_SORT_KEY","DEFAULT_SORT_DIR","FloatingIpsList","useLingui","navigate","searchParams","strict","projectId","allocateModalOpen","toggleAllocateModal","localSearchTerm","setLocalSearchTerm","search","debounceTimer","undefined","clearTimeout","current","sortSettings","setSortSettings","options","label","t","value","sortBy","sortDirection","filterSettings","setFilterSettings","filters","displayName","filterName","values","supportsMultiValue","selectedFilters","searchTerm","data","permissions","network","canUser","useQuery","project_id","permission","select","canCreate","urlFilters","urlSortBy","urlSortDirection","urlSearchTerm","prev","status","handleSortChange","newSortSettings","settings","toString","replace","handleFilterChange","newFilterSettings","handleSearchChange","term","floatingIps","isLoading","isError","error","floatingIp","list","sort_key","sort_dir","placeholderData","length","title","message","div","className","variant","distribution","alignment","gap","selectClassName","onSortByChange","v","onSortDirectionChange","dir","onClick","direction","comboboxClassName","onChange","selected","newSelected","placeholder","data-testid","onInput","e","currentTarget","window","setTimeout","onSearch","onClear","onDelete","filterToRemove","filter","f","name","open","onClose","FloatingIpsList","RouteComponent","component"],"sources":["../../src/client/routes/_auth/projects/$projectId/network/floatingips/-components/-table/constants.tsx","../../src/client/routes/_auth/projects/$projectId/network/floatingips/-components/-table/FloatingIpTableRow.tsx","../../src/client/routes/_auth/projects/$projectId/network/floatingips/-components/-table/FloatingIpListContainer.tsx","../../src/client/routes/_auth/projects/$projectId/network/floatingips/-components/-modals/AllocateFloatingIpModal.tsx","../../src/client/routes/_auth/projects/$projectId/network/floatingips/urlHelpers.ts","../../src/client/routes/_auth/projects/$projectId/network/floatingips/-components/FloatingIpsList.tsx","../../src/client/routes/_auth/projects/$projectId/network/floatingips/index.tsx?tsr-split=component"],"sourcesContent":["import { MdError, MdRemoveCircle, MdCheckCircle } from \"react-icons/md\"\nimport { t } from \"@lingui/core/macro\"\nimport { FloatingIpStatus } from \"@/server/Network/types/floatingIp\"\n\ntype FloatingIpStatusDisplay = {\n text: string\n icon: React.ReactNode\n}\n\nexport const STATUS_CONFIG: Record<FloatingIpStatus, FloatingIpStatusDisplay> = {\n ACTIVE: {\n text: \"Active\",\n icon: <MdCheckCircle size={18} color=\"white\" fill=\"#4FB81C\" />,\n },\n DOWN: {\n text: \"Down\",\n icon: <MdRemoveCircle size={18} color=\"white\" fill=\"#969696\" />,\n },\n ERROR: {\n text: \"Error\",\n icon: <MdError size={18} color=\"white\" fill=\"#C70000\" />,\n },\n} as const\n\nexport const TABLE_COLUMNS = () =>\n [\n t`Status`,\n t`Floating IP Address`,\n t`Fixed IP Address`,\n t`Subnet`,\n t`Description`,\n \"\", // empty column for item-actions with context menu containing \"Preview\", \"Edit Description\", \"Attach\", \"Detach\" and \"Release\"\n ] as const\n","import { useNavigate } from \"@tanstack/react-router\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport {\n DataGridCell,\n DataGridRow,\n PopupMenu,\n PopupMenuItem,\n PopupMenuOptions,\n} from \"@cloudoperators/juno-ui-components\"\nimport { FloatingIp } from \"@/server/Network/types/floatingIp\"\nimport { STATUS_CONFIG } from \"./constants\"\nimport { FloatingIpActionModals } from \"../-modals/FloatingIpActionModals\"\nimport { useProjectId } from \"@/client/hooks\"\n\ninterface FloatingIpTableRowProps {\n floatingIp: FloatingIp\n}\n\nexport const FloatingIpTableRow = ({ floatingIp }: FloatingIpTableRowProps) => {\n const { t } = useLingui()\n const navigate = useNavigate()\n const projectId = useProjectId()\n\n const navigateToDetailsPage = () => {\n navigate({\n to: \"/projects/$projectId/network/floatingips/$floatingIpId\",\n params: { projectId, floatingIpId: floatingIp.id },\n })\n }\n\n return (\n <DataGridRow key={floatingIp.id} data-testid={`floating-ip-row-${floatingIp.id}`} onClick={navigateToDetailsPage}>\n <DataGridCell>\n <div className=\"flex items-center gap-2\">\n {STATUS_CONFIG[floatingIp.status].icon}\n {STATUS_CONFIG[floatingIp.status].text}\n </div>\n </DataGridCell>\n <DataGridCell>{floatingIp.floating_ip_address}</DataGridCell>\n <DataGridCell>{floatingIp.fixed_ip_address || \"—\"}</DataGridCell>\n <DataGridCell>{floatingIp.floating_network_id}</DataGridCell>\n <DataGridCell>{floatingIp.description || \"—\"}</DataGridCell>\n <DataGridCell onClick={(e) => e.stopPropagation()} className=\"items-end pr-0\">\n <FloatingIpActionModals floatingIp={floatingIp}>\n {({ toggleEditModal, toggleAttachModal, toggleDetachModal, toggleReleaseModal }) => (\n <PopupMenu>\n <PopupMenuOptions>\n <PopupMenuItem label={t`Preview`} onClick={navigateToDetailsPage} />\n <PopupMenuItem label={t`Edit Description`} onClick={toggleEditModal} />\n <PopupMenuItem label={t`Attach`} onClick={toggleAttachModal} />\n <PopupMenuItem label={t`Detach`} onClick={toggleDetachModal} />\n <PopupMenuItem label={t`Release`} onClick={toggleReleaseModal} />\n </PopupMenuOptions>\n </PopupMenu>\n )}\n </FloatingIpActionModals>\n </DataGridCell>\n </DataGridRow>\n )\n}\n","import { useLingui } from \"@lingui/react/macro\"\nimport { DataGrid, DataGridHeadCell, DataGridRow, DataGridCell, Status } from \"@cloudoperators/juno-ui-components\"\nimport { FloatingIp } from \"@/server/Network/types/floatingIp\"\nimport { FloatingIpTableRow } from \"./FloatingIpTableRow\"\nimport { TABLE_COLUMNS } from \"./constants\"\n\ninterface FloatingIpListContainerProps {\n floatingIps: FloatingIp[]\n isLoading: boolean\n isError: boolean\n error: { message?: string } | null\n}\n\nexport const FloatingIpListContainer = ({ floatingIps, isLoading, isError, error }: FloatingIpListContainerProps) => {\n const { t } = useLingui()\n const columns = TABLE_COLUMNS()\n const columnCount = columns.length\n\n if (isLoading) {\n return <Status status=\"progress\" title={t`Loading Floating IPs...`} />\n }\n\n if (isError) {\n return <Status status=\"error\" title={error?.message ?? t`Failed to load Floating IPs`} />\n }\n\n return (\n <DataGrid columns={columnCount} minContentColumns={[columnCount - 1]}>\n <DataGridRow>\n {columns.map((label) => (\n <DataGridHeadCell key={label}>{label}</DataGridHeadCell>\n ))}\n </DataGridRow>\n {floatingIps.length > 0 ? (\n floatingIps.map((ip) => <FloatingIpTableRow key={ip.id} floatingIp={ip} />)\n ) : (\n <DataGridRow>\n <DataGridCell colSpan={columnCount}>\n <Status\n status=\"empty\"\n title={t`No Floating IPs found`}\n body={t`There are no Floating IPs available for this project. Floating IPs allow you to map public IP addresses to instances.`}\n />\n </DataGridCell>\n </DataGridRow>\n )}\n </DataGrid>\n )\n}\n","import { z } from \"zod\"\nimport { useForm, useStore } from \"@tanstack/react-form\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport {\n Modal,\n Form,\n FormSection,\n Spinner,\n Message,\n Textarea,\n TextInput,\n Select,\n SelectOption,\n toast,\n} from \"@cloudoperators/juno-ui-components\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useProjectId } from \"@/client/hooks\"\nimport { getFloatingIpAllocatedToast } from \"./FloatingIpToastNotifications\"\n\nexport interface AllocateFloatingIpModalProps {\n open: boolean\n onClose: () => void\n}\n\nconst ipv4Regex = /^(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}$/\nconst ipv6Regex =\n /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(([0-9a-fA-F]{1,4}:){1,7}:)|(([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4})|(([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2})|(([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3})|(([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4})|(([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5})|([0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6}))|(:((:[0-9a-fA-F]{1,4}){1,7}|:))|(::([fF]{4}(:0{1,4})?:)?((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|(([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})))$/\nconst isValidIpAddress = (value: string) => ipv4Regex.test(value) || ipv6Regex.test(value)\nconst dnsNameRegex = /^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)*[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/\n\nexport const AllocateFloatingIpModal = ({ open, onClose }: AllocateFloatingIpModalProps) => {\n const { t } = useLingui()\n const projectId = useProjectId()\n const utils = trpcReact.useUtils()\n\n const { isPending, ...createFloatingIpMutation } = trpcReact.network.floatingIp.create.useMutation({\n onSettled: () => utils.network.floatingIp.list.invalidate(),\n })\n\n const {\n data: externalNetworks = [],\n isLoading: isExternalNetworksLoading,\n error: externalNetworksError,\n } = trpcReact.network.floatingIp.listExternalNetworks.useQuery({ project_id: projectId })\n\n const {\n data: dnsDomains = [],\n isLoading: isDnsDomainsLoading,\n error: dnsDomainsError,\n } = trpcReact.network.floatingIp.listDnsDomains.useQuery({ project_id: projectId })\n\n const {\n data: availablePorts = [],\n isLoading: isPortsLoading,\n error: portsError,\n } = trpcReact.network.floatingIp.listAvailablePorts.useQuery({ project_id: projectId })\n\n const formSchema = z.object({\n floating_network_id: z.string(),\n dns_domain: z.string(),\n dns_name: z\n .string()\n .trim()\n .max(63, t`DNS name must be at most 63 characters.`)\n .refine((value) => value === \"\" || dnsNameRegex.test(value), {\n message: t`Must be a valid PQDN or FQDN (alphanumeric and hyphens only, cannot start or end with hyphen).`,\n }),\n description: z\n .string()\n .trim()\n .max(255, t`Description must be at most 255 characters.`),\n floating_ip_address: z\n .string()\n .trim()\n .refine((value) => value === \"\" || isValidIpAddress(value), {\n message: t`Must be a valid IPv4 or IPv6 address (for example: 172.24.4.228 or 2001:db8::1).`,\n }),\n port_id: z.string(),\n fixed_ip_address: z.string(),\n })\n\n const form = useForm({\n defaultValues: {\n floating_network_id: \"\",\n dns_domain: \"\",\n dns_name: \"\",\n description: \"\",\n floating_ip_address: \"\",\n port_id: \"\",\n fixed_ip_address: \"\",\n },\n validators: {\n onSubmit: formSchema,\n },\n onSubmit: async ({ value }) => {\n if (isPending) return\n\n const created = await createFloatingIpMutation.mutateAsync({\n project_id: projectId,\n floating_network_id: value.floating_network_id,\n ...(value.dns_domain && { dns_domain: value.dns_domain }),\n ...(value.dns_name && { dns_name: value.dns_name }),\n ...(value.description && { description: value.description }),\n ...(value.floating_ip_address && { floating_ip_address: value.floating_ip_address }),\n ...(value.port_id && { port_id: value.port_id }),\n ...(value.fixed_ip_address && { fixed_ip_address: value.fixed_ip_address }),\n })\n const { message, ...options } = getFloatingIpAllocatedToast(created.floating_ip_address ?? created.id)\n toast.success(message, options)\n handleClose()\n },\n })\n\n const handleClose = () => {\n if (isPending) return\n\n form.reset()\n createFloatingIpMutation.reset()\n onClose()\n }\n\n const currentPortId = useStore(form.store, (state) => state.values.port_id)\n const currentFloatingNetworkId = useStore(form.store, (state) => state.values.floating_network_id)\n const selectedPort = availablePorts.find((port) => port.id === currentPortId)\n const portFixedIps = selectedPort?.fixed_ips ?? []\n\n const formErrorMessage =\n (externalNetworksError?.message || dnsDomainsError?.message || portsError?.message) ??\n createFloatingIpMutation.error?.message ??\n null\n\n return (\n <Modal\n open={open}\n size=\"large\"\n title={t`Allocate Floating IP`}\n onCancel={handleClose}\n cancelButtonLabel={t`Cancel`}\n confirmButtonLabel={t`Allocate`}\n onConfirm={form.handleSubmit}\n disableConfirmButton={isPending || !currentFloatingNetworkId}\n >\n {formErrorMessage && (\n <Message dismissible={false} variant=\"error\" className=\"mb-4\">\n {formErrorMessage}\n </Message>\n )}\n\n {isPending && (\n <div className=\"mb-4 flex items-center justify-center gap-2\">\n <Spinner variant=\"primary\" />\n <span className=\"text-theme-high text-sm\">\n <Trans>Allocating Floating IP...</Trans>\n </span>\n </div>\n )}\n\n {!isPending && (\n <Form\n className=\"mb-0\"\n id=\"allocate-floating-ip-form\"\n onSubmit={(e) => {\n e.preventDefault()\n form.handleSubmit()\n }}\n >\n <FormSection className=\"mb-4\">\n <form.Field\n name=\"floating_network_id\"\n children={(field) => (\n <Select\n id={field.name}\n name={field.name}\n value={field.state.value}\n onChange={(value) => field.handleChange(typeof value === \"string\" ? value : \"\")}\n label={t`External Network`}\n helptext={t`The ID of the network associated with the floating IP.`}\n placeholder={t`Select an external network`}\n disabled={isPending || isExternalNetworksLoading}\n required\n loading={isExternalNetworksLoading}\n >\n {externalNetworks.map(({ id, name }) => (\n <SelectOption key={id} value={id} label={name ? `${name} (${id})` : id} />\n ))}\n </Select>\n )}\n />\n </FormSection>\n <FormSection className=\"mb-4\">\n <form.Field\n name=\"dns_domain\"\n children={(field) => (\n <Select\n id={field.name}\n name={field.name}\n value={field.state.value}\n onChange={(value) => field.handleChange(typeof value === \"string\" ? value : \"\")}\n label={t`DNS Domain`}\n helptext={t`Select a DNS domain.`}\n disabled={isPending || isDnsDomainsLoading}\n loading={isDnsDomainsLoading}\n >\n {dnsDomains.map(({ id, name }) => (\n <SelectOption key={id} value={name} label={name} />\n ))}\n </Select>\n )}\n />\n </FormSection>\n <FormSection className=\"mb-4\">\n <form.Field\n name=\"dns_name\"\n children={(field) => (\n <TextInput\n id={field.name}\n name={field.name}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n label={t`DNS Name`}\n placeholder={t`Enter DNS name`}\n helptext={t`Enter a valid PQDN or FQDN (max 63 characters) to associate with the floating IP. A and PTR records are created automatically.`}\n errortext={field.state.meta.errors.map((e) => e?.message).join(\", \")}\n disabled={isPending}\n />\n )}\n />\n </FormSection>\n <FormSection className=\"mb-4\">\n <form.Field\n name=\"description\"\n children={(field) => (\n <Textarea\n id={field.name}\n name={field.name}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n placeholder={t`Description`}\n errortext={field.state.meta.errors.map((e) => e?.message).join(\", \")}\n disabled={isPending}\n />\n )}\n />\n </FormSection>\n <FormSection className=\"mb-4\">\n <form.Field\n name=\"floating_ip_address\"\n children={(field) => (\n <TextInput\n id={field.name}\n name={field.name}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n label={t`Floating IP Address`}\n placeholder={t`Enter a floating IP`}\n helptext={t`Enter a floating IP or leave blank to auto-assign one`}\n errortext={field.state.meta.errors.map((e) => e?.message).join(\", \")}\n disabled={isPending}\n />\n )}\n />\n </FormSection>\n <FormSection className=\"mb-4\">\n <form.Field\n name=\"port_id\"\n children={(field) => (\n <Select\n id={field.name}\n name={field.name}\n value={field.state.value}\n onChange={(value) => {\n const portId = typeof value === \"string\" ? value : \"\"\n field.handleChange(portId)\n const port = availablePorts.find((p) => p.id === portId)\n const ips = port?.fixed_ips ?? []\n form.setFieldValue(\"fixed_ip_address\", ips.length === 1 ? ips[0].ip_address : \"\")\n }}\n label={t`Port ID`}\n placeholder={t`Select port to associate`}\n errortext={field.state.meta.errors.map((e) => e?.message).join(\", \")}\n disabled={isPending || isPortsLoading}\n loading={isPortsLoading}\n >\n {availablePorts.map((port) => (\n <SelectOption\n key={port.id}\n value={port.id}\n label={port.name ? `${port.name} (${port.id})` : port.id}\n />\n ))}\n </Select>\n )}\n />\n </FormSection>\n <FormSection>\n <form.Field\n name=\"fixed_ip_address\"\n children={(field) => (\n <Select\n id={field.name}\n name={field.name}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(value) => field.handleChange(typeof value === \"string\" ? value : \"\")}\n label={t`Fixed IP Address`}\n placeholder={t`Select a fixed IP address`}\n helptext={t`Associates on the selected port. If the port has multiple IPs, select the desired fixed IP address.`}\n errortext={field.state.meta.errors.map((e) => e?.message).join(\", \")}\n disabled={isPending || portFixedIps.length === 0}\n >\n {portFixedIps.map(({ ip_address }) => (\n <SelectOption key={ip_address} value={ip_address} label={ip_address} />\n ))}\n </Select>\n )}\n />\n </FormSection>\n </Form>\n )}\n </Modal>\n )\n}\n","import { SelectedFilter, Filter } from \"@/client/components/ListToolbar/types\"\n\ntype FloatingIpsSearchParams = {\n status?: string\n search?: string\n sortBy?: string\n sortDirection?: \"asc\" | \"desc\"\n}\n\n/**\n * Parses URL search params into SelectedFilter array for ListToolbar\n */\nexport const parseFiltersFromUrl = (searchParams: FloatingIpsSearchParams): SelectedFilter[] => {\n const filters: SelectedFilter[] = []\n\n // Status filter\n if (searchParams.status) {\n filters.push({ name: \"status\", value: searchParams.status })\n }\n\n return filters\n}\n\n/**\n * Builds filter parameters for API request from SelectedFilter array\n */\nexport const buildFilterParams = (\n selectedFilters: SelectedFilter[],\n filterDefinitions: Filter[]\n): Record<string, string> => {\n const params: Record<string, string> = {}\n\n if (!selectedFilters?.length) return params\n\n // Group selected filters by filter name\n const filterGroups = selectedFilters\n .filter((sf) => !sf.inactive)\n .reduce(\n (acc, sf) => {\n if (!acc[sf.name]) acc[sf.name] = []\n acc[sf.name].push(sf.value)\n return acc\n },\n {} as Record<string, string[]>\n )\n\n // Build parameters based on whether filter supports multiple values\n Object.entries(filterGroups).forEach(([filterName, values]) => {\n const filterDef = filterDefinitions.find((f) => f.filterName === filterName)\n\n if (filterDef?.supportsMultiValue && values.length > 1) {\n params[filterName] = `in:${values.join(\",\")}`\n } else {\n params[filterName] = values[0]\n }\n })\n\n return params\n}\n\n/**\n * Merges a newly selected filter into the current list.\n * - Ignores duplicates (same name + value).\n * - For single-value filters, replaces any existing entry with the same name.\n * - For multi-value filters, appends.\n */\nexport const applyFilterSelection = (\n current: SelectedFilter[],\n selected: SelectedFilter,\n filterDefinitions: Filter[]\n): SelectedFilter[] => {\n const alreadySelected = current.some((f) => f.name === selected.name && f.value === selected.value)\n if (alreadySelected) return current\n\n const supportsMulti = filterDefinitions.find((f) => f.filterName === selected.name)?.supportsMultiValue\n return supportsMulti ? [...current, selected] : [...current.filter((f) => f.name !== selected.name), selected]\n}\n\n/**\n * Builds URL search params object from filter settings for navigation\n */\nexport const buildUrlSearchParams = (\n selectedFilters: SelectedFilter[],\n filterDefinitions: Filter[],\n baseParams: {\n search?: string\n sortBy?: string\n sortDirection?: \"asc\" | \"desc\"\n }\n): FloatingIpsSearchParams => {\n const newParams: FloatingIpsSearchParams = {\n search: baseParams.search,\n sortBy: baseParams.sortBy,\n sortDirection: baseParams.sortDirection,\n }\n\n if (!selectedFilters?.length) return newParams\n\n const filterGroups = selectedFilters\n .filter((sf) => !sf.inactive)\n .reduce(\n (acc, sf) => {\n if (!acc[sf.name]) acc[sf.name] = []\n acc[sf.name].push(sf.value)\n return acc\n },\n {} as Record<string, string[]>\n )\n\n Object.entries(filterGroups).forEach(([filterName, values]) => {\n const filterDef = filterDefinitions.find((f) => f.filterName === filterName)\n\n if (filterDef?.supportsMultiValue && values.length > 1) {\n // Type assertion needed because we're dynamically setting filter fields\n ;(newParams as Record<string, string>)[filterName] = `in:${values.join(\",\")}`\n } else {\n ;(newParams as Record<string, string>)[filterName] = values[0]\n }\n })\n\n return newParams\n}\n","import { useState, useRef, useEffect } from \"react\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { useNavigate, useSearch } from \"@tanstack/react-router\"\nimport { Button, Stack, DataGridToolbar, SearchInput, Message, Status } from \"@cloudoperators/juno-ui-components\"\nimport { FloatingIpQueryParameters } from \"@/server/Network/types/floatingIp\"\nimport { SortInput } from \"@/client/components/ListToolbar/SortInput\"\nimport { SelectedFilters } from \"@/client/components/ListToolbar/SelectedFilters\"\nimport { FiltersInput } from \"@/client/components/ListToolbar/FiltersInput\"\nimport { FilterSettings, SortSettings } from \"@/client/components/ListToolbar/types\"\nimport { ContentHeader } from \"@/client/components/ContentHeader/ContentHeader\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useModal } from \"@/client/utils/useModal\"\nimport { useProjectId } from \"@/client/hooks\"\nimport { FloatingIpListContainer } from \"./-table/FloatingIpListContainer\"\nimport { AllocateFloatingIpModal } from \"./-modals/AllocateFloatingIpModal\"\nimport { parseFiltersFromUrl, buildFilterParams, buildUrlSearchParams, applyFilterSelection } from \"../urlHelpers\"\n\nconst DEFAULT_SORT_KEY = \"fixed_ip_address\"\nconst DEFAULT_SORT_DIR = \"asc\"\nexport type FloatingIpsSortKey = NonNullable<FloatingIpQueryParameters[\"sort_key\"]>\n\ntype FloatingIpsSearchParams = {\n status?: string\n search?: string\n sortBy?: string\n sortDirection?: \"asc\" | \"desc\"\n}\n\ntype RequiredSortSettings = {\n options: SortSettings[\"options\"]\n sortBy: string\n sortDirection: \"asc\" | \"desc\"\n}\n\nexport const FloatingIpsList = () => {\n const { t } = useLingui()\n const navigate = useNavigate()\n const searchParams = useSearch({ strict: false }) as FloatingIpsSearchParams\n const projectId = useProjectId()\n const [allocateModalOpen, toggleAllocateModal] = useModal(false)\n const [localSearchTerm, setLocalSearchTerm] = useState(searchParams.search || \"\")\n const debounceTimer = useRef<number | undefined>(undefined)\n\n useEffect(() => () => clearTimeout(debounceTimer.current), [])\n\n const [sortSettings, setSortSettings] = useState<RequiredSortSettings>({\n options: [\n { label: t`Fixed IP Address`, value: \"fixed_ip_address\" },\n { label: t`Floating IP Address`, value: \"floating_ip_address\" },\n { label: t`Floating Network ID`, value: \"floating_network_id\" },\n { label: t`ID`, value: \"id\" },\n { label: t`Router ID`, value: \"router_id\" },\n { label: t`Status`, value: \"status\" },\n { label: t`Tenant ID`, value: \"tenant_id\" },\n { label: t`Project ID`, value: \"project_id\" },\n ],\n sortBy: searchParams.sortBy || DEFAULT_SORT_KEY,\n sortDirection: searchParams.sortDirection || DEFAULT_SORT_DIR,\n })\n\n const [filterSettings, setFilterSettings] = useState<FilterSettings>({\n filters: [\n {\n displayName: t`Status`,\n filterName: \"status\",\n values: [\"ACTIVE\", \"DOWN\", \"ERROR\"],\n supportsMultiValue: false,\n },\n ],\n selectedFilters: parseFiltersFromUrl(searchParams),\n })\n\n const searchTerm = searchParams.search || \"\"\n\n const { data: permissions } = trpcReact.network.canUser.useQuery(\n {\n project_id: projectId,\n permission: [\"network:floatingips:create\"],\n },\n {\n select: ([canCreate]) => ({\n canCreate,\n }),\n }\n )\n\n useEffect(() => {\n const urlFilters = parseFiltersFromUrl(searchParams)\n const urlSortBy = searchParams.sortBy || DEFAULT_SORT_KEY\n const urlSortDirection = searchParams.sortDirection || DEFAULT_SORT_DIR\n const urlSearchTerm = searchParams.search || \"\"\n\n setFilterSettings((prev) => ({ ...prev, selectedFilters: urlFilters }))\n setSortSettings((prev) => ({ ...prev, sortBy: urlSortBy, sortDirection: urlSortDirection }))\n setLocalSearchTerm(urlSearchTerm)\n }, [searchParams.status, searchParams.sortBy, searchParams.sortDirection, searchParams.search])\n\n const handleSortChange = (newSortSettings: SortSettings) => {\n const settings: RequiredSortSettings = {\n options: newSortSettings.options,\n sortBy: newSortSettings.sortBy?.toString() || DEFAULT_SORT_KEY,\n sortDirection: newSortSettings.sortDirection || DEFAULT_SORT_DIR,\n }\n setSortSettings(settings)\n navigate({\n search: ((prev: FloatingIpsSearchParams) => ({\n ...prev,\n sortBy: settings.sortBy,\n sortDirection: settings.sortDirection,\n })) as unknown as true,\n replace: false,\n })\n }\n\n const handleFilterChange = (newFilterSettings: FilterSettings) => {\n setFilterSettings(newFilterSettings)\n navigate({\n search: ((prev: FloatingIpsSearchParams) =>\n buildUrlSearchParams(newFilterSettings.selectedFilters || [], newFilterSettings.filters, {\n search: prev.search,\n sortBy: prev.sortBy,\n sortDirection: prev.sortDirection,\n })) as unknown as true,\n replace: false,\n })\n }\n\n const handleSearchChange = (term: string, replace = false) => {\n navigate({\n search: ((prev: FloatingIpsSearchParams) => ({\n ...prev,\n search: term || undefined,\n })) as unknown as true,\n replace,\n })\n }\n\n const {\n data: floatingIps = [],\n isLoading,\n isError,\n error,\n } = trpcReact.network.floatingIp.list.useQuery(\n {\n project_id: projectId,\n sort_key: sortSettings.sortBy as FloatingIpsSortKey,\n sort_dir: sortSettings.sortDirection,\n ...buildFilterParams(filterSettings.selectedFilters || [], filterSettings.filters),\n ...(searchTerm ? { searchTerm } : {}),\n },\n {\n placeholderData: (prev) => prev,\n }\n )\n\n if (isError && !floatingIps.length) {\n return <Status status=\"error\" title={error?.message ?? t`Failed to load Floating IPs`} />\n }\n\n return (\n <>\n <ContentHeader title={t`Floating IPs`} projectId={projectId} />\n\n <div className=\"relative\">\n {/* Non-blocking error banner for refetch failures with cached data */}\n {isError && floatingIps.length > 0 && (\n <Message variant=\"error\" className=\"mb-4\">\n {error?.message ?? t`Failed to refresh Floating IPs. Showing cached data.`}\n </Message>\n )}\n\n {/* Zone 1 — sort + create button, no background */}\n <Stack distribution=\"end\" alignment=\"center\" gap=\"2\" className=\"pb-2\">\n <Stack gap=\"2\">\n <SortInput\n options={sortSettings.options}\n sortBy={sortSettings.sortBy}\n sortDirection={sortSettings.sortDirection ?? \"asc\"}\n selectClassName=\"min-w-52\"\n onSortByChange={(v) =>\n handleSortChange({ ...sortSettings, sortBy: v, sortDirection: sortSettings.sortDirection })\n }\n onSortDirectionChange={(dir) => handleSortChange({ ...sortSettings, sortDirection: dir })}\n />\n {permissions?.canCreate && (\n <Button onClick={toggleAllocateModal} variant=\"primary\" className=\"whitespace-nowrap\">\n <Trans>Allocate Floating IP</Trans>\n </Button>\n )}\n </Stack>\n </Stack>\n\n {/* Zone 2 — filter + search + active filter pills */}\n <DataGridToolbar>\n <Stack direction=\"vertical\" gap=\"2\">\n <Stack distribution=\"between\" alignment=\"center\">\n <FiltersInput\n filters={filterSettings.filters}\n selectClassName=\"sm:min-w-40\"\n comboboxClassName=\"sm:min-w-40\"\n onChange={(selected) => {\n const newSelected = applyFilterSelection(\n filterSettings.selectedFilters || [],\n selected,\n filterSettings.filters\n )\n if (newSelected === (filterSettings.selectedFilters || [])) return\n handleFilterChange({ ...filterSettings, selectedFilters: newSelected })\n }}\n />\n <SearchInput\n placeholder={t`Search floating IPs...`}\n data-testid=\"searchbar\"\n value={localSearchTerm}\n onInput={(e: React.FormEvent<HTMLInputElement>) => {\n const v = e.currentTarget.value\n setLocalSearchTerm(v)\n clearTimeout(debounceTimer.current)\n debounceTimer.current = window.setTimeout(() => handleSearchChange(v, true), 500)\n }}\n onSearch={(v) => {\n clearTimeout(debounceTimer.current)\n handleSearchChange(typeof v === \"string\" ? v : \"\", false)\n }}\n onClear={() => {\n clearTimeout(debounceTimer.current)\n setLocalSearchTerm(\"\")\n handleSearchChange(\"\", false)\n }}\n />\n </Stack>\n {filterSettings.selectedFilters && filterSettings.selectedFilters.length > 0 && (\n <SelectedFilters\n selectedFilters={filterSettings.selectedFilters}\n onDelete={(filterToRemove) =>\n handleFilterChange({\n ...filterSettings,\n selectedFilters: (filterSettings.selectedFilters || []).filter(\n (f) => !(f.name === filterToRemove.name && f.value === filterToRemove.value)\n ),\n })\n }\n onClear={() => handleFilterChange({ ...filterSettings, selectedFilters: [] })}\n />\n )}\n </Stack>\n </DataGridToolbar>\n\n <FloatingIpListContainer\n floatingIps={floatingIps}\n isLoading={isLoading}\n isError={isError && !floatingIps.length}\n error={error}\n />\n\n {allocateModalOpen && <AllocateFloatingIpModal open={allocateModalOpen} onClose={toggleAllocateModal} />}\n </div>\n </>\n )\n}\n","import { createFileRoute } from \"@tanstack/react-router\"\nimport { z } from \"zod\"\nimport { t } from \"@lingui/core/macro\"\nimport { FloatingIpQueryParametersSchema, FloatingIpStatusSchema } from \"@/server/Network/types/floatingIp\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { FloatingIpsList } from \"./-components/FloatingIpsList\"\n\nconst floatingIpsSearchFields = {\n status: FloatingIpStatusSchema.optional(),\n search: z.string().optional(),\n sortBy: FloatingIpQueryParametersSchema.shape.sort_key.unwrap().optional(),\n sortDirection: z.enum([\"asc\", \"desc\"]).optional(),\n}\n\nconst floatingIpsSearchSchema = z.looseObject(floatingIpsSearchFields)\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/network/floatingips/\")({\n staticData: {\n section: \"network\",\n service: \"floatingips\",\n analytics: {\n name: \"network.floatingips.list\",\n },\n } satisfies RouteInfo,\n validateSearch: (search) => {\n const result = floatingIpsSearchSchema.safeParse(search)\n if (result.success) return result.data\n return {\n ...search,\n status: floatingIpsSearchFields.status.safeParse(search.status).success ? search.status : undefined,\n search: floatingIpsSearchFields.search.safeParse(search.search).success ? search.search : undefined,\n sortBy: floatingIpsSearchFields.sortBy.safeParse(search.sortBy).success ? search.sortBy : undefined,\n sortDirection: floatingIpsSearchFields.sortDirection.safeParse(search.sortDirection).success\n ? search.sortDirection\n : undefined,\n }\n },\n head: () => ({ meta: [{ title: t`Floating IPs` }] }),\n component: RouteComponent,\n})\n\nfunction RouteComponent() {\n return <FloatingIpsList />\n}\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Returns the ordered breadcrumb chain for the current route.
3
+ * Reads static crumbs from route staticData and dynamic crumbs from useSetBreadcrumb.
4
+ * Works with any TanStack Router instance — suitable for embedded sub-apps (e.g. SCI services).
5
+ *
6
+ * Requirements:
7
+ * - Must be rendered inside DynamicBreadcrumbProvider and a lingui I18nProvider
8
+ * - To include SCI extension crumbs in OSS, use the Breadcrumbs component which merges BreadcrumbExtensionContext
9
+ */
10
+ export type BreadcrumbItem = {
11
+ label?: string;
12
+ icon?: string;
13
+ onClick?: () => void;
14
+ active?: boolean;
15
+ };
16
+ export declare function useBreadcrumbs(): BreadcrumbItem[];
@@ -0,0 +1,10 @@
1
+ import { BreadcrumbItem } from './useBreadcrumbs';
2
+ /**
3
+ * Pushes breadcrumb items from an extension service (SCI) into OSS's breadcrumb bar.
4
+ * Items are appended after the service-level crumb and cleared when the component unmounts.
5
+ *
6
+ * Requirements:
7
+ * - Must be rendered inside `BreadcrumbExtensionProvider` (mounted at `$projectId.tsx`)
8
+ * - Pass the full ordered list on every render; the hook diffs by serialised label+icon+active key
9
+ */
10
+ export declare function usePushBreadcrumbs(breadcrumbs: BreadcrumbItem[]): void;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Registers a dynamic breadcrumb for a route. Call inside a route component, passing Route.id.
3
+ * The entry is added when text is defined and removed when text becomes undefined or the component unmounts.
4
+ *
5
+ * Requirements:
6
+ * - Must be rendered inside `DynamicBreadcrumbProvider` (mounted at `_auth.tsx`)
7
+ * - Pass `Route.id` as routeId so `useBreadcrumbs` can correlate it with the correct match
8
+ */
9
+ export declare function useSetBreadcrumb(routeId: string, text: string | undefined, options?: {
10
+ to?: string;
11
+ }): void;
@@ -1,4 +1,4 @@
1
- import { n as e } from "./AuthProvider-BS5OVv8n.mjs";
1
+ import { n as e } from "./AuthProvider-CVSAwW9f.mjs";
2
2
  import "./useProjectId-DBc5lpoU.mjs";
3
3
  import { useParams as t } from "@tanstack/react-router";
4
4
  //#region src/client/hooks/useDomainId.ts
@@ -19,4 +19,4 @@ function r() {
19
19
  //#endregion
20
20
  export { n, r as t };
21
21
 
22
- //# sourceMappingURL=hooks-LutR2Yg3.mjs.map
22
+ //# sourceMappingURL=hooks-D0yKIumu.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks-LutR2Yg3.mjs","names":["useAuth","useDomainId","user","domainId","domain","id","Error","useParams","useAuth","useScope","auth","projectId","strict","userDomainId","user","domain","id"],"sources":["../../src/client/hooks/useDomainId.ts","../../src/client/hooks/useScope.ts"],"sourcesContent":["import { useAuth } from \"@/client/store/AuthProvider\"\n\n/**\n * Get the current user's domain ID from the authentication context.\n *\n * This hook provides access to the domain ID of the currently authenticated user.\n * The domain ID is obtained from the user's session, not from URL parameters.\n *\n * @throws {Error} If user is not authenticated or domain ID is not available\n * @returns {string} The current domain ID from the user's session\n *\n * @example\n * ```tsx\n * function UsersList() {\n * const domainId = useDomainId()\n *\n * const { data } = trpc.identity.users.list.useQuery({\n * domain_id: domainId\n * })\n * }\n * ```\n */\nexport function useDomainId(): string {\n const { user } = useAuth()\n\n const domainId = user?.domain?.id\n\n if (!domainId) {\n throw new Error(\n \"useDomainId() requires an authenticated user with a domain. \" +\n \"This is likely an authentication error. \" +\n \"Ensure the user is logged in and has a domain assigned.\"\n )\n }\n\n return domainId\n}\n","import { useParams } from \"@tanstack/react-router\"\nimport { useAuth } from \"../store/AuthProvider\"\n\nexport function useScope() {\n const auth = useAuth()\n const { projectId } = useParams({ strict: false })\n\n const userDomainId = auth.user?.domain?.id\n return {\n userDomainId,\n projectId,\n }\n}\n"],"mappings":";;;;AAsBA,SAAgBC,IAAAA;CACd,IAAM,EAAEC,YAASF,EAAAA,GAEXG,IAAWD,GAAME,QAAQC;CAE/B,IAAI,CAACF,GACH,MAAUG,MACR,6JAEE;CAIN,OAAOH;AACT;;;ACjCA,SAAgBM,IAAAA;CACd,IAAMC,IAAOF,EAAAA,GACP,EAAEG,iBAAcJ,EAAU,EAAEK,QAAQ,GAAM,CAAA;CAGhD,OAAO;EACLC,cAFmBH,EAAKI,MAAMC,QAAQC;EAGtCL;CACF;AACF"}
1
+ {"version":3,"file":"hooks-D0yKIumu.mjs","names":["useAuth","useDomainId","user","domainId","domain","id","Error","useParams","useAuth","useScope","auth","projectId","strict","userDomainId","user","domain","id"],"sources":["../../src/client/hooks/useDomainId.ts","../../src/client/hooks/useScope.ts"],"sourcesContent":["import { useAuth } from \"@/client/store/AuthProvider\"\n\n/**\n * Get the current user's domain ID from the authentication context.\n *\n * This hook provides access to the domain ID of the currently authenticated user.\n * The domain ID is obtained from the user's session, not from URL parameters.\n *\n * @throws {Error} If user is not authenticated or domain ID is not available\n * @returns {string} The current domain ID from the user's session\n *\n * @example\n * ```tsx\n * function UsersList() {\n * const domainId = useDomainId()\n *\n * const { data } = trpc.identity.users.list.useQuery({\n * domain_id: domainId\n * })\n * }\n * ```\n */\nexport function useDomainId(): string {\n const { user } = useAuth()\n\n const domainId = user?.domain?.id\n\n if (!domainId) {\n throw new Error(\n \"useDomainId() requires an authenticated user with a domain. \" +\n \"This is likely an authentication error. \" +\n \"Ensure the user is logged in and has a domain assigned.\"\n )\n }\n\n return domainId\n}\n","import { useParams } from \"@tanstack/react-router\"\nimport { useAuth } from \"../store/AuthProvider\"\n\nexport function useScope() {\n const auth = useAuth()\n const { projectId } = useParams({ strict: false })\n\n const userDomainId = auth.user?.domain?.id\n return {\n userDomainId,\n projectId,\n }\n}\n"],"mappings":";;;;AAsBA,SAAgBC,IAAAA;CACd,IAAM,EAAEC,YAASF,EAAAA,GAEXG,IAAWD,GAAME,QAAQC;CAE/B,IAAI,CAACF,GACH,MAAUG,MACR,6JAEE;CAIN,OAAOH;AACT;;;ACjCA,SAAgBM,IAAAA;CACd,IAAMC,IAAOF,EAAAA,GACP,EAAEG,iBAAcJ,EAAU,EAAEK,QAAQ,GAAM,CAAA;CAGhD,OAAO;EACLC,cAFmBH,EAAKI,MAAMC,QAAQC;EAGtCL;CACF;AACF"}