@cobaltcore-dev/aurora 0.2.2 → 0.3.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/AuroraApp.d.ts +10 -0
- package/dist/client/{ContentHeader-DtBiIwRY.mjs → ContentHeader-B_PWrxbw.mjs} +17 -17
- package/dist/client/{ContentHeader-DtBiIwRY.mjs.map → ContentHeader-B_PWrxbw.mjs.map} +1 -1
- package/dist/client/{DeleteFlavorModal-rmuYIafD.mjs → DeleteFlavorModal-BkPrQKyE.mjs} +146 -146
- package/dist/client/{DeleteFlavorModal-rmuYIafD.mjs.map → DeleteFlavorModal-BkPrQKyE.mjs.map} +1 -1
- package/dist/client/{EditSecurityGroupModal-B7Sz9puM.mjs → EditSecurityGroupModal-ad4uzlt0.mjs} +14 -14
- package/dist/client/{EditSecurityGroupModal-B7Sz9puM.mjs.map → EditSecurityGroupModal-ad4uzlt0.mjs.map} +1 -1
- package/dist/client/{FloatingIpActionModals-CfRJiZqD.mjs → FloatingIpActionModals-lKMwLuL8.mjs} +51 -51
- package/dist/client/{FloatingIpActionModals-CfRJiZqD.mjs.map → FloatingIpActionModals-lKMwLuL8.mjs.map} +1 -1
- package/dist/client/{ImageToastNotifications-Cw30RXsw.mjs → ImageToastNotifications--U13YiQ_.mjs} +328 -328
- package/dist/client/{ImageToastNotifications-Cw30RXsw.mjs.map → ImageToastNotifications--U13YiQ_.mjs.map} +1 -1
- package/dist/client/{ListToolbar-DuazvsAu.mjs → ListToolbar-C5lzTrit.mjs} +56 -56
- package/dist/client/{ListToolbar-DuazvsAu.mjs.map → ListToolbar-C5lzTrit.mjs.map} +1 -1
- package/dist/client/{RouteError-Cyto623-.mjs → RouteError-iP1Vd6bY.mjs} +2 -2
- package/dist/client/{RouteError-Cyto623-.mjs.map → RouteError-iP1Vd6bY.mjs.map} +1 -1
- package/dist/client/{_flavorId-B-1fYadl.mjs → _flavorId-BaNXUJhA.mjs} +49 -49
- package/dist/client/_flavorId-BaNXUJhA.mjs.map +1 -0
- package/dist/client/{_flavorId-BYfIHIV_.mjs → _flavorId-CnO76tuy.mjs} +10 -10
- package/dist/client/_flavorId-CnO76tuy.mjs.map +1 -0
- package/dist/client/{_floatingIpId-IrnN-ozB.mjs → _floatingIpId-C8G20nNt.mjs} +2 -2
- package/dist/client/{_floatingIpId-IrnN-ozB.mjs.map → _floatingIpId-C8G20nNt.mjs.map} +1 -1
- package/dist/client/{_floatingIpId-FQ5P2qMV.mjs → _floatingIpId-DdKnjdIV.mjs} +36 -36
- package/dist/client/{_floatingIpId-FQ5P2qMV.mjs.map → _floatingIpId-DdKnjdIV.mjs.map} +1 -1
- package/dist/client/{_imageId-Tx_9bqEc.mjs → _imageId-DdSbxFqG.mjs} +135 -135
- package/dist/client/_imageId-DdSbxFqG.mjs.map +1 -0
- package/dist/client/{_pcaId-CFuKY82d.mjs → _pcaId-DFkYJEb5.mjs} +136 -136
- package/dist/client/{_pcaId-CFuKY82d.mjs.map → _pcaId-DFkYJEb5.mjs.map} +1 -1
- package/dist/client/{_pcaId-Bck7S7gJ.mjs → _pcaId-DX_S-3hE.mjs} +2 -2
- package/dist/client/{_pcaId-Bck7S7gJ.mjs.map → _pcaId-DX_S-3hE.mjs.map} +1 -1
- package/dist/client/{_projectId-PSpuCKO7.mjs → _projectId-DYrcZ3E3.mjs} +9 -9
- package/dist/client/{_projectId-PSpuCKO7.mjs.map → _projectId-DYrcZ3E3.mjs.map} +1 -1
- package/dist/client/{_projectId-B1VjDd0Z.mjs → _projectId-Dha4XqX4.mjs} +3 -3
- package/dist/client/{_projectId-B1VjDd0Z.mjs.map → _projectId-Dha4XqX4.mjs.map} +1 -1
- package/dist/client/_projectId-DsSVV2EA.mjs +316 -0
- package/dist/client/_projectId-DsSVV2EA.mjs.map +1 -0
- package/dist/client/{_projectId-Pxp-RXK4.mjs → _projectId-KH5si25Q.mjs} +2 -2
- package/dist/client/{_projectId-Pxp-RXK4.mjs.map → _projectId-KH5si25Q.mjs.map} +1 -1
- package/dist/client/{_securityGroupId-VV2lUcGQ.mjs → _securityGroupId-DgaSqYex.mjs} +2 -2
- package/dist/client/{_securityGroupId-VV2lUcGQ.mjs.map → _securityGroupId-DgaSqYex.mjs.map} +1 -1
- package/dist/client/{_securityGroupId-Dqi6ddw4.mjs → _securityGroupId-O7FXfx0M.mjs} +306 -306
- package/dist/client/{_securityGroupId-Dqi6ddw4.mjs.map → _securityGroupId-O7FXfx0M.mjs.map} +1 -1
- package/dist/client/{about-B2AzqxFI.mjs → about-DN8n8sN8.mjs} +8 -8
- package/dist/client/{about-B2AzqxFI.mjs.map → about-DN8n8sN8.mjs.map} +1 -1
- package/dist/client/{build-Cf7iWbpH.mjs → build-CZRvXrAL.mjs} +1047 -1042
- package/dist/client/{build-Cf7iWbpH.mjs.map → build-CZRvXrAL.mjs.map} +1 -1
- package/dist/client/{constants-CCgR6fKI.mjs → constants-akdIBeTX.mjs} +6 -6
- package/dist/client/{constants-CCgR6fKI.mjs.map → constants-akdIBeTX.mjs.map} +1 -1
- package/dist/client/{containers-BWERuY0O.mjs → containers-BE2QiLBs.mjs} +748 -748
- package/dist/client/{containers-BWERuY0O.mjs.map → containers-BE2QiLBs.mjs.map} +1 -1
- package/dist/client/containers-Cs5vOeR2.mjs.map +1 -1
- package/dist/client/{containers-DovytjVP.mjs → containers-DmwhE9Uz.mjs} +6 -6
- package/dist/client/containers-DmwhE9Uz.mjs.map +1 -0
- package/dist/client/flavors-BXPYAFyQ.mjs.map +1 -1
- package/dist/client/{flavors-CUiALHcB.mjs → flavors-CY7A6--v.mjs} +2 -2
- package/dist/client/{flavors-CUiALHcB.mjs.map → flavors-CY7A6--v.mjs.map} +1 -1
- package/dist/client/{flavors-Bovz-I2U.mjs → flavors-pEcGkCut.mjs} +150 -150
- package/dist/client/{flavors-Bovz-I2U.mjs.map → flavors-pEcGkCut.mjs.map} +1 -1
- package/dist/client/{floatingips-BrjDiY2t.mjs → floatingips-BtL4d4m-.mjs} +118 -118
- package/dist/client/{floatingips-BrjDiY2t.mjs.map → floatingips-BtL4d4m-.mjs.map} +1 -1
- package/dist/client/{images-DaaCUXMI.mjs → images-C19gCFSy.mjs} +389 -389
- package/dist/client/{images-DaaCUXMI.mjs.map → images-C19gCFSy.mjs.map} +1 -1
- package/dist/client/images-DM9I8G0p.mjs.map +1 -1
- package/dist/client/{images-BZP3pBqj.mjs → images-I9gQfRa7.mjs} +2 -2
- package/dist/client/{images-BZP3pBqj.mjs.map → images-I9gQfRa7.mjs.map} +1 -1
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.js +416 -418
- package/dist/client/index.js.map +1 -1
- package/dist/client/objects-B4yrYf_a.mjs.map +1 -1
- package/dist/client/{objects-D4zBka5e.mjs → objects-BrYe_RaJ.mjs} +6 -6
- package/dist/client/objects-BrYe_RaJ.mjs.map +1 -0
- package/dist/client/{objects-Cw4Vu01M.mjs → objects-DOYFFn3Y.mjs} +1013 -1013
- package/dist/client/{objects-Cw4Vu01M.mjs.map → objects-DOYFFn3Y.mjs.map} +1 -1
- package/dist/client/{overview-2J54-loz.mjs → overview-BjRSFSBh.mjs} +2 -2
- package/dist/client/{overview-2J54-loz.mjs.map → overview-BjRSFSBh.mjs.map} +1 -1
- package/dist/client/{overview-BnmukbFh.mjs → overview-C4gjtc2q.mjs} +7 -7
- package/dist/client/{overview-BnmukbFh.mjs.map → overview-C4gjtc2q.mjs.map} +1 -1
- package/dist/client/{overview-D0AAvsmL.mjs → overview-CmQkJ4Hh.mjs} +2 -2
- package/dist/client/{overview-D0AAvsmL.mjs.map → overview-CmQkJ4Hh.mjs.map} +1 -1
- package/dist/client/{overview-BtIXpYBo.mjs → overview-DTLIAKkJ.mjs} +2 -2
- package/dist/client/{overview-BtIXpYBo.mjs.map → overview-DTLIAKkJ.mjs.map} +1 -1
- package/dist/client/{pca-V2aaOxZA.mjs → pca-CYFJxSZ2.mjs} +70 -70
- package/dist/client/{pca-V2aaOxZA.mjs.map → pca-CYFJxSZ2.mjs.map} +1 -1
- package/dist/client/{pca-BqZycwCu.mjs → pca-DzixU9Dl.mjs} +2 -2
- package/dist/client/{pca-BqZycwCu.mjs.map → pca-DzixU9Dl.mjs.map} +1 -1
- package/dist/client/projects-BsN4bvU2.mjs.map +1 -1
- package/dist/client/{projects-0feOw_b6.mjs → projects-BtyjXGq2.mjs} +2 -2
- package/dist/client/projects-BtyjXGq2.mjs.map +1 -0
- package/dist/client/projects-D3hOC1cy.mjs +95 -0
- package/dist/client/projects-D3hOC1cy.mjs.map +1 -0
- package/dist/client/{projects-jyIHL6DE.mjs → projects-DwVawmll.mjs} +2 -2
- package/dist/client/projects-DwVawmll.mjs.map +1 -0
- package/dist/client/{securitygroups-B4MkSBtI.mjs → securitygroups-DMCIDHQS.mjs} +114 -114
- package/dist/client/{securitygroups-B4MkSBtI.mjs.map → securitygroups-DMCIDHQS.mjs.map} +1 -1
- package/package.json +3 -3
- package/dist/client/_flavorId-B-1fYadl.mjs.map +0 -1
- package/dist/client/_flavorId-BYfIHIV_.mjs.map +0 -1
- package/dist/client/_imageId-Tx_9bqEc.mjs.map +0 -1
- package/dist/client/_projectId-Bs4W9hos.mjs +0 -283
- package/dist/client/_projectId-Bs4W9hos.mjs.map +0 -1
- package/dist/client/containers-DovytjVP.mjs.map +0 -1
- package/dist/client/objects-D4zBka5e.mjs.map +0 -1
- package/dist/client/projects-0feOw_b6.mjs.map +0 -1
- package/dist/client/projects-C1IYOvFQ.mjs +0 -144
- package/dist/client/projects-C1IYOvFQ.mjs.map +0 -1
- package/dist/client/projects-jyIHL6DE.mjs.map +0 -1
package/dist/client/{DeleteFlavorModal-rmuYIafD.mjs.map → DeleteFlavorModal-BkPrQKyE.mjs.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeleteFlavorModal-rmuYIafD.mjs","names":["React","DataGridRow","DataGridCell","TextInput","ButtonRow","Button","SpecFormRow","specKey","value","errors","isLoading","onKeyChange","onValueChange","onSave","onCancel","useLingui","className","onChange","e","target","placeholder","t","errortext","key","required","icon","onClick","variant","title","disabled","React","useState","useEffect","DataGridRow","DataGridCell","Button","Stack","Spinner","SpecRow","specKey","value","isDeleting","onDelete","canDelete","useLingui","confirm","setConfirm","timer","setTimeout","clearTimeout","handleConfirmDelete","button","variant","onClick","title","t","aria-label","data-testid","disabled","icon","distribution","alignment","React","use","Suspense","useState","startTransition","useErrorTranslation","Modal","Message","DataGrid","DataGridRow","DataGridHeadCell","DataGridCell","Stack","Button","Spinner","SpecFormRow","SpecRow","createPermissionsPromise","client","project","compute","canUser","query","project_id","permission","then","canCreate","canDelete","createExtraSpecsPromise","flavorId","getExtraSpecs","SpecsLoading","colSpan","distribution","alignment","variant","EditSpecContent","permissionsPromise","extraSpecsPromise","flavor","onSpecsUpdate","isAddingSpec","setIsAddingSpec","setMessage","useLingui","translateError","permissions","initialExtraSpecs","extraSpecs","setExtraSpecs","key","setKey","value","setValue","errors","setErrors","isDeleting","setIsDeleting","validateForm","trimmedKey","trim","trimmedValue","newErrors","Object","keys","includes","length","resetForm","handleSave","text","t","type","createExtraSpecs","mutate","id","extra_specs","newSpecs","error","Error","message","handleDelete","keyToDelete","deleteExtraSpec","handleKeyChange","newKey","prev","undefined","handleValueChange","newValue","shouldShowEmptyState","direction","className","label","data-testid","onClick","disabled","columns","specKey","isLoading","onKeyChange","onValueChange","onSave","onCancel","entries","map","specValue","onDelete","EditSpecModal","isOpen","onClose","setExtraSpecsPromise","useMemo","useEffect","handleClose","handleSpecsUpdate","specs","Promise","resolve","title","open","size","div","onDismiss","fallback","React","DataGridRow","DataGridCell","TextInput","ButtonRow","Button","TenantAccessFormRow","tenantId","flavorId","errors","isLoading","onTenantIdChange","onSave","onCancel","useLingui","className","value","onChange","e","target","placeholder","t","errortext","required","icon","onClick","variant","title","disabled","React","useState","useEffect","DataGridRow","DataGridCell","Button","Stack","Spinner","TenantAccessRow","access","isDeleting","onDelete","canDelete","useLingui","confirm","setConfirm","timer","setTimeout","clearTimeout","handleConfirmDelete","button","variant","onClick","title","t","aria-label","data-testid","disabled","tenantId","tenant_id","icon","flavor_id","className","distribution","alignment","React","use","Suspense","useState","startTransition","useEffect","useMemo","useErrorTranslation","Modal","Message","DataGrid","DataGridRow","DataGridHeadCell","DataGridCell","Stack","Spinner","Button","TenantAccessFormRow","TenantAccessRow","createPermissionsPromise","client","project","compute","canUser","query","project_id","permission","then","canAdd","canRemove","createFlavorAccessPromise","flavorId","getFlavorAccess","AccessLoading","colSpan","distribution","alignment","variant","AccessContent","permissionsPromise","flavorAccessPromise","flavor","onAccessUpdate","isAddingAccess","setIsAddingAccess","setMessage","useLingui","translateError","permissions","flavorAccess","tenantId","setTenantId","errors","setErrors","deletingTenants","setDeletingTenants","Set","isLoading","setIsLoading","isPublicFlavor","shouldShowEmptyState","length","validateForm","trimmedTenantId","trim","newErrors","some","access","tenant_id","Object","keys","resetForm","handleSave","text","t","type","updatedAccess","addTenantAccess","mutate","id","targetProjectId","error","errorMessage","message","handleRemoveTenant","tenantIdToRemove","prev","add","removeTenantAccess","newSet","delete","handleTenantIdChange","newTenantId","undefined","columns","className","direction","label","data-testid","onClick","disabled","onTenantIdChange","onSave","onCancel","map","isDeleting","has","onDelete","canDelete","ManageAccessModal","isOpen","onClose","filter","entry","idx","arr","findIndex","e","catch","msg","flavorAccessOverride","setFlavorAccessOverride","accessKey","activeFlavorAccessPromise","key","promise","handleClose","handleAccessUpdate","deduplicated","Promise","resolve","flavorName","name","title","open","size","div","onDismiss","dismissible","fallback","React","useState","Modal","Message","Spinner","ModalFooter","Button","ButtonRow","DataGrid","DataGridRow","DataGridHeadCell","DataGridCell","Stack","useErrorTranslation","DeleteFlavorModal","client","isOpen","onClose","project","flavor","onSuccess","useLingui","translateError","isLoading","setIsLoading","generalError","setGeneralError","handleDelete","id","t","compute","deleteFlavor","mutate","project_id","flavorId","handleClose","error","errorMessage","message","dismissError","onCancel","title","open","onConfirm","modalFooter","className","variant","onClick","disabled","size","distribution","alignment","div","onDismiss","text","columns","name","vcpus","ram","disk","swap"],"sources":["../../src/client/routes/_auth/projects/$projectId/compute/-components/Flavors/-components/SpecFormRow.tsx","../../src/client/routes/_auth/projects/$projectId/compute/-components/Flavors/-components/SpecRow.tsx","../../src/client/routes/_auth/projects/$projectId/compute/-components/Flavors/-components/EditSpecModal.tsx","../../src/client/routes/_auth/projects/$projectId/compute/-components/Flavors/-components/TenantAccessFormRow.tsx","../../src/client/routes/_auth/projects/$projectId/compute/-components/Flavors/-components/TenantAccessRow.tsx","../../src/client/routes/_auth/projects/$projectId/compute/-components/Flavors/-components/ManageAccessModal.tsx","../../src/client/routes/_auth/projects/$projectId/compute/-components/Flavors/-components/DeleteFlavorModal.tsx"],"sourcesContent":["import React from \"react\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { DataGridRow, DataGridCell, TextInput, ButtonRow, Button } from \"@cloudoperators/juno-ui-components\"\n\ninterface SpecFormRowProps {\n specKey: string\n value: string\n errors: { key?: string; value?: string }\n isLoading: boolean\n onKeyChange: (key: string) => void\n onValueChange: (value: string) => void\n onSave: () => void\n onCancel: () => void\n}\n\nexport const SpecFormRow: React.FC<SpecFormRowProps> = ({\n specKey,\n value,\n errors,\n isLoading,\n onKeyChange,\n onValueChange,\n onSave,\n onCancel,\n}) => {\n const { t } = useLingui()\n\n return (\n <DataGridRow>\n <DataGridCell className=\"pl-0\">\n <TextInput\n value={specKey}\n onChange={(e) => onKeyChange(e.target.value)}\n placeholder={t`Enter key`}\n errortext={errors.key}\n required\n />\n </DataGridCell>\n <DataGridCell className=\"pl-0\">\n <TextInput\n value={value}\n onChange={(e) => onValueChange(e.target.value)}\n placeholder={t`Enter value`}\n errortext={errors.value}\n required\n />\n </DataGridCell>\n <DataGridCell>\n <ButtonRow>\n <Button icon=\"check\" onClick={onSave} variant=\"primary\" title={t`Save Metadata`} disabled={isLoading} />\n <Button icon=\"cancel\" onClick={onCancel} title={t`Cancel`} disabled={isLoading} />\n </ButtonRow>\n </DataGridCell>\n </DataGridRow>\n )\n}\n","import React, { useState, useEffect } from \"react\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { DataGridRow, DataGridCell, Button, Stack, Spinner } from \"@cloudoperators/juno-ui-components\"\n\ninterface SpecRowProps {\n specKey: string\n value: string\n isDeleting: boolean\n onDelete: () => void\n canDelete?: boolean\n}\n\nexport const SpecRow: React.FC<SpecRowProps> = ({ specKey, value, isDeleting, onDelete, canDelete }) => {\n const { t } = useLingui()\n const [confirm, setConfirm] = useState(false)\n useEffect(() => {\n if (confirm) {\n const timer = setTimeout(() => {\n setConfirm(false)\n }, 3000)\n\n return () => clearTimeout(timer)\n }\n }, [confirm])\n\n const handleConfirmDelete = () => {\n setConfirm(false)\n onDelete()\n }\n\n const button = () => {\n if (!canDelete) {\n return <></>\n }\n if (confirm) {\n return (\n <Button\n variant=\"primary-danger\"\n onClick={handleConfirmDelete}\n title={t`Delete`}\n aria-label={t`Delete`}\n data-testid=\"confirm-deletion\"\n disabled={isDeleting}\n >\n {t`Delete`}\n </Button>\n )\n } else {\n return (\n <Button\n icon=\"deleteForever\"\n onClick={() => setConfirm(true)}\n title={t`Delete ${specKey}`}\n aria-label={t`Delete ${specKey}`}\n data-testid={`delete-${specKey}`}\n disabled={isDeleting}\n />\n )\n }\n }\n\n return (\n <DataGridRow>\n <DataGridCell>{specKey}</DataGridCell>\n <DataGridCell>{value}</DataGridCell>\n <DataGridCell>\n {isDeleting ? (\n <Stack distribution=\"center\" alignment=\"center\">\n <Spinner variant=\"primary\" />\n </Stack>\n ) : (\n <Stack distribution=\"end\" alignment=\"end\">\n {button()}\n </Stack>\n )}\n </DataGridCell>\n </DataGridRow>\n )\n}\n","import React, { use, Suspense, useState, startTransition } from \"react\"\nimport { TrpcClient } from \"@/client/trpcClient\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { useErrorTranslation } from \"@/client/utils/useErrorTranslation\"\nimport {\n Modal,\n Message,\n DataGrid,\n DataGridRow,\n DataGridHeadCell,\n DataGridCell,\n Stack,\n Button,\n Spinner,\n} from \"@cloudoperators/juno-ui-components\"\nimport { Flavor } from \"@/server/Compute/types/flavor\"\nimport { SpecFormRow } from \"./SpecFormRow\"\nimport { SpecRow } from \"./SpecRow\"\n\ninterface EditSpecModalProps {\n client: TrpcClient\n isOpen: boolean\n onClose: () => void\n project: string\n flavor: Flavor | null\n}\n\nconst createPermissionsPromise = (client: TrpcClient, project: string) => {\n return client.compute.canUser\n .query({\n project_id: project,\n permission: [\"flavor_specs:create\", \"flavor_specs:delete\"],\n })\n .then(([canCreate, canDelete]) => ({ canCreate, canDelete }))\n}\n\nconst createExtraSpecsPromise = (client: TrpcClient, project: string, flavorId: string) => {\n return client.compute.getExtraSpecs.query({\n project_id: project,\n flavorId: flavorId,\n })\n}\n\nfunction SpecsLoading() {\n return (\n <DataGridRow>\n <DataGridCell colSpan={3}>\n <Stack distribution=\"center\" alignment=\"center\">\n <Spinner variant=\"primary\" />\n </Stack>\n </DataGridCell>\n </DataGridRow>\n )\n}\n\nfunction EditSpecContent({\n permissionsPromise,\n extraSpecsPromise,\n client,\n project,\n flavor,\n onSpecsUpdate,\n isAddingSpec,\n setIsAddingSpec,\n setMessage,\n}: {\n permissionsPromise: Promise<{ canCreate: boolean; canDelete: boolean }>\n extraSpecsPromise: Promise<Record<string, string>>\n client: TrpcClient\n project: string\n flavor: Flavor\n onSpecsUpdate: (specs: Record<string, string>) => void\n isAddingSpec: boolean\n setIsAddingSpec: (adding: boolean) => void\n message: { text: string; type: \"error\" | \"info\" } | null\n setMessage: (msg: { text: string; type: \"error\" | \"info\" } | null) => void\n}) {\n const { t } = useLingui()\n const { translateError } = useErrorTranslation()\n\n const permissions = use(permissionsPromise)\n const initialExtraSpecs = use(extraSpecsPromise)\n\n const [extraSpecs, setExtraSpecs] = useState(initialExtraSpecs)\n const [key, setKey] = useState(\"\")\n const [value, setValue] = useState(\"\")\n const [errors, setErrors] = useState<{ key?: string; value?: string }>({})\n const [isDeleting, setIsDeleting] = useState<string | null>(null)\n\n const validateForm = () => {\n const trimmedKey = key.trim()\n const trimmedValue = value.trim()\n const newErrors: { key?: string; value?: string } = {}\n\n if (!trimmedKey) {\n newErrors.key = \"Key is required.\"\n } else if (Object.keys(extraSpecs).includes(trimmedKey)) {\n newErrors.key = \"Key already exists.\"\n }\n\n if (!trimmedValue) {\n newErrors.value = \"Value is required.\"\n }\n\n setErrors(newErrors)\n return Object.keys(newErrors).length === 0\n }\n\n const resetForm = () => {\n setKey(\"\")\n setValue(\"\")\n setErrors({})\n }\n\n const handleSave = async () => {\n if (!validateForm()) {\n setMessage({ text: t`Please fix the validation errors below.`, type: \"error\" })\n return\n }\n\n try {\n const trimmedKey = key.trim()\n const trimmedValue = value.trim()\n\n await client.compute.createExtraSpecs.mutate({\n project_id: project,\n flavorId: flavor.id,\n extra_specs: { [trimmedKey]: trimmedValue },\n })\n\n const newSpecs = { [trimmedKey]: trimmedValue, ...extraSpecs }\n setExtraSpecs(newSpecs)\n onSpecsUpdate(newSpecs)\n\n setMessage({\n text: t`Metadata \"${trimmedKey}\" has been added successfully.`,\n type: \"info\",\n })\n resetForm()\n setIsAddingSpec(false)\n } catch (error) {\n setMessage({\n text: translateError(error instanceof Error ? error.message : \"Failed to create extra spec\"),\n type: \"error\",\n })\n }\n }\n\n const handleDelete = async (keyToDelete: string) => {\n try {\n setIsDeleting(keyToDelete)\n await client.compute.deleteExtraSpec.mutate({\n project_id: project,\n flavorId: flavor.id,\n key: keyToDelete,\n })\n\n const newSpecs = { ...extraSpecs }\n delete newSpecs[keyToDelete]\n setExtraSpecs(newSpecs)\n onSpecsUpdate(newSpecs)\n\n setMessage({\n text: t`Metadata \"${keyToDelete}\" has been deleted successfully.`,\n type: \"info\",\n })\n } catch (error) {\n setMessage({\n text: translateError(error instanceof Error ? error.message : `Failed to delete extra spec \"${keyToDelete}\"`),\n type: \"error\",\n })\n } finally {\n setIsDeleting(null)\n }\n }\n\n const handleKeyChange = (newKey: string) => {\n setKey(newKey)\n if (errors.key) setErrors((prev) => ({ ...prev, key: undefined }))\n }\n\n const handleValueChange = (newValue: string) => {\n setValue(newValue)\n if (errors.value) setErrors((prev) => ({ ...prev, value: undefined }))\n }\n\n const shouldShowEmptyState = Object.keys(extraSpecs).length === 0 && !isAddingSpec\n\n return (\n <>\n {permissions.canCreate && (\n <Stack direction=\"horizontal\" className=\"bg-theme-background-lvl-1 justify-end p-2\">\n <Button\n label={t`Add Metadata`}\n data-testid=\"addExtraButton\"\n onClick={() => setIsAddingSpec(true)}\n variant=\"primary\"\n disabled={isAddingSpec}\n />\n </Stack>\n )}\n\n <DataGrid columns={3}>\n <DataGridRow>\n <DataGridHeadCell>{t`Key`}</DataGridHeadCell>\n <DataGridHeadCell>{t`Value`}</DataGridHeadCell>\n <DataGridHeadCell></DataGridHeadCell>\n </DataGridRow>\n\n {isAddingSpec && (\n <SpecFormRow\n specKey={key}\n value={value}\n errors={errors}\n isLoading={false}\n onKeyChange={handleKeyChange}\n onValueChange={handleValueChange}\n onSave={handleSave}\n onCancel={() => {\n resetForm()\n setIsAddingSpec(false)\n setMessage(null)\n }}\n />\n )}\n\n {Object.entries(extraSpecs).map(([specKey, specValue]) => (\n <SpecRow\n key={specKey}\n specKey={specKey}\n value={specValue}\n isDeleting={isDeleting === specKey}\n onDelete={() => handleDelete(specKey)}\n canDelete={permissions.canDelete}\n />\n ))}\n\n {shouldShowEmptyState && (\n <DataGridRow>\n <DataGridCell colSpan={3} className=\"text-theme-default py-4 text-center\">\n {t`No extra specs found. Click \"Add Metadata\" to create one.`}\n </DataGridCell>\n </DataGridRow>\n )}\n </DataGrid>\n </>\n )\n}\n\nexport const EditSpecModal: React.FC<EditSpecModalProps> = ({ client, isOpen, onClose, project, flavor }) => {\n const { t } = useLingui()\n\n const [message, setMessage] = useState<{ text: string; type: \"error\" | \"info\" } | null>(null)\n const [isAddingSpec, setIsAddingSpec] = useState(false)\n const [extraSpecsPromise, setExtraSpecsPromise] = useState<Promise<Record<string, string>> | null>(null)\n\n const permissionsPromise = React.useMemo(\n () => (isOpen ? createPermissionsPromise(client, project) : null),\n [client, project, isOpen]\n )\n\n React.useEffect(() => {\n if (isOpen && flavor?.id) {\n startTransition(() => {\n setExtraSpecsPromise(createExtraSpecsPromise(client, project, flavor.id))\n })\n }\n }, [isOpen, flavor?.id, client, project])\n\n const handleClose = () => {\n setMessage(null)\n setIsAddingSpec(false)\n setExtraSpecsPromise(null)\n onClose()\n }\n\n const handleSpecsUpdate = (specs: Record<string, string>) => {\n startTransition(() => {\n setExtraSpecsPromise(Promise.resolve(specs))\n })\n }\n\n if (!isOpen || !flavor || !permissionsPromise || !extraSpecsPromise) {\n return null\n }\n\n return (\n <Modal onCancel={handleClose} title={t`Edit Metadata`} open={isOpen} size=\"large\">\n <div>\n {message && (\n <Message onDismiss={() => setMessage(null)} text={message.text} variant={message.type} className=\"mb-4\" />\n )}\n\n <Suspense fallback={<SpecsLoading />}>\n <EditSpecContent\n permissionsPromise={permissionsPromise}\n extraSpecsPromise={extraSpecsPromise}\n client={client}\n project={project}\n flavor={flavor}\n onSpecsUpdate={handleSpecsUpdate}\n isAddingSpec={isAddingSpec}\n setIsAddingSpec={setIsAddingSpec}\n message={message}\n setMessage={setMessage}\n />\n </Suspense>\n </div>\n </Modal>\n )\n}\n","import React from \"react\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { DataGridRow, DataGridCell, TextInput, ButtonRow, Button } from \"@cloudoperators/juno-ui-components\"\n\ninterface TenantAccessFormRowProps {\n tenantId: string\n flavorId: string\n errors: { tenantId?: string }\n isLoading: boolean\n onTenantIdChange: (tenantId: string) => void\n onSave: () => void\n onCancel: () => void\n}\n\nexport const TenantAccessFormRow: React.FC<TenantAccessFormRowProps> = ({\n tenantId,\n flavorId,\n errors,\n isLoading,\n onTenantIdChange,\n onSave,\n onCancel,\n}) => {\n const { t } = useLingui()\n\n return (\n <DataGridRow>\n <DataGridCell>{flavorId}</DataGridCell>\n <DataGridCell className=\"pl-0\">\n <TextInput\n value={tenantId}\n onChange={(e) => onTenantIdChange(e.target.value)}\n placeholder={t`Enter tenant ID`}\n errortext={errors.tenantId}\n required\n />\n </DataGridCell>\n <DataGridCell>\n <ButtonRow>\n <Button icon=\"check\" onClick={onSave} variant=\"primary\" title={t`Add Tenant Access`} disabled={isLoading} />\n <Button icon=\"cancel\" onClick={onCancel} title={t`Cancel`} disabled={isLoading} />\n </ButtonRow>\n </DataGridCell>\n </DataGridRow>\n )\n}\n","import React, { useState, useEffect } from \"react\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { DataGridRow, DataGridCell, Button, Stack, Spinner } from \"@cloudoperators/juno-ui-components\"\n\ninterface FlavorAccess {\n flavor_id: string\n tenant_id: string\n}\n\ninterface TenantAccessRowProps {\n access: FlavorAccess\n isDeleting: boolean\n onDelete: () => void\n canDelete: boolean\n}\n\nexport const TenantAccessRow: React.FC<TenantAccessRowProps> = ({ access, isDeleting, onDelete, canDelete }) => {\n const { t } = useLingui()\n const [confirm, setConfirm] = useState(false)\n\n useEffect(() => {\n if (confirm) {\n const timer = setTimeout(() => {\n setConfirm(false)\n }, 3000)\n\n return () => clearTimeout(timer)\n }\n }, [confirm])\n\n const handleConfirmDelete = () => {\n setConfirm(false)\n onDelete()\n }\n\n const button = () => {\n if (!canDelete) {\n return <></>\n }\n if (confirm) {\n return (\n <Button\n variant=\"primary-danger\"\n onClick={handleConfirmDelete}\n title={t`Remove tenant access`}\n aria-label={t`Remove tenant access`}\n data-testid=\"confirm-removal\"\n disabled={isDeleting}\n >\n {t`Remove`}\n </Button>\n )\n } else {\n const tenantId = access.tenant_id\n\n return (\n <Button\n icon=\"deleteForever\"\n onClick={() => setConfirm(true)}\n title={t`Remove access for ${tenantId}`}\n aria-label={t`Remove access for ${tenantId}`}\n data-testid={`remove-${tenantId}`}\n disabled={isDeleting}\n />\n )\n }\n }\n\n return (\n <DataGridRow>\n <DataGridCell>{access.flavor_id}</DataGridCell>\n <DataGridCell className=\"break-all\">{access.tenant_id}</DataGridCell>\n <DataGridCell>\n {isDeleting ? (\n <Stack distribution=\"center\" alignment=\"center\">\n <Spinner variant=\"primary\" />\n </Stack>\n ) : (\n <Stack distribution=\"end\" alignment=\"end\">\n {button()}\n </Stack>\n )}\n </DataGridCell>\n </DataGridRow>\n )\n}\n","import React, { use, Suspense, useState, startTransition, useEffect, useMemo } from \"react\"\nimport { TrpcClient } from \"@/client/trpcClient\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { useErrorTranslation } from \"@/client/utils/useErrorTranslation\"\nimport {\n Modal,\n Message,\n DataGrid,\n DataGridRow,\n DataGridHeadCell,\n DataGridCell,\n Stack,\n Spinner,\n Button,\n} from \"@cloudoperators/juno-ui-components\"\nimport { Flavor } from \"@/server/Compute/types/flavor\"\nimport { TenantAccessFormRow } from \"./TenantAccessFormRow\"\nimport { TenantAccessRow } from \"./TenantAccessRow\"\n\ninterface ManageAccessProps {\n client: TrpcClient\n isOpen: boolean\n onClose: () => void\n project: string\n flavor: Flavor | null\n}\n\ninterface FlavorAccess {\n flavor_id: string\n tenant_id: string\n}\n\nconst createPermissionsPromise = (client: TrpcClient, project: string) => {\n return client.compute.canUser\n .query({\n project_id: project,\n permission: [\"flavors:add_project\", \"flavors:remove_project\"],\n })\n .then(([canAdd, canRemove]) => ({ canAdd, canRemove }))\n}\n\nconst createFlavorAccessPromise = (client: TrpcClient, project: string, flavorId: string) => {\n return client.compute.getFlavorAccess.query({\n project_id: project,\n flavorId: flavorId,\n })\n}\n\nfunction AccessLoading() {\n return (\n <DataGridRow>\n <DataGridCell colSpan={3}>\n <Stack distribution=\"center\" alignment=\"center\">\n <Spinner variant=\"primary\" />\n </Stack>\n </DataGridCell>\n </DataGridRow>\n )\n}\n\nfunction AccessContent({\n permissionsPromise,\n flavorAccessPromise,\n client,\n project,\n flavor,\n onAccessUpdate,\n isAddingAccess,\n setIsAddingAccess,\n setMessage,\n}: {\n permissionsPromise: Promise<{ canAdd: boolean; canRemove: boolean }>\n flavorAccessPromise: Promise<FlavorAccess[]>\n client: TrpcClient\n project: string\n flavor: Flavor\n onAccessUpdate: (access: FlavorAccess[]) => void\n isAddingAccess: boolean\n setIsAddingAccess: (adding: boolean) => void\n setMessage: (msg: { text: string; type: \"error\" | \"info\" } | null) => void\n}) {\n const { t } = useLingui()\n const { translateError } = useErrorTranslation()\n\n const permissions = use(permissionsPromise)\n const flavorAccess = use(flavorAccessPromise) // Direkt verwenden - React 19 macht es reaktiv\n\n const [tenantId, setTenantId] = useState(\"\")\n const [errors, setErrors] = useState<{ tenantId?: string }>({})\n const [deletingTenants, setDeletingTenants] = useState<Set<string>>(new Set())\n const [isLoading, setIsLoading] = useState(false)\n\n const isPublicFlavor = flavor[\"os-flavor-access:is_public\"] !== false\n const shouldShowEmptyState = flavorAccess.length === 0 && !isAddingAccess\n\n const validateForm = () => {\n const trimmedTenantId = tenantId.trim()\n const newErrors: { tenantId?: string } = {}\n\n if (!trimmedTenantId) {\n newErrors.tenantId = \"Tenant ID is required.\"\n } else if (flavorAccess.some((access) => access.tenant_id === trimmedTenantId)) {\n newErrors.tenantId = \"This tenant already has access to this flavor.\"\n }\n\n setErrors(newErrors)\n return Object.keys(newErrors).length === 0\n }\n\n const resetForm = () => {\n setTenantId(\"\")\n setErrors({})\n }\n\n const handleSave = async () => {\n if (!validateForm()) {\n setMessage({ text: t`Please fix the validation errors below.`, type: \"error\" })\n return\n }\n\n setIsLoading(true)\n try {\n const trimmedTenantId = tenantId.trim()\n\n const updatedAccess = await client.compute.addTenantAccess.mutate({\n project_id: project,\n flavorId: flavor.id,\n targetProjectId: trimmedTenantId,\n })\n\n onAccessUpdate(updatedAccess)\n\n setMessage({\n text: t`Tenant access for \"${trimmedTenantId}\" has been added successfully.`,\n type: \"info\",\n })\n resetForm()\n setIsAddingAccess(false)\n } catch (error) {\n const errorMessage = (error as Error)?.message || \"Failed to add tenant access\"\n\n setMessage({\n text: translateError(errorMessage || \"Failed to add tenant access\"),\n type: \"error\",\n })\n } finally {\n setIsLoading(false)\n }\n }\n\n const handleRemoveTenant = async (tenantIdToRemove: string) => {\n setDeletingTenants((prev) => new Set(prev).add(tenantIdToRemove))\n\n try {\n const updatedAccess = await client.compute.removeTenantAccess.mutate({\n project_id: project,\n flavorId: flavor.id,\n targetProjectId: tenantIdToRemove,\n })\n\n onAccessUpdate(updatedAccess)\n setMessage({\n text: t`Tenant access for \"${tenantIdToRemove}\" has been removed successfully.`,\n type: \"info\",\n })\n } catch (error) {\n const errorMessage = (error as Error)?.message || \"Failed to remove tenant access\"\n\n setMessage({\n text: translateError(errorMessage || `Failed to remove tenant access for \"${tenantIdToRemove}\"`),\n type: \"error\",\n })\n } finally {\n setDeletingTenants((prev) => {\n const newSet = new Set(prev)\n newSet.delete(tenantIdToRemove)\n return newSet\n })\n }\n }\n\n const handleTenantIdChange = (newTenantId: string) => {\n setTenantId(newTenantId)\n if (errors.tenantId) setErrors((prev) => ({ ...prev, tenantId: undefined }))\n }\n\n if (isPublicFlavor) {\n return (\n <DataGrid columns={3}>\n <DataGridRow>\n <DataGridHeadCell>{t`Flavor ID`}</DataGridHeadCell>\n <DataGridHeadCell>{t`Tenant ID`}</DataGridHeadCell>\n <DataGridHeadCell> </DataGridHeadCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridCell colSpan={3} className=\"text-theme-default py-4 text-center\">\n {t`This is a public flavor. All tenants have access to it.`}\n </DataGridCell>\n </DataGridRow>\n </DataGrid>\n )\n }\n\n return (\n <>\n {permissions.canAdd && (\n <Stack direction=\"horizontal\" className=\"bg-theme-background-lvl-1 justify-end p-2\">\n <Button\n label={t`Add Tenant Access`}\n data-testid=\"addTenantButton\"\n onClick={() => setIsAddingAccess(true)}\n variant=\"primary\"\n disabled={isAddingAccess}\n />\n </Stack>\n )}\n\n <DataGrid columns={3}>\n <DataGridRow>\n <DataGridHeadCell>{t`Flavor ID`}</DataGridHeadCell>\n <DataGridHeadCell>{t`Tenant ID`}</DataGridHeadCell>\n <DataGridHeadCell></DataGridHeadCell>\n </DataGridRow>\n\n {isAddingAccess && (\n <TenantAccessFormRow\n tenantId={tenantId}\n flavorId={flavor.id}\n errors={errors}\n isLoading={isLoading}\n onTenantIdChange={handleTenantIdChange}\n onSave={handleSave}\n onCancel={() => {\n resetForm()\n setIsAddingAccess(false)\n setMessage(null)\n }}\n />\n )}\n\n {flavorAccess.map((access) => (\n <TenantAccessRow\n key={access.tenant_id}\n access={access}\n isDeleting={deletingTenants.has(access.tenant_id)}\n onDelete={() => handleRemoveTenant(access.tenant_id)}\n canDelete={permissions.canRemove}\n />\n ))}\n\n {shouldShowEmptyState && (\n <DataGridRow>\n <DataGridCell colSpan={3} className=\"text-theme-default py-4 text-center\">\n {t`No specific tenant access configured for this private flavor. Click \"Add Tenant Access\" to grant access.`}\n </DataGridCell>\n </DataGridRow>\n )}\n </DataGrid>\n </>\n )\n}\n\nexport const ManageAccessModal: React.FC<ManageAccessProps> = ({ client, isOpen, onClose, project, flavor }) => {\n const { t } = useLingui()\n const { translateError } = useErrorTranslation()\n\n const [message, setMessage] = useState<{ text: string; type: \"error\" | \"info\" } | null>(null)\n const [isAddingAccess, setIsAddingAccess] = useState(false)\n\n const permissionsPromise = useMemo(\n () => (isOpen ? createPermissionsPromise(client, project) : null),\n [client, project, isOpen]\n )\n\n const flavorAccessPromise = useMemo(() => {\n if (!isOpen || !flavor?.id) return null\n return createFlavorAccessPromise(client, project, flavor.id)\n .then((access) =>\n access.filter((entry, idx, arr) => arr.findIndex((e) => e.tenant_id === entry.tenant_id) === idx)\n )\n .catch((error) => {\n const msg = translateError((error as Error)?.message || \"GET_FLAVOR_ACCESS_FAILED\")\n setMessage({ text: msg, type: \"error\" })\n return [] as FlavorAccess[]\n })\n }, [isOpen, flavor?.id, client, project])\n\n useEffect(() => {\n if (isOpen) setMessage(null)\n }, [isOpen, flavor?.id])\n\n // After add/remove, the server returns the updated list. We store it as an override so\n // the UI reflects the change immediately without refetching. The key prevents a stale\n // override from a previously opened flavor from leaking into the current modal session.\n const [flavorAccessOverride, setFlavorAccessOverride] = useState<{\n key: string\n promise: Promise<FlavorAccess[]>\n } | null>(null)\n\n const accessKey = `${isOpen}-${flavor?.id}`\n const activeFlavorAccessPromise =\n flavorAccessOverride?.key === accessKey ? flavorAccessOverride.promise : flavorAccessPromise\n\n const handleClose = () => {\n setMessage(null)\n setIsAddingAccess(false)\n setFlavorAccessOverride(null)\n onClose()\n }\n\n const handleAccessUpdate = (access: FlavorAccess[]) => {\n const deduplicated = access.filter(\n (entry, idx, arr) => arr.findIndex((e) => e.tenant_id === entry.tenant_id) === idx\n )\n startTransition(() => {\n setFlavorAccessOverride({ key: accessKey, promise: Promise.resolve(deduplicated) })\n })\n }\n\n if (!isOpen || !flavor || !permissionsPromise || !activeFlavorAccessPromise) {\n return null\n }\n const flavorName = flavor.name\n\n return (\n <Modal onCancel={handleClose} title={t`Manage Access - ${flavorName}`} open={isOpen} size=\"xl\">\n <div>\n {message && (\n <Message\n onDismiss={() => setMessage(null)}\n text={message.text}\n variant={message.type}\n className=\"mb-4\"\n dismissible\n />\n )}\n\n <Suspense fallback={<AccessLoading />}>\n <AccessContent\n permissionsPromise={permissionsPromise}\n flavorAccessPromise={activeFlavorAccessPromise}\n client={client}\n project={project}\n flavor={flavor}\n onAccessUpdate={handleAccessUpdate}\n isAddingAccess={isAddingAccess}\n setIsAddingAccess={setIsAddingAccess}\n setMessage={setMessage}\n />\n </Suspense>\n </div>\n </Modal>\n )\n}\n","import React, { useState } from \"react\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { TrpcClient } from \"@/client/trpcClient\"\nimport {\n Modal,\n Message,\n Spinner,\n ModalFooter,\n Button,\n ButtonRow,\n DataGrid,\n DataGridRow,\n DataGridHeadCell,\n DataGridCell,\n Stack,\n} from \"@cloudoperators/juno-ui-components\"\nimport { Flavor } from \"@/server/Compute/types/flavor\"\nimport { Trans } from \"@lingui/react/macro\"\nimport { useErrorTranslation } from \"@/client/utils/useErrorTranslation\"\n\ninterface DeleteFlavorModalProps {\n client: TrpcClient\n isOpen: boolean\n onClose: () => void\n project: string\n flavor: Flavor | null\n onSuccess: () => void\n}\n\nexport const DeleteFlavorModal: React.FC<DeleteFlavorModalProps> = ({\n client,\n isOpen,\n onClose,\n project,\n flavor,\n onSuccess,\n}) => {\n const { t } = useLingui()\n const { translateError } = useErrorTranslation()\n const [isLoading, setIsLoading] = useState(false)\n const [generalError, setGeneralError] = useState<string | null>(null)\n\n const handleDelete = async () => {\n if (!flavor?.id) {\n setGeneralError(t`No flavor selected for deletion.`)\n return\n }\n\n setGeneralError(null)\n\n try {\n setIsLoading(true)\n\n await client.compute.deleteFlavor.mutate({\n project_id: project,\n flavorId: flavor.id,\n })\n onSuccess()\n handleClose()\n } catch (error) {\n const errorMessage = (error as Error)?.message\n ? translateError((error as Error).message)\n : t`Failed to delete flavor. Please try again.`\n setGeneralError(errorMessage)\n } finally {\n setIsLoading(false)\n }\n }\n\n const handleClose = () => {\n setGeneralError(null)\n onClose()\n }\n\n const dismissError = () => {\n setGeneralError(null)\n }\n\n return (\n <Modal\n onCancel={handleClose}\n title={t`Delete Flavor`}\n open={isOpen}\n onConfirm={handleDelete}\n modalFooter={\n <ModalFooter className=\"flex justify-end\">\n <ButtonRow>\n <Button variant=\"primary-danger\" onClick={handleDelete} disabled={isLoading}>\n {isLoading ? <Spinner size=\"small\" /> : <Trans>Delete</Trans>}\n </Button>\n <Button variant=\"default\" onClick={handleClose}>\n <Trans>Cancel</Trans>\n </Button>\n </ButtonRow>\n </ModalFooter>\n }\n >\n {isLoading && (\n <Stack distribution=\"center\" alignment=\"center\">\n <Spinner variant=\"primary\" />\n </Stack>\n )}\n {!isLoading && (\n <div>\n {generalError && <Message onDismiss={dismissError} text={generalError} variant=\"error\" className=\"mb-4\" />}\n\n <Message\n text={t`This action cannot be undone. The flavor will be permanently deleted.`}\n variant=\"danger\"\n className=\"mb-4\"\n />\n\n {flavor && (\n <DataGrid columns={2}>\n <DataGridRow>\n <DataGridHeadCell>{t`Name`}</DataGridHeadCell>\n <DataGridCell>{flavor.name}</DataGridCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridHeadCell>{t`ID`}</DataGridHeadCell>\n <DataGridCell>{flavor.id}</DataGridCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridHeadCell>{t`VCPUs`}</DataGridHeadCell>\n <DataGridCell>{flavor.vcpus}</DataGridCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridHeadCell>{t`RAM`}</DataGridHeadCell>\n <DataGridCell>{flavor.ram} MiB</DataGridCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridHeadCell>{t`Disk`}</DataGridHeadCell>\n <DataGridCell>{flavor.disk} GiB</DataGridCell>\n </DataGridRow>\n {flavor.swap && (\n <DataGridRow>\n <DataGridHeadCell>{t`Swap`}</DataGridHeadCell>\n <DataGridCell>{flavor.swap} MiB</DataGridCell>\n </DataGridRow>\n )}\n </DataGrid>\n )}\n </div>\n )}\n </Modal>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DeleteFlavorModal-BkPrQKyE.mjs","names":["React","DataGridRow","DataGridCell","TextInput","ButtonRow","Button","SpecFormRow","specKey","value","errors","isLoading","onKeyChange","onValueChange","onSave","onCancel","useLingui","className","onChange","e","target","placeholder","t","errortext","key","required","icon","onClick","variant","title","disabled","React","useState","useEffect","DataGridRow","DataGridCell","Button","Stack","Spinner","SpecRow","specKey","value","isDeleting","onDelete","canDelete","useLingui","confirm","setConfirm","timer","setTimeout","clearTimeout","handleConfirmDelete","button","variant","onClick","title","t","aria-label","data-testid","disabled","icon","distribution","alignment","React","use","Suspense","useState","startTransition","useErrorTranslation","Modal","Message","DataGrid","DataGridRow","DataGridHeadCell","DataGridCell","Stack","Button","Spinner","SpecFormRow","SpecRow","createPermissionsPromise","client","project","compute","canUser","query","project_id","permission","then","canCreate","canDelete","createExtraSpecsPromise","flavorId","getExtraSpecs","SpecsLoading","colSpan","distribution","alignment","variant","EditSpecContent","permissionsPromise","extraSpecsPromise","flavor","onSpecsUpdate","isAddingSpec","setIsAddingSpec","setMessage","useLingui","translateError","permissions","initialExtraSpecs","extraSpecs","setExtraSpecs","key","setKey","value","setValue","errors","setErrors","isDeleting","setIsDeleting","validateForm","trimmedKey","trim","trimmedValue","newErrors","Object","keys","includes","length","resetForm","handleSave","text","t","type","createExtraSpecs","mutate","id","extra_specs","newSpecs","error","Error","message","handleDelete","keyToDelete","deleteExtraSpec","handleKeyChange","newKey","prev","undefined","handleValueChange","newValue","shouldShowEmptyState","direction","className","label","data-testid","onClick","disabled","columns","specKey","isLoading","onKeyChange","onValueChange","onSave","onCancel","entries","map","specValue","onDelete","EditSpecModal","isOpen","onClose","setExtraSpecsPromise","useMemo","useEffect","handleClose","handleSpecsUpdate","specs","Promise","resolve","title","open","size","div","onDismiss","fallback","React","DataGridRow","DataGridCell","TextInput","ButtonRow","Button","TenantAccessFormRow","tenantId","flavorId","errors","isLoading","onTenantIdChange","onSave","onCancel","useLingui","className","value","onChange","e","target","placeholder","t","errortext","required","icon","onClick","variant","title","disabled","React","useState","useEffect","DataGridRow","DataGridCell","Button","Stack","Spinner","TenantAccessRow","access","isDeleting","onDelete","canDelete","useLingui","confirm","setConfirm","timer","setTimeout","clearTimeout","handleConfirmDelete","button","variant","onClick","title","t","aria-label","data-testid","disabled","tenantId","tenant_id","icon","flavor_id","className","distribution","alignment","React","use","Suspense","useState","startTransition","useEffect","useMemo","useErrorTranslation","Modal","Message","DataGrid","DataGridRow","DataGridHeadCell","DataGridCell","Stack","Spinner","Button","TenantAccessFormRow","TenantAccessRow","createPermissionsPromise","client","project","compute","canUser","query","project_id","permission","then","canAdd","canRemove","createFlavorAccessPromise","flavorId","getFlavorAccess","AccessLoading","colSpan","distribution","alignment","variant","AccessContent","permissionsPromise","flavorAccessPromise","flavor","onAccessUpdate","isAddingAccess","setIsAddingAccess","setMessage","useLingui","translateError","permissions","flavorAccess","tenantId","setTenantId","errors","setErrors","deletingTenants","setDeletingTenants","Set","isLoading","setIsLoading","isPublicFlavor","shouldShowEmptyState","length","validateForm","trimmedTenantId","trim","newErrors","some","access","tenant_id","Object","keys","resetForm","handleSave","text","t","type","updatedAccess","addTenantAccess","mutate","id","targetProjectId","error","errorMessage","message","handleRemoveTenant","tenantIdToRemove","prev","add","removeTenantAccess","newSet","delete","handleTenantIdChange","newTenantId","undefined","columns","className","direction","label","data-testid","onClick","disabled","onTenantIdChange","onSave","onCancel","map","isDeleting","has","onDelete","canDelete","ManageAccessModal","isOpen","onClose","filter","entry","idx","arr","findIndex","e","catch","msg","flavorAccessOverride","setFlavorAccessOverride","accessKey","activeFlavorAccessPromise","key","promise","handleClose","handleAccessUpdate","deduplicated","Promise","resolve","flavorName","name","title","open","size","div","onDismiss","dismissible","fallback","React","useState","Modal","Message","Spinner","ModalFooter","Button","ButtonRow","DataGrid","DataGridRow","DataGridHeadCell","DataGridCell","Stack","useErrorTranslation","DeleteFlavorModal","client","isOpen","onClose","project","flavor","onSuccess","useLingui","translateError","isLoading","setIsLoading","generalError","setGeneralError","handleDelete","id","t","compute","deleteFlavor","mutate","project_id","flavorId","handleClose","error","errorMessage","message","dismissError","onCancel","title","open","onConfirm","modalFooter","className","variant","onClick","disabled","size","distribution","alignment","div","onDismiss","text","columns","name","vcpus","ram","disk","swap"],"sources":["../../src/client/routes/_auth/projects/$projectId/compute/-components/Flavors/-components/SpecFormRow.tsx","../../src/client/routes/_auth/projects/$projectId/compute/-components/Flavors/-components/SpecRow.tsx","../../src/client/routes/_auth/projects/$projectId/compute/-components/Flavors/-components/EditSpecModal.tsx","../../src/client/routes/_auth/projects/$projectId/compute/-components/Flavors/-components/TenantAccessFormRow.tsx","../../src/client/routes/_auth/projects/$projectId/compute/-components/Flavors/-components/TenantAccessRow.tsx","../../src/client/routes/_auth/projects/$projectId/compute/-components/Flavors/-components/ManageAccessModal.tsx","../../src/client/routes/_auth/projects/$projectId/compute/-components/Flavors/-components/DeleteFlavorModal.tsx"],"sourcesContent":["import React from \"react\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { DataGridRow, DataGridCell, TextInput, ButtonRow, Button } from \"@cloudoperators/juno-ui-components\"\n\ninterface SpecFormRowProps {\n specKey: string\n value: string\n errors: { key?: string; value?: string }\n isLoading: boolean\n onKeyChange: (key: string) => void\n onValueChange: (value: string) => void\n onSave: () => void\n onCancel: () => void\n}\n\nexport const SpecFormRow: React.FC<SpecFormRowProps> = ({\n specKey,\n value,\n errors,\n isLoading,\n onKeyChange,\n onValueChange,\n onSave,\n onCancel,\n}) => {\n const { t } = useLingui()\n\n return (\n <DataGridRow>\n <DataGridCell className=\"pl-0\">\n <TextInput\n value={specKey}\n onChange={(e) => onKeyChange(e.target.value)}\n placeholder={t`Enter key`}\n errortext={errors.key}\n required\n />\n </DataGridCell>\n <DataGridCell className=\"pl-0\">\n <TextInput\n value={value}\n onChange={(e) => onValueChange(e.target.value)}\n placeholder={t`Enter value`}\n errortext={errors.value}\n required\n />\n </DataGridCell>\n <DataGridCell>\n <ButtonRow>\n <Button icon=\"check\" onClick={onSave} variant=\"primary\" title={t`Save Metadata`} disabled={isLoading} />\n <Button icon=\"cancel\" onClick={onCancel} title={t`Cancel`} disabled={isLoading} />\n </ButtonRow>\n </DataGridCell>\n </DataGridRow>\n )\n}\n","import React, { useState, useEffect } from \"react\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { DataGridRow, DataGridCell, Button, Stack, Spinner } from \"@cloudoperators/juno-ui-components\"\n\ninterface SpecRowProps {\n specKey: string\n value: string\n isDeleting: boolean\n onDelete: () => void\n canDelete?: boolean\n}\n\nexport const SpecRow: React.FC<SpecRowProps> = ({ specKey, value, isDeleting, onDelete, canDelete }) => {\n const { t } = useLingui()\n const [confirm, setConfirm] = useState(false)\n useEffect(() => {\n if (confirm) {\n const timer = setTimeout(() => {\n setConfirm(false)\n }, 3000)\n\n return () => clearTimeout(timer)\n }\n }, [confirm])\n\n const handleConfirmDelete = () => {\n setConfirm(false)\n onDelete()\n }\n\n const button = () => {\n if (!canDelete) {\n return <></>\n }\n if (confirm) {\n return (\n <Button\n variant=\"primary-danger\"\n onClick={handleConfirmDelete}\n title={t`Delete`}\n aria-label={t`Delete`}\n data-testid=\"confirm-deletion\"\n disabled={isDeleting}\n >\n {t`Delete`}\n </Button>\n )\n } else {\n return (\n <Button\n icon=\"deleteForever\"\n onClick={() => setConfirm(true)}\n title={t`Delete ${specKey}`}\n aria-label={t`Delete ${specKey}`}\n data-testid={`delete-${specKey}`}\n disabled={isDeleting}\n />\n )\n }\n }\n\n return (\n <DataGridRow>\n <DataGridCell>{specKey}</DataGridCell>\n <DataGridCell>{value}</DataGridCell>\n <DataGridCell>\n {isDeleting ? (\n <Stack distribution=\"center\" alignment=\"center\">\n <Spinner variant=\"primary\" />\n </Stack>\n ) : (\n <Stack distribution=\"end\" alignment=\"end\">\n {button()}\n </Stack>\n )}\n </DataGridCell>\n </DataGridRow>\n )\n}\n","import React, { use, Suspense, useState, startTransition } from \"react\"\nimport { TrpcClient } from \"@/client/trpcClient\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { useErrorTranslation } from \"@/client/utils/useErrorTranslation\"\nimport {\n Modal,\n Message,\n DataGrid,\n DataGridRow,\n DataGridHeadCell,\n DataGridCell,\n Stack,\n Button,\n Spinner,\n} from \"@cloudoperators/juno-ui-components\"\nimport { Flavor } from \"@/server/Compute/types/flavor\"\nimport { SpecFormRow } from \"./SpecFormRow\"\nimport { SpecRow } from \"./SpecRow\"\n\ninterface EditSpecModalProps {\n client: TrpcClient\n isOpen: boolean\n onClose: () => void\n project: string\n flavor: Flavor | null\n}\n\nconst createPermissionsPromise = (client: TrpcClient, project: string) => {\n return client.compute.canUser\n .query({\n project_id: project,\n permission: [\"flavor_specs:create\", \"flavor_specs:delete\"],\n })\n .then(([canCreate, canDelete]) => ({ canCreate, canDelete }))\n}\n\nconst createExtraSpecsPromise = (client: TrpcClient, project: string, flavorId: string) => {\n return client.compute.getExtraSpecs.query({\n project_id: project,\n flavorId: flavorId,\n })\n}\n\nfunction SpecsLoading() {\n return (\n <DataGridRow>\n <DataGridCell colSpan={3}>\n <Stack distribution=\"center\" alignment=\"center\">\n <Spinner variant=\"primary\" />\n </Stack>\n </DataGridCell>\n </DataGridRow>\n )\n}\n\nfunction EditSpecContent({\n permissionsPromise,\n extraSpecsPromise,\n client,\n project,\n flavor,\n onSpecsUpdate,\n isAddingSpec,\n setIsAddingSpec,\n setMessage,\n}: {\n permissionsPromise: Promise<{ canCreate: boolean; canDelete: boolean }>\n extraSpecsPromise: Promise<Record<string, string>>\n client: TrpcClient\n project: string\n flavor: Flavor\n onSpecsUpdate: (specs: Record<string, string>) => void\n isAddingSpec: boolean\n setIsAddingSpec: (adding: boolean) => void\n message: { text: string; type: \"error\" | \"info\" } | null\n setMessage: (msg: { text: string; type: \"error\" | \"info\" } | null) => void\n}) {\n const { t } = useLingui()\n const { translateError } = useErrorTranslation()\n\n const permissions = use(permissionsPromise)\n const initialExtraSpecs = use(extraSpecsPromise)\n\n const [extraSpecs, setExtraSpecs] = useState(initialExtraSpecs)\n const [key, setKey] = useState(\"\")\n const [value, setValue] = useState(\"\")\n const [errors, setErrors] = useState<{ key?: string; value?: string }>({})\n const [isDeleting, setIsDeleting] = useState<string | null>(null)\n\n const validateForm = () => {\n const trimmedKey = key.trim()\n const trimmedValue = value.trim()\n const newErrors: { key?: string; value?: string } = {}\n\n if (!trimmedKey) {\n newErrors.key = \"Key is required.\"\n } else if (Object.keys(extraSpecs).includes(trimmedKey)) {\n newErrors.key = \"Key already exists.\"\n }\n\n if (!trimmedValue) {\n newErrors.value = \"Value is required.\"\n }\n\n setErrors(newErrors)\n return Object.keys(newErrors).length === 0\n }\n\n const resetForm = () => {\n setKey(\"\")\n setValue(\"\")\n setErrors({})\n }\n\n const handleSave = async () => {\n if (!validateForm()) {\n setMessage({ text: t`Please fix the validation errors below.`, type: \"error\" })\n return\n }\n\n try {\n const trimmedKey = key.trim()\n const trimmedValue = value.trim()\n\n await client.compute.createExtraSpecs.mutate({\n project_id: project,\n flavorId: flavor.id,\n extra_specs: { [trimmedKey]: trimmedValue },\n })\n\n const newSpecs = { [trimmedKey]: trimmedValue, ...extraSpecs }\n setExtraSpecs(newSpecs)\n onSpecsUpdate(newSpecs)\n\n setMessage({\n text: t`Metadata \"${trimmedKey}\" has been added successfully.`,\n type: \"info\",\n })\n resetForm()\n setIsAddingSpec(false)\n } catch (error) {\n setMessage({\n text: translateError(error instanceof Error ? error.message : \"Failed to create extra spec\"),\n type: \"error\",\n })\n }\n }\n\n const handleDelete = async (keyToDelete: string) => {\n try {\n setIsDeleting(keyToDelete)\n await client.compute.deleteExtraSpec.mutate({\n project_id: project,\n flavorId: flavor.id,\n key: keyToDelete,\n })\n\n const newSpecs = { ...extraSpecs }\n delete newSpecs[keyToDelete]\n setExtraSpecs(newSpecs)\n onSpecsUpdate(newSpecs)\n\n setMessage({\n text: t`Metadata \"${keyToDelete}\" has been deleted successfully.`,\n type: \"info\",\n })\n } catch (error) {\n setMessage({\n text: translateError(error instanceof Error ? error.message : `Failed to delete extra spec \"${keyToDelete}\"`),\n type: \"error\",\n })\n } finally {\n setIsDeleting(null)\n }\n }\n\n const handleKeyChange = (newKey: string) => {\n setKey(newKey)\n if (errors.key) setErrors((prev) => ({ ...prev, key: undefined }))\n }\n\n const handleValueChange = (newValue: string) => {\n setValue(newValue)\n if (errors.value) setErrors((prev) => ({ ...prev, value: undefined }))\n }\n\n const shouldShowEmptyState = Object.keys(extraSpecs).length === 0 && !isAddingSpec\n\n return (\n <>\n {permissions.canCreate && (\n <Stack direction=\"horizontal\" className=\"bg-theme-background-lvl-1 justify-end p-2\">\n <Button\n label={t`Add Metadata`}\n data-testid=\"addExtraButton\"\n onClick={() => setIsAddingSpec(true)}\n variant=\"primary\"\n disabled={isAddingSpec}\n />\n </Stack>\n )}\n\n <DataGrid columns={3}>\n <DataGridRow>\n <DataGridHeadCell>{t`Key`}</DataGridHeadCell>\n <DataGridHeadCell>{t`Value`}</DataGridHeadCell>\n <DataGridHeadCell></DataGridHeadCell>\n </DataGridRow>\n\n {isAddingSpec && (\n <SpecFormRow\n specKey={key}\n value={value}\n errors={errors}\n isLoading={false}\n onKeyChange={handleKeyChange}\n onValueChange={handleValueChange}\n onSave={handleSave}\n onCancel={() => {\n resetForm()\n setIsAddingSpec(false)\n setMessage(null)\n }}\n />\n )}\n\n {Object.entries(extraSpecs).map(([specKey, specValue]) => (\n <SpecRow\n key={specKey}\n specKey={specKey}\n value={specValue}\n isDeleting={isDeleting === specKey}\n onDelete={() => handleDelete(specKey)}\n canDelete={permissions.canDelete}\n />\n ))}\n\n {shouldShowEmptyState && (\n <DataGridRow>\n <DataGridCell colSpan={3} className=\"text-theme-default py-4 text-center\">\n {t`No extra specs found. Click \"Add Metadata\" to create one.`}\n </DataGridCell>\n </DataGridRow>\n )}\n </DataGrid>\n </>\n )\n}\n\nexport const EditSpecModal: React.FC<EditSpecModalProps> = ({ client, isOpen, onClose, project, flavor }) => {\n const { t } = useLingui()\n\n const [message, setMessage] = useState<{ text: string; type: \"error\" | \"info\" } | null>(null)\n const [isAddingSpec, setIsAddingSpec] = useState(false)\n const [extraSpecsPromise, setExtraSpecsPromise] = useState<Promise<Record<string, string>> | null>(null)\n\n const permissionsPromise = React.useMemo(\n () => (isOpen ? createPermissionsPromise(client, project) : null),\n [client, project, isOpen]\n )\n\n React.useEffect(() => {\n if (isOpen && flavor?.id) {\n startTransition(() => {\n setExtraSpecsPromise(createExtraSpecsPromise(client, project, flavor.id))\n })\n }\n }, [isOpen, flavor?.id, client, project])\n\n const handleClose = () => {\n setMessage(null)\n setIsAddingSpec(false)\n setExtraSpecsPromise(null)\n onClose()\n }\n\n const handleSpecsUpdate = (specs: Record<string, string>) => {\n startTransition(() => {\n setExtraSpecsPromise(Promise.resolve(specs))\n })\n }\n\n if (!isOpen || !flavor || !permissionsPromise || !extraSpecsPromise) {\n return null\n }\n\n return (\n <Modal onCancel={handleClose} title={t`Edit Metadata`} open={isOpen} size=\"large\">\n <div>\n {message && (\n <Message onDismiss={() => setMessage(null)} text={message.text} variant={message.type} className=\"mb-4\" />\n )}\n\n <Suspense fallback={<SpecsLoading />}>\n <EditSpecContent\n permissionsPromise={permissionsPromise}\n extraSpecsPromise={extraSpecsPromise}\n client={client}\n project={project}\n flavor={flavor}\n onSpecsUpdate={handleSpecsUpdate}\n isAddingSpec={isAddingSpec}\n setIsAddingSpec={setIsAddingSpec}\n message={message}\n setMessage={setMessage}\n />\n </Suspense>\n </div>\n </Modal>\n )\n}\n","import React from \"react\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { DataGridRow, DataGridCell, TextInput, ButtonRow, Button } from \"@cloudoperators/juno-ui-components\"\n\ninterface TenantAccessFormRowProps {\n tenantId: string\n flavorId: string\n errors: { tenantId?: string }\n isLoading: boolean\n onTenantIdChange: (tenantId: string) => void\n onSave: () => void\n onCancel: () => void\n}\n\nexport const TenantAccessFormRow: React.FC<TenantAccessFormRowProps> = ({\n tenantId,\n flavorId,\n errors,\n isLoading,\n onTenantIdChange,\n onSave,\n onCancel,\n}) => {\n const { t } = useLingui()\n\n return (\n <DataGridRow>\n <DataGridCell>{flavorId}</DataGridCell>\n <DataGridCell className=\"pl-0\">\n <TextInput\n value={tenantId}\n onChange={(e) => onTenantIdChange(e.target.value)}\n placeholder={t`Enter tenant ID`}\n errortext={errors.tenantId}\n required\n />\n </DataGridCell>\n <DataGridCell>\n <ButtonRow>\n <Button icon=\"check\" onClick={onSave} variant=\"primary\" title={t`Add Tenant Access`} disabled={isLoading} />\n <Button icon=\"cancel\" onClick={onCancel} title={t`Cancel`} disabled={isLoading} />\n </ButtonRow>\n </DataGridCell>\n </DataGridRow>\n )\n}\n","import React, { useState, useEffect } from \"react\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { DataGridRow, DataGridCell, Button, Stack, Spinner } from \"@cloudoperators/juno-ui-components\"\n\ninterface FlavorAccess {\n flavor_id: string\n tenant_id: string\n}\n\ninterface TenantAccessRowProps {\n access: FlavorAccess\n isDeleting: boolean\n onDelete: () => void\n canDelete: boolean\n}\n\nexport const TenantAccessRow: React.FC<TenantAccessRowProps> = ({ access, isDeleting, onDelete, canDelete }) => {\n const { t } = useLingui()\n const [confirm, setConfirm] = useState(false)\n\n useEffect(() => {\n if (confirm) {\n const timer = setTimeout(() => {\n setConfirm(false)\n }, 3000)\n\n return () => clearTimeout(timer)\n }\n }, [confirm])\n\n const handleConfirmDelete = () => {\n setConfirm(false)\n onDelete()\n }\n\n const button = () => {\n if (!canDelete) {\n return <></>\n }\n if (confirm) {\n return (\n <Button\n variant=\"primary-danger\"\n onClick={handleConfirmDelete}\n title={t`Remove tenant access`}\n aria-label={t`Remove tenant access`}\n data-testid=\"confirm-removal\"\n disabled={isDeleting}\n >\n {t`Remove`}\n </Button>\n )\n } else {\n const tenantId = access.tenant_id\n\n return (\n <Button\n icon=\"deleteForever\"\n onClick={() => setConfirm(true)}\n title={t`Remove access for ${tenantId}`}\n aria-label={t`Remove access for ${tenantId}`}\n data-testid={`remove-${tenantId}`}\n disabled={isDeleting}\n />\n )\n }\n }\n\n return (\n <DataGridRow>\n <DataGridCell>{access.flavor_id}</DataGridCell>\n <DataGridCell className=\"break-all\">{access.tenant_id}</DataGridCell>\n <DataGridCell>\n {isDeleting ? (\n <Stack distribution=\"center\" alignment=\"center\">\n <Spinner variant=\"primary\" />\n </Stack>\n ) : (\n <Stack distribution=\"end\" alignment=\"end\">\n {button()}\n </Stack>\n )}\n </DataGridCell>\n </DataGridRow>\n )\n}\n","import React, { use, Suspense, useState, startTransition, useEffect, useMemo } from \"react\"\nimport { TrpcClient } from \"@/client/trpcClient\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { useErrorTranslation } from \"@/client/utils/useErrorTranslation\"\nimport {\n Modal,\n Message,\n DataGrid,\n DataGridRow,\n DataGridHeadCell,\n DataGridCell,\n Stack,\n Spinner,\n Button,\n} from \"@cloudoperators/juno-ui-components\"\nimport { Flavor } from \"@/server/Compute/types/flavor\"\nimport { TenantAccessFormRow } from \"./TenantAccessFormRow\"\nimport { TenantAccessRow } from \"./TenantAccessRow\"\n\ninterface ManageAccessProps {\n client: TrpcClient\n isOpen: boolean\n onClose: () => void\n project: string\n flavor: Flavor | null\n}\n\ninterface FlavorAccess {\n flavor_id: string\n tenant_id: string\n}\n\nconst createPermissionsPromise = (client: TrpcClient, project: string) => {\n return client.compute.canUser\n .query({\n project_id: project,\n permission: [\"flavors:add_project\", \"flavors:remove_project\"],\n })\n .then(([canAdd, canRemove]) => ({ canAdd, canRemove }))\n}\n\nconst createFlavorAccessPromise = (client: TrpcClient, project: string, flavorId: string) => {\n return client.compute.getFlavorAccess.query({\n project_id: project,\n flavorId: flavorId,\n })\n}\n\nfunction AccessLoading() {\n return (\n <DataGridRow>\n <DataGridCell colSpan={3}>\n <Stack distribution=\"center\" alignment=\"center\">\n <Spinner variant=\"primary\" />\n </Stack>\n </DataGridCell>\n </DataGridRow>\n )\n}\n\nfunction AccessContent({\n permissionsPromise,\n flavorAccessPromise,\n client,\n project,\n flavor,\n onAccessUpdate,\n isAddingAccess,\n setIsAddingAccess,\n setMessage,\n}: {\n permissionsPromise: Promise<{ canAdd: boolean; canRemove: boolean }>\n flavorAccessPromise: Promise<FlavorAccess[]>\n client: TrpcClient\n project: string\n flavor: Flavor\n onAccessUpdate: (access: FlavorAccess[]) => void\n isAddingAccess: boolean\n setIsAddingAccess: (adding: boolean) => void\n setMessage: (msg: { text: string; type: \"error\" | \"info\" } | null) => void\n}) {\n const { t } = useLingui()\n const { translateError } = useErrorTranslation()\n\n const permissions = use(permissionsPromise)\n const flavorAccess = use(flavorAccessPromise) // Direkt verwenden - React 19 macht es reaktiv\n\n const [tenantId, setTenantId] = useState(\"\")\n const [errors, setErrors] = useState<{ tenantId?: string }>({})\n const [deletingTenants, setDeletingTenants] = useState<Set<string>>(new Set())\n const [isLoading, setIsLoading] = useState(false)\n\n const isPublicFlavor = flavor[\"os-flavor-access:is_public\"] !== false\n const shouldShowEmptyState = flavorAccess.length === 0 && !isAddingAccess\n\n const validateForm = () => {\n const trimmedTenantId = tenantId.trim()\n const newErrors: { tenantId?: string } = {}\n\n if (!trimmedTenantId) {\n newErrors.tenantId = \"Tenant ID is required.\"\n } else if (flavorAccess.some((access) => access.tenant_id === trimmedTenantId)) {\n newErrors.tenantId = \"This tenant already has access to this flavor.\"\n }\n\n setErrors(newErrors)\n return Object.keys(newErrors).length === 0\n }\n\n const resetForm = () => {\n setTenantId(\"\")\n setErrors({})\n }\n\n const handleSave = async () => {\n if (!validateForm()) {\n setMessage({ text: t`Please fix the validation errors below.`, type: \"error\" })\n return\n }\n\n setIsLoading(true)\n try {\n const trimmedTenantId = tenantId.trim()\n\n const updatedAccess = await client.compute.addTenantAccess.mutate({\n project_id: project,\n flavorId: flavor.id,\n targetProjectId: trimmedTenantId,\n })\n\n onAccessUpdate(updatedAccess)\n\n setMessage({\n text: t`Tenant access for \"${trimmedTenantId}\" has been added successfully.`,\n type: \"info\",\n })\n resetForm()\n setIsAddingAccess(false)\n } catch (error) {\n const errorMessage = (error as Error)?.message || \"Failed to add tenant access\"\n\n setMessage({\n text: translateError(errorMessage || \"Failed to add tenant access\"),\n type: \"error\",\n })\n } finally {\n setIsLoading(false)\n }\n }\n\n const handleRemoveTenant = async (tenantIdToRemove: string) => {\n setDeletingTenants((prev) => new Set(prev).add(tenantIdToRemove))\n\n try {\n const updatedAccess = await client.compute.removeTenantAccess.mutate({\n project_id: project,\n flavorId: flavor.id,\n targetProjectId: tenantIdToRemove,\n })\n\n onAccessUpdate(updatedAccess)\n setMessage({\n text: t`Tenant access for \"${tenantIdToRemove}\" has been removed successfully.`,\n type: \"info\",\n })\n } catch (error) {\n const errorMessage = (error as Error)?.message || \"Failed to remove tenant access\"\n\n setMessage({\n text: translateError(errorMessage || `Failed to remove tenant access for \"${tenantIdToRemove}\"`),\n type: \"error\",\n })\n } finally {\n setDeletingTenants((prev) => {\n const newSet = new Set(prev)\n newSet.delete(tenantIdToRemove)\n return newSet\n })\n }\n }\n\n const handleTenantIdChange = (newTenantId: string) => {\n setTenantId(newTenantId)\n if (errors.tenantId) setErrors((prev) => ({ ...prev, tenantId: undefined }))\n }\n\n if (isPublicFlavor) {\n return (\n <DataGrid columns={3}>\n <DataGridRow>\n <DataGridHeadCell>{t`Flavor ID`}</DataGridHeadCell>\n <DataGridHeadCell>{t`Tenant ID`}</DataGridHeadCell>\n <DataGridHeadCell> </DataGridHeadCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridCell colSpan={3} className=\"text-theme-default py-4 text-center\">\n {t`This is a public flavor. All tenants have access to it.`}\n </DataGridCell>\n </DataGridRow>\n </DataGrid>\n )\n }\n\n return (\n <>\n {permissions.canAdd && (\n <Stack direction=\"horizontal\" className=\"bg-theme-background-lvl-1 justify-end p-2\">\n <Button\n label={t`Add Tenant Access`}\n data-testid=\"addTenantButton\"\n onClick={() => setIsAddingAccess(true)}\n variant=\"primary\"\n disabled={isAddingAccess}\n />\n </Stack>\n )}\n\n <DataGrid columns={3}>\n <DataGridRow>\n <DataGridHeadCell>{t`Flavor ID`}</DataGridHeadCell>\n <DataGridHeadCell>{t`Tenant ID`}</DataGridHeadCell>\n <DataGridHeadCell></DataGridHeadCell>\n </DataGridRow>\n\n {isAddingAccess && (\n <TenantAccessFormRow\n tenantId={tenantId}\n flavorId={flavor.id}\n errors={errors}\n isLoading={isLoading}\n onTenantIdChange={handleTenantIdChange}\n onSave={handleSave}\n onCancel={() => {\n resetForm()\n setIsAddingAccess(false)\n setMessage(null)\n }}\n />\n )}\n\n {flavorAccess.map((access) => (\n <TenantAccessRow\n key={access.tenant_id}\n access={access}\n isDeleting={deletingTenants.has(access.tenant_id)}\n onDelete={() => handleRemoveTenant(access.tenant_id)}\n canDelete={permissions.canRemove}\n />\n ))}\n\n {shouldShowEmptyState && (\n <DataGridRow>\n <DataGridCell colSpan={3} className=\"text-theme-default py-4 text-center\">\n {t`No specific tenant access configured for this private flavor. Click \"Add Tenant Access\" to grant access.`}\n </DataGridCell>\n </DataGridRow>\n )}\n </DataGrid>\n </>\n )\n}\n\nexport const ManageAccessModal: React.FC<ManageAccessProps> = ({ client, isOpen, onClose, project, flavor }) => {\n const { t } = useLingui()\n const { translateError } = useErrorTranslation()\n\n const [message, setMessage] = useState<{ text: string; type: \"error\" | \"info\" } | null>(null)\n const [isAddingAccess, setIsAddingAccess] = useState(false)\n\n const permissionsPromise = useMemo(\n () => (isOpen ? createPermissionsPromise(client, project) : null),\n [client, project, isOpen]\n )\n\n const flavorAccessPromise = useMemo(() => {\n if (!isOpen || !flavor?.id) return null\n return createFlavorAccessPromise(client, project, flavor.id)\n .then((access) =>\n access.filter((entry, idx, arr) => arr.findIndex((e) => e.tenant_id === entry.tenant_id) === idx)\n )\n .catch((error) => {\n const msg = translateError((error as Error)?.message || \"GET_FLAVOR_ACCESS_FAILED\")\n setMessage({ text: msg, type: \"error\" })\n return [] as FlavorAccess[]\n })\n }, [isOpen, flavor?.id, client, project])\n\n useEffect(() => {\n if (isOpen) setMessage(null)\n }, [isOpen, flavor?.id])\n\n // After add/remove, the server returns the updated list. We store it as an override so\n // the UI reflects the change immediately without refetching. The key prevents a stale\n // override from a previously opened flavor from leaking into the current modal session.\n const [flavorAccessOverride, setFlavorAccessOverride] = useState<{\n key: string\n promise: Promise<FlavorAccess[]>\n } | null>(null)\n\n const accessKey = `${isOpen}-${flavor?.id}`\n const activeFlavorAccessPromise =\n flavorAccessOverride?.key === accessKey ? flavorAccessOverride.promise : flavorAccessPromise\n\n const handleClose = () => {\n setMessage(null)\n setIsAddingAccess(false)\n setFlavorAccessOverride(null)\n onClose()\n }\n\n const handleAccessUpdate = (access: FlavorAccess[]) => {\n const deduplicated = access.filter(\n (entry, idx, arr) => arr.findIndex((e) => e.tenant_id === entry.tenant_id) === idx\n )\n startTransition(() => {\n setFlavorAccessOverride({ key: accessKey, promise: Promise.resolve(deduplicated) })\n })\n }\n\n if (!isOpen || !flavor || !permissionsPromise || !activeFlavorAccessPromise) {\n return null\n }\n const flavorName = flavor.name\n\n return (\n <Modal onCancel={handleClose} title={t`Manage Access - ${flavorName}`} open={isOpen} size=\"xl\">\n <div>\n {message && (\n <Message\n onDismiss={() => setMessage(null)}\n text={message.text}\n variant={message.type}\n className=\"mb-4\"\n dismissible\n />\n )}\n\n <Suspense fallback={<AccessLoading />}>\n <AccessContent\n permissionsPromise={permissionsPromise}\n flavorAccessPromise={activeFlavorAccessPromise}\n client={client}\n project={project}\n flavor={flavor}\n onAccessUpdate={handleAccessUpdate}\n isAddingAccess={isAddingAccess}\n setIsAddingAccess={setIsAddingAccess}\n setMessage={setMessage}\n />\n </Suspense>\n </div>\n </Modal>\n )\n}\n","import React, { useState } from \"react\"\nimport { useLingui } from \"@lingui/react/macro\"\nimport { TrpcClient } from \"@/client/trpcClient\"\nimport {\n Modal,\n Message,\n Spinner,\n ModalFooter,\n Button,\n ButtonRow,\n DataGrid,\n DataGridRow,\n DataGridHeadCell,\n DataGridCell,\n Stack,\n} from \"@cloudoperators/juno-ui-components\"\nimport { Flavor } from \"@/server/Compute/types/flavor\"\nimport { Trans } from \"@lingui/react/macro\"\nimport { useErrorTranslation } from \"@/client/utils/useErrorTranslation\"\n\ninterface DeleteFlavorModalProps {\n client: TrpcClient\n isOpen: boolean\n onClose: () => void\n project: string\n flavor: Flavor | null\n onSuccess: () => void\n}\n\nexport const DeleteFlavorModal: React.FC<DeleteFlavorModalProps> = ({\n client,\n isOpen,\n onClose,\n project,\n flavor,\n onSuccess,\n}) => {\n const { t } = useLingui()\n const { translateError } = useErrorTranslation()\n const [isLoading, setIsLoading] = useState(false)\n const [generalError, setGeneralError] = useState<string | null>(null)\n\n const handleDelete = async () => {\n if (!flavor?.id) {\n setGeneralError(t`No flavor selected for deletion.`)\n return\n }\n\n setGeneralError(null)\n\n try {\n setIsLoading(true)\n\n await client.compute.deleteFlavor.mutate({\n project_id: project,\n flavorId: flavor.id,\n })\n onSuccess()\n handleClose()\n } catch (error) {\n const errorMessage = (error as Error)?.message\n ? translateError((error as Error).message)\n : t`Failed to delete flavor. Please try again.`\n setGeneralError(errorMessage)\n } finally {\n setIsLoading(false)\n }\n }\n\n const handleClose = () => {\n setGeneralError(null)\n onClose()\n }\n\n const dismissError = () => {\n setGeneralError(null)\n }\n\n return (\n <Modal\n onCancel={handleClose}\n title={t`Delete Flavor`}\n open={isOpen}\n onConfirm={handleDelete}\n modalFooter={\n <ModalFooter className=\"flex justify-end\">\n <ButtonRow>\n <Button variant=\"primary-danger\" onClick={handleDelete} disabled={isLoading}>\n {isLoading ? <Spinner size=\"small\" /> : <Trans>Delete</Trans>}\n </Button>\n <Button variant=\"default\" onClick={handleClose}>\n <Trans>Cancel</Trans>\n </Button>\n </ButtonRow>\n </ModalFooter>\n }\n >\n {isLoading && (\n <Stack distribution=\"center\" alignment=\"center\">\n <Spinner variant=\"primary\" />\n </Stack>\n )}\n {!isLoading && (\n <div>\n {generalError && <Message onDismiss={dismissError} text={generalError} variant=\"error\" className=\"mb-4\" />}\n\n <Message\n text={t`This action cannot be undone. The flavor will be permanently deleted.`}\n variant=\"danger\"\n className=\"mb-4\"\n />\n\n {flavor && (\n <DataGrid columns={2}>\n <DataGridRow>\n <DataGridHeadCell>{t`Name`}</DataGridHeadCell>\n <DataGridCell>{flavor.name}</DataGridCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridHeadCell>{t`ID`}</DataGridHeadCell>\n <DataGridCell>{flavor.id}</DataGridCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridHeadCell>{t`VCPUs`}</DataGridHeadCell>\n <DataGridCell>{flavor.vcpus}</DataGridCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridHeadCell>{t`RAM`}</DataGridHeadCell>\n <DataGridCell>{flavor.ram} MiB</DataGridCell>\n </DataGridRow>\n <DataGridRow>\n <DataGridHeadCell>{t`Disk`}</DataGridHeadCell>\n <DataGridCell>{flavor.disk} GiB</DataGridCell>\n </DataGridRow>\n {flavor.swap && (\n <DataGridRow>\n <DataGridHeadCell>{t`Swap`}</DataGridHeadCell>\n <DataGridCell>{flavor.swap} MiB</DataGridCell>\n </DataGridRow>\n )}\n </DataGrid>\n )}\n </div>\n )}\n </Modal>\n )\n}\n"],"mappings":";;;;;;AAeA,IAAaM,KAA2C,EACtDC,YACAC,UACAC,WACAC,cACAC,gBACAC,kBACAC,WACAC,kBACD;CACC,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQC,GAAAA;AAEd,QACE,kBAACd,GAAAA,EAAAA,UAAAA;EACC,kBAACC,GAAAA;GAAac,WAAU;aACtB,kBAACb,GAAAA;IACCK,OAAOD;IACPU,WAAWC,MAAMP,EAAYO,EAAEC,OAAOX,MAAK;IAC3CY,aAAaC,EAAAA,EAAC,EAAA,IAAA,UAAU,CAAA;IACxBC,WAAWb,EAAOc;IAClBC,UAAQ;;;EAGZ,kBAACtB,GAAAA;GAAac,WAAU;aACtB,kBAACb,GAAAA;IACQK;IACPS,WAAWC,MAAMN,EAAcM,EAAEC,OAAOX,MAAK;IAC7CY,aAAaC,EAAAA,EAAC,EAAA,IAAA,UAAY,CAAA;IAC1BC,WAAWb,EAAOD;IAClBgB,UAAQ;;;EAGZ,kBAACtB,GAAAA,EAAAA,UACC,kBAACE,GAAAA,EAAAA,UAAAA,CACC,kBAACC,GAAAA;GAAOoB,MAAK;GAAQC,SAASb;GAAQc,SAAQ;GAAUC,OAAOP,EAAAA,EAAC,EAAA,IAAA,UAAc,CAAA;GAAGQ,UAAUnB;MAC3F,kBAACL,GAAAA;GAAOoB,MAAK;GAASC,SAASZ;GAAUc,OAAOP,EAAAA,EAAC,EAAA,IAAA,UAAO,CAAA;GAAGQ,UAAUnB;;;GCtClE4B,KAAmC,EAAEC,YAASC,UAAOC,eAAYC,aAAUC,mBAAW;CACjG,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQC,GAAAA,EACR,CAACC,GAASC,KAAcf,EAAS,GAAA;AA+CvC,QA9CAC,QAAU;AACR,MAAIa,GAAS;GACX,IAAME,IAAQC,iBAAW;AACvBF,MAAW,GAAA;MACV,IAAA;AAEH,gBAAaG,aAAaF,EAAAA;;IAE3B,CAACF,EAAQ,CAAA,EAuCV,kBAACZ,GAAAA,EAAAA,UAAAA;EACC,kBAACC,GAAAA,EAAAA,UAAcK,GAAAA,CAAAA;EACf,kBAACL,GAAAA,EAAAA,UAAcM,GAAAA,CAAAA;EACf,kBAACN,GAAAA,EAAAA,UACEO,IACC,kBAACL,GAAAA;GAAMwB,cAAa;GAASC,WAAU;aACrC,kBAACxB,GAAAA,EAAQe,SAAQ,WAAA,CAAA;OAGnB,kBAAChB,GAAAA;GAAMwB,cAAa;GAAMC,WAAU;aAxCrClB,IAGDE,IAEA,kBAACV,GAAAA;IACCiB,SAAQ;IACRC,eAboB;AAE1BX,KADAI,EAAW,GAAA,EACXJ,GAAAA;;IAYMY,OAAOC,EAAAA,EAAC,EAAA,IAAA,UAAO,CAAA;IACfC,cAAYD,EAAAA,EAAC,EAAA,IAAA,UAAO,CAAA;IACpBE,eAAY;IACZC,UAAUjB;cAETc,EAAAA,EAAC,EAAA,IAAA,UAAO,CAAA;QAKX,kBAACpB,GAAAA;IACCwB,MAAK;IACLN,eAAeP,EAAW,GAAA;IAC1BQ,OAAOC,EAAAA,EAAC;;eAAUhB,YAAAA;KAAQ,CAAA;IAC1BiB,cAAYD,EAAAA,EAAC;;eAAUhB,YAAAA;KAAQ,CAAA;IAC/BkB,eAAa,UAAUlB;IACvBmB,UAAUjB;QAvBP,kBAAA,GAAA,EAAA,CAAA;;;GCLPsC,KAA4BC,GAAoBC,MAC7CD,EAAOE,QAAQC,QACnBC,MAAM;CACLC,YAAYJ;CACZK,YAAY,CAAC,uBAAuB,sBAAsB;CAC5D,CAAA,CACCC,MAAM,CAACC,GAAWC,QAAgB;CAAED;CAAWC;CAAU,EAAA,EAGxDC,KAA2BV,GAAoBC,GAAiBU,MAC7DX,EAAOE,QAAQU,cAAcR,MAAM;CACxCC,YAAYJ;CACFU;CACZ,CAAA;AAGF,SAASE,IAAAA;AACP,QACE,kBAACtB,GAAAA,EAAAA,UACC,kBAACE,GAAAA;EAAaqB,SAAS;YACrB,kBAACpB,GAAAA;GAAMqB,cAAa;GAASC,WAAU;aACrC,kBAACpB,GAAAA,EAAQqB,SAAQ,WAAA,CAAA;;;;AAO3B,SAASC,EAAgB,EACvBC,uBACAC,sBACApB,WACAC,YACAoB,WACAC,kBACAC,iBACAC,oBACAC,iBAYD;CACC,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQC,GAAAA,EACR,EAAEC,sBAAmBxC,GAAAA,EAErByC,IAAc7C,EAAIoC,EAAAA,EAGlB,CAACW,GAAYC,KAAiB9C,EAFVF,EAAIqC,EAAAA,CAEeS,EACvC,CAACG,GAAKC,KAAUhD,EAAS,GAAA,EACzB,CAACiD,GAAOC,KAAYlD,EAAS,GAAA,EAC7B,CAACmD,GAAQC,KAAapD,EAA2C,EAAC,CAAA,EAClE,CAACqD,GAAYC,KAAiBtD,EAAwB,KAAA,EAEtDuD,UAAe;EACnB,IAAMC,IAAaT,EAAIU,MAAI,EACrBC,IAAeT,EAAMQ,MAAI,EACzBE,IAA8C,EAAC;AAarD,SAXKH,IAEMI,OAAOC,KAAKhB,EAAAA,CAAYiB,SAASN,EAAAA,KAC1CG,EAAUZ,MAAM,yBAFhBY,EAAUZ,MAAM,oBAKbW,MACHC,EAAUV,QAAQ,uBAGpBG,EAAUO,EAAAA,EACHC,OAAOC,KAAKF,EAAAA,CAAWI,WAAW;IAGrCC,UAAY;AAGhBZ,EAFAJ,EAAO,GAAA,EACPE,EAAS,GAAA,EACTE,EAAU,EAAC,CAAA;IAGPa,IAAa,YAAA;AACjB,MAAI,CAACV,GAAAA,EAAgB;AACnBf,KAAW;IAAE0B,MAAMC,EAAAA,EAAC,EAAA,IAAA,UAAwC,CAAA;IAAGC,MAAM;IAAQ,CAAA;AAC7E;;AAGF,MAAI;GACF,IAAMZ,IAAaT,EAAIU,MAAI,EACrBC,IAAeT,EAAMQ,MAAI;AAE/B,SAAM1C,EAAOE,QAAQoD,iBAAiBC,OAAO;IAC3ClD,YAAYJ;IACZU,UAAUU,EAAOmC;IACjBC,aAAa,GAAGhB,IAAaE,GAAa;IAC5C,CAAA;GAEA,IAAMe,IAAW;KAAGjB,IAAaE;IAAc,GAAGb;IAAW;AAS7DN,GARAO,EAAc2B,EAAAA,EACdpC,EAAcoC,EAAAA,EAEdjC,EAAW;IACT0B,MAAMC,EAAAA,EAAC;;eAAaX,eAAAA;KAAyC,CAAA;IAC7DY,MAAM;IACR,CAAA,EACAJ,GAAAA,EACAzB,EAAgB,GAAA;WACTmC,GAAO;AACdlC,KAAW;IACT0B,MAAMxB,EAAegC,aAAiBC,QAAQD,EAAME,UAAU,8BAAA;IAC9DR,MAAM;IACR,CAAA;;IAIES,IAAe,OAAOC,MAAAA;AAC1B,MAAI;AAEF,GADAxB,EAAcwB,EAAAA,EACd,MAAM/D,EAAOE,QAAQ8D,gBAAgBT,OAAO;IAC1ClD,YAAYJ;IACZU,UAAUU,EAAOmC;IACjBxB,KAAK+B;IACP,CAAA;GAEA,IAAML,IAAW,EAAE,GAAG5B,GAAW;AAKjCL,GAJA,OAAOiC,EAASK,IAChBhC,EAAc2B,EAAAA,EACdpC,EAAcoC,EAAAA,EAEdjC,EAAW;IACT0B,MAAMC,EAAAA,EAAC;;eAAaW,gBAAAA;KAA4C,CAAA;IAChEV,MAAM;IACR,CAAA;WACOM,GAAO;AACdlC,KAAW;IACT0B,MAAMxB,EAAegC,aAAiBC,QAAQD,EAAME,UAAU,gCAAgCE,EAAY,GAAE;IAC5GV,MAAM;IACR,CAAA;YACQ;AACRd,KAAc,KAAA;;IAIZ0B,KAAmBC,MAAAA;AAEvB,EADAjC,EAAOiC,EAAAA,EACH9B,EAAOJ,OAAKK,GAAW8B,OAAU;GAAE,GAAGA;GAAMnC,KAAKoC,KAAAA;GAAU,EAAA;IAG3DC,KAAqBC,MAAAA;AAEzB,EADAnC,EAASmC,EAAAA,EACLlC,EAAOF,SAAOG,GAAW8B,OAAU;GAAE,GAAGA;GAAMjC,OAAOkC,KAAAA;GAAU,EAAA;IAG/DG,IAAuB1B,OAAOC,KAAKhB,EAAAA,CAAYkB,WAAW,KAAK,CAACzB;AAEtE,QACE,kBAAA,GAAA,EAAA,UAAA,CACGK,EAAYpB,aACX,kBAACd,GAAAA;EAAM8E,WAAU;EAAaC,WAAU;YACtC,kBAAC9E,GAAAA;GACC+E,OAAOtB,EAAAA,EAAC,EAAA,IAAA,UAAa,CAAA;GACrBuB,eAAY;GACZC,eAAepD,EAAgB,GAAA;GAC/BP,SAAQ;GACR4D,UAAUtD;;KAKhB,kBAACjC,GAAAA;EAASwF,SAAS;;GACjB,kBAACvF,GAAAA,EAAAA,UAAAA;IACC,kBAACC,GAAAA,EAAAA,UAAkB4D,EAAAA,EAAC,EAAA,IAAA,UAAI,CAAA,EAAA,CAAA;IACxB,kBAAC5D,GAAAA,EAAAA,UAAkB4D,EAAAA,EAAC,EAAA,IAAA,UAAM,CAAA,EAAA,CAAA;IAC1B,kBAAC5D,GAAAA,EAAAA,CAAAA;;GAGF+B,KACC,kBAAC1B,GAAAA;IACCkF,SAAS/C;IACFE;IACCE;IACR4C,WAAW;IACXC,aAAahB;IACbiB,eAAeb;IACfc,QAAQjC;IACRkC,gBAAU;AAGR3D,KAFAwB,GAAAA,EACAzB,EAAgB,GAAA,EAChBC,EAAW,KAAA;;;GAKhBoB,OAAOwC,QAAQvD,EAAAA,CAAYwD,KAAK,CAACP,GAASQ,OACzC,kBAACzF,GAAAA;IAEUiF;IACT7C,OAAOqD;IACPjD,YAAYA,MAAeyC;IAC3BS,gBAAgB1B,EAAaiB,EAAAA;IAC7BtE,WAAWmB,EAAYnB;MALlBsE,EAAAA,CAAAA;GASRR,KACC,kBAAChF,GAAAA,EAAAA,UACC,kBAACE,GAAAA;IAAaqB,SAAS;IAAG2D,WAAU;cACjCrB,EAAAA,EAAC,EAAA,IAAA,UAA0D,CAAA;;;;;AAS1E,IAAaqC,KAA+C,EAAEzF,WAAQ0F,WAAQC,YAAS1F,YAASoB,gBAAQ;CACtG,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQK,GAAAA,EAER,CAACmC,GAASpC,KAAcxC,EAA0D,KAAA,EAClF,CAACsC,GAAcC,KAAmBvC,EAAS,GAAA,EAC3C,CAACmC,GAAmBwE,KAAwB3G,EAAiD,KAAA,EAE7FkC,IAAqBrC,EAAM+G,cACxBH,IAAS3F,EAAyBC,GAAQC,EAAAA,GAAW,MAC5D;EAACD;EAAQC;EAASyF;EAAO,CAAA;AA4B3B,QAzBA5G,EAAMgH,gBAAU;AACd,EAAIJ,KAAUrE,GAAQmC,MACpBtE,QAAgB;AACd0G,KAAqBlF,EAAwBV,GAAQC,GAASoB,EAAOmC,GAAE,CAAA;IACzE;IAED;EAACkC;EAAQrE,GAAQmC;EAAIxD;EAAQC;EAAQ,CAAA,EAepC,CAACyF,KAAU,CAACrE,KAAU,CAACF,KAAsB,CAACC,IACzC,OAIP,kBAAChC,GAAAA;EAAMgG,gBAlBW;AAIlBO,GAHAlE,EAAW,KAAA,EACXD,EAAgB,GAAA,EAChBoE,EAAqB,KAAA,EACrBD,GAAAA;;EAc8BS,OAAOhD,EAAAA,EAAC,EAAA,IAAA,UAAc,CAAA;EAAGiD,MAAMX;EAAQY,MAAK;YACxE,kBAACC,OAAAA,EAAAA,UAAAA,CACE1C,KACC,kBAACxE,GAAAA;GAAQmH,iBAAiB/E,EAAW,KAAA;GAAO0B,MAAMU,EAAQV;GAAMlC,SAAS4C,EAAQR;GAAMoB,WAAU;MAGnG,kBAACzF,GAAAA;GAASyH,UAAU,kBAAC5F,GAAAA,EAAAA,CAAAA;aACnB,kBAACK,GAAAA;IACqBC;IACDC;IACXpB;IACCC;IACDoB;IACRC,gBAxBiB2E,MAAAA;AACzB/G,aAAgB;AACd0G,QAAqBM,QAAQC,QAAQF,EAAAA,CAAAA;OACvC;;IAsBsB1E;IACGC;IACRqC;IACGpC;;;;GClSXuF,KAA2D,EACtEC,aACAC,aACAC,WACAC,cACAC,qBACAC,WACAC,kBACD;CACC,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQC,GAAAA;AAEd,QACE,kBAACb,GAAAA,EAAAA,UAAAA;EACC,kBAACC,GAAAA,EAAAA,UAAcM,GAAAA,CAAAA;EACf,kBAACN,GAAAA;GAAaa,WAAU;aACtB,kBAACZ,GAAAA;IACCa,OAAOT;IACPU,WAAWC,MAAMP,EAAiBO,EAAEC,OAAOH,MAAK;IAChDI,aAAaC,EAAAA,EAAC,EAAA,IAAA,UAAgB,CAAA;IAC9BC,WAAWb,EAAOF;IAClBgB,UAAQ;;;EAGZ,kBAACrB,GAAAA,EAAAA,UACC,kBAACE,GAAAA,EAAAA,UAAAA,CACC,kBAACC,GAAAA;GAAOmB,MAAK;GAAQC,SAASb;GAAQc,SAAQ;GAAUC,OAAON,EAAAA,EAAC,EAAA,IAAA,UAAkB,CAAA;GAAGO,UAAUlB;MAC/F,kBAACL,GAAAA;GAAOmB,MAAK;GAASC,SAASZ;GAAUc,OAAON,EAAAA,EAAC,EAAA,IAAA,UAAO,CAAA;GAAGO,UAAUlB;;;GCxBlE2B,KAAmD,EAAEC,WAAQC,eAAYC,aAAUC,mBAAW;CACzG,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQC,GAAAA,EACR,CAACC,GAASC,KAAcd,EAAS,GAAA;AAEvCC,SAAU;AACR,MAAIY,GAAS;GACX,IAAME,IAAQC,iBAAW;AACvBF,MAAW,GAAA;MACV,IAAA;AAEH,gBAAaG,aAAaF,EAAAA;;IAE3B,CAACF,EAAQ,CAAA;CAEZ,IAAMK,UAAsB;AAE1BR,EADAI,EAAW,GAAA,EACXJ,GAAAA;;AAoCF,QACE,kBAACR,GAAAA,EAAAA,UAAAA;EACC,kBAACC,GAAAA,EAAAA,UAAcK,EAAOsB,WAAAA,CAAAA;EACtB,kBAAC3B,GAAAA;GAAa4B,WAAU;aAAavB,EAAOoB;;EAC5C,kBAACzB,GAAAA,EAAAA,UACEM,IACC,kBAACJ,GAAAA;GAAM2B,cAAa;GAASC,WAAU;aACrC,kBAAC3B,GAAAA,EAAQc,SAAQ,WAAA,CAAA;OAGnB,kBAACf,GAAAA;GAAM2B,cAAa;GAAMC,WAAU;oBA3C7B;AACb,QAAI,CAACtB,EACH,QAAO,kBAAA,GAAA,EAAA,CAAA;AAET,QAAIE,EACF,QACE,kBAACT,GAAAA;KACCgB,SAAQ;KACRC,SAASH;KACTI,OAAOC,EAAAA,EAAC,EAAA,IAAA,UAAqB,CAAA;KAC7BC,cAAYD,EAAAA,EAAC,EAAA,IAAA,UAAqB,CAAA;KAClCE,eAAY;KACZC,UAAUjB;eAETc,EAAAA,EAAC,EAAA,IAAA,UAAO,CAAA;;IAGR;KACL,IAAMI,IAAWnB,EAAOoB;AAExB,YACE,kBAACxB,GAAAA;MACCyB,MAAK;MACLR,eAAeP,EAAW,GAAA;MAC1BQ,OAAOC,EAAAA,EAAC;;iBAAqBI,aAAAA;OAAS,CAAA;MACtCH,cAAYD,EAAAA,EAAC;;iBAAqBI,aAAAA;OAAS,CAAA;MAC3CF,eAAa,UAAUE;MACvBD,UAAUjB;;;OAiBPU;;;GC/CPkC,KAA4BC,GAAoBC,MAC7CD,EAAOE,QAAQC,QACnBC,MAAM;CACLC,YAAYJ;CACZK,YAAY,CAAC,uBAAuB,yBAAyB;CAC/D,CAAA,CACCC,MAAM,CAACC,GAAQC,QAAgB;CAAED;CAAQC;CAAU,EAAA,EAGlDC,KAA6BV,GAAoBC,GAAiBU,MAC/DX,EAAOE,QAAQU,gBAAgBR,MAAM;CAC1CC,YAAYJ;CACFU;CACZ,CAAA;AAGF,SAASE,IAAAA;AACP,QACE,kBAACtB,GAAAA,EAAAA,UACC,kBAACE,GAAAA;EAAaqB,SAAS;YACrB,kBAACpB,GAAAA;GAAMqB,cAAa;GAASC,WAAU;aACrC,kBAACrB,GAAAA,EAAQsB,SAAQ,WAAA,CAAA;;;;AAO3B,SAASC,EAAc,EACrBC,uBACAC,wBACApB,WACAC,YACAoB,WACAC,mBACAC,mBACAC,sBACAC,iBAWD;CACC,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQC,GAAAA,EACR,EAAEC,sBAAmBxC,GAAAA,EAErByC,IAAc/C,EAAIsC,EAAAA,EAClBU,IAAehD,EAAIuC,EAAAA,EAEnB,CAACU,GAAUC,KAAehD,EAAS,GAAA,EACnC,CAACiD,GAAQC,KAAalD,EAAgC,EAAC,CAAA,EACvD,CAACmD,GAAiBC,KAAsBpD,kBAAsB,IAAIqD,KAAAA,CAAAA,EAClE,CAACC,GAAWC,KAAgBvD,EAAS,GAAA,EAErCwD,IAAiBlB,EAAO,kCAAkC,IAC1DmB,IAAuBX,EAAaY,WAAW,KAAK,CAAClB,GAErDmB,UAAe;EACnB,IAAMC,IAAkBb,EAASc,MAAI,EAC/BC,IAAmC,EAAC;AAS1C,SAPKF,IAEMd,EAAaiB,MAAMC,MAAWA,EAAOC,cAAcL,EAAAA,KAC5DE,EAAUf,WAAW,oDAFrBe,EAAUf,WAAW,0BAKvBG,EAAUY,EAAAA,EACHI,OAAOC,KAAKL,EAAAA,CAAWJ,WAAW;IAGrCU,UAAY;AAEhBlB,EADAF,EAAY,GAAA,EACZE,EAAU,EAAC,CAAA;IAGPmB,IAAa,YAAA;AACjB,MAAI,CAACV,GAAAA,EAAgB;AACnBjB,KAAW;IAAE4B,MAAMC,EAAAA,EAAC,EAAA,IAAA,UAAwC,CAAA;IAAGC,MAAM;IAAQ,CAAA;AAC7E;;AAGFjB,IAAa,GAAA;AACb,MAAI;GACF,IAAMK,IAAkBb,EAASc,MAAI;AAerCpB,GAPAF,EANsB,MAAMtB,EAAOE,QAAQuD,gBAAgBC,OAAO;IAChErD,YAAYJ;IACZU,UAAUU,EAAOsC;IACjBC,iBAAiBjB;IACnB,CAAA,CAEea,EAEf/B,EAAW;IACT4B,MAAMC,EAAAA,EAAC;;eAAsBX,oBAAAA;KAA8C,CAAA;IAC3EY,MAAM;IACR,CAAA,EACAJ,GAAAA,EACA3B,EAAkB,GAAA;WACXqC,GAAO;AAGdpC,KAAW;IACT4B,MAAM1B,EAHa,GAAkBoC,WAAW,8BAGX;IACrCR,MAAM;IACR,CAAA;YACQ;AACRjB,KAAa,GAAA;;IAIX0B,IAAqB,OAAOC,MAAAA;AAChC9B,KAAoB+B,MAAS,IAAI9B,IAAI8B,EAAAA,CAAMC,IAAIF,EAAAA,CAAAA;AAE/C,MAAI;AAQFxC,GADAH,EANsB,MAAMtB,EAAOE,QAAQkE,mBAAmBV,OAAO;IACnErD,YAAYJ;IACZU,UAAUU,EAAOsC;IACjBC,iBAAiBK;IACnB,CAAA,CAEeT,EACf/B,EAAW;IACT4B,MAAMC,EAAAA,EAAC;;eAAsBW,qBAAAA;KAAiD,CAAA;IAC9EV,MAAM;IACR,CAAA;WACOM,GAAO;AAGdpC,KAAW;IACT4B,MAAM1B,EAHa,GAAkBoC,WAAW,iCAG+C;IAC/FR,MAAM;IACR,CAAA;YACQ;AACRpB,MAAoB+B,MAAAA;IAClB,IAAMG,IAAS,IAAIjC,IAAI8B,EAAAA;AAEvB,WADAG,EAAOC,OAAOL,EAAAA,EACPI;KACT;;;AA0BJ,QAjBI9B,IAEA,kBAACjD,GAAAA;EAASoF,SAAS;aACjB,kBAACnF,GAAAA,EAAAA,UAAAA;GACC,kBAACC,GAAAA,EAAAA,UAAkB8D,EAAAA,EAAC,EAAA,IAAA,UAAU,CAAA,EAAA,CAAA;GAC9B,kBAAC9D,GAAAA,EAAAA,UAAkB8D,EAAAA,EAAC,EAAA,IAAA,UAAU,CAAA,EAAA,CAAA;GAC9B,kBAAC9D,GAAAA,EAAAA,UAAiB,KAAA,CAAA;QAEpB,kBAACD,GAAAA,EAAAA,UACC,kBAACE,GAAAA;GAAaqB,SAAS;GAAG6D,WAAU;aACjCrB,EAAAA,EAAC,EAAA,IAAA,UAAwD,CAAA;;MAQlE,kBAAA,GAAA,EAAA,UAAA,CACG1B,EAAYpB,UACX,kBAACd,GAAAA;EAAMkF,WAAU;EAAaD,WAAU;YACtC,kBAAC/E,GAAAA;GACCiF,OAAOvB,EAAAA,EAAC,EAAA,IAAA,UAAkB,CAAA;GAC1BwB,eAAY;GACZC,eAAevD,EAAkB,GAAA;GACjCP,SAAQ;GACR+D,UAAUzD;;KAKhB,kBAACjC,GAAAA;EAASoF,SAAS;;GACjB,kBAACnF,GAAAA,EAAAA,UAAAA;IACC,kBAACC,GAAAA,EAAAA,UAAkB8D,EAAAA,EAAC,EAAA,IAAA,UAAU,CAAA,EAAA,CAAA;IAC9B,kBAAC9D,GAAAA,EAAAA,UAAkB8D,EAAAA,EAAC,EAAA,IAAA,UAAU,CAAA,EAAA,CAAA;IAC9B,kBAAC9D,GAAAA,EAAAA,CAAAA;;GAGF+B,KACC,kBAAC1B,GAAAA;IACWiC;IACVnB,UAAUU,EAAOsC;IACT3B;IACGK;IACX4C,mBAjDoBT,MAAAA;AAE5B,KADAzC,EAAYyC,EAAAA,EACRxC,EAAOF,YAAUG,GAAWiC,OAAU;MAAE,GAAGA;MAAMpC,UAAU2C,KAAAA;MAAU,EAAA;;IAgDjES,QAAQ9B;IACR+B,gBAAU;AAGR1D,KAFA0B,GAAAA,EACA3B,EAAkB,GAAA,EAClBC,EAAW,KAAA;;;GAKhBI,EAAauD,KAAKrC,MACjB,kBAACjD,GAAAA;IAESiD;IACRsC,YAAYnD,EAAgBoD,IAAIvC,EAAOC,UAAS;IAChDuC,gBAAgBvB,EAAmBjB,EAAOC,UAAS;IACnDwC,WAAW5D,EAAYnB;MAJlBsC,EAAOC,UAAS,CAAA;GAQxBR,KACC,kBAACjD,GAAAA,EAAAA,UACC,kBAACE,GAAAA;IAAaqB,SAAS;IAAG6D,WAAU;cACjCrB,EAAAA,EAAC,EAAA,IAAA,UAAyG,CAAA;;;;;AASzH,IAAamC,KAAkD,EAAEzF,WAAQ0F,WAAQC,YAAS1F,YAASoB,gBAAQ;CACzG,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQK,GAAAA,EACR,EAAEC,sBAAmBxC,GAAAA,EAErB,CAAC4E,GAAStC,KAAc1C,EAA0D,KAAA,EAClF,CAACwC,GAAgBC,KAAqBzC,EAAS,GAAA,EAE/CoC,IAAqBjC,QAClBwG,IAAS3F,EAAyBC,GAAQC,EAAAA,GAAW,MAC5D;EAACD;EAAQC;EAASyF;EAAO,CAAA,EAGrBtE,IAAsBlC,QACtB,CAACwG,KAAU,CAACrE,GAAQsC,KAAW,OAC5BjD,EAA0BV,GAAQC,GAASoB,EAAOsC,GAAE,CACxDpD,MAAMwC,MACLA,EAAO6C,QAAQC,GAAOC,GAAKC,MAAQA,EAAIC,WAAWC,MAAMA,EAAEjD,cAAc6C,EAAM7C,UAAS,KAAM8C,EAAAA,CAAAA,CAE9FI,OAAOrC,OAENpC,EAAW;EAAE4B,MADD1B,EAAe,GAAkBoC,WAAW,2BAAA;EAChCR,MAAM;EAAQ,CAAA,EAC/B,EAAE,EACX,EACD;EAACmC;EAAQrE,GAAQsC;EAAI3D;EAAQC;EAAQ,CAAA;AAExChB,SAAU;AACR,EAAIyG,KAAQjE,EAAW,KAAA;IACtB,CAACiE,GAAQrE,GAAQsC,GAAG,CAAA;CAKvB,IAAM,CAACyC,GAAsBC,KAA2BtH,EAG9C,KAAA,EAEJuH,IAAY,GAAGZ,EAAO,GAAGrE,GAAQsC,MACjC4C,IACJH,GAAsBI,QAAQF,IAAYF,EAAqBK,UAAUrF,GAErEsF,UAAc;AAIlBf,EAHAlE,EAAW,KAAA,EACXD,EAAkB,GAAA,EAClB6E,EAAwB,KAAA,EACxBV,GAAAA;IAGIgB,KAAsB5D,MAAAA;EAC1B,IAAM6D,IAAe7D,EAAO6C,QACzBC,GAAOC,GAAKC,MAAQA,EAAIC,WAAWC,MAAMA,EAAEjD,cAAc6C,EAAM7C,UAAS,KAAM8C,EAAAA;AAEjF9G,UAAgB;AACdqH,KAAwB;IAAEG,KAAKF;IAAWG,SAASI,QAAQC,QAAQF,EAAAA;IAAc,CAAA;IACnF;;AAGF,KAAI,CAAClB,KAAU,CAACrE,KAAU,CAACF,KAAsB,CAACoF,EAChD,QAAO;CAET,IAAMQ,IAAa1F,EAAO2F;AAE1B,QACE,kBAAC5H,GAAAA;EAAM+F,UAAUuB;EAAaO,OAAO3D,EAAAA,EAAC;;aAAmByD,eAAAA;GAAW,CAAA;EAAGG,MAAMxB;EAAQyB,MAAK;YACxF,kBAACC,OAAAA,EAAAA,UAAAA,CACErD,KACC,kBAAC1E,GAAAA;GACCgI,iBAAiB5F,EAAW,KAAA;GAC5B4B,MAAMU,EAAQV;GACdpC,SAAS8C,EAAQR;GACjBoB,WAAU;GACV2C,aAAW;MAIf,kBAACxI,GAAAA;GAASyI,UAAU,kBAAC1G,GAAAA,EAAAA,CAAAA;aACnB,kBAACK,GAAAA;IACqBC;IACpBC,qBAAqBmF;IACbvG;IACCC;IACDoB;IACRC,gBAAgBqF;IACApF;IACGC;IACPC;;;;GC9TX6G,KAAuD,EAClEC,WACAC,WACAC,YACAC,YACAC,WACAC,mBACD;CACC,IAAM,EAAA,MAAA,GAAA,GAAA,MAAQC,GAAAA,EACR,EAAEC,sBAAmBT,GAAAA,EACrB,CAACU,GAAWC,KAAgBvB,EAAS,GAAA,EACrC,CAACwB,GAAcC,KAAmBzB,EAAwB,KAAA,EAE1D0B,IAAe,YAAA;AACnB,MAAI,CAACR,GAAQS,IAAI;AACfF,KAAgBG,EAAAA,EAAC,EAAA,IAAA,UAAiC,CAAA,CAAA;AAClD;;AAGFH,IAAgB,KAAA;AAEhB,MAAI;AAQFS,GAPAX,EAAa,GAAA,EAEb,MAAMT,EAAOe,QAAQC,aAAaC,OAAO;IACvCC,YAAYf;IACZgB,UAAUf,EAAOS;IACnB,CAAA,EACAR,GAAAA,EACAe,GAAAA;WACOC,GAAO;AAIdV,KAHqB,GAAkBY,UACnChB,EAAe,EAAiBgB,QAAO,GACvCT,EAAAA,EAAC,EAAA,IAAA,UAA2C,CAAA,CAChCQ;YACR;AACRb,KAAa,GAAA;;IAIXW,UAAc;AAElBlB,EADAS,EAAgB,KAAA,EAChBT,GAAAA;;AAOF,QACE,kBAACf,GAAAA;EACCsC,UAAUL;EACVM,OAAOZ,EAAAA,EAAC,EAAA,IAAA,UAAc,CAAA;EACtBa,MAAM1B;EACN2B,WAAWhB;EACXiB,aACE,kBAACvC,GAAAA;GAAYwC,WAAU;aACrB,kBAACtC,GAAAA,EAAAA,UAAAA,CACC,kBAACD,GAAAA;IAAOwC,SAAQ;IAAiBC,SAASpB;IAAcqB,UAAUzB;cAC/DA,IAAY,kBAACnB,GAAAA,EAAQ6C,MAAK,SAAA,CAAA,GAAa,kBAAA,GAAA,EAAA,IAAA,UAAA,CAAA;OAE1C,kBAAC3C,GAAAA;IAAOwC,SAAQ;IAAUC,SAASZ;cACjC,kBAAA,GAAA,EAAA,IAAA,UAAA,CAAA;;;aAMPZ,KACC,kBAACX,GAAAA;GAAMsC,cAAa;GAASC,WAAU;aACrC,kBAAC/C,GAAAA,EAAQ0C,SAAQ,WAAA,CAAA;MAGpB,CAACvB,KACA,kBAAC6B,OAAAA,EAAAA,UAAAA;GACE3B,KAAgB,kBAACtB,GAAAA;IAAQkD,iBA9Bb;AACnB3B,OAAgB,KAAA;;IA6ByC4B,MAAM7B;IAAcqB,SAAQ;IAAQD,WAAU;;GAEjG,kBAAC1C,GAAAA;IACCmD,MAAMzB,EAAAA,EAAC,EAAA,IAAA,UAAsE,CAAA;IAC7EiB,SAAQ;IACRD,WAAU;;GAGX1B,KACC,kBAACX,GAAAA;IAAS+C,SAAS;;KACjB,kBAAC9C,GAAAA,EAAAA,UAAAA,CACC,kBAACC,GAAAA,EAAAA,UAAkBmB,EAAAA,EAAC,EAAA,IAAA,UAAK,CAAA,EAAA,CAAA,EACzB,kBAAClB,GAAAA,EAAAA,UAAcQ,EAAOqC,MAAAA,CAAAA,CAAAA,EAAAA,CAAAA;KAExB,kBAAC/C,GAAAA,EAAAA,UAAAA,CACC,kBAACC,GAAAA,EAAAA,UAAkBmB,EAAAA,EAAC,EAAA,IAAA,UAAG,CAAA,EAAA,CAAA,EACvB,kBAAClB,GAAAA,EAAAA,UAAcQ,EAAOS,IAAAA,CAAAA,CAAAA,EAAAA,CAAAA;KAExB,kBAACnB,GAAAA,EAAAA,UAAAA,CACC,kBAACC,GAAAA,EAAAA,UAAkBmB,EAAAA,EAAC,EAAA,IAAA,UAAM,CAAA,EAAA,CAAA,EAC1B,kBAAClB,GAAAA,EAAAA,UAAcQ,EAAOsC,OAAAA,CAAAA,CAAAA,EAAAA,CAAAA;KAExB,kBAAChD,GAAAA,EAAAA,UAAAA,CACC,kBAACC,GAAAA,EAAAA,UAAkBmB,EAAAA,EAAC,EAAA,IAAA,UAAI,CAAA,EAAA,CAAA,EACxB,kBAAClB,GAAAA,EAAAA,UAAAA,CAAcQ,EAAOuC,KAAI,OAAA,EAAA,CAAA,CAAA,EAAA,CAAA;KAE5B,kBAACjD,GAAAA,EAAAA,UAAAA,CACC,kBAACC,GAAAA,EAAAA,UAAkBmB,EAAAA,EAAC,EAAA,IAAA,UAAK,CAAA,EAAA,CAAA,EACzB,kBAAClB,GAAAA,EAAAA,UAAAA,CAAcQ,EAAOwC,MAAK,OAAA,EAAA,CAAA,CAAA,EAAA,CAAA;KAE5BxC,EAAOyC,QACN,kBAACnD,GAAAA,EAAAA,UAAAA,CACC,kBAACC,GAAAA,EAAAA,UAAkBmB,EAAAA,EAAC,EAAA,IAAA,UAAK,CAAA,EAAA,CAAA,EACzB,kBAAClB,GAAAA,EAAAA,UAAAA,CAAcQ,EAAOyC,MAAK,OAAA,EAAA,CAAA,CAAA,EAAA,CAAA"}
|
package/dist/client/{EditSecurityGroupModal-B7Sz9puM.mjs → EditSecurityGroupModal-ad4uzlt0.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as e, K as t,
|
|
1
|
+
import { C as e, K as t, Z as n, at as r, c as i, h as a, it as o, n as s, rt as c, s as l, w as u, z as d } from "./build-CZRvXrAL.mjs";
|
|
2
2
|
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect as m, useState as h } from "react";
|
|
4
4
|
import { Trans as g, useLingui as _ } from "@lingui/react";
|
|
@@ -40,36 +40,36 @@ var v = ({ securityGroup: v, open: y, onClose: b, onUpdate: x, isLoading: S = !1
|
|
|
40
40
|
}, N = () => {
|
|
41
41
|
k({}), b();
|
|
42
42
|
};
|
|
43
|
-
return /* @__PURE__ */ p(
|
|
43
|
+
return /* @__PURE__ */ p(r, {
|
|
44
44
|
open: y,
|
|
45
45
|
onCancel: N,
|
|
46
46
|
size: "large",
|
|
47
47
|
title: w._({ id: "yu9G3x" }),
|
|
48
|
-
modalFooter: /* @__PURE__ */ f(
|
|
48
|
+
modalFooter: /* @__PURE__ */ f(d, {
|
|
49
49
|
className: "flex justify-end",
|
|
50
|
-
children: /* @__PURE__ */ p(a, { children: [/* @__PURE__ */ f(
|
|
50
|
+
children: /* @__PURE__ */ p(a, { children: [/* @__PURE__ */ f(i, {
|
|
51
51
|
variant: "default",
|
|
52
52
|
onClick: N,
|
|
53
53
|
disabled: S,
|
|
54
54
|
children: /* @__PURE__ */ f(g, { id: "dEgA5A" })
|
|
55
|
-
}), /* @__PURE__ */ f(
|
|
55
|
+
}), /* @__PURE__ */ f(i, {
|
|
56
56
|
variant: "primary",
|
|
57
57
|
onClick: (e) => {
|
|
58
58
|
M(e);
|
|
59
59
|
},
|
|
60
60
|
disabled: S,
|
|
61
61
|
"data-testid": "update-security-group-button",
|
|
62
|
-
children: S ? /* @__PURE__ */ f(
|
|
62
|
+
children: S ? /* @__PURE__ */ f(n, { size: "small" }) : /* @__PURE__ */ f(g, { id: "Df0YHr" })
|
|
63
63
|
})] })
|
|
64
64
|
}),
|
|
65
65
|
children: [
|
|
66
|
-
C && /* @__PURE__ */ f(
|
|
66
|
+
C && /* @__PURE__ */ f(t, {
|
|
67
67
|
dismissible: !1,
|
|
68
68
|
variant: "error",
|
|
69
69
|
className: "mb-4",
|
|
70
70
|
children: C
|
|
71
71
|
}),
|
|
72
|
-
/* @__PURE__ */ f(
|
|
72
|
+
/* @__PURE__ */ f(t, {
|
|
73
73
|
dismissible: !1,
|
|
74
74
|
variant: "info",
|
|
75
75
|
className: "mb-4",
|
|
@@ -77,19 +77,19 @@ var v = ({ securityGroup: v, open: y, onClose: b, onUpdate: x, isLoading: S = !1
|
|
|
77
77
|
}),
|
|
78
78
|
S && /* @__PURE__ */ p("div", {
|
|
79
79
|
className: "mb-4 flex items-center justify-center gap-2",
|
|
80
|
-
children: [/* @__PURE__ */ f(
|
|
80
|
+
children: [/* @__PURE__ */ f(n, { variant: "primary" }), /* @__PURE__ */ f("span", {
|
|
81
81
|
className: "text-theme-high text-sm",
|
|
82
82
|
children: /* @__PURE__ */ f(g, { id: "V804LY" })
|
|
83
83
|
})]
|
|
84
84
|
}),
|
|
85
|
-
!S && /* @__PURE__ */ f(
|
|
85
|
+
!S && /* @__PURE__ */ f(o, {
|
|
86
86
|
className: "mb-6",
|
|
87
|
-
children: /* @__PURE__ */ p(
|
|
87
|
+
children: /* @__PURE__ */ p(s, {
|
|
88
88
|
className: "mb-6",
|
|
89
89
|
children: [
|
|
90
90
|
/* @__PURE__ */ f(c, {
|
|
91
91
|
className: "mb-6",
|
|
92
|
-
children: /* @__PURE__ */ f(
|
|
92
|
+
children: /* @__PURE__ */ f(u, {
|
|
93
93
|
id: "name",
|
|
94
94
|
name: "name",
|
|
95
95
|
label: w._({ id: "6YtxFj" }),
|
|
@@ -103,7 +103,7 @@ var v = ({ securityGroup: v, open: y, onClose: b, onUpdate: x, isLoading: S = !1
|
|
|
103
103
|
}),
|
|
104
104
|
/* @__PURE__ */ f(c, {
|
|
105
105
|
className: "mb-6",
|
|
106
|
-
children: /* @__PURE__ */ f(
|
|
106
|
+
children: /* @__PURE__ */ f(l, {
|
|
107
107
|
id: "description",
|
|
108
108
|
name: "description",
|
|
109
109
|
label: w._({ id: "Nu4oKW" }),
|
|
@@ -134,4 +134,4 @@ var v = ({ securityGroup: v, open: y, onClose: b, onUpdate: x, isLoading: S = !1
|
|
|
134
134
|
//#endregion
|
|
135
135
|
export { v as t };
|
|
136
136
|
|
|
137
|
-
//# sourceMappingURL=EditSecurityGroupModal-
|
|
137
|
+
//# sourceMappingURL=EditSecurityGroupModal-ad4uzlt0.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditSecurityGroupModal-
|
|
1
|
+
{"version":3,"file":"EditSecurityGroupModal-ad4uzlt0.mjs","names":["React","useState","useEffect","Modal","Form","FormRow","FormSection","TextInput","Checkbox","Button","ButtonRow","Spinner","ModalFooter","Textarea","Message","EditSecurityGroupModal","securityGroup","open","onClose","onUpdate","isLoading","error","useLingui","properties","setProperties","name","description","stateful","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"],"sources":["../../src/client/routes/_auth/projects/$projectId/network/securitygroups/-components/-modals/EditSecurityGroupModal.tsx"],"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 Checkbox,\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 stateful: boolean\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 stateful: securityGroup.stateful ?? true,\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 stateful: securityGroup.stateful ?? true,\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 const updateData: Omit<UpdateSecurityGroupInput, \"securityGroupId\" | \"project_id\"> = {\n name: properties.name.trim(),\n description: properties.description.trim() || undefined,\n stateful: properties.stateful,\n }\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 {/* Info message about stateful changes */}\n <Message dismissible={false} variant=\"info\" className=\"mb-4\">\n <Trans>\n Note: The 'stateful' attribute cannot be changed if this security group is currently in use by one or more\n ports.\n </Trans>\n </Message>\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\n <FormRow className=\"mb-0\">\n <Checkbox\n id=\"stateful\"\n name=\"stateful\"\n label={t`Stateful`}\n checked={properties.stateful}\n onChange={handleInputChange}\n disabled={isLoading}\n />\n </FormRow>\n </FormSection>\n </Form>\n )}\n </Modal>\n )\n}\n"],"mappings":"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"}
|