diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 57f5a0251..17c20bdba 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -19,6 +19,8 @@ on: permissions: contents: read + actions: read + security-events: write jobs: analyze: diff --git a/frontend/src/lib/hooks/api/appConfig.ts b/frontend/src/lib/hooks/api/appConfig.ts index f452ad067..e3ee0fdcb 100644 --- a/frontend/src/lib/hooks/api/appConfig.ts +++ b/frontend/src/lib/hooks/api/appConfig.ts @@ -1,6 +1,9 @@ import { appConfigApiClient as api } from 'lib/api'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import { ApplicationConfigPropertiesKafkaClusters } from 'generated-sources'; +import { + ApplicationConfig, + ApplicationConfigPropertiesKafkaClusters, +} from 'generated-sources'; import { QUERY_REFETCH_OFF_OPTIONS } from 'lib/constants'; export function useAppInfo() { @@ -15,26 +18,43 @@ export function useAppConfig() { return useQuery(['app', 'config'], () => api.getCurrentConfig()); } -export function useUpdateAppConfig({ initialName }: { initialName?: string }) { +function aggregateClusters( + cluster: ApplicationConfigPropertiesKafkaClusters, + existingConfig: ApplicationConfig, + initialName?: string, + deleteCluster?: boolean +): ApplicationConfigPropertiesKafkaClusters[] { + const existingClusters = existingConfig.properties?.kafka?.clusters || []; + + if (!initialName) { + return [...existingClusters, cluster]; + } + + if (!deleteCluster) { + return existingClusters.map((c) => (c.name === initialName ? cluster : c)); + } + + return existingClusters.filter((c) => c.name !== initialName); +} + +export function useUpdateAppConfig({ + initialName, + deleteCluster, +}: { + initialName?: string; + deleteCluster?: boolean; +}) { const client = useQueryClient(); return useMutation( async (cluster: ApplicationConfigPropertiesKafkaClusters) => { const existingConfig = await api.getCurrentConfig(); - const existingClusters = existingConfig.properties?.kafka?.clusters || []; - - let clusters: ApplicationConfigPropertiesKafkaClusters[] = []; - if (existingClusters.length > 0) { - if (!initialName) { - clusters = [...existingClusters, cluster]; - } else { - clusters = existingClusters.map((c) => - c.name === initialName ? cluster : c - ); - } - } else { - clusters = [cluster]; - } + const clusters = aggregateClusters( + cluster, + existingConfig, + initialName, + deleteCluster + ); const config = { ...existingConfig, diff --git a/frontend/src/widgets/ClusterConfigForm/index.tsx b/frontend/src/widgets/ClusterConfigForm/index.tsx index d4007cf48..cc57cb52c 100644 --- a/frontend/src/widgets/ClusterConfigForm/index.tsx +++ b/frontend/src/widgets/ClusterConfigForm/index.tsx @@ -22,6 +22,7 @@ import Metrics from 'widgets/ClusterConfigForm/Sections/Metrics'; import CustomAuthentication from 'widgets/ClusterConfigForm/Sections/CustomAuthentication'; import Authentication from 'widgets/ClusterConfigForm/Sections/Authentication/Authentication'; import KSQL from 'widgets/ClusterConfigForm/Sections/KSQL'; +import { useConfirm } from 'lib/hooks/useConfirm'; interface ClusterConfigFormProps { hasCustomConfig?: boolean; @@ -52,12 +53,36 @@ const ClusterConfigForm: React.FC = ({ const validate = useValidateAppConfig(); const update = useUpdateAppConfig({ initialName: initialValues.name }); + const deleteCluster = useUpdateAppConfig({ + initialName: initialValues.name, + deleteCluster: true, + }); + const confirm = useConfirm(true); + const { value: isFormDisabled, setTrue: disableForm, setFalse: enableForm, } = useBoolean(); + const confirmClusterDelete = () => + confirm('Are you sure want to delete this cluster?', async () => { + if (initialValues.name) { + const data = methods.getValues(); + const config = transformFormDataToPayload(data); + try { + await deleteCluster.mutateAsync(config); + navigate('/'); + } catch (error) { + showAlert('error', { + id: 'app-config-update-error', + title: 'Error updating application config', + message: 'There was an error updating the application config', + }); + } + } + }); + const onSubmit = async (data: ClusterConfigFormValues) => { const config = transformFormDataToPayload(data); try { @@ -146,6 +171,16 @@ const ClusterConfigForm: React.FC = ({ > Submit + {initialValues.name && ( + + )}