@cobaltcore-dev/aurora 0.7.0 → 0.8.1

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 (108) hide show
  1. package/README.md +101 -7
  2. package/dist/client/AuroraApp.d.ts +38 -0
  3. package/dist/client/{ContentHeader-kx1Th5Sq.mjs → ContentHeader-C51H95X8.mjs} +24 -20
  4. package/dist/client/ContentHeader-C51H95X8.mjs.map +1 -0
  5. package/dist/client/{DeleteFlavorModal-C3cb7YiJ.mjs → DeleteFlavorModal-C3m7bQJu.mjs} +163 -163
  6. package/dist/client/{DeleteFlavorModal-C3cb7YiJ.mjs.map → DeleteFlavorModal-C3m7bQJu.mjs.map} +1 -1
  7. package/dist/client/{EditSecurityGroupModal-CpP54WIK.mjs → EditSecurityGroupModal-DKusxfta.mjs} +18 -18
  8. package/dist/client/{EditSecurityGroupModal-CpP54WIK.mjs.map → EditSecurityGroupModal-DKusxfta.mjs.map} +1 -1
  9. package/dist/client/{FiltersInput-DxcyR6Bp.mjs → FiltersInput-GzR4D0q6.mjs} +21 -21
  10. package/dist/client/{FiltersInput-DxcyR6Bp.mjs.map → FiltersInput-GzR4D0q6.mjs.map} +1 -1
  11. package/dist/client/{FloatingIpActionModals-BP8RWHbu.mjs → FloatingIpActionModals-CRvROJ3H.mjs} +51 -51
  12. package/dist/client/{FloatingIpActionModals-BP8RWHbu.mjs.map → FloatingIpActionModals-CRvROJ3H.mjs.map} +1 -1
  13. package/dist/client/{ImageToastNotifications-TZ3EfQg-.mjs → ImageToastNotifications-BuDXpTkl.mjs} +344 -344
  14. package/dist/client/{ImageToastNotifications-TZ3EfQg-.mjs.map → ImageToastNotifications-BuDXpTkl.mjs.map} +1 -1
  15. package/dist/client/{RouteError-QSV7qOoJ.mjs → RouteError-DVAiT0mT.mjs} +2 -2
  16. package/dist/client/{RouteError-QSV7qOoJ.mjs.map → RouteError-DVAiT0mT.mjs.map} +1 -1
  17. package/dist/client/{SortInput-CYv2_Pur.mjs → SortInput-VK7IYqQv.mjs} +6 -6
  18. package/dist/client/{SortInput-CYv2_Pur.mjs.map → SortInput-VK7IYqQv.mjs.map} +1 -1
  19. package/dist/client/{_flavorId-C2x43-6S.mjs → _flavorId-DU4gcFna.mjs} +8 -8
  20. package/dist/client/{_flavorId-C2x43-6S.mjs.map → _flavorId-DU4gcFna.mjs.map} +1 -1
  21. package/dist/client/{_flavorId-CR8ZUI-P.mjs → _flavorId-iZE2j210.mjs} +62 -62
  22. package/dist/client/{_flavorId-CR8ZUI-P.mjs.map → _flavorId-iZE2j210.mjs.map} +1 -1
  23. package/dist/client/{_floatingIpId-BCk41_Lb.mjs → _floatingIpId-B5GMSLeQ.mjs} +2 -2
  24. package/dist/client/{_floatingIpId-BCk41_Lb.mjs.map → _floatingIpId-B5GMSLeQ.mjs.map} +1 -1
  25. package/dist/client/{_floatingIpId-BGrOAmPT.mjs → _floatingIpId-C2-BeRmF.mjs} +27 -27
  26. package/dist/client/{_floatingIpId-BGrOAmPT.mjs.map → _floatingIpId-C2-BeRmF.mjs.map} +1 -1
  27. package/dist/client/_imageId-zmaSymWe.mjs +534 -0
  28. package/dist/client/{_imageId-CvfD832b.mjs.map → _imageId-zmaSymWe.mjs.map} +1 -1
  29. package/dist/client/_pcaId-BwTvJJgh.mjs +479 -0
  30. package/dist/client/_pcaId-BwTvJJgh.mjs.map +1 -0
  31. package/dist/client/{_pcaId-DOHycvCf.mjs → _pcaId-DUHQd0rB.mjs} +2 -2
  32. package/dist/client/{_pcaId-DOHycvCf.mjs.map → _pcaId-DUHQd0rB.mjs.map} +1 -1
  33. package/dist/client/{_projectId-DOgwFiqD.mjs → _projectId-B_2sZKk-.mjs} +2 -2
  34. package/dist/client/_projectId-B_2sZKk-.mjs.map +1 -0
  35. package/dist/client/_projectId-C8BaEHUj.mjs +273 -0
  36. package/dist/client/_projectId-C8BaEHUj.mjs.map +1 -0
  37. package/dist/client/_projectId-COt93OEF.mjs +84 -0
  38. package/dist/client/_projectId-COt93OEF.mjs.map +1 -0
  39. package/dist/client/{_securityGroupId-KKw4RPdH.mjs → _securityGroupId-DYxmXUOP.mjs} +319 -319
  40. package/dist/client/{_securityGroupId-KKw4RPdH.mjs.map → _securityGroupId-DYxmXUOP.mjs.map} +1 -1
  41. package/dist/client/{_securityGroupId-CJJanWiY.mjs → _securityGroupId-fhK1CuZh.mjs} +2 -2
  42. package/dist/client/{_securityGroupId-CJJanWiY.mjs.map → _securityGroupId-fhK1CuZh.mjs.map} +1 -1
  43. package/dist/client/{_storageType-DYjo-6ej.mjs → _storageType-B-qGcGUQ.mjs} +699 -698
  44. package/dist/client/_storageType-B-qGcGUQ.mjs.map +1 -0
  45. package/dist/client/{_storageType-4wSxI__0.mjs → _storageType-CepuevDG.mjs} +2 -2
  46. package/dist/client/{_storageType-4wSxI__0.mjs.map → _storageType-CepuevDG.mjs.map} +1 -1
  47. package/dist/client/{about-Bo9vxGHy.mjs → about-Nsxkyh9U.mjs} +2 -2
  48. package/dist/client/{about-Bo9vxGHy.mjs.map → about-Nsxkyh9U.mjs.map} +1 -1
  49. package/dist/client/{build-DeJcDjPi.mjs → build-BdRRmNf5.mjs} +3290 -3274
  50. package/dist/client/{build-DeJcDjPi.mjs.map → build-BdRRmNf5.mjs.map} +1 -1
  51. package/dist/client/{constants-BmcGYeR-.mjs → constants-J5nm9hbP.mjs} +15 -15
  52. package/dist/client/{constants-BmcGYeR-.mjs.map → constants-J5nm9hbP.mjs.map} +1 -1
  53. package/dist/client/{flavors-BxFVqgnb.mjs → flavors-8bZVlzzb.mjs} +2 -2
  54. package/dist/client/{flavors-BxFVqgnb.mjs.map → flavors-8bZVlzzb.mjs.map} +1 -1
  55. package/dist/client/{flavors-CfdgjsZY.mjs → flavors-BfsEBUE-.mjs} +238 -221
  56. package/dist/client/flavors-BfsEBUE-.mjs.map +1 -0
  57. package/dist/client/{floatingips-ByRb82wS.mjs → floatingips-Dq4DXQYb.mjs} +90 -90
  58. package/dist/client/{floatingips-ByRb82wS.mjs.map → floatingips-Dq4DXQYb.mjs.map} +1 -1
  59. package/dist/client/{images-CenluYV8.mjs → images-8FOgju2f.mjs} +2 -2
  60. package/dist/client/{images-CenluYV8.mjs.map → images-8FOgju2f.mjs.map} +1 -1
  61. package/dist/client/images-BPnTuKFO2.mjs +1890 -0
  62. package/dist/client/images-BPnTuKFO2.mjs.map +1 -0
  63. package/dist/client/{images-C_dX7nY6.mjs → images-Dbjo4yKn.mjs} +2 -2
  64. package/dist/client/{images-C_dX7nY6.mjs.map → images-Dbjo4yKn.mjs.map} +1 -1
  65. package/dist/client/index.d.ts +1 -1
  66. package/dist/client/index.js +382 -351
  67. package/dist/client/index.js.map +1 -1
  68. package/dist/client/{objects-gxSjvbvF.mjs → objects-DKWp9RtR.mjs} +2 -2
  69. package/dist/client/{objects-gxSjvbvF.mjs.map → objects-DKWp9RtR.mjs.map} +1 -1
  70. package/dist/client/{objects-BJM6YeuF.mjs → objects-DaCuy_CB.mjs} +1156 -1156
  71. package/dist/client/{objects-BJM6YeuF.mjs.map → objects-DaCuy_CB.mjs.map} +1 -1
  72. package/dist/client/pca-5wOBf_KI.mjs +202 -0
  73. package/dist/client/pca-5wOBf_KI.mjs.map +1 -0
  74. package/dist/client/{pca-Bl8NmoVZ.mjs → pca-dhrOFfrE.mjs} +2 -2
  75. package/dist/client/{pca-Bl8NmoVZ.mjs.map → pca-dhrOFfrE.mjs.map} +1 -1
  76. package/dist/client/{projects-D2iewAzu.mjs → projects-B_PPyZD1.mjs} +2 -2
  77. package/dist/client/{projects-D2iewAzu.mjs.map → projects-B_PPyZD1.mjs.map} +1 -1
  78. package/dist/client/{projects-pe2_dCnV.mjs → projects-CHYn7L5e.mjs} +2 -2
  79. package/dist/client/{projects-pe2_dCnV.mjs.map → projects-CHYn7L5e.mjs.map} +1 -1
  80. package/dist/client/{projects-CgclWI16.mjs → projects-Dmewygrp.mjs} +12 -12
  81. package/dist/client/projects-Dmewygrp.mjs.map +1 -0
  82. package/dist/client/routeInfo-CHiJfum5.mjs +73 -0
  83. package/dist/client/routeInfo-CHiJfum5.mjs.map +1 -0
  84. package/dist/client/{securitygroups-DahZkVYQ.mjs → securitygroups-CNFLu9zS.mjs} +112 -112
  85. package/dist/client/{securitygroups-DahZkVYQ.mjs.map → securitygroups-CNFLu9zS.mjs.map} +1 -1
  86. package/dist/client/{useListWithFiltering-DaYcu5AB.mjs → useListWithFiltering-v2A0-SZb.mjs} +9 -9
  87. package/dist/client/{useListWithFiltering-DaYcu5AB.mjs.map → useListWithFiltering-v2A0-SZb.mjs.map} +1 -1
  88. package/dist/server/index.d.ts +6 -1
  89. package/dist/server/index.js +37 -52
  90. package/package.json +4 -4
  91. package/dist/client/ContentHeader-kx1Th5Sq.mjs.map +0 -1
  92. package/dist/client/_imageId-CvfD832b.mjs +0 -534
  93. package/dist/client/_pcaId-BxBt5DXi.mjs +0 -459
  94. package/dist/client/_pcaId-BxBt5DXi.mjs.map +0 -1
  95. package/dist/client/_projectId-BDSWnMGj.mjs +0 -46
  96. package/dist/client/_projectId-BDSWnMGj.mjs.map +0 -1
  97. package/dist/client/_projectId-DOgwFiqD.mjs.map +0 -1
  98. package/dist/client/_projectId-DS4nR59B.mjs +0 -299
  99. package/dist/client/_projectId-DS4nR59B.mjs.map +0 -1
  100. package/dist/client/_projectId-MxcHrXW4.mjs +0 -84
  101. package/dist/client/_projectId-MxcHrXW4.mjs.map +0 -1
  102. package/dist/client/_storageType-DYjo-6ej.mjs.map +0 -1
  103. package/dist/client/flavors-CfdgjsZY.mjs.map +0 -1
  104. package/dist/client/images-CKqIXUq52.mjs +0 -1873
  105. package/dist/client/images-CKqIXUq52.mjs.map +0 -1
  106. package/dist/client/pca-RSiWpJs9.mjs +0 -182
  107. package/dist/client/pca-RSiWpJs9.mjs.map +0 -1
  108. package/dist/client/projects-CgclWI16.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"_securityGroupId-KKw4RPdH.mjs","names":["ContentHeading","SecurityGroupHeader","name","id","div","className","p","DataGrid","DataGridRow","DataGridCell","DataGridHeadCell","Button","SecurityGroupBasicInfo","securityGroup","onEdit","isReadOnly","useLingui","BooleanValue","value","span","t","div","className","variant","onClick","disabled","columns","gridColumnTemplate","colSpan","title","description","undefined","id","tags","join","name","stateful","project_id","shared","Stack","SecurityGroupTabs","activeTab","onTabChange","showRBACTab","getTabClassName","tab","baseClasses","activeClasses","inactiveClasses","div","className","direction","gap","button","onClick","useState","Modal","Button","ModalFooter","ButtonRow","Message","TextInput","DeleteRuleDialog","rule","open","onClose","onConfirm","isLoading","error","useLingui","confirmText","setConfirmText","handleConfirm","id","handleClose","isConfirmDisabled","onCancel","size","title","t","modalFooter","className","variant","onClick","disabled","data-testid","div","dismissible","p","ul","li","direction","description","ethertype","protocol","port_range_min","port_range_max","remote_ip_prefix","remote_group_id","strong","value","onChange","e","target","placeholder","autoComplete","detectCIDRFamily","cidr","includes","validatePortRange","portMin","portMax","protocol","isNaN","valid","error","isTcpUdp","toLowerCase","validateIcmpTypeCode","type","code","isValidCIDR","parts","split","length","address","prefixStr","test","prefix","parseInt","octets","octet","num","toString","hasDoubleColon","segments","filter","s","segment","doubleColonCount","match","startsWith","endsWith","DEFAULT_IPV4_CIDR","DEFAULT_IPV6_CIDR","CUSTOM_TCP_RULE","CUSTOM_UDP_RULE","OTHER_PROTOCOL_RULE","PORT_MODE_SINGLE","PORT_MODE_RANGE","PORT_MODE_ALL","PORT_MIN","PORT_MAX","ICMP_MIN","ICMP_MAX","z","validatePortRange","validateIcmpTypeCode","isValidCIDR","detectCIDRFamily","CUSTOM_TCP_RULE","CUSTOM_UDP_RULE","OTHER_PROTOCOL_RULE","ICMP_MIN","ICMP_MAX","createRuleFormSchema","object","ruleType","string","min","direction","enum","ethertype","description","protocol","nullable","portFrom","portTo","icmpType","icmpCode","remoteSourceType","remoteCidr","remoteSecurityGroupId","superRefine","data","ctx","isTcpUdp","isIcmp","isCustomProtocol","showPortFields","includes","addIssue","code","ZodIssueCode","custom","message","path","parseInt","isNaN","result","valid","error","cidrFamily","DEFAULT_IPV4_CIDR","DEFAULT_VALUES","ruleType","direction","ethertype","description","protocol","portFrom","portTo","icmpType","icmpCode","remoteSourceType","remoteCidr","remoteSecurityGroupId","RULE_PRESETS","value","label","protocol","portRangeMin","portRangeMax","FormRow","Select","SelectOption","RULE_PRESETS","RuleTypeSection","form","disabled","useLingui","Field","name","mode","field","className","id","label","t","value","state","onChange","newRuleType","String","handleChange","setFieldValue","selectedPreset","find","p","protocol","portRangeMin","portRangeMax","map","preset","FormRow","RadioGroup","Radio","DirectionSection","form","disabled","useLingui","Field","name","directionField","label","t","selected","state","value","onChange","handleChange","String","required","div","className","EthertypeSection","ethertypeField","FormRow","TextInput","ProtocolSection","form","disabled","useLingui","Field","name","field","className","id","label","t","value","state","onChange","e","handleChange","target","errortext","meta","errors","message","placeholder","FormRow","TextInput","useStore","PortRangeSection","form","disabled","useLingui","portFromValue","store","state","values","portFrom","portFromError","fieldMeta","errors","message","portToError","portTo","isPortToDisabled","trim","className","div","Field","name","portFromField","id","label","t","value","onChange","e","newValue","target","handleChange","setFieldValue","validateField","invalid","meta","length","required","portToField","placeholder","p","FormRow","TextInput","IcmpSection","form","disabled","useLingui","className","div","Field","name","icmpTypeField","id","label","t","value","state","onChange","e","handleChange","target","errortext","meta","errors","message","placeholder","icmpCodeField","FormRow","TextInput","Select","SelectOption","RadioGroup","Radio","DEFAULT_IPV4_CIDR","DEFAULT_IPV6_CIDR","RemoteSourceSection","form","disabled","availableSecurityGroups","useLingui","Field","name","mode","remoteSourceTypeField","className","label","t","selected","state","value","onChange","newValue","String","handleChange","setFieldValue","div","remoteCidrField","ethertypeField","id","e","target","errortext","meta","errors","message","placeholder","remoteSecurityGroupIdField","map","sg","FormRow","Textarea","DescriptionSection","form","disabled","useLingui","Field","name","field","className","id","label","t","value","state","onChange","e","handleChange","target","placeholder","rows","React","useForm","Modal","Form","FormSection","Button","ButtonRow","Spinner","ModalFooter","Message","createRuleFormSchema","DEFAULT_VALUES","CUSTOM_TCP_RULE","CUSTOM_UDP_RULE","OTHER_PROTOCOL_RULE","RuleTypeSection","DirectionSection","EthertypeSection","ProtocolSection","PortRangeSection","IcmpSection","RemoteSourceSection","DescriptionSection","createFormTypeHelper","defaultValues","validators","onSubmit","AddRuleModal","securityGroupId","open","onClose","onCreate","isLoading","error","availableSecurityGroups","useLingui","form","value","payload","security_group_id","direction","ethertype","description","undefined","protocol","remote_ip_prefix","remote_group_id","remote_address_group_id","isTcpUdp","portFrom","parseInt","port_range_min","portTo","port_range_max","isIcmp","icmpType","icmpCode","remoteSourceType","remoteCidr","remoteSecurityGroupId","handleClose","reset","onCancel","size","title","t","modalFooter","className","Subscribe","state","isRuleTypeSelected","Boolean","values","ruleType","variant","onClick","disabled","isSubmitting","type","handleSubmit","data-testid","dismissible","div","span","e","preventDefault","showPortFields","includes","showIcmpFields","useState","useEffect","DataGrid","DataGridHeadCell","DataGridRow","DataGridCell","Button","Stack","PopupMenu","PopupMenuItem","PopupMenuOptions","DeleteRuleDialog","AddRuleModal","ListToolbar","useModal","SecurityGroupRulesTable","rules","totalRulesCount","onDeleteRule","isDeletingRule","deleteError","searchTerm","onSearchChange","sortSettings","onSortChange","filterSettings","onFilterChange","securityGroupId","onCreateRule","isCreatingRule","createRuleError","availableSecurityGroups","readOnly","useLingui","ruleToDelete","setRuleToDelete","isAddRuleModalOpen","toggleAddRuleModal","handleDeleteClick","rule","handleConfirmDelete","ruleId","handleCloseDeleteDialog","formatPortRange","protocol","port_range_min","port_range_max","typeValue","codeValue","t","String","direction","gap","totalCount","length","filteredCount","itemName","onFilter","onSort","onSearch","actions","variant","icon","onClick","columns","className","map","data-testid","id","description","ethertype","e","stopPropagation","label","open","onClose","onConfirm","isLoading","error","onCreate","DataGridRow","DataGridCell","PopupMenu","PopupMenuItem","PopupMenuOptions","RBACPolicyRow","policy","onDelete","useLingui","target_tenant","action","onClick","e","stopPropagation","className","label","t","z","useState","useForm","Modal","Form","FormSection","TextInput","Message","trpcReact","useProjectId","UUID_WITH_DASHES","UUID_WITHOUT_DASHES","isValidProjectID","value","test","AddRBACPolicyModal","isOpen","onClose","securityGroupId","useLingui","utils","useUtils","projectId","hasSubmitted","setHasSubmitted","formSchema","object","targetTenant","string","min","t","refine","message","createMutation","network","rbacPolicy","create","useMutation","onSuccess","list","invalidate","project_id","securityGroup","getById","handleClose","form","defaultValues","validators","onSubmit","isPending","mutate","trim","reset","handleConfirm","handleSubmit","open","onCancel","title","size","onConfirm","cancelButtonLabel","confirmButtonLabel","disableConfirmButton","error","variant","className","toLowerCase","includes","p","e","preventDefault","Field","name","onBlur","trimmedValue","undefined","onChange","children","field","showError","state","meta","isTouched","errors","length","firstError","errorMessage","id","label","handleChange","target","handleBlur","placeholder","required","helptext","disabled","errortext","invalid","z","useForm","useStore","Modal","Message","TextInput","Form","FormSection","DeleteRBACPolicyDialog","policy","open","onClose","onConfirm","isLoading","error","useLingui","formSchema","object","confirmText","string","refine","value","message","t","form","defaultValues","validators","onSubmit","id","handleClose","canRemove","store","state","isSubmitting","values","reset","onCancel","size","title","handleSubmit","cancelButtonLabel","confirmButtonLabel","disableConfirmButton","div","dismissible","variant","className","p","ul","li","target_tenant","action","object_type","e","preventDefault","strong","Field","name","children","field","onChange","handleChange","target","placeholder","autoComplete","disabled","data-testid","useState","useEffect","useMemo","DataGrid","DataGridRow","DataGridHeadCell","Stack","Spinner","Button","Message","trpcReact","useProjectId","RBACPolicyRow","AddRBACPolicyModal","DeleteRBACPolicyDialog","ListToolbar","useModal","SecurityGroupRBACPolicies","securityGroupId","utils","useUtils","useLingui","projectId","isAddModalOpen","toggleAddModal","policyToDelete","setPolicyToDelete","searchTerm","setSearchTerm","data","policies","isPending","isError","error","network","rbacPolicy","list","useQuery","project_id","refetchOnWindowFocus","deleteMutation","delete","useMutation","onSuccess","invalidate","securityGroup","getById","handleDeleteClick","policy","handleConfirmDelete","policyId","mutate","handleCloseDeleteDialog","isSuccess","filteredPolicies","searchLower","toLowerCase","filter","target_tenant","includes","action","handleSearchChange","value","searchValue","distribution","alignment","className","variant","message","totalCount","length","filteredCount","direction","gap","itemName","t","onSearch","actions","icon","onClick","columns","map","onDelete","id","open","onClose","onConfirm","isLoading","isOpen","Container","Stack","useState","SecurityGroupHeader","SecurityGroupBasicInfo","SecurityGroupTabs","SecurityGroupRulesTable","SecurityGroupRBACPolicies","SecurityGroupDetailsView","securityGroup","filteredAndSortedRules","onEdit","onDeleteRule","isDeletingRule","deleteRuleError","filterControls","onCreateRule","isCreatingRule","createRuleError","availableSecurityGroups","currentProjectId","activeTab","setActiveTab","isOwner","project_id","isShared","showRBACTab","px","py","direction","gap","name","id","isReadOnly","onTabChange","div","className","rules","totalRulesCount","security_group_rules","length","deleteError","searchTerm","onSearchChange","sortSettings","onSortChange","filterSettings","onFilterChange","securityGroupId","undefined","readOnly","useState","useMemo","trpcReact","useProjectId","useSecurityGroupDetails","securityGroupId","filterControls","editModalOpen","setEditModalOpen","projectId","utils","useUtils","securityGroupQuery","network","securityGroup","getById","useQuery","project_id","placeholderData","getData","filteredAndSortedRules","allRules","data","security_group_rules","result","directionFilter","filterSettings","selectedFilters","find","f","name","value","ethertypeFilter","protocolFilter","filter","rule","direction","ethertype","protocol","searchTerm","searchLower","toLowerCase","description","includes","sortSettings","sortBy","sortKey","sort","a","b","aValue","bValue","comparison","localeCompare","sortDirection","updateMutation","update","useMutation","onSuccess","invalidate","list","deleteRuleMutation","securityGroupRule","delete","createRuleMutation","create","handleEdit","handleCloseEditModal","handleUpdate","id","mutateAsync","handleDeleteRule","ruleId","handleCreateRule","ruleData","isLoading","isPending","isError","error","isUpdating","updateError","message","isDeletingRule","deleteRuleError","isCreatingRule","createRuleError","Breadcrumb","BreadcrumbItem","Button","ContentHeading","Stack","Spinner","useNavigate","Trans","useLingui","useMemo","useProjectId","SecurityGroupDetailsView","EditSecurityGroupModal","useSecurityGroupDetails","useListWithFiltering","trpcReact","Route","RouteComponent","securityGroupId","useParams","projectId","navigate","t","searchTerm","rulesSearchTerm","sortSettings","filterSettings","handleSearchChange","handleSortChange","handleFilterChange","defaultSortKey","defaultSortDir","sortOptions","label","value","filters","displayName","filterName","values","supportsMultiValue","filterControls","onSearchChange","onSortChange","onFilterChange","securityGroup","filteredAndSortedRules","isLoading","isError","error","isUpdating","updateError","isDeletingRule","deleteRuleError","isCreatingRule","createRuleError","editModalOpen","handleEdit","handleCloseEditModal","handleUpdate","handleDeleteRule","handleCreateRule","data","securityGroups","network","list","useQuery","project_id","availableSecurityGroups","filter","sg","id","map","name","handleBack","to","params","errorMessage","message","component"],"sources":["../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-components/-details/SecurityGroupHeader.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-components/-details/SecurityGroupBasicInfo.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-components/-details/SecurityGroupTabs.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/DeleteRuleDialog.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/validation/validationHelpers.ts","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/constants.ts","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/validation/formSchema.ts","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/types.ts","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/rulePresets.ts","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/sections/RuleTypeSection.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/sections/DirectionEthertypeSection.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/sections/ProtocolSection.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/sections/PortRangeSection.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/sections/IcmpSection.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/sections/RemoteSourceSection.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/sections/DescriptionSection.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/AddRuleModal.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-components/-details/SecurityGroupRulesTable.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-components/-details/RBACPolicyRow.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRBACPolicyModal.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/DeleteRBACPolicyDialog.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-components/-details/SecurityGroupRBACPolicies.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-components/SecurityGroupDetailsView.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-hooks/useSecurityGroupDetails.ts","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/index.tsx?tsr-split=component"],"sourcesContent":["import { ContentHeading } from \"@cloudoperators/juno-ui-components\"\nimport { Trans } from \"@lingui/react/macro\"\n\ninterface SecurityGroupHeaderProps {\n name?: string | null\n id: string\n}\n\nexport function SecurityGroupHeader({ name, id }: SecurityGroupHeaderProps) {\n return (\n <div className=\"mb-2\">\n <ContentHeading>{`'${name || id}' Details`}</ContentHeading>\n <p className=\"text-theme-secondary mt-2 text-sm\">\n <Trans>\n Configure the ingress and egress rules that control which traffic is allowed for this security group.\n </Trans>\n </p>\n </div>\n )\n}\n","import { DataGrid, DataGridRow, DataGridCell, DataGridHeadCell, Button } from \"@cloudoperators/juno-ui-components\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport type { SecurityGroup } from \"@/server/Network/types/securityGroup\"\n\ninterface SecurityGroupBasicInfoProps {\n securityGroup: SecurityGroup\n onEdit?: () => void\n isReadOnly?: boolean\n}\n\nexport function SecurityGroupBasicInfo({ securityGroup, onEdit, isReadOnly = false }: SecurityGroupBasicInfoProps) {\n const { t } = useLingui()\n\n const BooleanValue = ({ value }: { value: boolean | undefined }) => <span>{value ? t`Yes` : t`No`}</span>\n\n return (\n <div>\n <div className=\"mb-4 flex flex-row-reverse\">\n {onEdit && !isReadOnly && (\n <Button variant=\"primary\" onClick={onEdit} disabled={isReadOnly}>\n <Trans>Edit</Trans>\n </Button>\n )}\n </div>\n\n <DataGrid columns={4} gridColumnTemplate=\"15% 35% 15% 35%\">\n <DataGridRow>\n <DataGridHeadCell>{t`Description`}</DataGridHeadCell>\n <DataGridCell colSpan={3}>\n <div\n className=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n title={securityGroup.description || undefined}\n >\n {securityGroup.description || t`—`}\n </div>\n </DataGridCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridHeadCell>{t`ID`}</DataGridHeadCell>\n <DataGridCell>\n <div className=\"overflow-hidden text-ellipsis whitespace-nowrap\" title={securityGroup.id}>\n {securityGroup.id}\n </div>\n </DataGridCell>\n <DataGridHeadCell>{t`Tags`}</DataGridHeadCell>\n <DataGridCell>\n <div\n className=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n title={securityGroup.tags?.join(\", \") || undefined}\n >\n {securityGroup.tags?.join(\", \") || t`—`}\n </div>\n </DataGridCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridHeadCell>{t`Name`}</DataGridHeadCell>\n <DataGridCell>\n <div className=\"overflow-hidden text-ellipsis whitespace-nowrap\" title={securityGroup.name || undefined}>\n {securityGroup.name}\n </div>\n </DataGridCell>\n <DataGridHeadCell>{t`Stateful`}</DataGridHeadCell>\n <DataGridCell>\n <BooleanValue value={securityGroup.stateful} />\n </DataGridCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridHeadCell>{t`Owning Project ID`}</DataGridHeadCell>\n <DataGridCell>\n <div\n className=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n title={securityGroup.project_id || undefined}\n >\n {securityGroup.project_id || t`—`}\n </div>\n </DataGridCell>\n <DataGridHeadCell>{t`Shared`}</DataGridHeadCell>\n <DataGridCell>\n <BooleanValue value={securityGroup.shared} />\n </DataGridCell>\n </DataGridRow>\n </DataGrid>\n </div>\n )\n}\n","import { Stack } from \"@cloudoperators/juno-ui-components\"\nimport { Trans } from \"@lingui/react/macro\"\n\nexport type TabType = \"rules\" | \"rbac\"\n\ninterface SecurityGroupTabsProps {\n activeTab: TabType\n onTabChange: (tab: TabType) => void\n showRBACTab?: boolean\n}\n\nexport function SecurityGroupTabs({ activeTab, onTabChange, showRBACTab = true }: SecurityGroupTabsProps) {\n const getTabClassName = (tab: TabType) => {\n const baseClasses = \"px-6 py-3 font-semibold border-b-2 transition-colors\"\n const activeClasses = \"border-theme-accent text-theme-highest\"\n const inactiveClasses = \"border-transparent text-theme-secondary hover:text-theme-high\"\n\n return `${baseClasses} ${activeTab === tab ? activeClasses : inactiveClasses}`\n }\n\n return (\n <div className=\"border-theme-background-lvl-3 mt-1 border-b\">\n <Stack direction=\"horizontal\" gap=\"0\">\n <button className={getTabClassName(\"rules\")} onClick={() => onTabChange(\"rules\")}>\n <Trans>Rules</Trans>\n </button>\n {showRBACTab && (\n <button className={getTabClassName(\"rbac\")} onClick={() => onTabChange(\"rbac\")}>\n <Trans>RBAC Policies</Trans>\n </button>\n )}\n </Stack>\n </div>\n )\n}\n","import { useState } from \"react\"\nimport { Modal, Button, ModalFooter, ButtonRow, Message, TextInput } from \"@cloudoperators/juno-ui-components\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport type { SecurityGroupRule } from \"@/server/Network/types/securityGroup\"\n\ninterface DeleteRuleDialogProps {\n rule: SecurityGroupRule | null\n open: boolean\n onClose: () => void\n onConfirm: (ruleId: string) => void\n isLoading: boolean\n error: string | null\n}\n\nexport function DeleteRuleDialog({ rule, open, onClose, onConfirm, isLoading, error }: DeleteRuleDialogProps) {\n const { t } = useLingui()\n const [confirmText, setConfirmText] = useState(\"\")\n\n const handleConfirm = () => {\n if (rule && confirmText === \"delete\") {\n onConfirm(rule.id)\n }\n }\n\n const handleClose = () => {\n setConfirmText(\"\")\n onClose()\n }\n\n const isConfirmDisabled = confirmText !== \"delete\" || isLoading\n\n if (!rule) return null\n\n return (\n <Modal\n open={open}\n onCancel={handleClose}\n size=\"small\"\n title={t`Delete Security Group Rule`}\n modalFooter={\n <ModalFooter className=\"flex justify-end\">\n <ButtonRow>\n <Button variant=\"default\" onClick={handleClose} disabled={isLoading}>\n <Trans>Cancel</Trans>\n </Button>\n <Button\n variant=\"primary-danger\"\n onClick={handleConfirm}\n disabled={isConfirmDisabled}\n data-testid=\"confirm-delete-rule-button\"\n >\n {isLoading ? <Trans>Deleting...</Trans> : <Trans>Delete Rule</Trans>}\n </Button>\n </ButtonRow>\n </ModalFooter>\n }\n >\n <div>\n {/* Error Message */}\n {error && (\n <Message dismissible={false} variant=\"error\" className=\"mt-4\">\n {error}\n </Message>\n )}\n\n {/* Warning */}\n <Trans>This action cannot be undone. The rule will be permanently deleted.</Trans>\n\n {/* Rule Details */}\n <div className=\"bg-theme-background-lvl-1 mt-4 mb-4 rounded p-4\">\n <p className=\"mb-2 font-semibold\">\n <Trans>Rule Details:</Trans>\n </p>\n <ul className=\"list-inside list-disc space-y-1 text-sm\">\n <li>\n <Trans>Direction</Trans>: {rule.direction}\n </li>\n {rule.description && (\n <li>\n <Trans>Description</Trans>: {rule.description}\n </li>\n )}\n <li>\n <Trans>Ethertype</Trans>: {rule.ethertype}\n </li>\n {rule.protocol && (\n <li>\n <Trans>Protocol</Trans>: {rule.protocol}\n </li>\n )}\n {rule.port_range_min !== null && rule.port_range_max !== null && (\n <li>\n <Trans>Port Range</Trans>:{\" \"}\n {rule.port_range_min === rule.port_range_max\n ? rule.port_range_min\n : `${rule.port_range_min}-${rule.port_range_max}`}\n </li>\n )}\n {rule.remote_ip_prefix && (\n <li>\n <Trans>Remote IP</Trans>: {rule.remote_ip_prefix}\n </li>\n )}\n {rule.remote_group_id && (\n <li>\n <Trans>Remote Security Group</Trans>: {rule.remote_group_id}\n </li>\n )}\n </ul>\n </div>\n\n {/* Confirmation Input */}\n <div className=\"mt-4\">\n <p className=\"mb-2 text-sm\">\n <Trans>\n Type <strong>delete</strong> to confirm:\n </Trans>\n </p>\n <TextInput\n value={confirmText}\n onChange={(e) => setConfirmText(e.target.value)}\n placeholder={t`delete`}\n autoComplete=\"off\"\n disabled={isLoading}\n data-testid=\"delete-rule-confirmation-input\"\n />\n </div>\n </div>\n </Modal>\n )\n}\n","/**\n * Security Group Rule Validation Utilities\n *\n * These utilities are used for frontend validation of security group rules.\n * They provide consistent validation logic for CIDR notation, port ranges, and ICMP values.\n */\n\n/**\n * Detects CIDR family (IPv4 or IPv6) from CIDR notation.\n * Returns \"IPv4\" if CIDR contains \".\", \"IPv6\" if contains \":\", or null if neither.\n */\nexport function detectCIDRFamily(cidr: string): \"IPv4\" | \"IPv6\" | null {\n if (cidr.includes(\".\")) {\n return \"IPv4\"\n }\n if (cidr.includes(\":\")) {\n return \"IPv6\"\n }\n return null\n}\n\n/**\n * Validates port numbers for security group rules.\n * For TCP/UDP: ports must be 1-65535\n * For other protocols: ports can be 0-65535\n * Also validates that min <= max when both are provided.\n * Handles NaN values by rejecting them.\n */\nexport function validatePortRange(\n portMin: number | null | undefined,\n portMax: number | null | undefined,\n protocol: string | null | undefined\n): { valid: boolean; error?: string } {\n // Check for NaN values\n if (portMin != null && isNaN(portMin)) {\n return { valid: false, error: \"Port must be a valid number\" }\n }\n if (portMax != null && isNaN(portMax)) {\n return { valid: false, error: \"Port must be a valid number\" }\n }\n\n const isTcpUdp = protocol?.toLowerCase() === \"tcp\" || protocol?.toLowerCase() === \"udp\"\n\n // For TCP/UDP, ports must be 1-65535\n if (isTcpUdp) {\n if (portMin != null && (portMin < 1 || portMin > 65535)) {\n return { valid: false, error: \"For TCP/UDP: port must be between 1 and 65535\" }\n }\n if (portMax != null && (portMax < 1 || portMax > 65535)) {\n return { valid: false, error: \"For TCP/UDP: port must be between 1 and 65535\" }\n }\n } else {\n // For other protocols, allow 0-65535\n if (portMin != null && (portMin < 0 || portMin > 65535)) {\n return { valid: false, error: \"Port must be between 0 and 65535\" }\n }\n if (portMax != null && (portMax < 0 || portMax > 65535)) {\n return { valid: false, error: \"Port must be between 0 and 65535\" }\n }\n }\n\n // Validate min <= max for all protocols\n if (portMin != null && portMax != null && portMin > portMax) {\n return { valid: false, error: \"port_range_min must be less than or equal to port_range_max\" }\n }\n\n return { valid: true }\n}\n\n/**\n * Validates ICMP type and code values (0-255 for both).\n * Handles NaN values by rejecting them.\n */\nexport function validateIcmpTypeCode(\n type: number | null | undefined,\n code: number | null | undefined\n): { valid: boolean; error?: string } {\n // Check for NaN values\n if (type != null && isNaN(type)) {\n return { valid: false, error: \"ICMP type must be a valid number\" }\n }\n if (code != null && isNaN(code)) {\n return { valid: false, error: \"ICMP code must be a valid number\" }\n }\n\n if (type != null && (type < 0 || type > 255)) {\n return { valid: false, error: \"ICMP type must be between 0 and 255\" }\n }\n\n if (code != null && (code < 0 || code > 255)) {\n return { valid: false, error: \"ICMP code must be between 0 and 255\" }\n }\n\n return { valid: true }\n}\n\n/**\n * Validates CIDR notation for IPv4 and IPv6 addresses.\n * - IPv4: octets must be 0-255, prefix length must be 0-32\n * - IPv6: proper hexadecimal format with colons, prefix length must be 0-128\n */\nexport function isValidCIDR(cidr: string): boolean {\n const parts = cidr.split(\"/\")\n if (parts.length !== 2) {\n return false\n }\n\n const [address, prefixStr] = parts\n\n // Validate prefix is digits-only (reject \"24foo\", \"24a\", etc.)\n if (!/^\\d+$/.test(prefixStr)) {\n return false\n }\n\n const prefix = parseInt(prefixStr, 10)\n\n // Check if prefix is a valid number\n if (isNaN(prefix) || prefix < 0) {\n return false\n }\n\n // Check for IPv4\n if (address.includes(\".\")) {\n // Validate IPv4 address format\n const octets = address.split(\".\")\n if (octets.length !== 4) {\n return false\n }\n\n // Validate each octet is 0-255\n for (const octet of octets) {\n const num = parseInt(octet, 10)\n if (isNaN(num) || num < 0 || num > 255 || octet !== num.toString()) {\n return false\n }\n }\n\n // Validate prefix length for IPv4 (0-32)\n return prefix <= 32\n }\n\n // Check for IPv6\n if (address.includes(\":\")) {\n // Reject malformed triple-colon addresses (e.g., \":::\")\n if (address.includes(\":::\")) {\n return false\n }\n\n // Validate prefix length for IPv6 (0-128)\n if (prefix > 128) {\n return false\n }\n\n // Basic IPv6 validation\n // Allow :: for compressed zeros\n const hasDoubleColon = address.includes(\"::\")\n const segments = address.split(\":\").filter((s) => s !== \"\")\n\n // IPv6 should have at most 8 segments (or fewer if :: is used)\n if (hasDoubleColon) {\n // With ::, we can have 0-7 segments\n if (segments.length > 7) {\n return false\n }\n } else {\n // Without ::, we must have exactly 8 segments\n if (segments.length !== 8) {\n return false\n }\n }\n\n // Validate each segment is valid hex (0-ffff)\n for (const segment of segments) {\n if (segment.length === 0 || segment.length > 4) {\n return false\n }\n if (!/^[0-9a-fA-F]+$/.test(segment)) {\n return false\n }\n }\n\n // Check for valid :: usage (only one occurrence)\n const doubleColonCount = (address.match(/::/g) || []).length\n if (doubleColonCount > 1) {\n return false\n }\n\n // Check for leading/trailing single colons (invalid unless part of ::)\n if (address.startsWith(\":\") && !address.startsWith(\"::\")) {\n return false\n }\n if (address.endsWith(\":\") && !address.endsWith(\"::\")) {\n return false\n }\n\n return true\n }\n\n return false\n}\n","// Default CIDR values\nexport const DEFAULT_IPV4_CIDR = \"0.0.0.0/0\"\nexport const DEFAULT_IPV6_CIDR = \"::/0\"\n\n// Custom rule type identifiers\nexport const CUSTOM_TCP_RULE = \"custom-tcp\"\nexport const CUSTOM_UDP_RULE = \"custom-udp\"\nexport const OTHER_PROTOCOL_RULE = \"other-protocol\"\n\n// Port modes\nexport const PORT_MODE_SINGLE = \"single\" as const\nexport const PORT_MODE_RANGE = \"range\" as const\nexport const PORT_MODE_ALL = \"all\" as const\n\n// Validation ranges\nexport const PORT_MIN = 1\nexport const PORT_MAX = 65535\nexport const ICMP_MIN = 0\nexport const ICMP_MAX = 255\n","import { z } from \"zod\"\nimport { validatePortRange, validateIcmpTypeCode, isValidCIDR, detectCIDRFamily } from \"./validationHelpers\"\nimport { CUSTOM_TCP_RULE, CUSTOM_UDP_RULE, OTHER_PROTOCOL_RULE, ICMP_MIN, ICMP_MAX } from \"../constants\"\n\n/**\n * Zod schema for AddRuleModal form validation.\n *\n * This schema validates all fields in the Add Rule form with conditional validation\n * based on protocol type, rule type, and other field dependencies.\n *\n * All validation logic is performed on the frontend to provide immediate feedback\n * and reduce server roundtrips. The backend only performs type checking.\n */\nexport const createRuleFormSchema = z\n .object({\n // Rule preset selector (UI only, affects which fields are populated)\n ruleType: z.string().min(1, \"Rule type is required\"),\n\n // Required fields - always present\n direction: z.enum([\"ingress\", \"egress\"]),\n ethertype: z.enum([\"IPv4\", \"IPv6\"]),\n\n // Optional description\n description: z.string(),\n\n // Protocol field - string for custom protocols, null for none\n protocol: z.string().nullable(),\n\n // Port-related fields (strings in form, converted to numbers during validation)\n portFrom: z.string(),\n portTo: z.string(),\n\n // ICMP fields (strings in form, converted to numbers during validation)\n icmpType: z.string(),\n icmpCode: z.string(),\n\n // Remote source configuration\n remoteSourceType: z.enum([\"cidr\", \"security_group\"]),\n remoteCidr: z.string(),\n remoteSecurityGroupId: z.string(),\n })\n .superRefine((data, ctx) => {\n // Determine which validations apply based on protocol and rule type\n const isTcpUdp = data.protocol === \"tcp\" || data.protocol === \"udp\"\n const isIcmp = data.protocol === \"icmp\" || data.protocol === \"ipv6-icmp\"\n const isCustomProtocol = data.ruleType === OTHER_PROTOCOL_RULE\n const showPortFields = isTcpUdp && [CUSTOM_TCP_RULE, CUSTOM_UDP_RULE].includes(data.ruleType)\n\n // Validation 1: Protocol is required for \"other-protocol\" rule type\n if (isCustomProtocol && !data.protocol) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Protocol is required\",\n path: [\"protocol\"],\n })\n }\n\n // Validation 2: Port validation (only if port fields are visible)\n if (showPortFields) {\n // Port (from) is always required\n if (!data.portFrom) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Port (from) is required\",\n path: [\"portFrom\"],\n })\n } else {\n const portFrom = parseInt(data.portFrom, 10)\n if (isNaN(portFrom)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Port must be a valid number\",\n path: [\"portFrom\"],\n })\n } else {\n // If Port (to) is empty, validate portFrom as single port\n if (!data.portTo) {\n const result = validatePortRange(portFrom, portFrom, data.protocol)\n if (!result.valid) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: result.error || \"Invalid port\",\n path: [\"portFrom\"],\n })\n }\n } else {\n // Both ports are provided - validate as range\n const portTo = parseInt(data.portTo, 10)\n if (isNaN(portTo)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Port must be a valid number\",\n path: [\"portTo\"],\n })\n } else {\n // Check that portFrom < portTo\n if (portFrom >= portTo) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: '\"Port (from)\" must be less than \"Port (to)\"',\n path: [\"portFrom\"],\n })\n } else {\n // Validate the range\n const result = validatePortRange(portFrom, portTo, data.protocol)\n if (!result.valid) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: result.error || \"Invalid port range\",\n path: [\"portFrom\"],\n })\n }\n }\n }\n }\n }\n }\n }\n\n // Validation 3: ICMP validation (only if ICMP protocol is selected)\n if (isIcmp) {\n // Parse values\n const icmpType = data.icmpType ? parseInt(data.icmpType, 10) : null\n const icmpCode = data.icmpCode ? parseInt(data.icmpCode, 10) : null\n\n // Step 1: Check for NaN values FIRST (early validation)\n if (data.icmpType && isNaN(icmpType!)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"ICMP type must be a valid number\",\n path: [\"icmpType\"],\n })\n }\n\n if (data.icmpCode && isNaN(icmpCode!)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"ICMP code must be a valid number\",\n path: [\"icmpCode\"],\n })\n }\n\n // Step 2: Check OpenStack requirement (Type required when Code is specified)\n // https://opendev.org/openstack/neutron/src/branch/master/neutron/db/securitygroups_db.py\n if (data.icmpCode && !data.icmpType) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"ICMP type is required when ICMP code is specified\",\n path: [\"icmpType\"],\n })\n }\n\n // Step 3: Use helper function for range validation (0-255)\n // Now we know values are valid numbers (or null)\n if (icmpType !== null || icmpCode !== null) {\n const result = validateIcmpTypeCode(icmpType, icmpCode)\n if (!result.valid) {\n // Parse error message to target specific fields\n if (result.error?.includes(\"type\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `ICMP type must be between ${ICMP_MIN} and ${ICMP_MAX}`,\n path: [\"icmpType\"],\n })\n }\n if (result.error?.includes(\"code\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `ICMP code must be between ${ICMP_MIN} and ${ICMP_MAX}`,\n path: [\"icmpCode\"],\n })\n }\n }\n }\n }\n\n // Validation 4: CIDR validation (only if CIDR remote source is selected)\n if (data.remoteSourceType === \"cidr\" && data.remoteCidr) {\n // Validate CIDR format\n if (!isValidCIDR(data.remoteCidr)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Invalid CIDR format. Examples: 0.0.0.0/0 (IPv4) or ::/0 (IPv6)\",\n path: [\"remoteCidr\"],\n })\n } else {\n // Validate ethertype matches CIDR family\n const cidrFamily = detectCIDRFamily(data.remoteCidr)\n if (cidrFamily && cidrFamily !== data.ethertype) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `CIDR family (${cidrFamily}) must match Ethertype (${data.ethertype})`,\n path: [\"remoteCidr\"],\n })\n }\n }\n }\n })\n\n/**\n * Type definition inferred from the Zod schema.\n * This ensures type safety between form values and validation schema.\n */\nexport type AddRuleFormValues = z.infer<typeof createRuleFormSchema>\n","import { DEFAULT_IPV4_CIDR } from \"./constants\"\nimport type { AddRuleFormValues } from \"./validation/formSchema\"\n\nexport const DEFAULT_VALUES: AddRuleFormValues = {\n ruleType: \"\",\n direction: \"ingress\",\n ethertype: \"IPv4\",\n description: \"\",\n protocol: null,\n portFrom: \"\",\n portTo: \"\",\n icmpType: \"\",\n icmpCode: \"\",\n remoteSourceType: \"cidr\",\n remoteCidr: DEFAULT_IPV4_CIDR,\n remoteSecurityGroupId: \"\",\n}\n","export interface RulePreset {\n value: string\n label: string\n protocol: string | null\n portRangeMin: number | null\n portRangeMax: number | null\n}\n\nexport const RULE_PRESETS: RulePreset[] = [\n // Empty default option - label rendered in UI with translation\n {\n value: \"\",\n label: \"\", // Rendered in RuleTypeSection with t()\n protocol: null,\n portRangeMin: null,\n portRangeMax: null,\n },\n // Custom rules (appears first)\n {\n value: \"custom-tcp\",\n label: \"Custom TCP Rule\",\n protocol: \"tcp\",\n portRangeMin: null,\n portRangeMax: null,\n },\n {\n value: \"custom-udp\",\n label: \"Custom UDP Rule\",\n protocol: \"udp\",\n portRangeMin: null,\n portRangeMax: null,\n },\n {\n value: \"custom-icmp\",\n label: \"Custom ICMP Rule\",\n protocol: \"icmp\",\n portRangeMin: null,\n portRangeMax: null,\n },\n {\n value: \"all-tcp\",\n label: \"All TCP\",\n protocol: \"tcp\",\n portRangeMin: 1,\n portRangeMax: 65535,\n },\n {\n value: \"all-udp\",\n label: \"All UDP\",\n protocol: \"udp\",\n portRangeMin: 1,\n portRangeMax: 65535,\n },\n {\n value: \"all-icmp\",\n label: \"All ICMP\",\n protocol: \"icmp\",\n portRangeMin: null,\n portRangeMax: null,\n },\n {\n value: \"other-protocol\",\n label: \"Other Protocol\",\n protocol: null,\n portRangeMin: null,\n portRangeMax: null,\n },\n\n // Common protocols\n {\n value: \"dns\",\n label: \"DNS\",\n protocol: \"tcp\",\n portRangeMin: 53,\n portRangeMax: 53,\n },\n {\n value: \"http\",\n label: \"HTTP\",\n protocol: \"tcp\",\n portRangeMin: 80,\n portRangeMax: 80,\n },\n {\n value: \"https\",\n label: \"HTTPS\",\n protocol: \"tcp\",\n portRangeMin: 443,\n portRangeMax: 443,\n },\n {\n value: \"imap\",\n label: \"IMAP\",\n protocol: \"tcp\",\n portRangeMin: 143,\n portRangeMax: 143,\n },\n {\n value: \"imaps\",\n label: \"IMAPS\",\n protocol: \"tcp\",\n portRangeMin: 993,\n portRangeMax: 993,\n },\n {\n value: \"ldap\",\n label: \"LDAP\",\n protocol: \"tcp\",\n portRangeMin: 389,\n portRangeMax: 389,\n },\n {\n value: \"ms-sql\",\n label: \"MS SQL\",\n protocol: \"tcp\",\n portRangeMin: 1433,\n portRangeMax: 1433,\n },\n {\n value: \"mysql\",\n label: \"MySQL\",\n protocol: \"tcp\",\n portRangeMin: 3306,\n portRangeMax: 3306,\n },\n {\n value: \"pop3\",\n label: \"POP3\",\n protocol: \"tcp\",\n portRangeMin: 110,\n portRangeMax: 110,\n },\n {\n value: \"pop3s\",\n label: \"POP3S\",\n protocol: \"tcp\",\n portRangeMin: 995,\n portRangeMax: 995,\n },\n {\n value: \"rdp\",\n label: \"RDP\",\n protocol: \"tcp\",\n portRangeMin: 3389,\n portRangeMax: 3389,\n },\n {\n value: \"ssh\",\n label: \"SSH\",\n protocol: \"tcp\",\n portRangeMin: 22,\n portRangeMax: 22,\n },\n {\n value: \"smtp\",\n label: \"SMTP\",\n protocol: \"tcp\",\n portRangeMin: 25,\n portRangeMax: 25,\n },\n {\n value: \"smtps\",\n label: \"SMTPS\",\n protocol: \"tcp\",\n portRangeMin: 465,\n portRangeMax: 465,\n },\n]\n","import { FormRow, Select, SelectOption } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { RULE_PRESETS } from \"../rulePresets\"\nimport type { AddRuleFormApi } from \"../AddRuleModal\"\n\ninterface RuleTypeSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n}\n\nexport function RuleTypeSection({ form, disabled = false }: RuleTypeSectionProps) {\n const { t } = useLingui()\n\n return (\n <form.Field name=\"ruleType\" mode=\"value\">\n {(field) => (\n <FormRow className=\"mb-6\">\n <Select\n id=\"ruleType\"\n label={t`Rule Type`}\n value={field.state.value}\n onChange={(value) => {\n const newRuleType = String(value || \"\")\n field.handleChange(newRuleType)\n\n // Don't update dependent fields if no preset is selected\n if (!newRuleType) {\n form.setFieldValue(\"protocol\", null)\n form.setFieldValue(\"portFrom\", \"\")\n form.setFieldValue(\"portTo\", \"\")\n form.setFieldValue(\"icmpType\", \"\")\n form.setFieldValue(\"icmpCode\", \"\")\n return\n }\n\n // Update dependent fields when preset changes\n const selectedPreset = RULE_PRESETS.find((p) => p.value === newRuleType)\n if (!selectedPreset) return\n\n // Update protocol field\n form.setFieldValue(\"protocol\", selectedPreset.protocol)\n\n // For TCP/UDP presets: update port fields\n if (selectedPreset.protocol === \"tcp\" || selectedPreset.protocol === \"udp\") {\n if (selectedPreset.portRangeMin !== null && selectedPreset.portRangeMax !== null) {\n // Preset has predefined ports (e.g., HTTP = 80)\n form.setFieldValue(\"portFrom\", String(selectedPreset.portRangeMin))\n form.setFieldValue(\"portTo\", String(selectedPreset.portRangeMax))\n } else {\n // Custom rule - clear ports so user can enter them\n form.setFieldValue(\"portFrom\", \"\")\n form.setFieldValue(\"portTo\", \"\")\n }\n } else {\n // Non-TCP/UDP protocols: clear port fields\n form.setFieldValue(\"portFrom\", \"\")\n form.setFieldValue(\"portTo\", \"\")\n }\n\n // Clear ICMP fields for non-ICMP protocols\n if (selectedPreset.protocol !== \"icmp\" && selectedPreset.protocol !== \"ipv6-icmp\") {\n form.setFieldValue(\"icmpType\", \"\")\n form.setFieldValue(\"icmpCode\", \"\")\n }\n }}\n disabled={disabled}\n >\n {RULE_PRESETS.map((preset) => {\n // Render placeholder option with translation\n if (preset.value === \"\") {\n return <SelectOption key={preset.value} value={preset.value} label={t`Select a rule type...`} />\n }\n return <SelectOption key={preset.value} value={preset.value} label={preset.label} />\n })}\n </Select>\n </FormRow>\n )}\n </form.Field>\n )\n}\n","import { FormRow, RadioGroup, Radio } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport type { AddRuleFormApi } from \"../AddRuleModal\"\n\ninterface DirectionSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n}\n\nexport function DirectionSection({ form, disabled = false }: DirectionSectionProps) {\n const { t } = useLingui()\n\n return (\n <form.Field name=\"direction\">\n {(directionField) => (\n <FormRow>\n <RadioGroup\n name=\"direction\"\n label={t`Direction`}\n selected={directionField.state.value}\n onChange={(value) => directionField.handleChange(String(value) as \"ingress\" | \"egress\")}\n required\n disabled={disabled}\n >\n <div className=\"flex gap-4\">\n <Radio value=\"ingress\" label={t`Ingress`} />\n <Radio value=\"egress\" label={t`Egress`} />\n </div>\n </RadioGroup>\n </FormRow>\n )}\n </form.Field>\n )\n}\n\ninterface EthertypeSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n}\n\nexport function EthertypeSection({ form, disabled = false }: EthertypeSectionProps) {\n const { t } = useLingui()\n\n return (\n <form.Field name=\"ethertype\">\n {(ethertypeField) => (\n <FormRow>\n <RadioGroup\n name=\"ethertype\"\n label={t`IP Version`}\n selected={ethertypeField.state.value}\n onChange={(value) => ethertypeField.handleChange(String(value) as \"IPv4\" | \"IPv6\")}\n required\n disabled={disabled}\n >\n <div className=\"flex gap-4\">\n <Radio value=\"IPv4\" label=\"IPv4\" />\n <Radio value=\"IPv6\" label=\"IPv6\" />\n </div>\n </RadioGroup>\n </FormRow>\n )}\n </form.Field>\n )\n}\n","import { FormRow, TextInput } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport type { AddRuleFormApi } from \"../AddRuleModal\"\n\ninterface ProtocolSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n}\n\nexport function ProtocolSection({ form, disabled = false }: ProtocolSectionProps) {\n const { t } = useLingui()\n\n return (\n <form.Field name=\"protocol\">\n {(field) => (\n <FormRow className=\"mb-6\">\n <TextInput\n id=\"protocol\"\n name=\"protocol\"\n label={t`Protocol`}\n value={field.state.value || \"\"}\n onChange={(e) => field.handleChange(e.target.value || null)}\n errortext={field.state.meta.errors[0]?.message}\n placeholder={t`tcp, udp, icmp, or protocol number`}\n disabled={disabled}\n />\n </FormRow>\n )}\n </form.Field>\n )\n}\n","import { FormRow, TextInput } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { useStore } from \"@tanstack/react-form\"\nimport type { AddRuleFormApi } from \"../AddRuleModal\"\n\ninterface PortRangeSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n}\n\nexport function PortRangeSection({ form, disabled = false }: PortRangeSectionProps) {\n const { t } = useLingui()\n\n // Watch portFrom value using useStore\n const portFromValue = useStore(form.store, (state) => state.values.portFrom)\n\n // Watch field errors using useStore\n const portFromError = useStore(form.store, (state) => state.fieldMeta.portFrom?.errors[0]?.message)\n const portToError = useStore(form.store, (state) => state.fieldMeta.portTo?.errors[0]?.message)\n\n // Determine if portTo should be disabled based on portFrom value\n const isPortToDisabled = disabled || !portFromValue || portFromValue.trim() === \"\"\n\n return (\n <FormRow className=\"mb-6\">\n <div className=\"flex items-center gap-4\">\n <form.Field name=\"portFrom\">\n {(portFromField) => {\n return (\n <div className=\"flex-1\">\n <TextInput\n id=\"portFrom\"\n name=\"portFrom\"\n label={t`Port (from)`}\n value={portFromField.state.value || \"\"}\n onChange={(e) => {\n const newValue = e.target.value\n portFromField.handleChange(newValue)\n\n // Clear portTo when portFrom is cleared\n if (!newValue || newValue.trim() === \"\") {\n form.setFieldValue(\"portTo\", \"\")\n }\n\n // Trigger validation of portTo when portFrom changes\n // This ensures cross-field validation (portFrom < portTo) updates immediately\n form.validateField(\"portTo\", \"change\")\n }}\n invalid={portFromField.state.meta.errors.length > 0}\n disabled={disabled}\n required\n />\n </div>\n )\n }}\n </form.Field>\n <div className=\"text-theme-secondary flex items-center justify-center\">—</div>\n <form.Field name=\"portTo\">\n {(portToField) => {\n return (\n <div className=\"flex-1\">\n <TextInput\n id=\"portTo\"\n name=\"portTo\"\n label={t`Port (to)`}\n value={portToField.state.value || \"\"}\n onChange={(e) => {\n portToField.handleChange(e.target.value)\n\n // Trigger validation of portFrom when portTo changes\n // This ensures cross-field validation (portFrom < portTo) updates immediately\n form.validateField(\"portFrom\", \"change\")\n }}\n invalid={portToField.state.meta.errors.length > 0}\n placeholder=\"\"\n disabled={isPortToDisabled}\n />\n </div>\n )\n }}\n </form.Field>\n </div>\n\n {/* Display errors before description */}\n {(portFromError || portToError) && (\n <div className=\"text-theme-error mt-2 text-sm\">\n {portFromError && <div>{portFromError}</div>}\n {portToError && <div>{portToError}</div>}\n </div>\n )}\n\n <p className=\"mt-2 text-sm\">\n {t`Enter a single port, or define a range by also filling \"Port (to)\". \"Port (to)\" is optional.`}\n </p>\n </FormRow>\n )\n}\n","import { FormRow, TextInput } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport type { AddRuleFormApi } from \"../AddRuleModal\"\n\ninterface IcmpSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n}\n\nexport function IcmpSection({ form, disabled = false }: IcmpSectionProps) {\n const { t } = useLingui()\n\n return (\n <FormRow className=\"mb-6\">\n <div className=\"flex w-full gap-4\">\n <form.Field name=\"icmpType\">\n {(icmpTypeField) => (\n <div className=\"flex-1\">\n <TextInput\n id=\"icmpType\"\n name=\"icmpType\"\n label={t`ICMP Type`}\n value={icmpTypeField.state.value}\n onChange={(e) => icmpTypeField.handleChange(e.target.value)}\n errortext={icmpTypeField.state.meta.errors[0]?.message}\n placeholder={t`Leave empty for all types`}\n disabled={disabled}\n />\n </div>\n )}\n </form.Field>\n <form.Field name=\"icmpCode\">\n {(icmpCodeField) => (\n <div className=\"flex-1\">\n <TextInput\n id=\"icmpCode\"\n name=\"icmpCode\"\n label={t`ICMP Code`}\n value={icmpCodeField.state.value}\n onChange={(e) => icmpCodeField.handleChange(e.target.value)}\n errortext={icmpCodeField.state.meta.errors[0]?.message}\n placeholder={t`Leave empty for all codes`}\n disabled={disabled}\n />\n </div>\n )}\n </form.Field>\n </div>\n </FormRow>\n )\n}\n","import { FormRow, TextInput, Select, SelectOption, RadioGroup, Radio } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { DEFAULT_IPV4_CIDR, DEFAULT_IPV6_CIDR } from \"../constants\"\nimport type { AddRuleFormApi } from \"../AddRuleModal\"\n\ninterface RemoteSourceSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n availableSecurityGroups: Array<{ id: string; name: string | null }>\n}\n\nexport function RemoteSourceSection({ form, disabled = false, availableSecurityGroups }: RemoteSourceSectionProps) {\n const { t } = useLingui()\n\n return (\n <>\n {/* Remote Source Type Toggle */}\n <form.Field name=\"remoteSourceType\" mode=\"value\">\n {(remoteSourceTypeField) => (\n <FormRow className=\"mb-1\">\n <RadioGroup\n name=\"remoteSourceType\"\n label={t`Remote Source`}\n selected={remoteSourceTypeField.state.value}\n onChange={(value) => {\n const newValue = String(value) as \"cidr\" | \"security_group\"\n remoteSourceTypeField.handleChange(newValue)\n\n // Auto-set ethertype to IPv4 when remote source is NOT security group\n if (newValue !== \"security_group\") {\n form.setFieldValue(\"ethertype\", \"IPv4\")\n }\n }}\n disabled={disabled}\n >\n <div className=\"flex gap-4\">\n <Radio value=\"cidr\" label={t`CIDR`} />\n <Radio value=\"security_group\" label={t`Security Group`} />\n </div>\n </RadioGroup>\n </FormRow>\n )}\n </form.Field>\n\n {/* Remote CIDR (conditional) */}\n <form.Field name=\"remoteSourceType\">\n {(remoteSourceTypeField) =>\n remoteSourceTypeField.state.value === \"cidr\" ? (\n <form.Field name=\"remoteCidr\">\n {(remoteCidrField) => (\n <form.Field name=\"ethertype\">\n {(ethertypeField) => (\n <FormRow className=\"mb-6\">\n <TextInput\n id=\"remoteCidr\"\n name=\"remoteCidr\"\n label={t`Remote IP Prefix`}\n value={remoteCidrField.state.value}\n onChange={(e) => remoteCidrField.handleChange(e.target.value)}\n errortext={remoteCidrField.state.meta.errors[0]?.message}\n placeholder={ethertypeField.state.value === \"IPv4\" ? DEFAULT_IPV4_CIDR : DEFAULT_IPV6_CIDR}\n disabled={disabled}\n />\n </FormRow>\n )}\n </form.Field>\n )}\n </form.Field>\n ) : null\n }\n </form.Field>\n\n {/* Remote Security Group (conditional) */}\n <form.Field name=\"remoteSourceType\">\n {(remoteSourceTypeField) =>\n remoteSourceTypeField.state.value === \"security_group\" ? (\n <form.Field name=\"remoteSecurityGroupId\">\n {(remoteSecurityGroupIdField) => (\n <FormRow className=\"mb-6\">\n <Select\n id=\"remoteSecurityGroupId\"\n label={t`Remote Security Group`}\n value={remoteSecurityGroupIdField.state.value}\n onChange={(value) => remoteSecurityGroupIdField.handleChange(String(value))}\n errortext={remoteSecurityGroupIdField.state.meta.errors[0]?.message}\n disabled={disabled}\n >\n <SelectOption value=\"\" label={t`Select a security group...`} />\n {availableSecurityGroups.map((sg) => (\n <SelectOption key={sg.id} value={sg.id} label={sg.name || sg.id} />\n ))}\n </Select>\n </FormRow>\n )}\n </form.Field>\n ) : null\n }\n </form.Field>\n </>\n )\n}\n","import { FormRow, Textarea } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport type { AddRuleFormApi } from \"../AddRuleModal\"\n\ninterface DescriptionSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n}\n\nexport function DescriptionSection({ form, disabled = false }: DescriptionSectionProps) {\n const { t } = useLingui()\n\n return (\n <form.Field name=\"description\">\n {(field) => (\n <FormRow className=\"mb-0\">\n <Textarea\n id=\"description\"\n name=\"description\"\n label={t`Description`}\n value={field.state.value}\n onChange={(e) => field.handleChange(e.target.value)}\n placeholder={t`Optional description`}\n disabled={disabled}\n rows={2}\n />\n </FormRow>\n )}\n </form.Field>\n )\n}\n","import React from \"react\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { useForm } from \"@tanstack/react-form\"\nimport {\n Modal,\n Form,\n FormSection,\n Button,\n ButtonRow,\n Spinner,\n ModalFooter,\n Message,\n} from \"@cloudoperators/juno-ui-components\"\nimport type { CreateSecurityGroupRuleInput } from \"@/server/Network/types/securityGroup\"\nimport { createRuleFormSchema } from \"./validation/formSchema\"\nimport { DEFAULT_VALUES } from \"./types\"\nimport { CUSTOM_TCP_RULE, CUSTOM_UDP_RULE, OTHER_PROTOCOL_RULE } from \"./constants\"\nimport { RuleTypeSection } from \"./sections/RuleTypeSection\"\nimport { DirectionSection, EthertypeSection } from \"./sections/DirectionEthertypeSection\"\nimport { ProtocolSection } from \"./sections/ProtocolSection\"\nimport { PortRangeSection } from \"./sections/PortRangeSection\"\nimport { IcmpSection } from \"./sections/IcmpSection\"\nimport { RemoteSourceSection } from \"./sections/RemoteSourceSection\"\nimport { DescriptionSection } from \"./sections/DescriptionSection\"\n\ninterface AddRuleModalProps {\n securityGroupId: string\n open: boolean\n onClose: () => void\n onCreate: (ruleData: Omit<CreateSecurityGroupRuleInput, \"project_id\">) => Promise<void>\n isLoading?: boolean\n error?: string | null\n availableSecurityGroups?: Array<{ id: string; name: string | null }>\n}\n\n/**\n * Helper function for TypeScript type inference.\n * This function is never called at runtime - it exists purely to help TypeScript\n * infer the return type of useForm for use in child components.\n * Note: Must include validators to match the actual form's type signature.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction createFormTypeHelper() {\n return useForm({\n defaultValues: DEFAULT_VALUES,\n validators: {\n onSubmit: createRuleFormSchema,\n },\n onSubmit: async () => {\n // Dummy implementation for type inference only\n },\n })\n}\n\n/**\n * Type for the TanStack Form instance used in this modal.\n * Inferred from the helper function above.\n */\nexport type AddRuleFormApi = ReturnType<typeof createFormTypeHelper>\n\nexport const AddRuleModal: React.FC<AddRuleModalProps> = ({\n securityGroupId,\n open,\n onClose,\n onCreate,\n isLoading = false,\n error = null,\n availableSecurityGroups = [],\n}) => {\n const { t } = useLingui()\n\n // Initialize TanStack Form\n const form = useForm({\n defaultValues: DEFAULT_VALUES,\n validators: {\n onSubmit: createRuleFormSchema,\n },\n onSubmit: async ({ value }) => {\n if (isLoading) {\n return\n }\n\n // Build API payload from form values (without project_id - added by parent)\n const payload: Omit<CreateSecurityGroupRuleInput, \"project_id\"> = {\n security_group_id: securityGroupId,\n direction: value.direction,\n ethertype: value.ethertype,\n description: value.description || undefined,\n protocol: value.protocol || null,\n // Initialize remote fields as undefined (will be set below if applicable)\n remote_ip_prefix: undefined,\n remote_group_id: undefined,\n remote_address_group_id: undefined,\n }\n\n // Add port range for TCP/UDP protocols\n const isTcpUdp = value.protocol === \"tcp\" || value.protocol === \"udp\"\n if (isTcpUdp) {\n if (value.portFrom) {\n const portFrom = parseInt(value.portFrom, 10)\n payload.port_range_min = portFrom\n\n if (value.portTo) {\n // Range: both portFrom and portTo are provided\n payload.port_range_max = parseInt(value.portTo, 10)\n } else {\n // Single port: only portFrom is provided\n payload.port_range_max = portFrom\n }\n }\n }\n\n // Add ICMP type/code (maps to port_range_min/max)\n const isIcmp = value.protocol === \"icmp\" || value.protocol === \"ipv6-icmp\"\n if (isIcmp) {\n if (value.icmpType) {\n payload.port_range_min = parseInt(value.icmpType, 10)\n }\n if (value.icmpCode) {\n payload.port_range_max = parseInt(value.icmpCode, 10)\n }\n }\n\n // Add remote source\n if (value.remoteSourceType === \"cidr\" && value.remoteCidr) {\n payload.remote_ip_prefix = value.remoteCidr\n } else if (value.remoteSourceType === \"security_group\" && value.remoteSecurityGroupId) {\n payload.remote_group_id = value.remoteSecurityGroupId\n }\n\n await onCreate(payload)\n handleClose()\n },\n })\n\n const handleClose = () => {\n form.reset()\n onClose()\n }\n\n return (\n <Modal\n open={open}\n onCancel={handleClose}\n size=\"large\"\n title={t`Add Security Group Rule`}\n modalFooter={\n <ModalFooter className=\"flex justify-end\">\n <form.Subscribe>\n {(state: { isSubmitting: boolean; values: { ruleType: string } }) => {\n const isRuleTypeSelected = Boolean(state.values.ruleType)\n return (\n <ButtonRow>\n <Button variant=\"default\" onClick={handleClose} disabled={isLoading || state.isSubmitting}>\n <Trans>Cancel</Trans>\n </Button>\n <Button\n variant=\"primary\"\n type=\"button\"\n onClick={() => form.handleSubmit()}\n disabled={isLoading || state.isSubmitting || !isRuleTypeSelected}\n data-testid=\"add-rule-button\"\n >\n {state.isSubmitting || isLoading ? <Spinner size=\"small\" /> : <Trans>Add Rule</Trans>}\n </Button>\n </ButtonRow>\n )\n }}\n </form.Subscribe>\n </ModalFooter>\n }\n >\n {/* Error Message */}\n {error && (\n <Message dismissible={false} variant=\"error\" className=\"mb-4\">\n {error}\n </Message>\n )}\n\n {isLoading && (\n <div className=\"mb-4 flex items-center justify-center gap-2\">\n <Spinner variant=\"primary\" />\n <span className=\"text-theme-secondary text-sm\">\n <Trans>Creating security group rule...</Trans>\n </span>\n </div>\n )}\n\n <Form\n className=\"mb-6\"\n onSubmit={(e) => {\n e.preventDefault()\n form.handleSubmit()\n }}\n >\n <FormSection className=\"mb-6\">\n {/* Rule Type Preset */}\n <RuleTypeSection form={form} disabled={isLoading} />\n\n {/* Show other fields only when rule type is selected */}\n <form.Subscribe>\n {(state: {\n values: { ruleType: string; protocol: string | null; remoteSourceType: \"cidr\" | \"security_group\" }\n }) => {\n const isRuleTypeSelected = Boolean(state.values.ruleType)\n\n if (!isRuleTypeSelected) {\n return null\n }\n\n const isTcpUdp = state.values.protocol === \"tcp\" || state.values.protocol === \"udp\"\n const showPortFields = isTcpUdp && [CUSTOM_TCP_RULE, CUSTOM_UDP_RULE].includes(state.values.ruleType)\n const showIcmpFields = state.values.protocol === \"icmp\" || state.values.protocol === \"ipv6-icmp\"\n\n return (\n <>\n {/* Direction */}\n <DirectionSection form={form} disabled={isLoading} />\n\n {/* Protocol (conditional for \"Other Protocol\") */}\n {state.values.ruleType === OTHER_PROTOCOL_RULE && (\n <ProtocolSection form={form} disabled={isLoading} />\n )}\n\n {/* Port Range (conditional for Custom TCP/UDP) */}\n {showPortFields && <PortRangeSection form={form} disabled={isLoading} />}\n\n {/* ICMP Fields (conditional for ICMP protocols) */}\n {showIcmpFields && <IcmpSection form={form} disabled={isLoading} />}\n\n {/* Remote Source (CIDR or Security Group) */}\n <RemoteSourceSection\n form={form}\n disabled={isLoading}\n availableSecurityGroups={availableSecurityGroups}\n />\n\n {/* Ethertype (conditional for Security Group remote source) */}\n {state.values.remoteSourceType === \"security_group\" && (\n <EthertypeSection form={form} disabled={isLoading} />\n )}\n\n {/* Description */}\n <DescriptionSection form={form} disabled={isLoading} />\n </>\n )\n }}\n </form.Subscribe>\n </FormSection>\n </Form>\n </Modal>\n )\n}\n","import { useState, useEffect } from \"react\"\nimport {\n DataGrid,\n DataGridHeadCell,\n DataGridRow,\n DataGridCell,\n Button,\n Stack,\n PopupMenu,\n PopupMenuItem,\n PopupMenuOptions,\n} from \"@cloudoperators/juno-ui-components\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport type { SecurityGroupRule, CreateSecurityGroupRuleInput } from \"@/server/Network/types/securityGroup\"\nimport type { FilterSettings, SortSettings } from \"@/client/components/ListToolbar/types\"\nimport type { ListSortConfig } from \"@/client/utils/useListWithFiltering\"\nimport { DeleteRuleDialog } from \"../../-modals/DeleteRuleDialog\"\nimport { AddRuleModal } from \"../../-modals/AddRuleModal/AddRuleModal\"\nimport { ListToolbar } from \"@/client/components/ListToolbar\"\nimport { useModal } from \"@/client/utils/useModal\"\n\ninterface SecurityGroupRulesTableProps {\n rules: SecurityGroupRule[] // Filtered rules\n totalRulesCount?: number // Total rules count before filtering\n onDeleteRule: (ruleId: string) => void\n isDeletingRule: boolean\n deleteError: string | null\n // Client-side filtering and sorting controls\n searchTerm?: string\n onSearchChange?: (searchTerm: string | number | string[] | undefined) => void\n sortSettings?: ListSortConfig<\"direction\" | \"protocol\" | \"description\">\n onSortChange?: (sortSettings: SortSettings) => void\n filterSettings?: FilterSettings\n onFilterChange?: (filterSettings: FilterSettings) => void\n // Add rule functionality\n securityGroupId?: string\n onCreateRule?: (ruleData: Omit<CreateSecurityGroupRuleInput, \"project_id\">) => Promise<void>\n isCreatingRule?: boolean\n createRuleError?: string | null\n availableSecurityGroups?: Array<{ id: string; name: string | null }>\n readOnly?: boolean // Hide actions column and add rule button for shared security groups\n}\n\nexport function SecurityGroupRulesTable({\n rules,\n totalRulesCount,\n onDeleteRule,\n isDeletingRule,\n deleteError,\n searchTerm = \"\",\n onSearchChange,\n sortSettings,\n onSortChange,\n filterSettings,\n onFilterChange,\n securityGroupId,\n onCreateRule,\n isCreatingRule = false,\n createRuleError = null,\n availableSecurityGroups = [],\n readOnly = false,\n}: SecurityGroupRulesTableProps) {\n const { t } = useLingui()\n const [ruleToDelete, setRuleToDelete] = useState<SecurityGroupRule | null>(null)\n const [isAddRuleModalOpen, toggleAddRuleModal] = useModal()\n\n const handleDeleteClick = (rule: SecurityGroupRule) => {\n setRuleToDelete(rule)\n }\n\n const handleConfirmDelete = (ruleId: string) => {\n onDeleteRule(ruleId)\n }\n\n const handleCloseDeleteDialog = () => {\n if (!isDeletingRule) {\n setRuleToDelete(null)\n }\n }\n\n // Close dialog after successful deletion\n useEffect(() => {\n if (!isDeletingRule && !deleteError) {\n setRuleToDelete(null)\n }\n }, [isDeletingRule, deleteError])\n\n // Format port range display\n const formatPortRange = (rule: SecurityGroupRule): string => {\n if (rule.protocol === \"icmp\" || rule.protocol === \"ipv6-icmp\") {\n if (rule.port_range_min !== null && rule.port_range_max !== null) {\n const typeValue = rule.port_range_min\n const codeValue = rule.port_range_max\n return t`Type: ${typeValue}, Code: ${codeValue}`\n }\n return t`-`\n }\n\n if (rule.port_range_min === null || rule.port_range_max === null) {\n return t`-`\n }\n\n if (rule.port_range_min === rule.port_range_max) {\n return String(rule.port_range_min)\n }\n\n return `${rule.port_range_min}-${rule.port_range_max}`\n }\n\n return (\n <>\n <Stack direction=\"vertical\" gap=\"4\">\n <ListToolbar\n totalCount={totalRulesCount ?? rules.length}\n filteredCount={rules.length}\n itemName={t`rules`}\n filterSettings={filterSettings}\n onFilter={onFilterChange}\n sortSettings={sortSettings}\n onSort={onSortChange}\n searchTerm={searchTerm}\n onSearch={onSearchChange}\n actions={\n !readOnly &&\n onCreateRule && (\n <Button variant=\"primary\" icon=\"addCircle\" onClick={toggleAddRuleModal}>\n <Trans>Add rule</Trans>\n </Button>\n )\n }\n />\n\n {/* Rules Table */}\n {rules.length === 0 ? (\n <Trans>There are no rules for this security group</Trans>\n ) : (\n <DataGrid columns={readOnly ? 5 : 6} className=\"security-group-rules-table\">\n <DataGridRow>\n <DataGridHeadCell>{t`Direction`}</DataGridHeadCell>\n <DataGridHeadCell>{t`Description`}</DataGridHeadCell>\n <DataGridHeadCell>{t`Ethertype`}</DataGridHeadCell>\n <DataGridHeadCell>{t`Protocol`}</DataGridHeadCell>\n <DataGridHeadCell>{t`Range`}</DataGridHeadCell>\n {!readOnly && <DataGridHeadCell>{t`Actions`}</DataGridHeadCell>}\n </DataGridRow>\n {rules.map((rule) => (\n <DataGridRow key={rule.id} data-testid={`rule-row-${rule.id}`}>\n <DataGridCell>{rule.direction || t`—`}</DataGridCell>\n <DataGridCell>{rule.description || t`—`}</DataGridCell>\n <DataGridCell>{rule.ethertype}</DataGridCell>\n <DataGridCell>{rule.protocol || t`-`}</DataGridCell>\n <DataGridCell>{formatPortRange(rule)}</DataGridCell>\n {!readOnly && (\n <DataGridCell onClick={(e) => e.stopPropagation()} className=\"items-end justify-end pr-0\">\n <PopupMenu>\n <PopupMenuOptions>\n <PopupMenuItem label={t`Delete`} onClick={() => handleDeleteClick(rule)} />\n </PopupMenuOptions>\n </PopupMenu>\n </DataGridCell>\n )}\n </DataGridRow>\n ))}\n </DataGrid>\n )}\n </Stack>\n\n {/* Delete Confirmation Dialog */}\n {!readOnly && (\n <DeleteRuleDialog\n rule={ruleToDelete}\n open={!!ruleToDelete}\n onClose={handleCloseDeleteDialog}\n onConfirm={handleConfirmDelete}\n isLoading={isDeletingRule}\n error={deleteError}\n />\n )}\n\n {/* Add Rule Modal */}\n {!readOnly && securityGroupId && onCreateRule && isAddRuleModalOpen && (\n <AddRuleModal\n securityGroupId={securityGroupId}\n open={isAddRuleModalOpen}\n onClose={toggleAddRuleModal}\n onCreate={onCreateRule}\n isLoading={isCreatingRule}\n error={createRuleError}\n availableSecurityGroups={availableSecurityGroups}\n />\n )}\n </>\n )\n}\n","import {\n DataGridRow,\n DataGridCell,\n PopupMenu,\n PopupMenuItem,\n PopupMenuOptions,\n} from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport type { RBACPolicy } from \"@/server/Network/types/rbacPolicy\"\n\ninterface RBACPolicyRowProps {\n policy: RBACPolicy\n onDelete: () => void\n}\n\nexport function RBACPolicyRow({ policy, onDelete }: RBACPolicyRowProps) {\n const { t } = useLingui()\n\n return (\n <DataGridRow>\n <DataGridCell>{policy.target_tenant}</DataGridCell>\n <DataGridCell>{policy.action}</DataGridCell>\n <DataGridCell onClick={(e) => e.stopPropagation()} className=\"items-end justify-end pr-0\">\n <PopupMenu>\n <PopupMenuOptions>\n <PopupMenuItem label={t`Remove`} onClick={onDelete} />\n </PopupMenuOptions>\n </PopupMenu>\n </DataGridCell>\n </DataGridRow>\n )\n}\n","import { z } from \"zod\"\nimport { useState } from \"react\"\nimport { useForm } from \"@tanstack/react-form\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { Modal, Form, FormSection, TextInput, Message } from \"@cloudoperators/juno-ui-components\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useProjectId } from \"@/client/hooks\"\n\ninterface AddRBACPolicyModalProps {\n isOpen: boolean\n onClose: () => void\n securityGroupId: string\n}\n\n// UUID pattern - supports both formats:\n// - With dashes: 12345678-1234-1234-1234-123456789abc\n// - Without dashes: 12345678123412341234123456789abc (OpenStack format)\nconst UUID_WITH_DASHES = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\nconst UUID_WITHOUT_DASHES = /^[0-9a-f]{32}$/i\n\nfunction isValidProjectID(value: string): boolean {\n return UUID_WITH_DASHES.test(value) || UUID_WITHOUT_DASHES.test(value)\n}\n\nexport function AddRBACPolicyModal({ isOpen, onClose, securityGroupId }: AddRBACPolicyModalProps) {\n const { t } = useLingui()\n const utils = trpcReact.useUtils()\n const projectId = useProjectId()\n const [hasSubmitted, setHasSubmitted] = useState(false)\n\n const formSchema = z.object({\n targetTenant: z\n .string()\n .min(1, t`Target project ID is required`)\n .refine(isValidProjectID, {\n message: t`Invalid project ID format. Must be 32 hexadecimal characters (e.g., b90f9c4bc76140e18540b2cec1299e2a) or UUID format (e.g., 12345678-1234-1234-1234-123456789abc)`,\n }),\n })\n\n const createMutation = trpcReact.network.rbacPolicy.create.useMutation({\n onSuccess: () => {\n utils.network.rbacPolicy.list.invalidate({ project_id: projectId, securityGroupId })\n utils.network.securityGroup.getById.invalidate({ project_id: projectId, securityGroupId })\n handleClose()\n },\n })\n\n const form = useForm({\n defaultValues: {\n targetTenant: \"\",\n },\n validators: {\n onSubmit: formSchema,\n },\n onSubmit: async ({ value }) => {\n if (createMutation.isPending) return\n\n createMutation.mutate({\n project_id: projectId,\n securityGroupId,\n targetTenant: value.targetTenant.trim(),\n })\n },\n })\n\n const handleClose = () => {\n form.reset()\n createMutation.reset()\n setHasSubmitted(false)\n onClose()\n }\n\n const handleConfirm = async () => {\n setHasSubmitted(true)\n await form.handleSubmit()\n }\n\n return (\n <Modal\n open={isOpen}\n onCancel={handleClose}\n title={t`Share Security Group`}\n size=\"large\"\n onConfirm={handleConfirm}\n cancelButtonLabel={t`Cancel`}\n confirmButtonLabel={t`Share`}\n disableConfirmButton={createMutation.isPending}\n >\n {createMutation.error && (\n <Message variant=\"error\" className=\"mb-4\">\n {(() => {\n const message = createMutation.error.message.toLowerCase()\n if (message.includes(\"conflict\") || message.includes(\"409\")) {\n return t`This security group is already shared with the specified project.`\n } else if (message.includes(\"not found\") || message.includes(\"404\")) {\n return t`The specified project does not exist or you don't have permission to share with it.`\n } else if (message.includes(\"forbidden\") || message.includes(\"403\")) {\n return t`You don't have permission to share this security group.`\n } else {\n return createMutation.error.message\n }\n })()}\n </Message>\n )}\n\n <p className=\"mb-4\">\n <Trans>\n Share this security group with another project. The target project will be able to view and use this security\n group, but will not be able to modify or delete it.\n </Trans>\n </p>\n\n <Form\n className=\"mb-0\"\n onSubmit={(e) => {\n e.preventDefault()\n handleConfirm()\n }}\n >\n <FormSection>\n <form.Field\n name=\"targetTenant\"\n validators={{\n onBlur: ({ value }) => {\n const trimmedValue = value.trim()\n if (!trimmedValue) {\n return t`Target project ID is required`\n }\n if (!isValidProjectID(trimmedValue)) {\n return t`Invalid project ID format. Must be 32 hexadecimal characters (e.g., b90f9c4bc76140e18540b2cec1299e2a) or UUID format (e.g., 12345678-1234-1234-1234-123456789abc)`\n }\n return undefined\n },\n onChange: ({ value }) => {\n // Validate on change only after first submit attempt\n if (!hasSubmitted) return undefined\n\n const trimmedValue = value.trim()\n if (!trimmedValue) {\n return t`Target project ID is required`\n }\n if (!isValidProjectID(trimmedValue)) {\n return t`Invalid project ID format. Must be 32 hexadecimal characters (e.g., b90f9c4bc76140e18540b2cec1299e2a) or UUID format (e.g., 12345678-1234-1234-1234-123456789abc)`\n }\n return undefined\n },\n }}\n children={(field) => {\n // Get first error message as string\n const showError = (field.state.meta.isTouched || hasSubmitted) && field.state.meta.errors.length > 0\n const firstError = field.state.meta.errors[0]\n const errorMessage = showError\n ? typeof firstError === \"string\"\n ? firstError\n : firstError?.message\n : undefined\n\n return (\n <TextInput\n id={field.name}\n name={field.name}\n label={t`Target Project ID`}\n value={field.state.value}\n onChange={(e) => field.handleChange(e.target.value)}\n onBlur={field.handleBlur}\n placeholder={t`e.g., b90f9c4bc76140e18540b2cec1299e2a`}\n required\n helptext={t`Enter the ID of the project you want to share this security group with. You can find project IDs in the account/project switcher or in the Identity service.`}\n disabled={createMutation.isPending}\n errortext={errorMessage}\n invalid={showError}\n />\n )\n }}\n />\n </FormSection>\n </Form>\n </Modal>\n )\n}\n","import { z } from \"zod\"\nimport { useForm, useStore } from \"@tanstack/react-form\"\nimport { Modal, Message, TextInput, Form, FormSection } from \"@cloudoperators/juno-ui-components\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport type { RBACPolicy } from \"@/server/Network/types/rbacPolicy\"\n\ninterface DeleteRBACPolicyDialogProps {\n policy: RBACPolicy\n open: boolean\n onClose: () => void\n onConfirm: (policyId: string) => void\n isLoading: boolean\n error: string | null\n}\n\nexport function DeleteRBACPolicyDialog({\n policy,\n open,\n onClose,\n onConfirm,\n isLoading,\n error,\n}: DeleteRBACPolicyDialogProps) {\n const { t } = useLingui()\n\n const formSchema = z.object({\n confirmText: z.string().refine((value) => value === \"remove\", {\n message: t`Type \"remove\" to confirm`,\n }),\n })\n\n const form = useForm({\n defaultValues: {\n confirmText: \"\",\n },\n validators: {\n onSubmit: formSchema,\n },\n onSubmit: async () => {\n if (isLoading) return\n\n onConfirm(policy.id)\n handleClose()\n },\n })\n\n // Creates a reactive subscription so the component re-renders, which allows the confirm button to enable once the user types \"remove\"\n const canRemove = useStore(form.store, (state) => state.isSubmitting || state.values.confirmText !== \"remove\")\n\n const handleClose = () => {\n form.reset()\n onClose()\n }\n\n return (\n <Modal\n open={open}\n onCancel={handleClose}\n size=\"small\"\n title={t`Remove RBAC Policy`}\n onConfirm={form.handleSubmit}\n cancelButtonLabel={t`Cancel`}\n confirmButtonLabel={isLoading ? t`Removing...` : t`Remove Policy`}\n disableConfirmButton={isLoading || canRemove}\n >\n <div>\n {/* Error Message */}\n {error && (\n <Message dismissible={false} variant=\"error\" className=\"mt-4\">\n {error}\n </Message>\n )}\n\n {/* Warning */}\n <Trans>\n This action cannot be undone. The target project will lose access to this security group immediately.\n </Trans>\n\n {/* Policy Details */}\n <div className=\"bg-theme-background-lvl-1 mt-4 mb-4 rounded p-4\">\n <p className=\"mb-2 font-semibold\">\n <Trans>RBAC Policy Details:</Trans>\n </p>\n <ul className=\"list-inside list-disc space-y-1 text-sm\">\n <li>\n <Trans>Target Project ID</Trans>: {policy.target_tenant}\n </li>\n <li>\n <Trans>Action</Trans>: {policy.action}\n </li>\n <li>\n <Trans>Object Type</Trans>: {policy.object_type}\n </li>\n </ul>\n </div>\n\n {/* Confirmation Input */}\n {!isLoading && (\n <Form\n className=\"mt-4 mb-0\"\n onSubmit={(e) => {\n e.preventDefault()\n form.handleSubmit()\n }}\n >\n <FormSection>\n <p className=\"mb-2 text-sm\">\n <Trans>\n Type <strong>remove</strong> to confirm:\n </Trans>\n </p>\n <form.Field\n name=\"confirmText\"\n children={(field) => (\n <TextInput\n id={field.name}\n name={field.name}\n value={field.state.value}\n onChange={(e) => field.handleChange(e.target.value)}\n placeholder={t`remove`}\n autoComplete=\"off\"\n disabled={isLoading}\n data-testid=\"remove-policy-confirmation-input\"\n />\n )}\n />\n </FormSection>\n </Form>\n )}\n </div>\n </Modal>\n )\n}\n","import { useState, useEffect, useMemo } from \"react\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport {\n DataGrid,\n DataGridRow,\n DataGridHeadCell,\n Stack,\n Spinner,\n Button,\n Message,\n} from \"@cloudoperators/juno-ui-components\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useProjectId } from \"@/client/hooks\"\nimport type { RBACPolicy } from \"@/server/Network/types/rbacPolicy\"\nimport { RBACPolicyRow } from \"./RBACPolicyRow\"\nimport { AddRBACPolicyModal } from \"../../-modals/AddRBACPolicyModal\"\nimport { DeleteRBACPolicyDialog } from \"../../-modals/DeleteRBACPolicyDialog\"\nimport { ListToolbar } from \"@/client/components/ListToolbar\"\nimport { useModal } from \"@/client/utils/useModal\"\n\ninterface SecurityGroupRBACPoliciesProps {\n securityGroupId: string\n}\n\nexport function SecurityGroupRBACPolicies({ securityGroupId }: SecurityGroupRBACPoliciesProps) {\n const utils = trpcReact.useUtils()\n const { t } = useLingui()\n const projectId = useProjectId()\n\n const [isAddModalOpen, toggleAddModal] = useModal()\n const [policyToDelete, setPolicyToDelete] = useState<RBACPolicy | null>(null)\n const [searchTerm, setSearchTerm] = useState(\"\")\n\n // Query RBAC policies\n const {\n data: policies,\n isPending,\n isError,\n error,\n } = trpcReact.network.rbacPolicy.list.useQuery(\n { project_id: projectId, securityGroupId },\n {\n refetchOnWindowFocus: false,\n }\n )\n\n // Delete mutation\n const deleteMutation = trpcReact.network.rbacPolicy.delete.useMutation({\n onSuccess: () => {\n utils.network.rbacPolicy.list.invalidate({ project_id: projectId, securityGroupId })\n utils.network.securityGroup.getById.invalidate({ project_id: projectId, securityGroupId })\n },\n })\n\n const handleDeleteClick = (policy: RBACPolicy) => {\n setPolicyToDelete(policy)\n }\n\n const handleConfirmDelete = (policyId: string) => {\n deleteMutation.mutate({ project_id: projectId, policyId })\n }\n\n const handleCloseDeleteDialog = () => {\n if (!deleteMutation.isPending) {\n setPolicyToDelete(null)\n }\n }\n\n // Close dialog after successful deletion\n useEffect(() => {\n if (!deleteMutation.isPending && !deleteMutation.error && deleteMutation.isSuccess) {\n setPolicyToDelete(null)\n }\n }, [deleteMutation.isPending, deleteMutation.error, deleteMutation.isSuccess])\n\n // Client-side search filtering\n const filteredPolicies = useMemo(() => {\n if (!policies) return []\n\n if (!searchTerm) {\n return policies\n }\n\n const searchLower = searchTerm.toLowerCase()\n return policies.filter(\n (policy) =>\n policy.target_tenant?.toLowerCase().includes(searchLower) || policy.action?.toLowerCase().includes(searchLower)\n )\n }, [policies, searchTerm])\n\n const handleSearchChange = (value: string | number | string[] | undefined) => {\n const searchValue = typeof value === \"string\" ? value : \"\"\n setSearchTerm(searchValue)\n }\n\n if (isPending) {\n return (\n <Stack distribution=\"center\" alignment=\"center\" className=\"py-8\">\n <Spinner variant=\"primary\" />\n </Stack>\n )\n }\n\n if (isError) {\n return (\n <Message variant=\"error\" className=\"mb-4\">\n {error.message}\n </Message>\n )\n }\n\n const totalCount = policies?.length || 0\n const filteredCount = filteredPolicies.length\n\n return (\n <>\n <Stack direction=\"vertical\" gap=\"4\">\n {/* Toolbar with Share button and search - same pattern as Rules */}\n <ListToolbar\n totalCount={totalCount}\n filteredCount={filteredCount}\n itemName={t`projects`}\n searchTerm={searchTerm}\n onSearch={handleSearchChange}\n actions={\n <Button variant=\"primary\" icon=\"addCircle\" onClick={toggleAddModal}>\n <Trans>Share Security Group</Trans>\n </Button>\n }\n />\n\n {/* RBAC Policies Table */}\n {filteredCount === 0 ? (\n searchTerm ? (\n <Trans>No policies match your search</Trans>\n ) : (\n <Trans>There are no RBAC policies for this security group</Trans>\n )\n ) : (\n <DataGrid columns={3}>\n <DataGridRow>\n <DataGridHeadCell>\n <Trans>Target Project ID</Trans>\n </DataGridHeadCell>\n <DataGridHeadCell>\n <Trans>Action</Trans>\n </DataGridHeadCell>\n <DataGridHeadCell>\n <Trans>Actions</Trans>\n </DataGridHeadCell>\n </DataGridRow>\n\n {filteredPolicies.map((policy) => (\n <RBACPolicyRow key={policy.id} policy={policy} onDelete={() => handleDeleteClick(policy)} />\n ))}\n </DataGrid>\n )}\n </Stack>\n\n {/* Delete Confirmation Dialog */}\n {!!policyToDelete && (\n <DeleteRBACPolicyDialog\n policy={policyToDelete}\n open={!!policyToDelete}\n onClose={handleCloseDeleteDialog}\n onConfirm={handleConfirmDelete}\n isLoading={deleteMutation.isPending}\n error={deleteMutation.error?.message || null}\n />\n )}\n\n {/* Add RBAC Policy Modal */}\n {isAddModalOpen && (\n <AddRBACPolicyModal isOpen={isAddModalOpen} onClose={toggleAddModal} securityGroupId={securityGroupId} />\n )}\n </>\n )\n}\n","import { Container, Stack } from \"@cloudoperators/juno-ui-components\"\nimport { useState } from \"react\"\nimport type {\n SecurityGroup,\n SecurityGroupRule,\n CreateSecurityGroupRuleInput,\n} from \"@/server/Network/types/securityGroup\"\nimport type { FilterSettings, SortSettings } from \"@/client/components/ListToolbar/types\"\nimport type { ListSortConfig } from \"@/client/utils/useListWithFiltering\"\nimport { SecurityGroupHeader, SecurityGroupBasicInfo, SecurityGroupTabs, type TabType } from \"./-details\"\nimport { SecurityGroupRulesTable } from \"./-details\"\nimport { SecurityGroupRBACPolicies } from \"./-details/SecurityGroupRBACPolicies\"\n\nexport interface RulesFilterControls {\n searchTerm: string\n onSearchChange: (term: string | number | string[] | undefined) => void\n sortSettings: ListSortConfig<\"direction\" | \"protocol\" | \"description\">\n onSortChange: (settings: SortSettings) => void\n filterSettings: FilterSettings\n onFilterChange: (settings: FilterSettings) => void\n}\n\ninterface SecurityGroupDetailsViewProps {\n securityGroup: SecurityGroup\n filteredAndSortedRules: SecurityGroupRule[]\n onEdit?: () => void\n onDeleteRule: (ruleId: string) => void\n isDeletingRule?: boolean\n deleteRuleError?: string | null\n filterControls: RulesFilterControls\n // Add rule functionality - passed through to SecurityGroupRulesTable\n onCreateRule?: (ruleData: Omit<CreateSecurityGroupRuleInput, \"project_id\">) => Promise<void>\n isCreatingRule?: boolean\n createRuleError?: string | null\n availableSecurityGroups?: Array<{ id: string; name: string | null }>\n currentProjectId: string\n}\n\nexport function SecurityGroupDetailsView({\n securityGroup,\n filteredAndSortedRules,\n onEdit,\n onDeleteRule,\n isDeletingRule = false,\n deleteRuleError = null,\n filterControls,\n onCreateRule,\n isCreatingRule = false,\n createRuleError = null,\n availableSecurityGroups = [],\n currentProjectId,\n}: SecurityGroupDetailsViewProps) {\n const [activeTab, setActiveTab] = useState<TabType>(\"rules\")\n\n // Determine if this is a shared security group (not owned by current project)\n const isOwner = securityGroup.project_id === currentProjectId\n const isShared = !isOwner\n const showRBACTab = isOwner\n\n return (\n <Container px={false} py>\n <Stack direction=\"vertical\" gap=\"4\">\n {/* Header Section */}\n <SecurityGroupHeader name={securityGroup.name} id={securityGroup.id} />\n\n {/* Basic Info Section */}\n <SecurityGroupBasicInfo securityGroup={securityGroup} onEdit={onEdit} isReadOnly={isShared} />\n\n {/* Tabs Navigation - Hide for shared security groups */}\n {!isShared && <SecurityGroupTabs activeTab={activeTab} onTabChange={setActiveTab} showRBACTab={showRBACTab} />}\n\n {/* Tab Content */}\n <div className=\"mt-6\">\n {activeTab === \"rules\" && (\n <SecurityGroupRulesTable\n rules={filteredAndSortedRules}\n totalRulesCount={securityGroup.security_group_rules?.length}\n onDeleteRule={onDeleteRule}\n isDeletingRule={isDeletingRule}\n deleteError={deleteRuleError}\n searchTerm={filterControls.searchTerm}\n onSearchChange={filterControls.onSearchChange}\n sortSettings={filterControls.sortSettings}\n onSortChange={filterControls.onSortChange}\n filterSettings={filterControls.filterSettings}\n onFilterChange={filterControls.onFilterChange}\n securityGroupId={securityGroup.id}\n onCreateRule={isShared ? undefined : onCreateRule}\n isCreatingRule={isCreatingRule}\n createRuleError={createRuleError}\n availableSecurityGroups={availableSecurityGroups}\n readOnly={isShared}\n />\n )}\n {activeTab === \"rbac\" && <SecurityGroupRBACPolicies securityGroupId={securityGroup.id} />}\n </div>\n </Stack>\n </Container>\n )\n}\n","import { useState, useMemo } from \"react\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useProjectId } from \"@/client/hooks\"\nimport type { UpdateSecurityGroupInput, CreateSecurityGroupRuleInput } from \"@/server/Network/types/securityGroup\"\nimport type { RulesFilterControls } from \"../-components/SecurityGroupDetailsView\"\n\ninterface UseSecurityGroupDetailsParams {\n securityGroupId: string\n filterControls: RulesFilterControls\n}\n\nexport function useSecurityGroupDetails({ securityGroupId, filterControls }: UseSecurityGroupDetailsParams) {\n const [editModalOpen, setEditModalOpen] = useState(false)\n const projectId = useProjectId()\n\n const utils = trpcReact.useUtils()\n\n // Query for security group\n // Use cached data from list page if available (instant loading)\n const securityGroupQuery = trpcReact.network.securityGroup.getById.useQuery(\n {\n project_id: projectId,\n securityGroupId,\n },\n {\n // Use cached data from list page as placeholder while fetching\n placeholderData: () => {\n return utils.network.securityGroup.getById.getData({ project_id: projectId, securityGroupId })\n },\n }\n )\n\n // Client-side filtering and sorting of rules\n const filteredAndSortedRules = useMemo(() => {\n const allRules = securityGroupQuery.data?.security_group_rules || []\n let result = allRules\n\n // Extract filters from filterSettings\n const directionFilter = filterControls.filterSettings.selectedFilters?.find((f) => f.name === \"direction\")?.value\n const ethertypeFilter = filterControls.filterSettings.selectedFilters?.find((f) => f.name === \"ethertype\")?.value\n const protocolFilter = filterControls.filterSettings.selectedFilters?.find((f) => f.name === \"protocol\")?.value\n\n // Filter by direction\n if (directionFilter && directionFilter !== \"all\") {\n result = result.filter((rule) => rule.direction === directionFilter)\n }\n\n // Filter by ethertype\n if (ethertypeFilter && ethertypeFilter !== \"all\") {\n result = result.filter((rule) => rule.ethertype === ethertypeFilter)\n }\n\n // Filter by protocol\n if (protocolFilter && protocolFilter !== \"all\") {\n result = result.filter((rule) => {\n // Handle null protocol as \"any\"\n if (rule.protocol === null) {\n return false\n }\n return rule.protocol === protocolFilter\n })\n }\n\n // Filter by search term\n if (filterControls.searchTerm) {\n const searchLower = filterControls.searchTerm.toLowerCase()\n result = result.filter(\n (rule) =>\n rule.description?.toLowerCase().includes(searchLower) ||\n rule.protocol?.toLowerCase().includes(searchLower) ||\n rule.ethertype?.toLowerCase().includes(searchLower)\n )\n }\n\n // Sort\n if (filterControls.sortSettings.sortBy) {\n const sortKey = filterControls.sortSettings.sortBy as \"direction\" | \"protocol\" | \"description\"\n result = [...result].sort((a, b) => {\n const aValue = (a[sortKey] || \"\") as string\n const bValue = (b[sortKey] || \"\") as string\n const comparison = aValue.localeCompare(bValue)\n return filterControls.sortSettings.sortDirection === \"asc\" ? comparison : -comparison\n })\n }\n\n return result\n }, [securityGroupQuery.data?.security_group_rules, filterControls])\n\n // Update mutation\n const updateMutation = trpcReact.network.securityGroup.update.useMutation({\n onSuccess: () => {\n utils.network.securityGroup.getById.invalidate({ project_id: projectId, securityGroupId })\n utils.network.securityGroup.list.invalidate()\n setEditModalOpen(false)\n },\n })\n\n // Delete rule mutation\n const deleteRuleMutation = trpcReact.network.securityGroupRule.delete.useMutation({\n onSuccess: () => {\n // Invalidate the security group query to refresh the rules list\n utils.network.securityGroup.getById.invalidate({ project_id: projectId, securityGroupId })\n utils.network.securityGroup.list.invalidate()\n },\n })\n\n // Create rule mutation\n const createRuleMutation = trpcReact.network.securityGroupRule.create.useMutation({\n onSuccess: () => {\n utils.network.securityGroup.getById.invalidate({ project_id: projectId, securityGroupId })\n utils.network.securityGroup.list.invalidate()\n },\n })\n\n // Handlers\n const handleEdit = () => {\n setEditModalOpen(true)\n }\n\n const handleCloseEditModal = () => {\n setEditModalOpen(false)\n }\n\n const handleUpdate = async (id: string, data: Omit<UpdateSecurityGroupInput, \"securityGroupId\" | \"project_id\">) => {\n await updateMutation.mutateAsync({\n project_id: projectId,\n securityGroupId: id,\n ...data,\n })\n }\n\n const handleDeleteRule = async (ruleId: string) => {\n await deleteRuleMutation.mutateAsync({ project_id: projectId, ruleId })\n }\n\n const handleCreateRule = async (ruleData: Omit<CreateSecurityGroupRuleInput, \"project_id\">) => {\n await createRuleMutation.mutateAsync({ project_id: projectId, ...ruleData })\n }\n\n return {\n // Data\n securityGroup: securityGroupQuery.data,\n filteredAndSortedRules,\n\n // Query states\n isLoading: securityGroupQuery.isPending,\n isError: securityGroupQuery.isError,\n error: securityGroupQuery.error,\n\n // Mutation states\n isUpdating: updateMutation.isPending,\n updateError: updateMutation.error?.message || null,\n isDeletingRule: deleteRuleMutation.isPending,\n deleteRuleError: deleteRuleMutation.error?.message || null,\n isCreatingRule: createRuleMutation.isPending,\n createRuleError: createRuleMutation.error?.message || null,\n\n // Modal states\n editModalOpen,\n\n // Handlers\n handleEdit,\n handleCloseEditModal,\n handleUpdate,\n handleDeleteRule,\n handleCreateRule,\n }\n}\n","import {\n Breadcrumb,\n BreadcrumbItem,\n Button,\n ContentHeading,\n Stack,\n Spinner,\n} from \"@cloudoperators/juno-ui-components/index\"\nimport { createFileRoute, redirect, useNavigate } from \"@tanstack/react-router\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { useMemo } from \"react\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport { useProjectId } from \"@/client/hooks\"\nimport { SecurityGroupDetailsView } from \"./-components/SecurityGroupDetailsView\"\nimport { EditSecurityGroupModal } from \"../-components/-modals/EditSecurityGroupModal\"\nimport { useSecurityGroupDetails } from \"./-hooks/useSecurityGroupDetails\"\nimport { useListWithFiltering } from \"@/client/utils/useListWithFiltering\"\nimport { trpcReact } from \"@/client/trpcClient\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/network/securitygroups/$securityGroupId/\")({\n staticData: {\n section: \"network\",\n service: \"securitygroups\",\n isDetail: true,\n sectionCrumb: { labelKey: \"Network\" },\n crumb: { labelKey: \"Security Groups\", to: \"/projects/$projectId/network/securitygroups\" },\n } satisfies RouteInfo,\n loader: async ({ context, params }) => {\n const sg = await context.trpcClient?.network.securityGroup.getById.query({\n project_id: params.projectId,\n securityGroupId: params.securityGroupId,\n })\n return { sgTitle: sg?.name || sg?.id || null }\n },\n head: ({ loaderData }) => ({\n meta: [{ title: loaderData?.sgTitle ?? \"Security Group\" }],\n }),\n component: RouteComponent,\n beforeLoad: async ({ context, params }) => {\n const { trpcClient } = context\n\n const availableServices = (await trpcClient?.auth.getAvailableServices.query()) || []\n\n const serviceIndex = getServiceIndex(availableServices)\n\n // Redirect to the \"Projects Overview\" page if network service not available\n if (!serviceIndex[\"network\"]) {\n throw redirect({\n to: \"/projects/$projectId/network/securitygroups\",\n params: { projectId: params.projectId },\n })\n }\n\n if (!serviceIndex[\"network\"][\"neutron\"]) {\n // Redirect to the \"Network Services Overview\" page if the \"Neutron\" service is not available\n throw redirect({\n to: \"/projects/$projectId/network/securitygroups\",\n params: { projectId: params.projectId },\n })\n }\n },\n})\n\nfunction RouteComponent() {\n const { securityGroupId } = Route.useParams()\n const projectId = useProjectId()\n const navigate = useNavigate()\n const { t } = useLingui()\n\n // Rules filtering using the same pattern as List page\n const {\n searchTerm: rulesSearchTerm,\n sortSettings,\n filterSettings,\n handleSearchChange,\n handleSortChange,\n handleFilterChange,\n } = useListWithFiltering<\"direction\" | \"protocol\" | \"description\">({\n defaultSortKey: \"direction\",\n defaultSortDir: \"asc\",\n sortOptions: [\n { label: t`Direction`, value: \"direction\" },\n { label: t`Protocol`, value: \"protocol\" },\n { label: t`Description`, value: \"description\" },\n ],\n filterSettings: {\n filters: [\n {\n displayName: t`Direction`,\n filterName: \"direction\",\n values: [\"ingress\", \"egress\"],\n supportsMultiValue: false,\n },\n {\n displayName: t`Ethertype`,\n filterName: \"ethertype\",\n values: [\"IPv4\", \"IPv6\"],\n supportsMultiValue: false,\n },\n {\n displayName: t`Protocol`,\n filterName: \"protocol\",\n values: [\"tcp\", \"udp\", \"icmp\", \"ipv6-icmp\"],\n supportsMultiValue: false,\n },\n ],\n },\n })\n\n // Group filter controls for the hook\n const filterControls = {\n searchTerm: rulesSearchTerm,\n onSearchChange: handleSearchChange,\n sortSettings,\n onSortChange: handleSortChange,\n filterSettings,\n onFilterChange: handleFilterChange,\n }\n\n // Use custom hook for logic (now includes filtering/sorting)\n const {\n securityGroup,\n filteredAndSortedRules,\n isLoading,\n isError,\n error,\n isUpdating,\n updateError,\n isDeletingRule,\n deleteRuleError,\n isCreatingRule,\n createRuleError,\n editModalOpen,\n handleEdit,\n handleCloseEditModal,\n handleUpdate,\n handleDeleteRule,\n handleCreateRule,\n } = useSecurityGroupDetails({\n securityGroupId,\n filterControls,\n })\n\n // Fetch available security groups for the Add Rule dropdown\n const { data: securityGroups } = trpcReact.network.securityGroup.list.useQuery({ project_id: projectId })\n const availableSecurityGroups = useMemo(() => {\n return (securityGroups || [])\n .filter((sg) => sg.id !== securityGroupId) // Exclude current group\n .map((sg) => ({\n id: sg.id,\n name: sg.name || sg.id,\n }))\n }, [securityGroups, securityGroupId])\n\n const handleBack = () => {\n navigate({\n to: \"/projects/$projectId/network/securitygroups\",\n params: { projectId },\n })\n }\n\n // Handle loading state\n if (isLoading) {\n return (\n <Stack className=\"fixed inset-0\" distribution=\"center\" alignment=\"center\" direction=\"vertical\">\n <Spinner variant=\"primary\" size=\"large\" className=\"mb-2\" />\n <Trans>Loading Security Group Details...</Trans>\n </Stack>\n )\n }\n\n // Handle error state\n if (isError) {\n const errorMessage = error?.message || \"Unknown error\"\n\n return (\n <Stack className=\"fixed inset-0\" distribution=\"center\" alignment=\"center\" direction=\"vertical\" gap=\"5\">\n <p className=\"text-theme-error font-semibold\">\n <Trans>Error loading security group</Trans>\n </p>\n <p className=\"text-theme-highest\">{errorMessage}</p>\n <Button onClick={handleBack} variant=\"primary\">\n <Trans>Back to Security Groups</Trans>\n </Button>\n </Stack>\n )\n }\n\n // Handle no data state\n if (!securityGroup) {\n return (\n <Stack className=\"fixed inset-0\" distribution=\"center\" alignment=\"center\" direction=\"vertical\" gap=\"5\">\n <p className=\"text-theme-secondary\">\n <Trans>Security group not found</Trans>\n </p>\n <Button onClick={handleBack} variant=\"primary\">\n <Trans>Back to Security Groups</Trans>\n </Button>\n </Stack>\n )\n }\n\n // Render success state\n return (\n <Stack direction=\"vertical\">\n <ContentHeading>{securityGroup.name || securityGroup.id}</ContentHeading>\n <Breadcrumb className=\"my-6\">\n <BreadcrumbItem onClick={handleBack} label={t`Security Groups`} />\n <BreadcrumbItem active label={securityGroup.id} />\n </Breadcrumb>\n\n <SecurityGroupDetailsView\n securityGroup={securityGroup}\n filteredAndSortedRules={filteredAndSortedRules}\n onEdit={handleEdit}\n onDeleteRule={handleDeleteRule}\n isDeletingRule={isDeletingRule}\n deleteRuleError={deleteRuleError}\n filterControls={filterControls}\n onCreateRule={handleCreateRule}\n isCreatingRule={isCreatingRule}\n createRuleError={createRuleError}\n availableSecurityGroups={availableSecurityGroups}\n currentProjectId={projectId}\n />\n\n <EditSecurityGroupModal\n securityGroup={securityGroup}\n open={editModalOpen}\n onClose={handleCloseEditModal}\n onUpdate={handleUpdate}\n isLoading={isUpdating}\n error={updateError}\n />\n </Stack>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"_securityGroupId-DYxmXUOP.mjs","names":["ContentHeading","SecurityGroupHeader","name","id","div","className","p","DataGrid","DataGridRow","DataGridCell","DataGridHeadCell","Button","SecurityGroupBasicInfo","securityGroup","onEdit","isReadOnly","useLingui","BooleanValue","value","span","t","div","className","variant","onClick","disabled","columns","gridColumnTemplate","colSpan","title","description","undefined","id","tags","join","name","stateful","project_id","shared","Stack","SecurityGroupTabs","activeTab","onTabChange","showRBACTab","getTabClassName","tab","baseClasses","activeClasses","inactiveClasses","div","className","direction","gap","button","onClick","useState","Modal","Button","ModalFooter","ButtonRow","Message","TextInput","DeleteRuleDialog","rule","open","onClose","onConfirm","isLoading","error","useLingui","confirmText","setConfirmText","handleConfirm","id","handleClose","isConfirmDisabled","onCancel","size","title","t","modalFooter","className","variant","onClick","disabled","data-testid","div","dismissible","p","ul","li","direction","description","ethertype","protocol","port_range_min","port_range_max","remote_ip_prefix","remote_group_id","strong","value","onChange","e","target","placeholder","autoComplete","detectCIDRFamily","cidr","includes","validatePortRange","portMin","portMax","protocol","isNaN","valid","error","isTcpUdp","toLowerCase","validateIcmpTypeCode","type","code","isValidCIDR","parts","split","length","address","prefixStr","test","prefix","parseInt","octets","octet","num","toString","hasDoubleColon","segments","filter","s","segment","doubleColonCount","match","startsWith","endsWith","DEFAULT_IPV4_CIDR","DEFAULT_IPV6_CIDR","CUSTOM_TCP_RULE","CUSTOM_UDP_RULE","OTHER_PROTOCOL_RULE","PORT_MODE_SINGLE","PORT_MODE_RANGE","PORT_MODE_ALL","PORT_MIN","PORT_MAX","ICMP_MIN","ICMP_MAX","z","validatePortRange","validateIcmpTypeCode","isValidCIDR","detectCIDRFamily","CUSTOM_TCP_RULE","CUSTOM_UDP_RULE","OTHER_PROTOCOL_RULE","ICMP_MIN","ICMP_MAX","createRuleFormSchema","object","ruleType","string","min","direction","enum","ethertype","description","protocol","nullable","portFrom","portTo","icmpType","icmpCode","remoteSourceType","remoteCidr","remoteSecurityGroupId","superRefine","data","ctx","isTcpUdp","isIcmp","isCustomProtocol","showPortFields","includes","addIssue","code","ZodIssueCode","custom","message","path","parseInt","isNaN","result","valid","error","cidrFamily","DEFAULT_IPV4_CIDR","DEFAULT_VALUES","ruleType","direction","ethertype","description","protocol","portFrom","portTo","icmpType","icmpCode","remoteSourceType","remoteCidr","remoteSecurityGroupId","RULE_PRESETS","value","label","protocol","portRangeMin","portRangeMax","FormRow","Select","SelectOption","RULE_PRESETS","RuleTypeSection","form","disabled","useLingui","Field","name","mode","field","className","id","label","t","value","state","onChange","newRuleType","String","handleChange","setFieldValue","selectedPreset","find","p","protocol","portRangeMin","portRangeMax","map","preset","FormRow","RadioGroup","Radio","DirectionSection","form","disabled","useLingui","Field","name","directionField","label","t","selected","state","value","onChange","handleChange","String","required","div","className","EthertypeSection","ethertypeField","FormRow","TextInput","ProtocolSection","form","disabled","useLingui","Field","name","field","className","id","label","t","value","state","onChange","e","handleChange","target","errortext","meta","errors","message","placeholder","FormRow","TextInput","useStore","PortRangeSection","form","disabled","useLingui","portFromValue","store","state","values","portFrom","portFromError","fieldMeta","errors","message","portToError","portTo","isPortToDisabled","trim","className","div","Field","name","portFromField","id","label","t","value","onChange","e","newValue","target","handleChange","setFieldValue","validateField","invalid","meta","length","required","portToField","placeholder","p","FormRow","TextInput","IcmpSection","form","disabled","useLingui","className","div","Field","name","icmpTypeField","id","label","t","value","state","onChange","e","handleChange","target","errortext","meta","errors","message","placeholder","icmpCodeField","FormRow","TextInput","Select","SelectOption","RadioGroup","Radio","DEFAULT_IPV4_CIDR","DEFAULT_IPV6_CIDR","RemoteSourceSection","form","disabled","availableSecurityGroups","useLingui","Field","name","mode","remoteSourceTypeField","className","label","t","selected","state","value","onChange","newValue","String","handleChange","setFieldValue","div","remoteCidrField","ethertypeField","id","e","target","errortext","meta","errors","message","placeholder","remoteSecurityGroupIdField","map","sg","FormRow","Textarea","DescriptionSection","form","disabled","useLingui","Field","name","field","className","id","label","t","value","state","onChange","e","handleChange","target","placeholder","rows","React","useForm","Modal","Form","FormSection","Button","ButtonRow","Spinner","ModalFooter","Message","createRuleFormSchema","DEFAULT_VALUES","CUSTOM_TCP_RULE","CUSTOM_UDP_RULE","OTHER_PROTOCOL_RULE","RuleTypeSection","DirectionSection","EthertypeSection","ProtocolSection","PortRangeSection","IcmpSection","RemoteSourceSection","DescriptionSection","createFormTypeHelper","defaultValues","validators","onSubmit","AddRuleModal","securityGroupId","open","onClose","onCreate","isLoading","error","availableSecurityGroups","useLingui","form","value","payload","security_group_id","direction","ethertype","description","undefined","protocol","remote_ip_prefix","remote_group_id","remote_address_group_id","isTcpUdp","portFrom","parseInt","port_range_min","portTo","port_range_max","isIcmp","icmpType","icmpCode","remoteSourceType","remoteCidr","remoteSecurityGroupId","handleClose","reset","onCancel","size","title","t","modalFooter","className","Subscribe","state","isRuleTypeSelected","Boolean","values","ruleType","variant","onClick","disabled","isSubmitting","type","handleSubmit","data-testid","dismissible","div","span","e","preventDefault","showPortFields","includes","showIcmpFields","useState","useEffect","DataGrid","DataGridHeadCell","DataGridRow","DataGridCell","Button","Stack","PopupMenu","PopupMenuItem","PopupMenuOptions","DeleteRuleDialog","AddRuleModal","ListToolbar","useModal","SecurityGroupRulesTable","rules","totalRulesCount","onDeleteRule","isDeletingRule","deleteError","searchTerm","onSearchChange","sortSettings","onSortChange","filterSettings","onFilterChange","securityGroupId","onCreateRule","isCreatingRule","createRuleError","availableSecurityGroups","readOnly","useLingui","ruleToDelete","setRuleToDelete","isAddRuleModalOpen","toggleAddRuleModal","handleDeleteClick","rule","handleConfirmDelete","ruleId","handleCloseDeleteDialog","formatPortRange","protocol","port_range_min","port_range_max","typeValue","codeValue","t","String","direction","gap","totalCount","length","filteredCount","itemName","onFilter","onSort","onSearch","actions","variant","icon","onClick","columns","className","map","data-testid","id","description","ethertype","e","stopPropagation","label","open","onClose","onConfirm","isLoading","error","onCreate","DataGridRow","DataGridCell","PopupMenu","PopupMenuItem","PopupMenuOptions","RBACPolicyRow","policy","onDelete","useLingui","target_tenant","action","onClick","e","stopPropagation","className","label","t","z","useState","useForm","Modal","Form","FormSection","TextInput","Message","trpcReact","useProjectId","UUID_WITH_DASHES","UUID_WITHOUT_DASHES","isValidProjectID","value","test","AddRBACPolicyModal","isOpen","onClose","securityGroupId","useLingui","utils","useUtils","projectId","hasSubmitted","setHasSubmitted","formSchema","object","targetTenant","string","min","t","refine","message","createMutation","network","rbacPolicy","create","useMutation","onSuccess","list","invalidate","project_id","securityGroup","getById","handleClose","form","defaultValues","validators","onSubmit","isPending","mutate","trim","reset","handleConfirm","handleSubmit","open","onCancel","title","size","onConfirm","cancelButtonLabel","confirmButtonLabel","disableConfirmButton","error","variant","className","toLowerCase","includes","p","e","preventDefault","Field","name","onBlur","trimmedValue","undefined","onChange","children","field","showError","state","meta","isTouched","errors","length","firstError","errorMessage","id","label","handleChange","target","handleBlur","placeholder","required","helptext","disabled","errortext","invalid","z","useForm","useStore","Modal","Message","TextInput","Form","FormSection","DeleteRBACPolicyDialog","policy","open","onClose","onConfirm","isLoading","error","useLingui","formSchema","object","confirmText","string","refine","value","message","t","form","defaultValues","validators","onSubmit","id","handleClose","canRemove","store","state","isSubmitting","values","reset","onCancel","size","title","handleSubmit","cancelButtonLabel","confirmButtonLabel","disableConfirmButton","div","dismissible","variant","className","p","ul","li","target_tenant","action","object_type","e","preventDefault","strong","Field","name","children","field","onChange","handleChange","target","placeholder","autoComplete","disabled","data-testid","useState","useEffect","useMemo","DataGrid","DataGridRow","DataGridHeadCell","Stack","Spinner","Button","Message","trpcReact","useProjectId","RBACPolicyRow","AddRBACPolicyModal","DeleteRBACPolicyDialog","ListToolbar","useModal","SecurityGroupRBACPolicies","securityGroupId","utils","useUtils","useLingui","projectId","isAddModalOpen","toggleAddModal","policyToDelete","setPolicyToDelete","searchTerm","setSearchTerm","data","policies","isPending","isError","error","network","rbacPolicy","list","useQuery","project_id","refetchOnWindowFocus","deleteMutation","delete","useMutation","onSuccess","invalidate","securityGroup","getById","handleDeleteClick","policy","handleConfirmDelete","policyId","mutate","handleCloseDeleteDialog","isSuccess","filteredPolicies","searchLower","toLowerCase","filter","target_tenant","includes","action","handleSearchChange","value","searchValue","distribution","alignment","className","variant","message","totalCount","length","filteredCount","direction","gap","itemName","t","onSearch","actions","icon","onClick","columns","map","onDelete","id","open","onClose","onConfirm","isLoading","isOpen","Container","Stack","useState","SecurityGroupHeader","SecurityGroupBasicInfo","SecurityGroupTabs","SecurityGroupRulesTable","SecurityGroupRBACPolicies","SecurityGroupDetailsView","securityGroup","filteredAndSortedRules","onEdit","onDeleteRule","isDeletingRule","deleteRuleError","filterControls","onCreateRule","isCreatingRule","createRuleError","availableSecurityGroups","currentProjectId","activeTab","setActiveTab","isOwner","project_id","isShared","showRBACTab","px","py","direction","gap","name","id","isReadOnly","onTabChange","div","className","rules","totalRulesCount","security_group_rules","length","deleteError","searchTerm","onSearchChange","sortSettings","onSortChange","filterSettings","onFilterChange","securityGroupId","undefined","readOnly","useState","useMemo","trpcReact","useProjectId","useSecurityGroupDetails","securityGroupId","filterControls","editModalOpen","setEditModalOpen","projectId","utils","useUtils","securityGroupQuery","network","securityGroup","getById","useQuery","project_id","placeholderData","getData","filteredAndSortedRules","allRules","data","security_group_rules","result","directionFilter","filterSettings","selectedFilters","find","f","name","value","ethertypeFilter","protocolFilter","filter","rule","direction","ethertype","protocol","searchTerm","searchLower","toLowerCase","description","includes","sortSettings","sortBy","sortKey","sort","a","b","aValue","bValue","comparison","localeCompare","sortDirection","updateMutation","update","useMutation","onSuccess","invalidate","list","deleteRuleMutation","securityGroupRule","delete","createRuleMutation","create","handleEdit","handleCloseEditModal","handleUpdate","id","mutateAsync","handleDeleteRule","ruleId","handleCreateRule","ruleData","isLoading","isPending","isError","error","isUpdating","updateError","message","isDeletingRule","deleteRuleError","isCreatingRule","createRuleError","Breadcrumb","BreadcrumbItem","Button","ContentHeading","Stack","Spinner","useNavigate","Trans","useLingui","useMemo","useProjectId","SecurityGroupDetailsView","EditSecurityGroupModal","useSecurityGroupDetails","useListWithFiltering","trpcReact","Route","RouteComponent","securityGroupId","useParams","projectId","navigate","t","searchTerm","rulesSearchTerm","sortSettings","filterSettings","handleSearchChange","handleSortChange","handleFilterChange","defaultSortKey","defaultSortDir","sortOptions","label","value","filters","displayName","filterName","values","supportsMultiValue","filterControls","onSearchChange","onSortChange","onFilterChange","securityGroup","filteredAndSortedRules","isLoading","isError","error","isUpdating","updateError","isDeletingRule","deleteRuleError","isCreatingRule","createRuleError","editModalOpen","handleEdit","handleCloseEditModal","handleUpdate","handleDeleteRule","handleCreateRule","data","securityGroups","network","list","useQuery","project_id","availableSecurityGroups","filter","sg","id","map","name","handleBack","to","params","errorMessage","message","component"],"sources":["../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-components/-details/SecurityGroupHeader.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-components/-details/SecurityGroupBasicInfo.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-components/-details/SecurityGroupTabs.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/DeleteRuleDialog.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/validation/validationHelpers.ts","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/constants.ts","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/validation/formSchema.ts","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/types.ts","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/rulePresets.ts","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/sections/RuleTypeSection.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/sections/DirectionEthertypeSection.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/sections/ProtocolSection.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/sections/PortRangeSection.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/sections/IcmpSection.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/sections/RemoteSourceSection.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/sections/DescriptionSection.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRuleModal/AddRuleModal.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-components/-details/SecurityGroupRulesTable.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-components/-details/RBACPolicyRow.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/AddRBACPolicyModal.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-modals/DeleteRBACPolicyDialog.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-components/-details/SecurityGroupRBACPolicies.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-components/SecurityGroupDetailsView.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/-hooks/useSecurityGroupDetails.ts","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/$securityGroupId/index.tsx?tsr-split=component"],"sourcesContent":["import { ContentHeading } from \"@cloudoperators/juno-ui-components\"\nimport { Trans } from \"@lingui/react/macro\"\n\ninterface SecurityGroupHeaderProps {\n name?: string | null\n id: string\n}\n\nexport function SecurityGroupHeader({ name, id }: SecurityGroupHeaderProps) {\n return (\n <div className=\"mb-2\">\n <ContentHeading>{`'${name || id}' Details`}</ContentHeading>\n <p className=\"text-theme-secondary mt-2 text-sm\">\n <Trans>\n Configure the ingress and egress rules that control which traffic is allowed for this security group.\n </Trans>\n </p>\n </div>\n )\n}\n","import { DataGrid, DataGridRow, DataGridCell, DataGridHeadCell, Button } from \"@cloudoperators/juno-ui-components\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport type { SecurityGroup } from \"@/server/Network/types/securityGroup\"\n\ninterface SecurityGroupBasicInfoProps {\n securityGroup: SecurityGroup\n onEdit?: () => void\n isReadOnly?: boolean\n}\n\nexport function SecurityGroupBasicInfo({ securityGroup, onEdit, isReadOnly = false }: SecurityGroupBasicInfoProps) {\n const { t } = useLingui()\n\n const BooleanValue = ({ value }: { value: boolean | undefined }) => <span>{value ? t`Yes` : t`No`}</span>\n\n return (\n <div>\n <div className=\"mb-4 flex flex-row-reverse\">\n {onEdit && !isReadOnly && (\n <Button variant=\"primary\" onClick={onEdit} disabled={isReadOnly}>\n <Trans>Edit</Trans>\n </Button>\n )}\n </div>\n\n <DataGrid columns={4} gridColumnTemplate=\"15% 35% 15% 35%\">\n <DataGridRow>\n <DataGridHeadCell>{t`Description`}</DataGridHeadCell>\n <DataGridCell colSpan={3}>\n <div\n className=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n title={securityGroup.description || undefined}\n >\n {securityGroup.description || t`—`}\n </div>\n </DataGridCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridHeadCell>{t`ID`}</DataGridHeadCell>\n <DataGridCell>\n <div className=\"overflow-hidden text-ellipsis whitespace-nowrap\" title={securityGroup.id}>\n {securityGroup.id}\n </div>\n </DataGridCell>\n <DataGridHeadCell>{t`Tags`}</DataGridHeadCell>\n <DataGridCell>\n <div\n className=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n title={securityGroup.tags?.join(\", \") || undefined}\n >\n {securityGroup.tags?.join(\", \") || t`—`}\n </div>\n </DataGridCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridHeadCell>{t`Name`}</DataGridHeadCell>\n <DataGridCell>\n <div className=\"overflow-hidden text-ellipsis whitespace-nowrap\" title={securityGroup.name || undefined}>\n {securityGroup.name}\n </div>\n </DataGridCell>\n <DataGridHeadCell>{t`Stateful`}</DataGridHeadCell>\n <DataGridCell>\n <BooleanValue value={securityGroup.stateful} />\n </DataGridCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridHeadCell>{t`Owning Project ID`}</DataGridHeadCell>\n <DataGridCell>\n <div\n className=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n title={securityGroup.project_id || undefined}\n >\n {securityGroup.project_id || t`—`}\n </div>\n </DataGridCell>\n <DataGridHeadCell>{t`Shared`}</DataGridHeadCell>\n <DataGridCell>\n <BooleanValue value={securityGroup.shared} />\n </DataGridCell>\n </DataGridRow>\n </DataGrid>\n </div>\n )\n}\n","import { Stack } from \"@cloudoperators/juno-ui-components\"\nimport { Trans } from \"@lingui/react/macro\"\n\nexport type TabType = \"rules\" | \"rbac\"\n\ninterface SecurityGroupTabsProps {\n activeTab: TabType\n onTabChange: (tab: TabType) => void\n showRBACTab?: boolean\n}\n\nexport function SecurityGroupTabs({ activeTab, onTabChange, showRBACTab = true }: SecurityGroupTabsProps) {\n const getTabClassName = (tab: TabType) => {\n const baseClasses = \"px-6 py-3 font-semibold border-b-2 transition-colors\"\n const activeClasses = \"border-theme-accent text-theme-highest\"\n const inactiveClasses = \"border-transparent text-theme-secondary hover:text-theme-high\"\n\n return `${baseClasses} ${activeTab === tab ? activeClasses : inactiveClasses}`\n }\n\n return (\n <div className=\"border-theme-background-lvl-3 mt-1 border-b\">\n <Stack direction=\"horizontal\" gap=\"0\">\n <button className={getTabClassName(\"rules\")} onClick={() => onTabChange(\"rules\")}>\n <Trans>Rules</Trans>\n </button>\n {showRBACTab && (\n <button className={getTabClassName(\"rbac\")} onClick={() => onTabChange(\"rbac\")}>\n <Trans>RBAC Policies</Trans>\n </button>\n )}\n </Stack>\n </div>\n )\n}\n","import { useState } from \"react\"\nimport { Modal, Button, ModalFooter, ButtonRow, Message, TextInput } from \"@cloudoperators/juno-ui-components\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport type { SecurityGroupRule } from \"@/server/Network/types/securityGroup\"\n\ninterface DeleteRuleDialogProps {\n rule: SecurityGroupRule | null\n open: boolean\n onClose: () => void\n onConfirm: (ruleId: string) => void\n isLoading: boolean\n error: string | null\n}\n\nexport function DeleteRuleDialog({ rule, open, onClose, onConfirm, isLoading, error }: DeleteRuleDialogProps) {\n const { t } = useLingui()\n const [confirmText, setConfirmText] = useState(\"\")\n\n const handleConfirm = () => {\n if (rule && confirmText === \"delete\") {\n onConfirm(rule.id)\n }\n }\n\n const handleClose = () => {\n setConfirmText(\"\")\n onClose()\n }\n\n const isConfirmDisabled = confirmText !== \"delete\" || isLoading\n\n if (!rule) return null\n\n return (\n <Modal\n open={open}\n onCancel={handleClose}\n size=\"small\"\n title={t`Delete Security Group Rule`}\n modalFooter={\n <ModalFooter className=\"flex justify-end\">\n <ButtonRow>\n <Button variant=\"default\" onClick={handleClose} disabled={isLoading}>\n <Trans>Cancel</Trans>\n </Button>\n <Button\n variant=\"primary-danger\"\n onClick={handleConfirm}\n disabled={isConfirmDisabled}\n data-testid=\"confirm-delete-rule-button\"\n >\n {isLoading ? <Trans>Deleting...</Trans> : <Trans>Delete Rule</Trans>}\n </Button>\n </ButtonRow>\n </ModalFooter>\n }\n >\n <div>\n {/* Error Message */}\n {error && (\n <Message dismissible={false} variant=\"error\" className=\"mt-4\">\n {error}\n </Message>\n )}\n\n {/* Warning */}\n <Trans>This action cannot be undone. The rule will be permanently deleted.</Trans>\n\n {/* Rule Details */}\n <div className=\"bg-theme-background-lvl-1 mt-4 mb-4 rounded p-4\">\n <p className=\"mb-2 font-semibold\">\n <Trans>Rule Details:</Trans>\n </p>\n <ul className=\"list-inside list-disc space-y-1 text-sm\">\n <li>\n <Trans>Direction</Trans>: {rule.direction}\n </li>\n {rule.description && (\n <li>\n <Trans>Description</Trans>: {rule.description}\n </li>\n )}\n <li>\n <Trans>Ethertype</Trans>: {rule.ethertype}\n </li>\n {rule.protocol && (\n <li>\n <Trans>Protocol</Trans>: {rule.protocol}\n </li>\n )}\n {rule.port_range_min !== null && rule.port_range_max !== null && (\n <li>\n <Trans>Port Range</Trans>:{\" \"}\n {rule.port_range_min === rule.port_range_max\n ? rule.port_range_min\n : `${rule.port_range_min}-${rule.port_range_max}`}\n </li>\n )}\n {rule.remote_ip_prefix && (\n <li>\n <Trans>Remote IP</Trans>: {rule.remote_ip_prefix}\n </li>\n )}\n {rule.remote_group_id && (\n <li>\n <Trans>Remote Security Group</Trans>: {rule.remote_group_id}\n </li>\n )}\n </ul>\n </div>\n\n {/* Confirmation Input */}\n <div className=\"mt-4\">\n <p className=\"mb-2 text-sm\">\n <Trans>\n Type <strong>delete</strong> to confirm:\n </Trans>\n </p>\n <TextInput\n value={confirmText}\n onChange={(e) => setConfirmText(e.target.value)}\n placeholder={t`delete`}\n autoComplete=\"off\"\n disabled={isLoading}\n data-testid=\"delete-rule-confirmation-input\"\n />\n </div>\n </div>\n </Modal>\n )\n}\n","/**\n * Security Group Rule Validation Utilities\n *\n * These utilities are used for frontend validation of security group rules.\n * They provide consistent validation logic for CIDR notation, port ranges, and ICMP values.\n */\n\n/**\n * Detects CIDR family (IPv4 or IPv6) from CIDR notation.\n * Returns \"IPv4\" if CIDR contains \".\", \"IPv6\" if contains \":\", or null if neither.\n */\nexport function detectCIDRFamily(cidr: string): \"IPv4\" | \"IPv6\" | null {\n if (cidr.includes(\".\")) {\n return \"IPv4\"\n }\n if (cidr.includes(\":\")) {\n return \"IPv6\"\n }\n return null\n}\n\n/**\n * Validates port numbers for security group rules.\n * For TCP/UDP: ports must be 1-65535\n * For other protocols: ports can be 0-65535\n * Also validates that min <= max when both are provided.\n * Handles NaN values by rejecting them.\n */\nexport function validatePortRange(\n portMin: number | null | undefined,\n portMax: number | null | undefined,\n protocol: string | null | undefined\n): { valid: boolean; error?: string } {\n // Check for NaN values\n if (portMin != null && isNaN(portMin)) {\n return { valid: false, error: \"Port must be a valid number\" }\n }\n if (portMax != null && isNaN(portMax)) {\n return { valid: false, error: \"Port must be a valid number\" }\n }\n\n const isTcpUdp = protocol?.toLowerCase() === \"tcp\" || protocol?.toLowerCase() === \"udp\"\n\n // For TCP/UDP, ports must be 1-65535\n if (isTcpUdp) {\n if (portMin != null && (portMin < 1 || portMin > 65535)) {\n return { valid: false, error: \"For TCP/UDP: port must be between 1 and 65535\" }\n }\n if (portMax != null && (portMax < 1 || portMax > 65535)) {\n return { valid: false, error: \"For TCP/UDP: port must be between 1 and 65535\" }\n }\n } else {\n // For other protocols, allow 0-65535\n if (portMin != null && (portMin < 0 || portMin > 65535)) {\n return { valid: false, error: \"Port must be between 0 and 65535\" }\n }\n if (portMax != null && (portMax < 0 || portMax > 65535)) {\n return { valid: false, error: \"Port must be between 0 and 65535\" }\n }\n }\n\n // Validate min <= max for all protocols\n if (portMin != null && portMax != null && portMin > portMax) {\n return { valid: false, error: \"port_range_min must be less than or equal to port_range_max\" }\n }\n\n return { valid: true }\n}\n\n/**\n * Validates ICMP type and code values (0-255 for both).\n * Handles NaN values by rejecting them.\n */\nexport function validateIcmpTypeCode(\n type: number | null | undefined,\n code: number | null | undefined\n): { valid: boolean; error?: string } {\n // Check for NaN values\n if (type != null && isNaN(type)) {\n return { valid: false, error: \"ICMP type must be a valid number\" }\n }\n if (code != null && isNaN(code)) {\n return { valid: false, error: \"ICMP code must be a valid number\" }\n }\n\n if (type != null && (type < 0 || type > 255)) {\n return { valid: false, error: \"ICMP type must be between 0 and 255\" }\n }\n\n if (code != null && (code < 0 || code > 255)) {\n return { valid: false, error: \"ICMP code must be between 0 and 255\" }\n }\n\n return { valid: true }\n}\n\n/**\n * Validates CIDR notation for IPv4 and IPv6 addresses.\n * - IPv4: octets must be 0-255, prefix length must be 0-32\n * - IPv6: proper hexadecimal format with colons, prefix length must be 0-128\n */\nexport function isValidCIDR(cidr: string): boolean {\n const parts = cidr.split(\"/\")\n if (parts.length !== 2) {\n return false\n }\n\n const [address, prefixStr] = parts\n\n // Validate prefix is digits-only (reject \"24foo\", \"24a\", etc.)\n if (!/^\\d+$/.test(prefixStr)) {\n return false\n }\n\n const prefix = parseInt(prefixStr, 10)\n\n // Check if prefix is a valid number\n if (isNaN(prefix) || prefix < 0) {\n return false\n }\n\n // Check for IPv4\n if (address.includes(\".\")) {\n // Validate IPv4 address format\n const octets = address.split(\".\")\n if (octets.length !== 4) {\n return false\n }\n\n // Validate each octet is 0-255\n for (const octet of octets) {\n const num = parseInt(octet, 10)\n if (isNaN(num) || num < 0 || num > 255 || octet !== num.toString()) {\n return false\n }\n }\n\n // Validate prefix length for IPv4 (0-32)\n return prefix <= 32\n }\n\n // Check for IPv6\n if (address.includes(\":\")) {\n // Reject malformed triple-colon addresses (e.g., \":::\")\n if (address.includes(\":::\")) {\n return false\n }\n\n // Validate prefix length for IPv6 (0-128)\n if (prefix > 128) {\n return false\n }\n\n // Basic IPv6 validation\n // Allow :: for compressed zeros\n const hasDoubleColon = address.includes(\"::\")\n const segments = address.split(\":\").filter((s) => s !== \"\")\n\n // IPv6 should have at most 8 segments (or fewer if :: is used)\n if (hasDoubleColon) {\n // With ::, we can have 0-7 segments\n if (segments.length > 7) {\n return false\n }\n } else {\n // Without ::, we must have exactly 8 segments\n if (segments.length !== 8) {\n return false\n }\n }\n\n // Validate each segment is valid hex (0-ffff)\n for (const segment of segments) {\n if (segment.length === 0 || segment.length > 4) {\n return false\n }\n if (!/^[0-9a-fA-F]+$/.test(segment)) {\n return false\n }\n }\n\n // Check for valid :: usage (only one occurrence)\n const doubleColonCount = (address.match(/::/g) || []).length\n if (doubleColonCount > 1) {\n return false\n }\n\n // Check for leading/trailing single colons (invalid unless part of ::)\n if (address.startsWith(\":\") && !address.startsWith(\"::\")) {\n return false\n }\n if (address.endsWith(\":\") && !address.endsWith(\"::\")) {\n return false\n }\n\n return true\n }\n\n return false\n}\n","// Default CIDR values\nexport const DEFAULT_IPV4_CIDR = \"0.0.0.0/0\"\nexport const DEFAULT_IPV6_CIDR = \"::/0\"\n\n// Custom rule type identifiers\nexport const CUSTOM_TCP_RULE = \"custom-tcp\"\nexport const CUSTOM_UDP_RULE = \"custom-udp\"\nexport const OTHER_PROTOCOL_RULE = \"other-protocol\"\n\n// Port modes\nexport const PORT_MODE_SINGLE = \"single\" as const\nexport const PORT_MODE_RANGE = \"range\" as const\nexport const PORT_MODE_ALL = \"all\" as const\n\n// Validation ranges\nexport const PORT_MIN = 1\nexport const PORT_MAX = 65535\nexport const ICMP_MIN = 0\nexport const ICMP_MAX = 255\n","import { z } from \"zod\"\nimport { validatePortRange, validateIcmpTypeCode, isValidCIDR, detectCIDRFamily } from \"./validationHelpers\"\nimport { CUSTOM_TCP_RULE, CUSTOM_UDP_RULE, OTHER_PROTOCOL_RULE, ICMP_MIN, ICMP_MAX } from \"../constants\"\n\n/**\n * Zod schema for AddRuleModal form validation.\n *\n * This schema validates all fields in the Add Rule form with conditional validation\n * based on protocol type, rule type, and other field dependencies.\n *\n * All validation logic is performed on the frontend to provide immediate feedback\n * and reduce server roundtrips. The backend only performs type checking.\n */\nexport const createRuleFormSchema = z\n .object({\n // Rule preset selector (UI only, affects which fields are populated)\n ruleType: z.string().min(1, \"Rule type is required\"),\n\n // Required fields - always present\n direction: z.enum([\"ingress\", \"egress\"]),\n ethertype: z.enum([\"IPv4\", \"IPv6\"]),\n\n // Optional description\n description: z.string(),\n\n // Protocol field - string for custom protocols, null for none\n protocol: z.string().nullable(),\n\n // Port-related fields (strings in form, converted to numbers during validation)\n portFrom: z.string(),\n portTo: z.string(),\n\n // ICMP fields (strings in form, converted to numbers during validation)\n icmpType: z.string(),\n icmpCode: z.string(),\n\n // Remote source configuration\n remoteSourceType: z.enum([\"cidr\", \"security_group\"]),\n remoteCidr: z.string(),\n remoteSecurityGroupId: z.string(),\n })\n .superRefine((data, ctx) => {\n // Determine which validations apply based on protocol and rule type\n const isTcpUdp = data.protocol === \"tcp\" || data.protocol === \"udp\"\n const isIcmp = data.protocol === \"icmp\" || data.protocol === \"ipv6-icmp\"\n const isCustomProtocol = data.ruleType === OTHER_PROTOCOL_RULE\n const showPortFields = isTcpUdp && [CUSTOM_TCP_RULE, CUSTOM_UDP_RULE].includes(data.ruleType)\n\n // Validation 1: Protocol is required for \"other-protocol\" rule type\n if (isCustomProtocol && !data.protocol) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Protocol is required\",\n path: [\"protocol\"],\n })\n }\n\n // Validation 2: Port validation (only if port fields are visible)\n if (showPortFields) {\n // Port (from) is always required\n if (!data.portFrom) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Port (from) is required\",\n path: [\"portFrom\"],\n })\n } else {\n const portFrom = parseInt(data.portFrom, 10)\n if (isNaN(portFrom)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Port must be a valid number\",\n path: [\"portFrom\"],\n })\n } else {\n // If Port (to) is empty, validate portFrom as single port\n if (!data.portTo) {\n const result = validatePortRange(portFrom, portFrom, data.protocol)\n if (!result.valid) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: result.error || \"Invalid port\",\n path: [\"portFrom\"],\n })\n }\n } else {\n // Both ports are provided - validate as range\n const portTo = parseInt(data.portTo, 10)\n if (isNaN(portTo)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Port must be a valid number\",\n path: [\"portTo\"],\n })\n } else {\n // Check that portFrom < portTo\n if (portFrom >= portTo) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: '\"Port (from)\" must be less than \"Port (to)\"',\n path: [\"portFrom\"],\n })\n } else {\n // Validate the range\n const result = validatePortRange(portFrom, portTo, data.protocol)\n if (!result.valid) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: result.error || \"Invalid port range\",\n path: [\"portFrom\"],\n })\n }\n }\n }\n }\n }\n }\n }\n\n // Validation 3: ICMP validation (only if ICMP protocol is selected)\n if (isIcmp) {\n // Parse values\n const icmpType = data.icmpType ? parseInt(data.icmpType, 10) : null\n const icmpCode = data.icmpCode ? parseInt(data.icmpCode, 10) : null\n\n // Step 1: Check for NaN values FIRST (early validation)\n if (data.icmpType && isNaN(icmpType!)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"ICMP type must be a valid number\",\n path: [\"icmpType\"],\n })\n }\n\n if (data.icmpCode && isNaN(icmpCode!)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"ICMP code must be a valid number\",\n path: [\"icmpCode\"],\n })\n }\n\n // Step 2: Check OpenStack requirement (Type required when Code is specified)\n // https://opendev.org/openstack/neutron/src/branch/master/neutron/db/securitygroups_db.py\n if (data.icmpCode && !data.icmpType) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"ICMP type is required when ICMP code is specified\",\n path: [\"icmpType\"],\n })\n }\n\n // Step 3: Use helper function for range validation (0-255)\n // Now we know values are valid numbers (or null)\n if (icmpType !== null || icmpCode !== null) {\n const result = validateIcmpTypeCode(icmpType, icmpCode)\n if (!result.valid) {\n // Parse error message to target specific fields\n if (result.error?.includes(\"type\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `ICMP type must be between ${ICMP_MIN} and ${ICMP_MAX}`,\n path: [\"icmpType\"],\n })\n }\n if (result.error?.includes(\"code\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `ICMP code must be between ${ICMP_MIN} and ${ICMP_MAX}`,\n path: [\"icmpCode\"],\n })\n }\n }\n }\n }\n\n // Validation 4: CIDR validation (only if CIDR remote source is selected)\n if (data.remoteSourceType === \"cidr\" && data.remoteCidr) {\n // Validate CIDR format\n if (!isValidCIDR(data.remoteCidr)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Invalid CIDR format. Examples: 0.0.0.0/0 (IPv4) or ::/0 (IPv6)\",\n path: [\"remoteCidr\"],\n })\n } else {\n // Validate ethertype matches CIDR family\n const cidrFamily = detectCIDRFamily(data.remoteCidr)\n if (cidrFamily && cidrFamily !== data.ethertype) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `CIDR family (${cidrFamily}) must match Ethertype (${data.ethertype})`,\n path: [\"remoteCidr\"],\n })\n }\n }\n }\n })\n\n/**\n * Type definition inferred from the Zod schema.\n * This ensures type safety between form values and validation schema.\n */\nexport type AddRuleFormValues = z.infer<typeof createRuleFormSchema>\n","import { DEFAULT_IPV4_CIDR } from \"./constants\"\nimport type { AddRuleFormValues } from \"./validation/formSchema\"\n\nexport const DEFAULT_VALUES: AddRuleFormValues = {\n ruleType: \"\",\n direction: \"ingress\",\n ethertype: \"IPv4\",\n description: \"\",\n protocol: null,\n portFrom: \"\",\n portTo: \"\",\n icmpType: \"\",\n icmpCode: \"\",\n remoteSourceType: \"cidr\",\n remoteCidr: DEFAULT_IPV4_CIDR,\n remoteSecurityGroupId: \"\",\n}\n","export interface RulePreset {\n value: string\n label: string\n protocol: string | null\n portRangeMin: number | null\n portRangeMax: number | null\n}\n\nexport const RULE_PRESETS: RulePreset[] = [\n // Empty default option - label rendered in UI with translation\n {\n value: \"\",\n label: \"\", // Rendered in RuleTypeSection with t()\n protocol: null,\n portRangeMin: null,\n portRangeMax: null,\n },\n // Custom rules (appears first)\n {\n value: \"custom-tcp\",\n label: \"Custom TCP Rule\",\n protocol: \"tcp\",\n portRangeMin: null,\n portRangeMax: null,\n },\n {\n value: \"custom-udp\",\n label: \"Custom UDP Rule\",\n protocol: \"udp\",\n portRangeMin: null,\n portRangeMax: null,\n },\n {\n value: \"custom-icmp\",\n label: \"Custom ICMP Rule\",\n protocol: \"icmp\",\n portRangeMin: null,\n portRangeMax: null,\n },\n {\n value: \"all-tcp\",\n label: \"All TCP\",\n protocol: \"tcp\",\n portRangeMin: 1,\n portRangeMax: 65535,\n },\n {\n value: \"all-udp\",\n label: \"All UDP\",\n protocol: \"udp\",\n portRangeMin: 1,\n portRangeMax: 65535,\n },\n {\n value: \"all-icmp\",\n label: \"All ICMP\",\n protocol: \"icmp\",\n portRangeMin: null,\n portRangeMax: null,\n },\n {\n value: \"other-protocol\",\n label: \"Other Protocol\",\n protocol: null,\n portRangeMin: null,\n portRangeMax: null,\n },\n\n // Common protocols\n {\n value: \"dns\",\n label: \"DNS\",\n protocol: \"tcp\",\n portRangeMin: 53,\n portRangeMax: 53,\n },\n {\n value: \"http\",\n label: \"HTTP\",\n protocol: \"tcp\",\n portRangeMin: 80,\n portRangeMax: 80,\n },\n {\n value: \"https\",\n label: \"HTTPS\",\n protocol: \"tcp\",\n portRangeMin: 443,\n portRangeMax: 443,\n },\n {\n value: \"imap\",\n label: \"IMAP\",\n protocol: \"tcp\",\n portRangeMin: 143,\n portRangeMax: 143,\n },\n {\n value: \"imaps\",\n label: \"IMAPS\",\n protocol: \"tcp\",\n portRangeMin: 993,\n portRangeMax: 993,\n },\n {\n value: \"ldap\",\n label: \"LDAP\",\n protocol: \"tcp\",\n portRangeMin: 389,\n portRangeMax: 389,\n },\n {\n value: \"ms-sql\",\n label: \"MS SQL\",\n protocol: \"tcp\",\n portRangeMin: 1433,\n portRangeMax: 1433,\n },\n {\n value: \"mysql\",\n label: \"MySQL\",\n protocol: \"tcp\",\n portRangeMin: 3306,\n portRangeMax: 3306,\n },\n {\n value: \"pop3\",\n label: \"POP3\",\n protocol: \"tcp\",\n portRangeMin: 110,\n portRangeMax: 110,\n },\n {\n value: \"pop3s\",\n label: \"POP3S\",\n protocol: \"tcp\",\n portRangeMin: 995,\n portRangeMax: 995,\n },\n {\n value: \"rdp\",\n label: \"RDP\",\n protocol: \"tcp\",\n portRangeMin: 3389,\n portRangeMax: 3389,\n },\n {\n value: \"ssh\",\n label: \"SSH\",\n protocol: \"tcp\",\n portRangeMin: 22,\n portRangeMax: 22,\n },\n {\n value: \"smtp\",\n label: \"SMTP\",\n protocol: \"tcp\",\n portRangeMin: 25,\n portRangeMax: 25,\n },\n {\n value: \"smtps\",\n label: \"SMTPS\",\n protocol: \"tcp\",\n portRangeMin: 465,\n portRangeMax: 465,\n },\n]\n","import { FormRow, Select, SelectOption } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { RULE_PRESETS } from \"../rulePresets\"\nimport type { AddRuleFormApi } from \"../AddRuleModal\"\n\ninterface RuleTypeSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n}\n\nexport function RuleTypeSection({ form, disabled = false }: RuleTypeSectionProps) {\n const { t } = useLingui()\n\n return (\n <form.Field name=\"ruleType\" mode=\"value\">\n {(field) => (\n <FormRow className=\"mb-6\">\n <Select\n id=\"ruleType\"\n label={t`Rule Type`}\n value={field.state.value}\n onChange={(value) => {\n const newRuleType = String(value || \"\")\n field.handleChange(newRuleType)\n\n // Don't update dependent fields if no preset is selected\n if (!newRuleType) {\n form.setFieldValue(\"protocol\", null)\n form.setFieldValue(\"portFrom\", \"\")\n form.setFieldValue(\"portTo\", \"\")\n form.setFieldValue(\"icmpType\", \"\")\n form.setFieldValue(\"icmpCode\", \"\")\n return\n }\n\n // Update dependent fields when preset changes\n const selectedPreset = RULE_PRESETS.find((p) => p.value === newRuleType)\n if (!selectedPreset) return\n\n // Update protocol field\n form.setFieldValue(\"protocol\", selectedPreset.protocol)\n\n // For TCP/UDP presets: update port fields\n if (selectedPreset.protocol === \"tcp\" || selectedPreset.protocol === \"udp\") {\n if (selectedPreset.portRangeMin !== null && selectedPreset.portRangeMax !== null) {\n // Preset has predefined ports (e.g., HTTP = 80)\n form.setFieldValue(\"portFrom\", String(selectedPreset.portRangeMin))\n form.setFieldValue(\"portTo\", String(selectedPreset.portRangeMax))\n } else {\n // Custom rule - clear ports so user can enter them\n form.setFieldValue(\"portFrom\", \"\")\n form.setFieldValue(\"portTo\", \"\")\n }\n } else {\n // Non-TCP/UDP protocols: clear port fields\n form.setFieldValue(\"portFrom\", \"\")\n form.setFieldValue(\"portTo\", \"\")\n }\n\n // Clear ICMP fields for non-ICMP protocols\n if (selectedPreset.protocol !== \"icmp\" && selectedPreset.protocol !== \"ipv6-icmp\") {\n form.setFieldValue(\"icmpType\", \"\")\n form.setFieldValue(\"icmpCode\", \"\")\n }\n }}\n disabled={disabled}\n >\n {RULE_PRESETS.map((preset) => {\n // Render placeholder option with translation\n if (preset.value === \"\") {\n return <SelectOption key={preset.value} value={preset.value} label={t`Select a rule type...`} />\n }\n return <SelectOption key={preset.value} value={preset.value} label={preset.label} />\n })}\n </Select>\n </FormRow>\n )}\n </form.Field>\n )\n}\n","import { FormRow, RadioGroup, Radio } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport type { AddRuleFormApi } from \"../AddRuleModal\"\n\ninterface DirectionSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n}\n\nexport function DirectionSection({ form, disabled = false }: DirectionSectionProps) {\n const { t } = useLingui()\n\n return (\n <form.Field name=\"direction\">\n {(directionField) => (\n <FormRow>\n <RadioGroup\n name=\"direction\"\n label={t`Direction`}\n selected={directionField.state.value}\n onChange={(value) => directionField.handleChange(String(value) as \"ingress\" | \"egress\")}\n required\n disabled={disabled}\n >\n <div className=\"flex gap-4\">\n <Radio value=\"ingress\" label={t`Ingress`} />\n <Radio value=\"egress\" label={t`Egress`} />\n </div>\n </RadioGroup>\n </FormRow>\n )}\n </form.Field>\n )\n}\n\ninterface EthertypeSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n}\n\nexport function EthertypeSection({ form, disabled = false }: EthertypeSectionProps) {\n const { t } = useLingui()\n\n return (\n <form.Field name=\"ethertype\">\n {(ethertypeField) => (\n <FormRow>\n <RadioGroup\n name=\"ethertype\"\n label={t`IP Version`}\n selected={ethertypeField.state.value}\n onChange={(value) => ethertypeField.handleChange(String(value) as \"IPv4\" | \"IPv6\")}\n required\n disabled={disabled}\n >\n <div className=\"flex gap-4\">\n <Radio value=\"IPv4\" label=\"IPv4\" />\n <Radio value=\"IPv6\" label=\"IPv6\" />\n </div>\n </RadioGroup>\n </FormRow>\n )}\n </form.Field>\n )\n}\n","import { FormRow, TextInput } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport type { AddRuleFormApi } from \"../AddRuleModal\"\n\ninterface ProtocolSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n}\n\nexport function ProtocolSection({ form, disabled = false }: ProtocolSectionProps) {\n const { t } = useLingui()\n\n return (\n <form.Field name=\"protocol\">\n {(field) => (\n <FormRow className=\"mb-6\">\n <TextInput\n id=\"protocol\"\n name=\"protocol\"\n label={t`Protocol`}\n value={field.state.value || \"\"}\n onChange={(e) => field.handleChange(e.target.value || null)}\n errortext={field.state.meta.errors[0]?.message}\n placeholder={t`tcp, udp, icmp, or protocol number`}\n disabled={disabled}\n />\n </FormRow>\n )}\n </form.Field>\n )\n}\n","import { FormRow, TextInput } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { useStore } from \"@tanstack/react-form\"\nimport type { AddRuleFormApi } from \"../AddRuleModal\"\n\ninterface PortRangeSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n}\n\nexport function PortRangeSection({ form, disabled = false }: PortRangeSectionProps) {\n const { t } = useLingui()\n\n // Watch portFrom value using useStore\n const portFromValue = useStore(form.store, (state) => state.values.portFrom)\n\n // Watch field errors using useStore\n const portFromError = useStore(form.store, (state) => state.fieldMeta.portFrom?.errors[0]?.message)\n const portToError = useStore(form.store, (state) => state.fieldMeta.portTo?.errors[0]?.message)\n\n // Determine if portTo should be disabled based on portFrom value\n const isPortToDisabled = disabled || !portFromValue || portFromValue.trim() === \"\"\n\n return (\n <FormRow className=\"mb-6\">\n <div className=\"flex items-center gap-4\">\n <form.Field name=\"portFrom\">\n {(portFromField) => {\n return (\n <div className=\"flex-1\">\n <TextInput\n id=\"portFrom\"\n name=\"portFrom\"\n label={t`Port (from)`}\n value={portFromField.state.value || \"\"}\n onChange={(e) => {\n const newValue = e.target.value\n portFromField.handleChange(newValue)\n\n // Clear portTo when portFrom is cleared\n if (!newValue || newValue.trim() === \"\") {\n form.setFieldValue(\"portTo\", \"\")\n }\n\n // Trigger validation of portTo when portFrom changes\n // This ensures cross-field validation (portFrom < portTo) updates immediately\n form.validateField(\"portTo\", \"change\")\n }}\n invalid={portFromField.state.meta.errors.length > 0}\n disabled={disabled}\n required\n />\n </div>\n )\n }}\n </form.Field>\n <div className=\"text-theme-secondary flex items-center justify-center\">—</div>\n <form.Field name=\"portTo\">\n {(portToField) => {\n return (\n <div className=\"flex-1\">\n <TextInput\n id=\"portTo\"\n name=\"portTo\"\n label={t`Port (to)`}\n value={portToField.state.value || \"\"}\n onChange={(e) => {\n portToField.handleChange(e.target.value)\n\n // Trigger validation of portFrom when portTo changes\n // This ensures cross-field validation (portFrom < portTo) updates immediately\n form.validateField(\"portFrom\", \"change\")\n }}\n invalid={portToField.state.meta.errors.length > 0}\n placeholder=\"\"\n disabled={isPortToDisabled}\n />\n </div>\n )\n }}\n </form.Field>\n </div>\n\n {/* Display errors before description */}\n {(portFromError || portToError) && (\n <div className=\"text-theme-error mt-2 text-sm\">\n {portFromError && <div>{portFromError}</div>}\n {portToError && <div>{portToError}</div>}\n </div>\n )}\n\n <p className=\"mt-2 text-sm\">\n {t`Enter a single port, or define a range by also filling \"Port (to)\". \"Port (to)\" is optional.`}\n </p>\n </FormRow>\n )\n}\n","import { FormRow, TextInput } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport type { AddRuleFormApi } from \"../AddRuleModal\"\n\ninterface IcmpSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n}\n\nexport function IcmpSection({ form, disabled = false }: IcmpSectionProps) {\n const { t } = useLingui()\n\n return (\n <FormRow className=\"mb-6\">\n <div className=\"flex w-full gap-4\">\n <form.Field name=\"icmpType\">\n {(icmpTypeField) => (\n <div className=\"flex-1\">\n <TextInput\n id=\"icmpType\"\n name=\"icmpType\"\n label={t`ICMP Type`}\n value={icmpTypeField.state.value}\n onChange={(e) => icmpTypeField.handleChange(e.target.value)}\n errortext={icmpTypeField.state.meta.errors[0]?.message}\n placeholder={t`Leave empty for all types`}\n disabled={disabled}\n />\n </div>\n )}\n </form.Field>\n <form.Field name=\"icmpCode\">\n {(icmpCodeField) => (\n <div className=\"flex-1\">\n <TextInput\n id=\"icmpCode\"\n name=\"icmpCode\"\n label={t`ICMP Code`}\n value={icmpCodeField.state.value}\n onChange={(e) => icmpCodeField.handleChange(e.target.value)}\n errortext={icmpCodeField.state.meta.errors[0]?.message}\n placeholder={t`Leave empty for all codes`}\n disabled={disabled}\n />\n </div>\n )}\n </form.Field>\n </div>\n </FormRow>\n )\n}\n","import { FormRow, TextInput, Select, SelectOption, RadioGroup, Radio } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { DEFAULT_IPV4_CIDR, DEFAULT_IPV6_CIDR } from \"../constants\"\nimport type { AddRuleFormApi } from \"../AddRuleModal\"\n\ninterface RemoteSourceSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n availableSecurityGroups: Array<{ id: string; name: string | null }>\n}\n\nexport function RemoteSourceSection({ form, disabled = false, availableSecurityGroups }: RemoteSourceSectionProps) {\n const { t } = useLingui()\n\n return (\n <>\n {/* Remote Source Type Toggle */}\n <form.Field name=\"remoteSourceType\" mode=\"value\">\n {(remoteSourceTypeField) => (\n <FormRow className=\"mb-1\">\n <RadioGroup\n name=\"remoteSourceType\"\n label={t`Remote Source`}\n selected={remoteSourceTypeField.state.value}\n onChange={(value) => {\n const newValue = String(value) as \"cidr\" | \"security_group\"\n remoteSourceTypeField.handleChange(newValue)\n\n // Auto-set ethertype to IPv4 when remote source is NOT security group\n if (newValue !== \"security_group\") {\n form.setFieldValue(\"ethertype\", \"IPv4\")\n }\n }}\n disabled={disabled}\n >\n <div className=\"flex gap-4\">\n <Radio value=\"cidr\" label={t`CIDR`} />\n <Radio value=\"security_group\" label={t`Security Group`} />\n </div>\n </RadioGroup>\n </FormRow>\n )}\n </form.Field>\n\n {/* Remote CIDR (conditional) */}\n <form.Field name=\"remoteSourceType\">\n {(remoteSourceTypeField) =>\n remoteSourceTypeField.state.value === \"cidr\" ? (\n <form.Field name=\"remoteCidr\">\n {(remoteCidrField) => (\n <form.Field name=\"ethertype\">\n {(ethertypeField) => (\n <FormRow className=\"mb-6\">\n <TextInput\n id=\"remoteCidr\"\n name=\"remoteCidr\"\n label={t`Remote IP Prefix`}\n value={remoteCidrField.state.value}\n onChange={(e) => remoteCidrField.handleChange(e.target.value)}\n errortext={remoteCidrField.state.meta.errors[0]?.message}\n placeholder={ethertypeField.state.value === \"IPv4\" ? DEFAULT_IPV4_CIDR : DEFAULT_IPV6_CIDR}\n disabled={disabled}\n />\n </FormRow>\n )}\n </form.Field>\n )}\n </form.Field>\n ) : null\n }\n </form.Field>\n\n {/* Remote Security Group (conditional) */}\n <form.Field name=\"remoteSourceType\">\n {(remoteSourceTypeField) =>\n remoteSourceTypeField.state.value === \"security_group\" ? (\n <form.Field name=\"remoteSecurityGroupId\">\n {(remoteSecurityGroupIdField) => (\n <FormRow className=\"mb-6\">\n <Select\n id=\"remoteSecurityGroupId\"\n label={t`Remote Security Group`}\n value={remoteSecurityGroupIdField.state.value}\n onChange={(value) => remoteSecurityGroupIdField.handleChange(String(value))}\n errortext={remoteSecurityGroupIdField.state.meta.errors[0]?.message}\n disabled={disabled}\n >\n <SelectOption value=\"\" label={t`Select a security group...`} />\n {availableSecurityGroups.map((sg) => (\n <SelectOption key={sg.id} value={sg.id} label={sg.name || sg.id} />\n ))}\n </Select>\n </FormRow>\n )}\n </form.Field>\n ) : null\n }\n </form.Field>\n </>\n )\n}\n","import { FormRow, Textarea } from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport type { AddRuleFormApi } from \"../AddRuleModal\"\n\ninterface DescriptionSectionProps {\n form: AddRuleFormApi\n disabled?: boolean\n}\n\nexport function DescriptionSection({ form, disabled = false }: DescriptionSectionProps) {\n const { t } = useLingui()\n\n return (\n <form.Field name=\"description\">\n {(field) => (\n <FormRow className=\"mb-0\">\n <Textarea\n id=\"description\"\n name=\"description\"\n label={t`Description`}\n value={field.state.value}\n onChange={(e) => field.handleChange(e.target.value)}\n placeholder={t`Optional description`}\n disabled={disabled}\n rows={2}\n />\n </FormRow>\n )}\n </form.Field>\n )\n}\n","import React from \"react\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { useForm } from \"@tanstack/react-form\"\nimport {\n Modal,\n Form,\n FormSection,\n Button,\n ButtonRow,\n Spinner,\n ModalFooter,\n Message,\n} from \"@cloudoperators/juno-ui-components\"\nimport type { CreateSecurityGroupRuleInput } from \"@/server/Network/types/securityGroup\"\nimport { createRuleFormSchema } from \"./validation/formSchema\"\nimport { DEFAULT_VALUES } from \"./types\"\nimport { CUSTOM_TCP_RULE, CUSTOM_UDP_RULE, OTHER_PROTOCOL_RULE } from \"./constants\"\nimport { RuleTypeSection } from \"./sections/RuleTypeSection\"\nimport { DirectionSection, EthertypeSection } from \"./sections/DirectionEthertypeSection\"\nimport { ProtocolSection } from \"./sections/ProtocolSection\"\nimport { PortRangeSection } from \"./sections/PortRangeSection\"\nimport { IcmpSection } from \"./sections/IcmpSection\"\nimport { RemoteSourceSection } from \"./sections/RemoteSourceSection\"\nimport { DescriptionSection } from \"./sections/DescriptionSection\"\n\ninterface AddRuleModalProps {\n securityGroupId: string\n open: boolean\n onClose: () => void\n onCreate: (ruleData: Omit<CreateSecurityGroupRuleInput, \"project_id\">) => Promise<void>\n isLoading?: boolean\n error?: string | null\n availableSecurityGroups?: Array<{ id: string; name: string | null }>\n}\n\n/**\n * Helper function for TypeScript type inference.\n * This function is never called at runtime - it exists purely to help TypeScript\n * infer the return type of useForm for use in child components.\n * Note: Must include validators to match the actual form's type signature.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction createFormTypeHelper() {\n return useForm({\n defaultValues: DEFAULT_VALUES,\n validators: {\n onSubmit: createRuleFormSchema,\n },\n onSubmit: async () => {\n // Dummy implementation for type inference only\n },\n })\n}\n\n/**\n * Type for the TanStack Form instance used in this modal.\n * Inferred from the helper function above.\n */\nexport type AddRuleFormApi = ReturnType<typeof createFormTypeHelper>\n\nexport const AddRuleModal: React.FC<AddRuleModalProps> = ({\n securityGroupId,\n open,\n onClose,\n onCreate,\n isLoading = false,\n error = null,\n availableSecurityGroups = [],\n}) => {\n const { t } = useLingui()\n\n // Initialize TanStack Form\n const form = useForm({\n defaultValues: DEFAULT_VALUES,\n validators: {\n onSubmit: createRuleFormSchema,\n },\n onSubmit: async ({ value }) => {\n if (isLoading) {\n return\n }\n\n // Build API payload from form values (without project_id - added by parent)\n const payload: Omit<CreateSecurityGroupRuleInput, \"project_id\"> = {\n security_group_id: securityGroupId,\n direction: value.direction,\n ethertype: value.ethertype,\n description: value.description || undefined,\n protocol: value.protocol || null,\n // Initialize remote fields as undefined (will be set below if applicable)\n remote_ip_prefix: undefined,\n remote_group_id: undefined,\n remote_address_group_id: undefined,\n }\n\n // Add port range for TCP/UDP protocols\n const isTcpUdp = value.protocol === \"tcp\" || value.protocol === \"udp\"\n if (isTcpUdp) {\n if (value.portFrom) {\n const portFrom = parseInt(value.portFrom, 10)\n payload.port_range_min = portFrom\n\n if (value.portTo) {\n // Range: both portFrom and portTo are provided\n payload.port_range_max = parseInt(value.portTo, 10)\n } else {\n // Single port: only portFrom is provided\n payload.port_range_max = portFrom\n }\n }\n }\n\n // Add ICMP type/code (maps to port_range_min/max)\n const isIcmp = value.protocol === \"icmp\" || value.protocol === \"ipv6-icmp\"\n if (isIcmp) {\n if (value.icmpType) {\n payload.port_range_min = parseInt(value.icmpType, 10)\n }\n if (value.icmpCode) {\n payload.port_range_max = parseInt(value.icmpCode, 10)\n }\n }\n\n // Add remote source\n if (value.remoteSourceType === \"cidr\" && value.remoteCidr) {\n payload.remote_ip_prefix = value.remoteCidr\n } else if (value.remoteSourceType === \"security_group\" && value.remoteSecurityGroupId) {\n payload.remote_group_id = value.remoteSecurityGroupId\n }\n\n await onCreate(payload)\n handleClose()\n },\n })\n\n const handleClose = () => {\n form.reset()\n onClose()\n }\n\n return (\n <Modal\n open={open}\n onCancel={handleClose}\n size=\"large\"\n title={t`Add Security Group Rule`}\n modalFooter={\n <ModalFooter className=\"flex justify-end\">\n <form.Subscribe>\n {(state: { isSubmitting: boolean; values: { ruleType: string } }) => {\n const isRuleTypeSelected = Boolean(state.values.ruleType)\n return (\n <ButtonRow>\n <Button variant=\"default\" onClick={handleClose} disabled={isLoading || state.isSubmitting}>\n <Trans>Cancel</Trans>\n </Button>\n <Button\n variant=\"primary\"\n type=\"button\"\n onClick={() => form.handleSubmit()}\n disabled={isLoading || state.isSubmitting || !isRuleTypeSelected}\n data-testid=\"add-rule-button\"\n >\n {state.isSubmitting || isLoading ? <Spinner size=\"small\" /> : <Trans>Add Rule</Trans>}\n </Button>\n </ButtonRow>\n )\n }}\n </form.Subscribe>\n </ModalFooter>\n }\n >\n {/* Error Message */}\n {error && (\n <Message dismissible={false} variant=\"error\" className=\"mb-4\">\n {error}\n </Message>\n )}\n\n {isLoading && (\n <div className=\"mb-4 flex items-center justify-center gap-2\">\n <Spinner variant=\"primary\" />\n <span className=\"text-theme-secondary text-sm\">\n <Trans>Creating security group rule...</Trans>\n </span>\n </div>\n )}\n\n <Form\n className=\"mb-6\"\n onSubmit={(e) => {\n e.preventDefault()\n form.handleSubmit()\n }}\n >\n <FormSection className=\"mb-6\">\n {/* Rule Type Preset */}\n <RuleTypeSection form={form} disabled={isLoading} />\n\n {/* Show other fields only when rule type is selected */}\n <form.Subscribe>\n {(state: {\n values: { ruleType: string; protocol: string | null; remoteSourceType: \"cidr\" | \"security_group\" }\n }) => {\n const isRuleTypeSelected = Boolean(state.values.ruleType)\n\n if (!isRuleTypeSelected) {\n return null\n }\n\n const isTcpUdp = state.values.protocol === \"tcp\" || state.values.protocol === \"udp\"\n const showPortFields = isTcpUdp && [CUSTOM_TCP_RULE, CUSTOM_UDP_RULE].includes(state.values.ruleType)\n const showIcmpFields = state.values.protocol === \"icmp\" || state.values.protocol === \"ipv6-icmp\"\n\n return (\n <>\n {/* Direction */}\n <DirectionSection form={form} disabled={isLoading} />\n\n {/* Protocol (conditional for \"Other Protocol\") */}\n {state.values.ruleType === OTHER_PROTOCOL_RULE && (\n <ProtocolSection form={form} disabled={isLoading} />\n )}\n\n {/* Port Range (conditional for Custom TCP/UDP) */}\n {showPortFields && <PortRangeSection form={form} disabled={isLoading} />}\n\n {/* ICMP Fields (conditional for ICMP protocols) */}\n {showIcmpFields && <IcmpSection form={form} disabled={isLoading} />}\n\n {/* Remote Source (CIDR or Security Group) */}\n <RemoteSourceSection\n form={form}\n disabled={isLoading}\n availableSecurityGroups={availableSecurityGroups}\n />\n\n {/* Ethertype (conditional for Security Group remote source) */}\n {state.values.remoteSourceType === \"security_group\" && (\n <EthertypeSection form={form} disabled={isLoading} />\n )}\n\n {/* Description */}\n <DescriptionSection form={form} disabled={isLoading} />\n </>\n )\n }}\n </form.Subscribe>\n </FormSection>\n </Form>\n </Modal>\n )\n}\n","import { useState, useEffect } from \"react\"\nimport {\n DataGrid,\n DataGridHeadCell,\n DataGridRow,\n DataGridCell,\n Button,\n Stack,\n PopupMenu,\n PopupMenuItem,\n PopupMenuOptions,\n} from \"@cloudoperators/juno-ui-components\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport type { SecurityGroupRule, CreateSecurityGroupRuleInput } from \"@/server/Network/types/securityGroup\"\nimport type { FilterSettings, SortSettings } from \"@/client/components/ListToolbar/types\"\nimport type { ListSortConfig } from \"@/client/utils/useListWithFiltering\"\nimport { DeleteRuleDialog } from \"../../-modals/DeleteRuleDialog\"\nimport { AddRuleModal } from \"../../-modals/AddRuleModal/AddRuleModal\"\nimport { ListToolbar } from \"@/client/components/ListToolbar\"\nimport { useModal } from \"@/client/utils/useModal\"\n\ninterface SecurityGroupRulesTableProps {\n rules: SecurityGroupRule[] // Filtered rules\n totalRulesCount?: number // Total rules count before filtering\n onDeleteRule: (ruleId: string) => void\n isDeletingRule: boolean\n deleteError: string | null\n // Client-side filtering and sorting controls\n searchTerm?: string\n onSearchChange?: (searchTerm: string | number | string[] | undefined) => void\n sortSettings?: ListSortConfig<\"direction\" | \"protocol\" | \"description\">\n onSortChange?: (sortSettings: SortSettings) => void\n filterSettings?: FilterSettings\n onFilterChange?: (filterSettings: FilterSettings) => void\n // Add rule functionality\n securityGroupId?: string\n onCreateRule?: (ruleData: Omit<CreateSecurityGroupRuleInput, \"project_id\">) => Promise<void>\n isCreatingRule?: boolean\n createRuleError?: string | null\n availableSecurityGroups?: Array<{ id: string; name: string | null }>\n readOnly?: boolean // Hide actions column and add rule button for shared security groups\n}\n\nexport function SecurityGroupRulesTable({\n rules,\n totalRulesCount,\n onDeleteRule,\n isDeletingRule,\n deleteError,\n searchTerm = \"\",\n onSearchChange,\n sortSettings,\n onSortChange,\n filterSettings,\n onFilterChange,\n securityGroupId,\n onCreateRule,\n isCreatingRule = false,\n createRuleError = null,\n availableSecurityGroups = [],\n readOnly = false,\n}: SecurityGroupRulesTableProps) {\n const { t } = useLingui()\n const [ruleToDelete, setRuleToDelete] = useState<SecurityGroupRule | null>(null)\n const [isAddRuleModalOpen, toggleAddRuleModal] = useModal()\n\n const handleDeleteClick = (rule: SecurityGroupRule) => {\n setRuleToDelete(rule)\n }\n\n const handleConfirmDelete = (ruleId: string) => {\n onDeleteRule(ruleId)\n }\n\n const handleCloseDeleteDialog = () => {\n if (!isDeletingRule) {\n setRuleToDelete(null)\n }\n }\n\n // Close dialog after successful deletion\n useEffect(() => {\n if (!isDeletingRule && !deleteError) {\n setRuleToDelete(null)\n }\n }, [isDeletingRule, deleteError])\n\n // Format port range display\n const formatPortRange = (rule: SecurityGroupRule): string => {\n if (rule.protocol === \"icmp\" || rule.protocol === \"ipv6-icmp\") {\n if (rule.port_range_min !== null && rule.port_range_max !== null) {\n const typeValue = rule.port_range_min\n const codeValue = rule.port_range_max\n return t`Type: ${typeValue}, Code: ${codeValue}`\n }\n return t`-`\n }\n\n if (rule.port_range_min === null || rule.port_range_max === null) {\n return t`-`\n }\n\n if (rule.port_range_min === rule.port_range_max) {\n return String(rule.port_range_min)\n }\n\n return `${rule.port_range_min}-${rule.port_range_max}`\n }\n\n return (\n <>\n <Stack direction=\"vertical\" gap=\"4\">\n <ListToolbar\n totalCount={totalRulesCount ?? rules.length}\n filteredCount={rules.length}\n itemName={t`rules`}\n filterSettings={filterSettings}\n onFilter={onFilterChange}\n sortSettings={sortSettings}\n onSort={onSortChange}\n searchTerm={searchTerm}\n onSearch={onSearchChange}\n actions={\n !readOnly &&\n onCreateRule && (\n <Button variant=\"primary\" icon=\"addCircle\" onClick={toggleAddRuleModal}>\n <Trans>Add rule</Trans>\n </Button>\n )\n }\n />\n\n {/* Rules Table */}\n {rules.length === 0 ? (\n <Trans>There are no rules for this security group</Trans>\n ) : (\n <DataGrid columns={readOnly ? 5 : 6} className=\"security-group-rules-table\">\n <DataGridRow>\n <DataGridHeadCell>{t`Direction`}</DataGridHeadCell>\n <DataGridHeadCell>{t`Description`}</DataGridHeadCell>\n <DataGridHeadCell>{t`Ethertype`}</DataGridHeadCell>\n <DataGridHeadCell>{t`Protocol`}</DataGridHeadCell>\n <DataGridHeadCell>{t`Range`}</DataGridHeadCell>\n {!readOnly && <DataGridHeadCell>{t`Actions`}</DataGridHeadCell>}\n </DataGridRow>\n {rules.map((rule) => (\n <DataGridRow key={rule.id} data-testid={`rule-row-${rule.id}`}>\n <DataGridCell>{rule.direction || t`—`}</DataGridCell>\n <DataGridCell>{rule.description || t`—`}</DataGridCell>\n <DataGridCell>{rule.ethertype}</DataGridCell>\n <DataGridCell>{rule.protocol || t`-`}</DataGridCell>\n <DataGridCell>{formatPortRange(rule)}</DataGridCell>\n {!readOnly && (\n <DataGridCell onClick={(e) => e.stopPropagation()} className=\"items-end justify-end pr-0\">\n <PopupMenu>\n <PopupMenuOptions>\n <PopupMenuItem label={t`Delete`} onClick={() => handleDeleteClick(rule)} />\n </PopupMenuOptions>\n </PopupMenu>\n </DataGridCell>\n )}\n </DataGridRow>\n ))}\n </DataGrid>\n )}\n </Stack>\n\n {/* Delete Confirmation Dialog */}\n {!readOnly && (\n <DeleteRuleDialog\n rule={ruleToDelete}\n open={!!ruleToDelete}\n onClose={handleCloseDeleteDialog}\n onConfirm={handleConfirmDelete}\n isLoading={isDeletingRule}\n error={deleteError}\n />\n )}\n\n {/* Add Rule Modal */}\n {!readOnly && securityGroupId && onCreateRule && isAddRuleModalOpen && (\n <AddRuleModal\n securityGroupId={securityGroupId}\n open={isAddRuleModalOpen}\n onClose={toggleAddRuleModal}\n onCreate={onCreateRule}\n isLoading={isCreatingRule}\n error={createRuleError}\n availableSecurityGroups={availableSecurityGroups}\n />\n )}\n </>\n )\n}\n","import {\n DataGridRow,\n DataGridCell,\n PopupMenu,\n PopupMenuItem,\n PopupMenuOptions,\n} from \"@cloudoperators/juno-ui-components\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport type { RBACPolicy } from \"@/server/Network/types/rbacPolicy\"\n\ninterface RBACPolicyRowProps {\n policy: RBACPolicy\n onDelete: () => void\n}\n\nexport function RBACPolicyRow({ policy, onDelete }: RBACPolicyRowProps) {\n const { t } = useLingui()\n\n return (\n <DataGridRow>\n <DataGridCell>{policy.target_tenant}</DataGridCell>\n <DataGridCell>{policy.action}</DataGridCell>\n <DataGridCell onClick={(e) => e.stopPropagation()} className=\"items-end justify-end pr-0\">\n <PopupMenu>\n <PopupMenuOptions>\n <PopupMenuItem label={t`Remove`} onClick={onDelete} />\n </PopupMenuOptions>\n </PopupMenu>\n </DataGridCell>\n </DataGridRow>\n )\n}\n","import { z } from \"zod\"\nimport { useState } from \"react\"\nimport { useForm } from \"@tanstack/react-form\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { Modal, Form, FormSection, TextInput, Message } from \"@cloudoperators/juno-ui-components\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useProjectId } from \"@/client/hooks\"\n\ninterface AddRBACPolicyModalProps {\n isOpen: boolean\n onClose: () => void\n securityGroupId: string\n}\n\n// UUID pattern - supports both formats:\n// - With dashes: 12345678-1234-1234-1234-123456789abc\n// - Without dashes: 12345678123412341234123456789abc (OpenStack format)\nconst UUID_WITH_DASHES = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\nconst UUID_WITHOUT_DASHES = /^[0-9a-f]{32}$/i\n\nfunction isValidProjectID(value: string): boolean {\n return UUID_WITH_DASHES.test(value) || UUID_WITHOUT_DASHES.test(value)\n}\n\nexport function AddRBACPolicyModal({ isOpen, onClose, securityGroupId }: AddRBACPolicyModalProps) {\n const { t } = useLingui()\n const utils = trpcReact.useUtils()\n const projectId = useProjectId()\n const [hasSubmitted, setHasSubmitted] = useState(false)\n\n const formSchema = z.object({\n targetTenant: z\n .string()\n .min(1, t`Target project ID is required`)\n .refine(isValidProjectID, {\n message: t`Invalid project ID format. Must be 32 hexadecimal characters (e.g., b90f9c4bc76140e18540b2cec1299e2a) or UUID format (e.g., 12345678-1234-1234-1234-123456789abc)`,\n }),\n })\n\n const createMutation = trpcReact.network.rbacPolicy.create.useMutation({\n onSuccess: () => {\n utils.network.rbacPolicy.list.invalidate({ project_id: projectId, securityGroupId })\n utils.network.securityGroup.getById.invalidate({ project_id: projectId, securityGroupId })\n handleClose()\n },\n })\n\n const form = useForm({\n defaultValues: {\n targetTenant: \"\",\n },\n validators: {\n onSubmit: formSchema,\n },\n onSubmit: async ({ value }) => {\n if (createMutation.isPending) return\n\n createMutation.mutate({\n project_id: projectId,\n securityGroupId,\n targetTenant: value.targetTenant.trim(),\n })\n },\n })\n\n const handleClose = () => {\n form.reset()\n createMutation.reset()\n setHasSubmitted(false)\n onClose()\n }\n\n const handleConfirm = async () => {\n setHasSubmitted(true)\n await form.handleSubmit()\n }\n\n return (\n <Modal\n open={isOpen}\n onCancel={handleClose}\n title={t`Share Security Group`}\n size=\"large\"\n onConfirm={handleConfirm}\n cancelButtonLabel={t`Cancel`}\n confirmButtonLabel={t`Share`}\n disableConfirmButton={createMutation.isPending}\n >\n {createMutation.error && (\n <Message variant=\"error\" className=\"mb-4\">\n {(() => {\n const message = createMutation.error.message.toLowerCase()\n if (message.includes(\"conflict\") || message.includes(\"409\")) {\n return t`This security group is already shared with the specified project.`\n } else if (message.includes(\"not found\") || message.includes(\"404\")) {\n return t`The specified project does not exist or you don't have permission to share with it.`\n } else if (message.includes(\"forbidden\") || message.includes(\"403\")) {\n return t`You don't have permission to share this security group.`\n } else {\n return createMutation.error.message\n }\n })()}\n </Message>\n )}\n\n <p className=\"mb-4\">\n <Trans>\n Share this security group with another project. The target project will be able to view and use this security\n group, but will not be able to modify or delete it.\n </Trans>\n </p>\n\n <Form\n className=\"mb-0\"\n onSubmit={(e) => {\n e.preventDefault()\n handleConfirm()\n }}\n >\n <FormSection>\n <form.Field\n name=\"targetTenant\"\n validators={{\n onBlur: ({ value }) => {\n const trimmedValue = value.trim()\n if (!trimmedValue) {\n return t`Target project ID is required`\n }\n if (!isValidProjectID(trimmedValue)) {\n return t`Invalid project ID format. Must be 32 hexadecimal characters (e.g., b90f9c4bc76140e18540b2cec1299e2a) or UUID format (e.g., 12345678-1234-1234-1234-123456789abc)`\n }\n return undefined\n },\n onChange: ({ value }) => {\n // Validate on change only after first submit attempt\n if (!hasSubmitted) return undefined\n\n const trimmedValue = value.trim()\n if (!trimmedValue) {\n return t`Target project ID is required`\n }\n if (!isValidProjectID(trimmedValue)) {\n return t`Invalid project ID format. Must be 32 hexadecimal characters (e.g., b90f9c4bc76140e18540b2cec1299e2a) or UUID format (e.g., 12345678-1234-1234-1234-123456789abc)`\n }\n return undefined\n },\n }}\n children={(field) => {\n // Get first error message as string\n const showError = (field.state.meta.isTouched || hasSubmitted) && field.state.meta.errors.length > 0\n const firstError = field.state.meta.errors[0]\n const errorMessage = showError\n ? typeof firstError === \"string\"\n ? firstError\n : firstError?.message\n : undefined\n\n return (\n <TextInput\n id={field.name}\n name={field.name}\n label={t`Target Project ID`}\n value={field.state.value}\n onChange={(e) => field.handleChange(e.target.value)}\n onBlur={field.handleBlur}\n placeholder={t`e.g., b90f9c4bc76140e18540b2cec1299e2a`}\n required\n helptext={t`Enter the ID of the project you want to share this security group with. You can find project IDs in the account/project switcher or in the Identity service.`}\n disabled={createMutation.isPending}\n errortext={errorMessage}\n invalid={showError}\n />\n )\n }}\n />\n </FormSection>\n </Form>\n </Modal>\n )\n}\n","import { z } from \"zod\"\nimport { useForm, useStore } from \"@tanstack/react-form\"\nimport { Modal, Message, TextInput, Form, FormSection } from \"@cloudoperators/juno-ui-components\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport type { RBACPolicy } from \"@/server/Network/types/rbacPolicy\"\n\ninterface DeleteRBACPolicyDialogProps {\n policy: RBACPolicy\n open: boolean\n onClose: () => void\n onConfirm: (policyId: string) => void\n isLoading: boolean\n error: string | null\n}\n\nexport function DeleteRBACPolicyDialog({\n policy,\n open,\n onClose,\n onConfirm,\n isLoading,\n error,\n}: DeleteRBACPolicyDialogProps) {\n const { t } = useLingui()\n\n const formSchema = z.object({\n confirmText: z.string().refine((value) => value === \"remove\", {\n message: t`Type \"remove\" to confirm`,\n }),\n })\n\n const form = useForm({\n defaultValues: {\n confirmText: \"\",\n },\n validators: {\n onSubmit: formSchema,\n },\n onSubmit: async () => {\n if (isLoading) return\n\n onConfirm(policy.id)\n handleClose()\n },\n })\n\n // Creates a reactive subscription so the component re-renders, which allows the confirm button to enable once the user types \"remove\"\n const canRemove = useStore(form.store, (state) => state.isSubmitting || state.values.confirmText !== \"remove\")\n\n const handleClose = () => {\n form.reset()\n onClose()\n }\n\n return (\n <Modal\n open={open}\n onCancel={handleClose}\n size=\"small\"\n title={t`Remove RBAC Policy`}\n onConfirm={form.handleSubmit}\n cancelButtonLabel={t`Cancel`}\n confirmButtonLabel={isLoading ? t`Removing...` : t`Remove Policy`}\n disableConfirmButton={isLoading || canRemove}\n >\n <div>\n {/* Error Message */}\n {error && (\n <Message dismissible={false} variant=\"error\" className=\"mt-4\">\n {error}\n </Message>\n )}\n\n {/* Warning */}\n <Trans>\n This action cannot be undone. The target project will lose access to this security group immediately.\n </Trans>\n\n {/* Policy Details */}\n <div className=\"bg-theme-background-lvl-1 mt-4 mb-4 rounded p-4\">\n <p className=\"mb-2 font-semibold\">\n <Trans>RBAC Policy Details:</Trans>\n </p>\n <ul className=\"list-inside list-disc space-y-1 text-sm\">\n <li>\n <Trans>Target Project ID</Trans>: {policy.target_tenant}\n </li>\n <li>\n <Trans>Action</Trans>: {policy.action}\n </li>\n <li>\n <Trans>Object Type</Trans>: {policy.object_type}\n </li>\n </ul>\n </div>\n\n {/* Confirmation Input */}\n {!isLoading && (\n <Form\n className=\"mt-4 mb-0\"\n onSubmit={(e) => {\n e.preventDefault()\n form.handleSubmit()\n }}\n >\n <FormSection>\n <p className=\"mb-2 text-sm\">\n <Trans>\n Type <strong>remove</strong> to confirm:\n </Trans>\n </p>\n <form.Field\n name=\"confirmText\"\n children={(field) => (\n <TextInput\n id={field.name}\n name={field.name}\n value={field.state.value}\n onChange={(e) => field.handleChange(e.target.value)}\n placeholder={t`remove`}\n autoComplete=\"off\"\n disabled={isLoading}\n data-testid=\"remove-policy-confirmation-input\"\n />\n )}\n />\n </FormSection>\n </Form>\n )}\n </div>\n </Modal>\n )\n}\n","import { useState, useEffect, useMemo } from \"react\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport {\n DataGrid,\n DataGridRow,\n DataGridHeadCell,\n Stack,\n Spinner,\n Button,\n Message,\n} from \"@cloudoperators/juno-ui-components\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useProjectId } from \"@/client/hooks\"\nimport type { RBACPolicy } from \"@/server/Network/types/rbacPolicy\"\nimport { RBACPolicyRow } from \"./RBACPolicyRow\"\nimport { AddRBACPolicyModal } from \"../../-modals/AddRBACPolicyModal\"\nimport { DeleteRBACPolicyDialog } from \"../../-modals/DeleteRBACPolicyDialog\"\nimport { ListToolbar } from \"@/client/components/ListToolbar\"\nimport { useModal } from \"@/client/utils/useModal\"\n\ninterface SecurityGroupRBACPoliciesProps {\n securityGroupId: string\n}\n\nexport function SecurityGroupRBACPolicies({ securityGroupId }: SecurityGroupRBACPoliciesProps) {\n const utils = trpcReact.useUtils()\n const { t } = useLingui()\n const projectId = useProjectId()\n\n const [isAddModalOpen, toggleAddModal] = useModal()\n const [policyToDelete, setPolicyToDelete] = useState<RBACPolicy | null>(null)\n const [searchTerm, setSearchTerm] = useState(\"\")\n\n // Query RBAC policies\n const {\n data: policies,\n isPending,\n isError,\n error,\n } = trpcReact.network.rbacPolicy.list.useQuery(\n { project_id: projectId, securityGroupId },\n {\n refetchOnWindowFocus: false,\n }\n )\n\n // Delete mutation\n const deleteMutation = trpcReact.network.rbacPolicy.delete.useMutation({\n onSuccess: () => {\n utils.network.rbacPolicy.list.invalidate({ project_id: projectId, securityGroupId })\n utils.network.securityGroup.getById.invalidate({ project_id: projectId, securityGroupId })\n },\n })\n\n const handleDeleteClick = (policy: RBACPolicy) => {\n setPolicyToDelete(policy)\n }\n\n const handleConfirmDelete = (policyId: string) => {\n deleteMutation.mutate({ project_id: projectId, policyId })\n }\n\n const handleCloseDeleteDialog = () => {\n if (!deleteMutation.isPending) {\n setPolicyToDelete(null)\n }\n }\n\n // Close dialog after successful deletion\n useEffect(() => {\n if (!deleteMutation.isPending && !deleteMutation.error && deleteMutation.isSuccess) {\n setPolicyToDelete(null)\n }\n }, [deleteMutation.isPending, deleteMutation.error, deleteMutation.isSuccess])\n\n // Client-side search filtering\n const filteredPolicies = useMemo(() => {\n if (!policies) return []\n\n if (!searchTerm) {\n return policies\n }\n\n const searchLower = searchTerm.toLowerCase()\n return policies.filter(\n (policy) =>\n policy.target_tenant?.toLowerCase().includes(searchLower) || policy.action?.toLowerCase().includes(searchLower)\n )\n }, [policies, searchTerm])\n\n const handleSearchChange = (value: string | number | string[] | undefined) => {\n const searchValue = typeof value === \"string\" ? value : \"\"\n setSearchTerm(searchValue)\n }\n\n if (isPending) {\n return (\n <Stack distribution=\"center\" alignment=\"center\" className=\"py-8\">\n <Spinner variant=\"primary\" />\n </Stack>\n )\n }\n\n if (isError) {\n return (\n <Message variant=\"error\" className=\"mb-4\">\n {error.message}\n </Message>\n )\n }\n\n const totalCount = policies?.length || 0\n const filteredCount = filteredPolicies.length\n\n return (\n <>\n <Stack direction=\"vertical\" gap=\"4\">\n {/* Toolbar with Share button and search - same pattern as Rules */}\n <ListToolbar\n totalCount={totalCount}\n filteredCount={filteredCount}\n itemName={t`projects`}\n searchTerm={searchTerm}\n onSearch={handleSearchChange}\n actions={\n <Button variant=\"primary\" icon=\"addCircle\" onClick={toggleAddModal}>\n <Trans>Share Security Group</Trans>\n </Button>\n }\n />\n\n {/* RBAC Policies Table */}\n {filteredCount === 0 ? (\n searchTerm ? (\n <Trans>No policies match your search</Trans>\n ) : (\n <Trans>There are no RBAC policies for this security group</Trans>\n )\n ) : (\n <DataGrid columns={3}>\n <DataGridRow>\n <DataGridHeadCell>\n <Trans>Target Project ID</Trans>\n </DataGridHeadCell>\n <DataGridHeadCell>\n <Trans>Action</Trans>\n </DataGridHeadCell>\n <DataGridHeadCell>\n <Trans>Actions</Trans>\n </DataGridHeadCell>\n </DataGridRow>\n\n {filteredPolicies.map((policy) => (\n <RBACPolicyRow key={policy.id} policy={policy} onDelete={() => handleDeleteClick(policy)} />\n ))}\n </DataGrid>\n )}\n </Stack>\n\n {/* Delete Confirmation Dialog */}\n {!!policyToDelete && (\n <DeleteRBACPolicyDialog\n policy={policyToDelete}\n open={!!policyToDelete}\n onClose={handleCloseDeleteDialog}\n onConfirm={handleConfirmDelete}\n isLoading={deleteMutation.isPending}\n error={deleteMutation.error?.message || null}\n />\n )}\n\n {/* Add RBAC Policy Modal */}\n {isAddModalOpen && (\n <AddRBACPolicyModal isOpen={isAddModalOpen} onClose={toggleAddModal} securityGroupId={securityGroupId} />\n )}\n </>\n )\n}\n","import { Container, Stack } from \"@cloudoperators/juno-ui-components\"\nimport { useState } from \"react\"\nimport type {\n SecurityGroup,\n SecurityGroupRule,\n CreateSecurityGroupRuleInput,\n} from \"@/server/Network/types/securityGroup\"\nimport type { FilterSettings, SortSettings } from \"@/client/components/ListToolbar/types\"\nimport type { ListSortConfig } from \"@/client/utils/useListWithFiltering\"\nimport { SecurityGroupHeader, SecurityGroupBasicInfo, SecurityGroupTabs, type TabType } from \"./-details\"\nimport { SecurityGroupRulesTable } from \"./-details\"\nimport { SecurityGroupRBACPolicies } from \"./-details/SecurityGroupRBACPolicies\"\n\nexport interface RulesFilterControls {\n searchTerm: string\n onSearchChange: (term: string | number | string[] | undefined) => void\n sortSettings: ListSortConfig<\"direction\" | \"protocol\" | \"description\">\n onSortChange: (settings: SortSettings) => void\n filterSettings: FilterSettings\n onFilterChange: (settings: FilterSettings) => void\n}\n\ninterface SecurityGroupDetailsViewProps {\n securityGroup: SecurityGroup\n filteredAndSortedRules: SecurityGroupRule[]\n onEdit?: () => void\n onDeleteRule: (ruleId: string) => void\n isDeletingRule?: boolean\n deleteRuleError?: string | null\n filterControls: RulesFilterControls\n // Add rule functionality - passed through to SecurityGroupRulesTable\n onCreateRule?: (ruleData: Omit<CreateSecurityGroupRuleInput, \"project_id\">) => Promise<void>\n isCreatingRule?: boolean\n createRuleError?: string | null\n availableSecurityGroups?: Array<{ id: string; name: string | null }>\n currentProjectId: string\n}\n\nexport function SecurityGroupDetailsView({\n securityGroup,\n filteredAndSortedRules,\n onEdit,\n onDeleteRule,\n isDeletingRule = false,\n deleteRuleError = null,\n filterControls,\n onCreateRule,\n isCreatingRule = false,\n createRuleError = null,\n availableSecurityGroups = [],\n currentProjectId,\n}: SecurityGroupDetailsViewProps) {\n const [activeTab, setActiveTab] = useState<TabType>(\"rules\")\n\n // Determine if this is a shared security group (not owned by current project)\n const isOwner = securityGroup.project_id === currentProjectId\n const isShared = !isOwner\n const showRBACTab = isOwner\n\n return (\n <Container px={false} py>\n <Stack direction=\"vertical\" gap=\"4\">\n {/* Header Section */}\n <SecurityGroupHeader name={securityGroup.name} id={securityGroup.id} />\n\n {/* Basic Info Section */}\n <SecurityGroupBasicInfo securityGroup={securityGroup} onEdit={onEdit} isReadOnly={isShared} />\n\n {/* Tabs Navigation - Hide for shared security groups */}\n {!isShared && <SecurityGroupTabs activeTab={activeTab} onTabChange={setActiveTab} showRBACTab={showRBACTab} />}\n\n {/* Tab Content */}\n <div className=\"mt-6\">\n {activeTab === \"rules\" && (\n <SecurityGroupRulesTable\n rules={filteredAndSortedRules}\n totalRulesCount={securityGroup.security_group_rules?.length}\n onDeleteRule={onDeleteRule}\n isDeletingRule={isDeletingRule}\n deleteError={deleteRuleError}\n searchTerm={filterControls.searchTerm}\n onSearchChange={filterControls.onSearchChange}\n sortSettings={filterControls.sortSettings}\n onSortChange={filterControls.onSortChange}\n filterSettings={filterControls.filterSettings}\n onFilterChange={filterControls.onFilterChange}\n securityGroupId={securityGroup.id}\n onCreateRule={isShared ? undefined : onCreateRule}\n isCreatingRule={isCreatingRule}\n createRuleError={createRuleError}\n availableSecurityGroups={availableSecurityGroups}\n readOnly={isShared}\n />\n )}\n {activeTab === \"rbac\" && <SecurityGroupRBACPolicies securityGroupId={securityGroup.id} />}\n </div>\n </Stack>\n </Container>\n )\n}\n","import { useState, useMemo } from \"react\"\nimport { trpcReact } from \"@/client/trpcClient\"\nimport { useProjectId } from \"@/client/hooks\"\nimport type { UpdateSecurityGroupInput, CreateSecurityGroupRuleInput } from \"@/server/Network/types/securityGroup\"\nimport type { RulesFilterControls } from \"../-components/SecurityGroupDetailsView\"\n\ninterface UseSecurityGroupDetailsParams {\n securityGroupId: string\n filterControls: RulesFilterControls\n}\n\nexport function useSecurityGroupDetails({ securityGroupId, filterControls }: UseSecurityGroupDetailsParams) {\n const [editModalOpen, setEditModalOpen] = useState(false)\n const projectId = useProjectId()\n\n const utils = trpcReact.useUtils()\n\n // Query for security group\n // Use cached data from list page if available (instant loading)\n const securityGroupQuery = trpcReact.network.securityGroup.getById.useQuery(\n {\n project_id: projectId,\n securityGroupId,\n },\n {\n // Use cached data from list page as placeholder while fetching\n placeholderData: () => {\n return utils.network.securityGroup.getById.getData({ project_id: projectId, securityGroupId })\n },\n }\n )\n\n // Client-side filtering and sorting of rules\n const filteredAndSortedRules = useMemo(() => {\n const allRules = securityGroupQuery.data?.security_group_rules || []\n let result = allRules\n\n // Extract filters from filterSettings\n const directionFilter = filterControls.filterSettings.selectedFilters?.find((f) => f.name === \"direction\")?.value\n const ethertypeFilter = filterControls.filterSettings.selectedFilters?.find((f) => f.name === \"ethertype\")?.value\n const protocolFilter = filterControls.filterSettings.selectedFilters?.find((f) => f.name === \"protocol\")?.value\n\n // Filter by direction\n if (directionFilter && directionFilter !== \"all\") {\n result = result.filter((rule) => rule.direction === directionFilter)\n }\n\n // Filter by ethertype\n if (ethertypeFilter && ethertypeFilter !== \"all\") {\n result = result.filter((rule) => rule.ethertype === ethertypeFilter)\n }\n\n // Filter by protocol\n if (protocolFilter && protocolFilter !== \"all\") {\n result = result.filter((rule) => {\n // Handle null protocol as \"any\"\n if (rule.protocol === null) {\n return false\n }\n return rule.protocol === protocolFilter\n })\n }\n\n // Filter by search term\n if (filterControls.searchTerm) {\n const searchLower = filterControls.searchTerm.toLowerCase()\n result = result.filter(\n (rule) =>\n rule.description?.toLowerCase().includes(searchLower) ||\n rule.protocol?.toLowerCase().includes(searchLower) ||\n rule.ethertype?.toLowerCase().includes(searchLower)\n )\n }\n\n // Sort\n if (filterControls.sortSettings.sortBy) {\n const sortKey = filterControls.sortSettings.sortBy as \"direction\" | \"protocol\" | \"description\"\n result = [...result].sort((a, b) => {\n const aValue = (a[sortKey] || \"\") as string\n const bValue = (b[sortKey] || \"\") as string\n const comparison = aValue.localeCompare(bValue)\n return filterControls.sortSettings.sortDirection === \"asc\" ? comparison : -comparison\n })\n }\n\n return result\n }, [securityGroupQuery.data?.security_group_rules, filterControls])\n\n // Update mutation\n const updateMutation = trpcReact.network.securityGroup.update.useMutation({\n onSuccess: () => {\n utils.network.securityGroup.getById.invalidate({ project_id: projectId, securityGroupId })\n utils.network.securityGroup.list.invalidate()\n setEditModalOpen(false)\n },\n })\n\n // Delete rule mutation\n const deleteRuleMutation = trpcReact.network.securityGroupRule.delete.useMutation({\n onSuccess: () => {\n // Invalidate the security group query to refresh the rules list\n utils.network.securityGroup.getById.invalidate({ project_id: projectId, securityGroupId })\n utils.network.securityGroup.list.invalidate()\n },\n })\n\n // Create rule mutation\n const createRuleMutation = trpcReact.network.securityGroupRule.create.useMutation({\n onSuccess: () => {\n utils.network.securityGroup.getById.invalidate({ project_id: projectId, securityGroupId })\n utils.network.securityGroup.list.invalidate()\n },\n })\n\n // Handlers\n const handleEdit = () => {\n setEditModalOpen(true)\n }\n\n const handleCloseEditModal = () => {\n setEditModalOpen(false)\n }\n\n const handleUpdate = async (id: string, data: Omit<UpdateSecurityGroupInput, \"securityGroupId\" | \"project_id\">) => {\n await updateMutation.mutateAsync({\n project_id: projectId,\n securityGroupId: id,\n ...data,\n })\n }\n\n const handleDeleteRule = async (ruleId: string) => {\n await deleteRuleMutation.mutateAsync({ project_id: projectId, ruleId })\n }\n\n const handleCreateRule = async (ruleData: Omit<CreateSecurityGroupRuleInput, \"project_id\">) => {\n await createRuleMutation.mutateAsync({ project_id: projectId, ...ruleData })\n }\n\n return {\n // Data\n securityGroup: securityGroupQuery.data,\n filteredAndSortedRules,\n\n // Query states\n isLoading: securityGroupQuery.isPending,\n isError: securityGroupQuery.isError,\n error: securityGroupQuery.error,\n\n // Mutation states\n isUpdating: updateMutation.isPending,\n updateError: updateMutation.error?.message || null,\n isDeletingRule: deleteRuleMutation.isPending,\n deleteRuleError: deleteRuleMutation.error?.message || null,\n isCreatingRule: createRuleMutation.isPending,\n createRuleError: createRuleMutation.error?.message || null,\n\n // Modal states\n editModalOpen,\n\n // Handlers\n handleEdit,\n handleCloseEditModal,\n handleUpdate,\n handleDeleteRule,\n handleCreateRule,\n }\n}\n","import {\n Breadcrumb,\n BreadcrumbItem,\n Button,\n ContentHeading,\n Stack,\n Spinner,\n} from \"@cloudoperators/juno-ui-components/index\"\nimport { createFileRoute, redirect, useNavigate } from \"@tanstack/react-router\"\nimport type { RouteInfo } from \"@/client/routes/routeInfo\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport { useMemo } from \"react\"\nimport { getServiceIndex } from \"@/server/Authentication/helpers\"\nimport { useProjectId } from \"@/client/hooks\"\nimport { SecurityGroupDetailsView } from \"./-components/SecurityGroupDetailsView\"\nimport { EditSecurityGroupModal } from \"../-components/-modals/EditSecurityGroupModal\"\nimport { useSecurityGroupDetails } from \"./-hooks/useSecurityGroupDetails\"\nimport { useListWithFiltering } from \"@/client/utils/useListWithFiltering\"\nimport { trpcReact } from \"@/client/trpcClient\"\n\nexport const Route = createFileRoute(\"/_auth/projects/$projectId/network/securitygroups/$securityGroupId/\")({\n staticData: {\n section: \"network\",\n service: \"securitygroups\",\n isDetail: true,\n sectionCrumb: { labelKey: \"Network\" },\n crumb: { labelKey: \"Security Groups\", to: \"/projects/$projectId/network/securitygroups\" },\n } satisfies RouteInfo,\n loader: async ({ context, params }) => {\n const sg = await context.trpcClient?.network.securityGroup.getById.query({\n project_id: params.projectId,\n securityGroupId: params.securityGroupId,\n })\n return { sgTitle: sg?.name || sg?.id || null }\n },\n head: ({ loaderData }) => ({\n meta: [{ title: loaderData?.sgTitle ?? \"Security Group\" }],\n }),\n component: RouteComponent,\n beforeLoad: async ({ context, params }) => {\n const { trpcClient } = context\n\n const availableServices = (await trpcClient?.auth.getAvailableServices.query()) || []\n\n const serviceIndex = getServiceIndex(availableServices)\n\n // Redirect to the \"Projects Overview\" page if network service not available\n if (!serviceIndex[\"network\"]) {\n throw redirect({\n to: \"/projects/$projectId/network/securitygroups\",\n params: { projectId: params.projectId },\n })\n }\n\n if (!serviceIndex[\"network\"][\"neutron\"]) {\n // Redirect to the \"Network Services Overview\" page if the \"Neutron\" service is not available\n throw redirect({\n to: \"/projects/$projectId/network/securitygroups\",\n params: { projectId: params.projectId },\n })\n }\n },\n})\n\nfunction RouteComponent() {\n const { securityGroupId } = Route.useParams()\n const projectId = useProjectId()\n const navigate = useNavigate()\n const { t } = useLingui()\n\n // Rules filtering using the same pattern as List page\n const {\n searchTerm: rulesSearchTerm,\n sortSettings,\n filterSettings,\n handleSearchChange,\n handleSortChange,\n handleFilterChange,\n } = useListWithFiltering<\"direction\" | \"protocol\" | \"description\">({\n defaultSortKey: \"direction\",\n defaultSortDir: \"asc\",\n sortOptions: [\n { label: t`Direction`, value: \"direction\" },\n { label: t`Protocol`, value: \"protocol\" },\n { label: t`Description`, value: \"description\" },\n ],\n filterSettings: {\n filters: [\n {\n displayName: t`Direction`,\n filterName: \"direction\",\n values: [\"ingress\", \"egress\"],\n supportsMultiValue: false,\n },\n {\n displayName: t`Ethertype`,\n filterName: \"ethertype\",\n values: [\"IPv4\", \"IPv6\"],\n supportsMultiValue: false,\n },\n {\n displayName: t`Protocol`,\n filterName: \"protocol\",\n values: [\"tcp\", \"udp\", \"icmp\", \"ipv6-icmp\"],\n supportsMultiValue: false,\n },\n ],\n },\n })\n\n // Group filter controls for the hook\n const filterControls = {\n searchTerm: rulesSearchTerm,\n onSearchChange: handleSearchChange,\n sortSettings,\n onSortChange: handleSortChange,\n filterSettings,\n onFilterChange: handleFilterChange,\n }\n\n // Use custom hook for logic (now includes filtering/sorting)\n const {\n securityGroup,\n filteredAndSortedRules,\n isLoading,\n isError,\n error,\n isUpdating,\n updateError,\n isDeletingRule,\n deleteRuleError,\n isCreatingRule,\n createRuleError,\n editModalOpen,\n handleEdit,\n handleCloseEditModal,\n handleUpdate,\n handleDeleteRule,\n handleCreateRule,\n } = useSecurityGroupDetails({\n securityGroupId,\n filterControls,\n })\n\n // Fetch available security groups for the Add Rule dropdown\n const { data: securityGroups } = trpcReact.network.securityGroup.list.useQuery({ project_id: projectId })\n const availableSecurityGroups = useMemo(() => {\n return (securityGroups || [])\n .filter((sg) => sg.id !== securityGroupId) // Exclude current group\n .map((sg) => ({\n id: sg.id,\n name: sg.name || sg.id,\n }))\n }, [securityGroups, securityGroupId])\n\n const handleBack = () => {\n navigate({\n to: \"/projects/$projectId/network/securitygroups\",\n params: { projectId },\n })\n }\n\n // Handle loading state\n if (isLoading) {\n return (\n <Stack className=\"fixed inset-0\" distribution=\"center\" alignment=\"center\" direction=\"vertical\">\n <Spinner variant=\"primary\" size=\"large\" className=\"mb-2\" />\n <Trans>Loading Security Group Details...</Trans>\n </Stack>\n )\n }\n\n // Handle error state\n if (isError) {\n const errorMessage = error?.message || \"Unknown error\"\n\n return (\n <Stack className=\"fixed inset-0\" distribution=\"center\" alignment=\"center\" direction=\"vertical\" gap=\"5\">\n <p className=\"text-theme-error font-semibold\">\n <Trans>Error loading security group</Trans>\n </p>\n <p className=\"text-theme-highest\">{errorMessage}</p>\n <Button onClick={handleBack} variant=\"primary\">\n <Trans>Back to Security Groups</Trans>\n </Button>\n </Stack>\n )\n }\n\n // Handle no data state\n if (!securityGroup) {\n return (\n <Stack className=\"fixed inset-0\" distribution=\"center\" alignment=\"center\" direction=\"vertical\" gap=\"5\">\n <p className=\"text-theme-secondary\">\n <Trans>Security group not found</Trans>\n </p>\n <Button onClick={handleBack} variant=\"primary\">\n <Trans>Back to Security Groups</Trans>\n </Button>\n </Stack>\n )\n }\n\n // Render success state\n return (\n <Stack direction=\"vertical\">\n <ContentHeading>{securityGroup.name || securityGroup.id}</ContentHeading>\n <Breadcrumb className=\"my-6\">\n <BreadcrumbItem onClick={handleBack} label={t`Security Groups`} />\n <BreadcrumbItem active label={securityGroup.id} />\n </Breadcrumb>\n\n <SecurityGroupDetailsView\n securityGroup={securityGroup}\n filteredAndSortedRules={filteredAndSortedRules}\n onEdit={handleEdit}\n onDeleteRule={handleDeleteRule}\n isDeletingRule={isDeletingRule}\n deleteRuleError={deleteRuleError}\n filterControls={filterControls}\n onCreateRule={handleCreateRule}\n isCreatingRule={isCreatingRule}\n createRuleError={createRuleError}\n availableSecurityGroups={availableSecurityGroups}\n currentProjectId={projectId}\n />\n\n <EditSecurityGroupModal\n securityGroup={securityGroup}\n open={editModalOpen}\n onClose={handleCloseEditModal}\n onUpdate={handleUpdate}\n isLoading={isUpdating}\n error={updateError}\n />\n </Stack>\n )\n}\n"],"mappings":"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"}