@cobaltcore-dev/aurora 0.23.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/App.d.ts +3 -2
- package/dist/client/AuroraApp.d.ts +25 -0
- package/dist/client/{AuthProvider-CQ6Yppoh.mjs → AuthProvider-BS5OVv8n.mjs} +4 -4
- package/dist/client/AuthProvider-BS5OVv8n.mjs.map +1 -0
- package/dist/client/{ContentHeader-9KZdhOoA.mjs → ContentHeader-BHMUzd9H.mjs} +27 -26
- package/dist/client/ContentHeader-BHMUzd9H.mjs.map +1 -0
- package/dist/client/DeleteFlavorModal-BP83t9zX.mjs +721 -0
- package/dist/client/DeleteFlavorModal-BP83t9zX.mjs.map +1 -0
- package/dist/client/FiltersInput-B8CNBg1L.mjs +82 -0
- package/dist/client/FiltersInput-B8CNBg1L.mjs.map +1 -0
- package/dist/client/{FloatingIpActionModals-BcceUHcg.mjs → FloatingIpActionModals-BraiJWBi.mjs} +66 -66
- package/dist/client/{FloatingIpActionModals-BcceUHcg.mjs.map → FloatingIpActionModals-BraiJWBi.mjs.map} +1 -1
- package/dist/client/ImageToastNotifications-BXMHJaIH.mjs +1131 -0
- package/dist/client/ImageToastNotifications-BXMHJaIH.mjs.map +1 -0
- package/dist/client/{RouteError-Rm08PcxN.mjs → RouteError-hAF8_jbe.mjs} +2 -2
- package/dist/client/{RouteError-Rm08PcxN.mjs.map → RouteError-hAF8_jbe.mjs.map} +1 -1
- package/dist/client/Slot-CWb612-_.mjs.map +1 -1
- package/dist/client/{SortInput-D_q_jDfe.mjs → SortInput-Cqs2poV3.mjs} +9 -9
- package/dist/client/{SortInput-D_q_jDfe.mjs.map → SortInput-Cqs2poV3.mjs.map} +1 -1
- package/dist/client/{StatusError-2ZU1gFpu.mjs → StatusError-C5KodQOq.mjs} +7 -7
- package/dist/client/{StatusError-2ZU1gFpu.mjs.map → StatusError-C5KodQOq.mjs.map} +1 -1
- package/dist/client/TwoColumnDescriptionList-DiDx3PnH.mjs +22 -0
- package/dist/client/TwoColumnDescriptionList-DiDx3PnH.mjs.map +1 -0
- package/dist/client/{_auth-D5_QNUos.mjs → _auth-DJ9wHZaj.mjs} +2 -2
- package/dist/client/_auth-DJ9wHZaj.mjs.map +1 -0
- package/dist/client/{_flavorId-CFmkmg2Y.mjs → _flavorId-BN_qessZ.mjs} +4 -4
- package/dist/client/{_flavorId-CFmkmg2Y.mjs.map → _flavorId-BN_qessZ.mjs.map} +1 -1
- package/dist/client/_flavorId-CJjEB_Ao.mjs +210 -0
- package/dist/client/_flavorId-CJjEB_Ao.mjs.map +1 -0
- package/dist/client/{_floatingIpId-Dzh6_JCI.mjs → _floatingIpId-CwDGHkWm.mjs} +4 -4
- package/dist/client/{_floatingIpId-Dzh6_JCI.mjs.map → _floatingIpId-CwDGHkWm.mjs.map} +1 -1
- package/dist/client/_floatingIpId-foMIwbE4.mjs +215 -0
- package/dist/client/_floatingIpId-foMIwbE4.mjs.map +1 -0
- package/dist/client/_imageId-BtJ7GmYB.mjs +558 -0
- package/dist/client/_imageId-BtJ7GmYB.mjs.map +1 -0
- package/dist/client/{_projectId-D-b7paXE.mjs → _projectId-BmtCuzJu.mjs} +4 -4
- package/dist/client/{_projectId-D-b7paXE.mjs.map → _projectId-BmtCuzJu.mjs.map} +1 -1
- package/dist/client/_projectId-Byt3GQDW.mjs +99 -0
- package/dist/client/_projectId-Byt3GQDW.mjs.map +1 -0
- package/dist/client/_projectId-NYk1IN_a.mjs +291 -0
- package/dist/client/_projectId-NYk1IN_a.mjs.map +1 -0
- package/dist/client/{_projectId-CAQkJHZ4.mjs → _projectId-QueiFczy.mjs} +3 -3
- package/dist/client/{_projectId-CAQkJHZ4.mjs.map → _projectId-QueiFczy.mjs.map} +1 -1
- package/dist/client/{_securityGroupId-DRkY3Gt6.mjs → _securityGroupId-BcbkRhsN.mjs} +4 -4
- package/dist/client/{_securityGroupId-DRkY3Gt6.mjs.map → _securityGroupId-BcbkRhsN.mjs.map} +1 -1
- package/dist/client/{_securityGroupId-DFdNKa2l.mjs → _securityGroupId-pPtJsCoe.mjs} +541 -527
- package/dist/client/_securityGroupId-pPtJsCoe.mjs.map +1 -0
- package/dist/client/_storageType-BmqrU06i.mjs +2202 -0
- package/dist/client/_storageType-BmqrU06i.mjs.map +1 -0
- package/dist/client/_storageType-zeSZe--V.mjs.map +1 -1
- package/dist/client/{about-C8tTrQaW.mjs → about-_73VmpTB.mjs} +8 -8
- package/dist/client/about-_73VmpTB.mjs.map +1 -0
- package/dist/client/assets/objectDownload.worker-CWWLPDyb.js.map +1 -0
- package/dist/client/assets/objectDownload.worker-kZlQuo3F.js.map +1 -0
- package/dist/client/{aurora-jyvXcI4T.mjs → aurora-EbwGRLLf.mjs} +2 -2
- package/dist/client/aurora-EbwGRLLf.mjs.map +1 -0
- package/dist/client/{build-CRLQyqu2.mjs → build-C_4vRMCq.mjs} +8072 -8533
- package/dist/client/build-C_4vRMCq.mjs.map +1 -0
- package/dist/client/components/Auth/LoginForm.d.ts +1 -1
- package/dist/client/components/Auth/SessionExpirationTimer.d.ts +1 -1
- package/dist/client/components/ContentHeader/ContentHeader.d.ts +1 -1
- package/dist/client/components/Error/RouteError.d.ts +1 -1
- package/dist/client/components/Error/StatusError.d.ts +1 -1
- package/dist/client/components/JsonEditor.d.ts +1 -1
- package/dist/client/components/ListToolbar/FiltersInput.d.ts +3 -1
- package/dist/client/components/ListToolbar/SelectedFilters.d.ts +1 -1
- package/dist/client/components/ListToolbar/index.d.ts +1 -1
- package/dist/client/components/ProjectView/ProjectInfoBox.d.ts +1 -1
- package/dist/client/components/Slot.d.ts +1 -1
- package/dist/client/components/TwoColumnDescriptionList.d.ts +11 -0
- package/dist/client/components/navigation/LanguageSelect.d.ts +1 -1
- package/dist/client/components/navigation/MainNavigation.d.ts +1 -1
- package/dist/client/components/navigation/UserMenu.d.ts +1 -1
- package/dist/client/{flavors-Dy-2mRGv.mjs → flavors-CiHCYrtZ.mjs} +2 -2
- package/dist/client/{flavors-Dy-2mRGv.mjs.map → flavors-CiHCYrtZ.mjs.map} +1 -1
- package/dist/client/flavors-DWMZ6TuJ.mjs.map +1 -1
- package/dist/client/{flavors-BfTXqmoD.mjs → flavors-DY-bDc8l.mjs} +196 -194
- package/dist/client/flavors-DY-bDc8l.mjs.map +1 -0
- package/dist/client/floatingips-Ci4jHkaG.mjs +591 -0
- package/dist/client/floatingips-Ci4jHkaG.mjs.map +1 -0
- package/dist/client/formatBytes-CZv_XyCY.mjs.map +1 -1
- package/dist/client/helpers-1PpYf-fC.mjs.map +1 -1
- package/dist/client/hooks/useAvailableViewportHeight.d.ts +8 -5
- package/dist/client/hooks/useVirtualizedTableBody.d.ts +1 -3
- package/dist/client/{hooks-Bw3sHHOg.mjs → hooks-LutR2Yg3.mjs} +2 -2
- package/dist/client/{hooks-Bw3sHHOg.mjs.map → hooks-LutR2Yg3.mjs.map} +1 -1
- package/dist/client/images-91U7tr9Y2.mjs +1976 -0
- package/dist/client/images-91U7tr9Y2.mjs.map +1 -0
- package/dist/client/{images-DPKUXryV.mjs → images-CS4kZQyu.mjs} +2 -2
- package/dist/client/{images-DPKUXryV.mjs.map → images-CS4kZQyu.mjs.map} +1 -1
- package/dist/client/images-NBf2bV43.mjs.map +1 -1
- package/dist/client/index.d.ts +4 -1
- package/dist/client/index.js +559 -545
- package/dist/client/index.js.map +1 -1
- package/dist/client/{md-CyCflQee.mjs → md-kvaGCNAK.mjs} +6 -78
- package/dist/client/{md-CyCflQee.mjs.map → md-kvaGCNAK.mjs.map} +1 -1
- package/dist/client/network-DuZm76BZ.mjs.map +1 -1
- package/dist/client/objects-C3azvW8m.mjs +10074 -0
- package/dist/client/objects-C3azvW8m.mjs.map +1 -0
- package/dist/client/objects-CM265S6b.mjs +56 -0
- package/dist/client/objects-CM265S6b.mjs.map +1 -0
- package/dist/client/objects-EE9Cd1wI.mjs +56 -0
- package/dist/client/objects-EE9Cd1wI.mjs.map +1 -0
- package/dist/client/projects-yiK0HGSA.mjs.map +1 -1
- package/dist/client/{routeInfo-CdTRlSxv.mjs → routeInfo-DXqB2HCf.mjs} +3 -3
- package/dist/client/routeInfo-DXqB2HCf.mjs.map +1 -0
- package/dist/client/router.d.ts +2 -1
- package/dist/client/{routes-BOf-GDMM.mjs → routes-CBd8CCuM.mjs} +27 -24
- package/dist/client/routes-CBd8CCuM.mjs.map +1 -0
- package/dist/client/{routes-CtfnI-aY.mjs → routes-CdDm-hhO.mjs} +2 -2
- package/dist/client/{routes-CtfnI-aY.mjs.map → routes-CdDm-hhO.mjs.map} +1 -1
- package/dist/client/securitygroups-Bd_uV4S9.mjs +595 -0
- package/dist/client/securitygroups-Bd_uV4S9.mjs.map +1 -0
- package/dist/client/{securitygroups-B8aLyFK7.mjs → securitygroups-Byte-iSp.mjs} +2 -2
- package/dist/client/{securitygroups-B8aLyFK7.mjs.map → securitygroups-Byte-iSp.mjs.map} +1 -1
- package/dist/client/services-D1PbooD1.mjs +6 -0
- package/dist/client/services-D1PbooD1.mjs.map +1 -0
- package/dist/client/services-DEMVtFyn.mjs +9 -0
- package/dist/client/services-DEMVtFyn.mjs.map +1 -0
- package/dist/client/store/AuthProvider.d.ts +1 -1
- package/dist/client/{trpcClient-Di56hpVv.mjs → trpcClient-D7gpR7YG.mjs} +2 -2
- package/dist/client/{trpcClient-Di56hpVv.mjs.map → trpcClient-D7gpR7YG.mjs.map} +1 -1
- package/dist/client/trpcClient.d.ts +139 -374
- package/dist/client/useModal-DCs1OJh7.mjs.map +1 -1
- package/dist/client/{useSecurityGroupPermissions-BPS1ibWq.mjs → useSecurityGroupPermissions-C29mzb3b.mjs} +15 -15
- package/dist/client/{useSecurityGroupPermissions-BPS1ibWq.mjs.map → useSecurityGroupPermissions-C29mzb3b.mjs.map} +1 -1
- package/dist/server/index.d.ts +164 -376
- package/dist/server/index.js +4223 -3131
- package/package.json +7 -9
- package/dist/client/AuthProvider-CQ6Yppoh.mjs.map +0 -1
- package/dist/client/BucketToastNotifications-Dq4dudkM.mjs +0 -665
- package/dist/client/BucketToastNotifications-Dq4dudkM.mjs.map +0 -1
- package/dist/client/ContentHeader-9KZdhOoA.mjs.map +0 -1
- package/dist/client/DeleteFlavorModal-Be2qZo4w.mjs +0 -713
- package/dist/client/DeleteFlavorModal-Be2qZo4w.mjs.map +0 -1
- package/dist/client/DeletePcaModal-CIFsGWyj.mjs +0 -80
- package/dist/client/DeletePcaModal-CIFsGWyj.mjs.map +0 -1
- package/dist/client/DetailsInfo-CHVD7d-W.mjs +0 -52
- package/dist/client/DetailsInfo-CHVD7d-W.mjs.map +0 -1
- package/dist/client/FiltersInput-DqT08Ib-.mjs +0 -81
- package/dist/client/FiltersInput-DqT08Ib-.mjs.map +0 -1
- package/dist/client/ImageToastNotifications-BGyX2J6j.mjs +0 -1219
- package/dist/client/ImageToastNotifications-BGyX2J6j.mjs.map +0 -1
- package/dist/client/_auth-D5_QNUos.mjs.map +0 -1
- package/dist/client/_flavorId-BsmqS9hP.mjs +0 -194
- package/dist/client/_flavorId-BsmqS9hP.mjs.map +0 -1
- package/dist/client/_floatingIpId-Bb9ZEJ6b.mjs +0 -228
- package/dist/client/_floatingIpId-Bb9ZEJ6b.mjs.map +0 -1
- package/dist/client/_imageId-C3As7sHE.mjs +0 -534
- package/dist/client/_imageId-C3As7sHE.mjs.map +0 -1
- package/dist/client/_pcaId-n0q0aDb6.mjs +0 -545
- package/dist/client/_pcaId-n0q0aDb6.mjs.map +0 -1
- package/dist/client/_projectId-BuBIFdgG.mjs +0 -291
- package/dist/client/_projectId-BuBIFdgG.mjs.map +0 -1
- package/dist/client/_projectId-DNZsNxJw.mjs +0 -98
- package/dist/client/_projectId-DNZsNxJw.mjs.map +0 -1
- package/dist/client/_securityGroupId-DFdNKa2l.mjs.map +0 -1
- package/dist/client/_storageType-Cn7TSOki.mjs +0 -81
- package/dist/client/_storageType-Cn7TSOki.mjs.map +0 -1
- package/dist/client/_storageType-_8Ambhxc.mjs +0 -2859
- package/dist/client/_storageType-_8Ambhxc.mjs.map +0 -1
- package/dist/client/about-C8tTrQaW.mjs.map +0 -1
- package/dist/client/assets/objectDownload.worker-BAc5Au4B.js.map +0 -1
- package/dist/client/aurora-jyvXcI4T.mjs.map +0 -1
- package/dist/client/build-CRLQyqu2.mjs.map +0 -1
- package/dist/client/flavors-BfTXqmoD.mjs.map +0 -1
- package/dist/client/floatingips-zhNK6Xxn.mjs +0 -562
- package/dist/client/floatingips-zhNK6Xxn.mjs.map +0 -1
- package/dist/client/images-DhZnqUG_.mjs +0 -1890
- package/dist/client/images-DhZnqUG_.mjs.map +0 -1
- package/dist/client/objects-B3mbk6V0.mjs +0 -6636
- package/dist/client/objects-B3mbk6V0.mjs.map +0 -1
- package/dist/client/objects-BQ8xvSW8.mjs +0 -103
- package/dist/client/objects-BQ8xvSW8.mjs.map +0 -1
- package/dist/client/objects-o2Cj_ndZ.mjs +0 -8
- package/dist/client/objects-o2Cj_ndZ.mjs.map +0 -1
- package/dist/client/pca-B60iWWfG.mjs +0 -251
- package/dist/client/pca-B60iWWfG.mjs.map +0 -1
- package/dist/client/pca-D0kKxHp4.mjs +0 -25
- package/dist/client/pca-D0kKxHp4.mjs.map +0 -1
- package/dist/client/pcaAccess-Br4kVjLQ.mjs +0 -9
- package/dist/client/pcaAccess-Br4kVjLQ.mjs.map +0 -1
- package/dist/client/routeInfo-CdTRlSxv.mjs.map +0 -1
- package/dist/client/routes-BOf-GDMM.mjs.map +0 -1
- package/dist/client/securitygroups-DRhFle2O.mjs +0 -589
- package/dist/client/securitygroups-DRhFle2O.mjs.map +0 -1
- package/dist/client/useListWithFiltering-aPTUNRaW.mjs +0 -32
- package/dist/client/useListWithFiltering-aPTUNRaW.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSecurityGroupPermissions-BPS1ibWq.mjs","names":["React","useState","useEffect","Modal","Form","FormRow","FormSection","TextInput","Button","ButtonRow","Spinner","ModalFooter","Textarea","Message","EditSecurityGroupModal","securityGroup","open","onClose","onUpdate","isLoading","error","useLingui","properties","setProperties","name","description","errors","setErrors","handleInputChange","e","value","type","target","checked","prev","newErrors","validateForm","trim","t","Object","keys","length","handleSubmit","preventDefault","updateData","undefined","id","handleClose","onCancel","size","title","modalFooter","className","variant","onClick","disabled","data-testid","dismissible","div","span","label","onChange","required","errortext","placeholder","rows","trpcReact","useSecurityGroupPermissions","projectId","data","permissions","canView","canCreate","canUpdate","canDelete","canCreateRule","canDeleteRule","canManageAccess","canViewRBAC","isLoading","isError","network","canUser","useQuery","project_id","permission","enabled","Boolean","select","canCreateRBAC","canDeleteRBAC","staleTime","Infinity","gcTime"],"sources":["../../src/client/routes/_auth/projects/$projectId/network/securitygroups/-components/-modals/EditSecurityGroupModal.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/-hooks/useSecurityGroupPermissions.ts"],"sourcesContent":["import React, { useState, useEffect } from \"react\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport {\n Modal,\n Form,\n FormRow,\n FormSection,\n TextInput,\n Button,\n ButtonRow,\n Spinner,\n ModalFooter,\n Textarea,\n Message,\n} from \"@cloudoperators/juno-ui-components\"\nimport type { SecurityGroup } from \"@/server/Network/types/securityGroup\"\nimport { UpdateSecurityGroupInput } from \"@/server/Network/types/securityGroup\"\n\ninterface EditSecurityGroupModalProps {\n securityGroup: SecurityGroup\n open: boolean\n onClose: () => void\n onUpdate?: (\n securityGroupId: string,\n data: Omit<UpdateSecurityGroupInput, \"securityGroupId\" | \"project_id\">\n ) => Promise<void>\n isLoading?: boolean\n error?: string | null\n}\n\ninterface SecurityGroupProperties {\n name: string\n description: string\n}\n\nexport const EditSecurityGroupModal: React.FC<EditSecurityGroupModalProps> = ({\n securityGroup,\n open,\n onClose,\n onUpdate,\n isLoading = false,\n error = null,\n}) => {\n const { t } = useLingui()\n\n const [properties, setProperties] = useState<SecurityGroupProperties>({\n name: securityGroup.name || \"\",\n description: securityGroup.description || \"\",\n })\n const [errors, setErrors] = useState<{ [key: string]: string }>({})\n\n // Update properties when securityGroup changes\n useEffect(() => {\n setProperties({\n name: securityGroup.name || \"\",\n description: securityGroup.description || \"\",\n })\n }, [securityGroup])\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n const { name, value, type } = e.target\n const checked = (e.target as HTMLInputElement).checked\n\n setProperties((prev) => ({\n ...prev,\n [name]: type === \"checkbox\" ? checked : value,\n }))\n\n if (errors[name]) {\n setErrors((prev) => {\n const newErrors = { ...prev }\n delete newErrors[name]\n return newErrors\n })\n }\n }\n\n const validateForm = (): boolean => {\n const newErrors: { [key: string]: string } = {}\n\n if (!properties.name || properties.name.trim() === \"\") {\n newErrors.name = t`Security group name is required`\n }\n\n setErrors(newErrors)\n return Object.keys(newErrors).length === 0\n }\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n\n if (!validateForm()) {\n return\n }\n\n if (onUpdate) {\n // Prepare base update data without stateful\n const updateData: Omit<UpdateSecurityGroupInput, \"securityGroupId\" | \"project_id\"> = {\n name: properties.name.trim(),\n description: properties.description.trim() || undefined,\n }\n\n // Note: We deliberately do NOT include 'stateful' field here\n // because it requires special 'update_security_group:stateful' permission\n // which needs cloud admin role. Regular users can only update name/description.\n\n await onUpdate(securityGroup.id, updateData)\n }\n }\n\n const handleClose = () => {\n setErrors({})\n onClose()\n }\n\n return (\n <Modal\n open={open}\n onCancel={handleClose}\n size=\"large\"\n title={t`Edit Security Group`}\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\"\n onClick={(e) => {\n handleSubmit(e)\n }}\n disabled={isLoading}\n data-testid=\"update-security-group-button\"\n >\n {isLoading ? <Spinner size=\"small\" /> : <Trans>Update Security Group</Trans>}\n </Button>\n </ButtonRow>\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-high text-sm\">\n <Trans>Updating security group...</Trans>\n </span>\n </div>\n )}\n\n {!isLoading && (\n <Form className=\"mb-6\">\n <FormSection className=\"mb-6\">\n <FormRow className=\"mb-6\">\n <TextInput\n id=\"name\"\n name=\"name\"\n label={t`Name`}\n value={properties.name}\n onChange={handleInputChange}\n required\n errortext={errors.name}\n placeholder={t`Type name`}\n disabled={isLoading}\n />\n </FormRow>\n\n <FormRow className=\"mb-6\">\n <Textarea\n id=\"description\"\n name=\"description\"\n label={t`Description`}\n value={properties.description}\n onChange={handleInputChange}\n placeholder={t`Description`}\n disabled={isLoading}\n rows={3}\n />\n </FormRow>\n {/* Note: Stateful checkbox is not shown here because it requires 'update_security_group:stateful' permission (cloud admin only) */}\n </FormSection>\n </Form>\n )}\n </Modal>\n )\n}\n","import { trpcReact } from \"@/client/trpcClient\"\n\nexport interface SecurityGroupPermissions {\n canView: boolean\n canCreate: boolean\n canUpdate: boolean\n canDelete: boolean\n canCreateRule: boolean\n canDeleteRule: boolean\n canManageAccess: boolean\n canViewRBAC: boolean\n}\n\n/**\n * Hook to fetch security group permissions for the current user\n * Uses React Query with infinite cache since permissions don't change during session\n */\nexport function useSecurityGroupPermissions(projectId: string) {\n const {\n data: permissions = {\n canView: false,\n canCreate: false,\n canUpdate: false,\n canDelete: false,\n canCreateRule: false,\n canDeleteRule: false,\n canManageAccess: false,\n canViewRBAC: false,\n },\n isLoading,\n isError,\n } = trpcReact.network.canUser.useQuery(\n {\n project_id: projectId || \"\",\n permission: [\n \"network:security_groups:read\",\n \"network:security_groups:create\",\n \"network:security_groups:update\",\n \"network:security_groups:delete\",\n \"network:security_group_rules:create\",\n \"network:security_group_rules:delete\",\n \"network:rbac_policies:create\",\n \"network:rbac_policies:delete\",\n \"network:rbac_policies:read\",\n ],\n },\n {\n enabled: Boolean(projectId), // Only fetch if we have a project ID\n select: ([\n canView,\n canCreate,\n canUpdate,\n canDelete,\n canCreateRule,\n canDeleteRule,\n canCreateRBAC,\n canDeleteRBAC,\n canViewRBAC,\n ]) => ({\n canView,\n canCreate,\n canUpdate,\n canDelete,\n canCreateRule,\n canDeleteRule,\n canManageAccess: canCreateRBAC && canDeleteRBAC,\n canViewRBAC,\n }),\n staleTime: Infinity, // Permissions don't change during session\n gcTime: Infinity, // Keep in cache forever (previously cacheTime)\n }\n )\n\n return {\n permissions,\n isLoading,\n isError,\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useSecurityGroupPermissions-C29mzb3b.mjs","names":["React","useState","useEffect","Modal","Form","FormRow","FormSection","TextInput","Button","ButtonRow","Spinner","ModalFooter","Textarea","Message","EditSecurityGroupModal","securityGroup","open","onClose","onUpdate","isLoading","error","useLingui","properties","setProperties","name","description","errors","setErrors","handleInputChange","e","value","type","target","checked","prev","newErrors","validateForm","trim","t","Object","keys","length","handleSubmit","preventDefault","updateData","undefined","id","handleClose","onCancel","size","title","modalFooter","className","variant","onClick","disabled","data-testid","dismissible","div","span","label","onChange","required","errortext","placeholder","rows","trpcReact","useSecurityGroupPermissions","projectId","data","permissions","canView","canCreate","canUpdate","canDelete","canCreateRule","canDeleteRule","canManageAccess","canViewRBAC","isLoading","isError","network","canUser","useQuery","project_id","permission","enabled","Boolean","select","canCreateRBAC","canDeleteRBAC","staleTime","Infinity","gcTime"],"sources":["../../src/client/routes/_auth/projects/$projectId/network/securitygroups/-components/-modals/EditSecurityGroupModal.tsx","../../src/client/routes/_auth/projects/$projectId/network/securitygroups/-hooks/useSecurityGroupPermissions.ts"],"sourcesContent":["import React, { useState, useEffect } from \"react\"\nimport { Trans, useLingui } from \"@lingui/react/macro\"\nimport {\n Modal,\n Form,\n FormRow,\n FormSection,\n TextInput,\n Button,\n ButtonRow,\n Spinner,\n ModalFooter,\n Textarea,\n Message,\n} from \"@cloudoperators/juno-ui-components\"\nimport type { SecurityGroup } from \"@/server/Network/types/securityGroup\"\nimport { UpdateSecurityGroupInput } from \"@/server/Network/types/securityGroup\"\n\ninterface EditSecurityGroupModalProps {\n securityGroup: SecurityGroup\n open: boolean\n onClose: () => void\n onUpdate?: (\n securityGroupId: string,\n data: Omit<UpdateSecurityGroupInput, \"securityGroupId\" | \"project_id\">\n ) => Promise<void>\n isLoading?: boolean\n error?: string | null\n}\n\ninterface SecurityGroupProperties {\n name: string\n description: string\n}\n\nexport const EditSecurityGroupModal: React.FC<EditSecurityGroupModalProps> = ({\n securityGroup,\n open,\n onClose,\n onUpdate,\n isLoading = false,\n error = null,\n}) => {\n const { t } = useLingui()\n\n const [properties, setProperties] = useState<SecurityGroupProperties>({\n name: securityGroup.name || \"\",\n description: securityGroup.description || \"\",\n })\n const [errors, setErrors] = useState<{ [key: string]: string }>({})\n\n // Update properties when securityGroup changes\n useEffect(() => {\n setProperties({\n name: securityGroup.name || \"\",\n description: securityGroup.description || \"\",\n })\n }, [securityGroup])\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n const { name, value, type } = e.target\n const checked = (e.target as HTMLInputElement).checked\n\n setProperties((prev) => ({\n ...prev,\n [name]: type === \"checkbox\" ? checked : value,\n }))\n\n if (errors[name]) {\n setErrors((prev) => {\n const newErrors = { ...prev }\n delete newErrors[name]\n return newErrors\n })\n }\n }\n\n const validateForm = (): boolean => {\n const newErrors: { [key: string]: string } = {}\n\n if (!properties.name || properties.name.trim() === \"\") {\n newErrors.name = t`Security group name is required`\n }\n\n setErrors(newErrors)\n return Object.keys(newErrors).length === 0\n }\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n\n if (!validateForm()) {\n return\n }\n\n if (onUpdate) {\n // Prepare base update data without stateful\n const updateData: Omit<UpdateSecurityGroupInput, \"securityGroupId\" | \"project_id\"> = {\n name: properties.name.trim(),\n description: properties.description.trim() || undefined,\n }\n\n // Note: We deliberately do NOT include 'stateful' field here\n // because it requires special 'update_security_group:stateful' permission\n // which needs cloud admin role. Regular users can only update name/description.\n\n await onUpdate(securityGroup.id, updateData)\n }\n }\n\n const handleClose = () => {\n setErrors({})\n onClose()\n }\n\n return (\n <Modal\n open={open}\n onCancel={handleClose}\n size=\"large\"\n title={t`Edit Security Group`}\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\"\n onClick={(e) => {\n handleSubmit(e)\n }}\n disabled={isLoading}\n data-testid=\"update-security-group-button\"\n >\n {isLoading ? <Spinner size=\"small\" /> : <Trans>Update Security Group</Trans>}\n </Button>\n </ButtonRow>\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-high text-sm\">\n <Trans>Updating security group...</Trans>\n </span>\n </div>\n )}\n\n {!isLoading && (\n <Form className=\"mb-6\">\n <FormSection className=\"mb-6\">\n <FormRow className=\"mb-6\">\n <TextInput\n id=\"name\"\n name=\"name\"\n label={t`Name`}\n value={properties.name}\n onChange={handleInputChange}\n required\n errortext={errors.name}\n placeholder={t`Type name`}\n disabled={isLoading}\n />\n </FormRow>\n\n <FormRow className=\"mb-6\">\n <Textarea\n id=\"description\"\n name=\"description\"\n label={t`Description`}\n value={properties.description}\n onChange={handleInputChange}\n placeholder={t`Description`}\n disabled={isLoading}\n rows={3}\n />\n </FormRow>\n {/* Note: Stateful checkbox is not shown here because it requires 'update_security_group:stateful' permission (cloud admin only) */}\n </FormSection>\n </Form>\n )}\n </Modal>\n )\n}\n","import { trpcReact } from \"@/client/trpcClient\"\n\nexport interface SecurityGroupPermissions {\n canView: boolean\n canCreate: boolean\n canUpdate: boolean\n canDelete: boolean\n canCreateRule: boolean\n canDeleteRule: boolean\n canManageAccess: boolean\n canViewRBAC: boolean\n}\n\n/**\n * Hook to fetch security group permissions for the current user\n * Uses React Query with infinite cache since permissions don't change during session\n */\nexport function useSecurityGroupPermissions(projectId: string) {\n const {\n data: permissions = {\n canView: false,\n canCreate: false,\n canUpdate: false,\n canDelete: false,\n canCreateRule: false,\n canDeleteRule: false,\n canManageAccess: false,\n canViewRBAC: false,\n },\n isLoading,\n isError,\n } = trpcReact.network.canUser.useQuery(\n {\n project_id: projectId || \"\",\n permission: [\n \"network:security_groups:read\",\n \"network:security_groups:create\",\n \"network:security_groups:update\",\n \"network:security_groups:delete\",\n \"network:security_group_rules:create\",\n \"network:security_group_rules:delete\",\n \"network:rbac_policies:create\",\n \"network:rbac_policies:delete\",\n \"network:rbac_policies:read\",\n ],\n },\n {\n enabled: Boolean(projectId), // Only fetch if we have a project ID\n select: ([\n canView,\n canCreate,\n canUpdate,\n canDelete,\n canCreateRule,\n canDeleteRule,\n canCreateRBAC,\n canDeleteRBAC,\n canViewRBAC,\n ]) => ({\n canView,\n canCreate,\n canUpdate,\n canDelete,\n canCreateRule,\n canDeleteRule,\n canManageAccess: canCreateRBAC && canDeleteRBAC,\n canViewRBAC,\n }),\n staleTime: Infinity, // Permissions don't change during session\n gcTime: Infinity, // Keep in cache forever (previously cacheTime)\n }\n )\n\n return {\n permissions,\n isLoading,\n isError,\n }\n}\n"],"mappings":";;;;;;AAmCA,IAAac,KAAiE,EAC5EC,kBACAC,SACAC,YACAC,aACAC,eAAY,IACZC,WAAQ,WACT;CACC,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQC,EAAAA,GAER,CAACC,GAAYC,KAAiBtB,EAAkC;EACpEuB,MAAMT,EAAcS,QAAQ;EAC5BC,aAAaV,EAAcU,eAAe;CAC5C,CAAA,GACM,CAACC,GAAQC,KAAa1B,EAAoC,CAAC,CAAA;CAGjEC,QAAU;EACRqB,EAAc;GACZC,MAAMT,EAAcS,QAAQ;GAC5BC,aAAaV,EAAcU,eAAe;EAC5C,CAAA;CACF,GAAG,CAACV,CAAc,CAAA;CAElB,IAAMa,KAAqBC,MAAAA;EACzB,IAAM,EAAEL,SAAMM,UAAOC,YAASF,EAAEG,QAC1BC,IAAU,EAAGD,OAA4BC;EAO/C,AALAV,GAAeW,OAAU;GACvB,GAAGA;IACFV,IAAOO,MAAS,aAAaE,IAAUH;EAC1C,EAAA,GAEIJ,EAAOF,MACTG,GAAWO,MAAAA;GACT,IAAMC,IAAY,EAAE,GAAGD,EAAK;GAE5B,OADA,OAAOC,EAAUX,IACVW;EACT,CAAA;CAEJ,GAEMC,UAAe;EACnB,IAAMD,IAAuC,CAAC;EAO9C,QALI,CAACb,EAAWE,QAAQF,EAAWE,KAAKa,KAAI,MAAO,QACjDF,EAAUX,OAAOc,EAAAA,EAAC,EAAA,IAAA,SAAgC,CAAA,IAGpDX,EAAUQ,CAAAA,GACHI,OAAOC,KAAKL,CAAAA,CAAAA,CAAWM,WAAW;CAC3C,GAEMC,IAAe,OAAOb,MAAAA;EAC1BA,MAAEc,eAAc,GAEXP,EAAAA,KAIDlB,GAAU;GAEZ,IAAM0B,IAA+E;IACnFpB,MAAMF,EAAWE,KAAKa,KAAI;IAC1BZ,aAAaH,EAAWG,YAAYY,KAAI,KAAMQ,KAAAA;GAChD;GAMA,MAAM3B,EAASH,EAAc+B,IAAIF,CAAAA;EACnC;CACF,GAEMG,UAAc;EAElB9B,AADAU,EAAU,CAAC,CAAA,GACXV,EAAAA;CACF;CAEA,OACE,gBAACd,GAAAA;EACOa;EACNgC,UAAUD;EACVE,MAAK;EACLC,OAAOZ,EAAAA,EAAC,EAAA,IAAA,SAAoB,CAAA;EAC5Ba,aACE,gBAACxC,GAAAA;GAAYyC,WAAU;GACrB,UAAA,gBAAC3C,GAAAA,EAAAA,UAAAA,CACC,gBAACD,GAAAA;IAAO6C,SAAQ;IAAUC,SAASP;IAAaQ,UAAUpC;IACxD,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;GAEF,CAAA,GAAA,gBAACX,GAAAA;IACC6C,SAAQ;IACRC,UAAUzB,MAAAA;KACRa,EAAab,CAAAA;IACf;IACA0B,UAAUpC;IACVqC,eAAY;IAEXrC,UAAAA,IAAY,gBAACT,GAAAA,EAAQuC,MAAK,QAAa,CAAA,IAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;;;;GAO/C7B,KACC,gBAACP,GAAAA;IAAQ4C,aAAa;IAAOJ,SAAQ;IAAQD,WAAU;IACpDhC,UAAAA;;GAIJD,KACC,gBAACuC,OAAAA;IAAIN,WAAU;IACb,UAAA,CAAA,gBAAC1C,GAAAA,EAAQ2C,SAAQ,UAAA,CAAA,GACjB,gBAACM,QAAAA;KAAKP,WAAU;KACd,UAAA,gBAAA,GAAA,EAAA,IAAA,SAAA,CAAA;;;GAKL,CAACjC,KACA,gBAACf,GAAAA;IAAKgD,WAAU;IACd,UAAA,gBAAC9C,GAAAA;KAAY8C,WAAU;KACrB,UAAA,CAAA,gBAAC/C,GAAAA;MAAQ+C,WAAU;MACjB,UAAA,gBAAC7C,GAAAA;OACCuC,IAAG;OACHtB,MAAK;OACLoC,OAAOtB,EAAAA,EAAC,EAAA,IAAA,SAAK,CAAA;OACbR,OAAOR,EAAWE;OAClBqC,UAAUjC;OACVkC,UAAQ;OACRC,WAAWrC,EAAOF;OAClBwC,aAAa1B,EAAAA,EAAC,EAAA,IAAA,SAAU,CAAA;OACxBiB,UAAUpC;;KAId,CAAA,GAAA,gBAACd,GAAAA;MAAQ+C,WAAU;MACjB,UAAA,gBAACxC,GAAAA;OACCkC,IAAG;OACHtB,MAAK;OACLoC,OAAOtB,EAAAA,EAAC,EAAA,IAAA,SAAY,CAAA;OACpBR,OAAOR,EAAWG;OAClBoC,UAAUjC;OACVoC,aAAa1B,EAAAA,EAAC,EAAA,IAAA,SAAY,CAAA;OAC1BiB,UAAUpC;OACV8C,MAAM;;;;;;;AAStB;;;AC/KA,SAAgBE,EAA4BC,GAAiB;CAC3D,IAAM,EACJC,MAAMC,IAAc;EAClBC,SAAS;EACTC,WAAW;EACXC,WAAW;EACXC,WAAW;EACXC,eAAe;EACfC,eAAe;EACfC,iBAAiB;EACjBC,aAAa;CACf,GACAC,cACAC,eACEd,EAAUe,QAAQC,QAAQC,SAC5B;EACEC,YAAYhB,KAAa;EACzBiB,YAAY;GACV;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACD;CACH,GACA;EACEC,SAASC,EAAQnB;EACjBoB,SAAS,CACPjB,GACAC,GACAC,GACAC,GACAC,GACAC,GACAa,GACAC,GACAZ,QACK;GACLP;GACAC;GACAC;GACAC;GACAC;GACAC;GACAC,iBAAiBY,KAAiBC;GAClCZ;EACF;EACAa,WAAWC;EACXC,QAAQD;CACV,CAAA;CAGF,OAAO;EACLtB;EACAS;EACAC;CACF;AACF"}
|