diff --git a/src/components/KymaModules/KymaModulesList.js b/src/components/KymaModules/KymaModulesList.js
index b03ebc7df9..4f17bf328c 100644
--- a/src/components/KymaModules/KymaModulesList.js
+++ b/src/components/KymaModules/KymaModulesList.js
@@ -1,4 +1,5 @@
import { useTranslation } from 'react-i18next';
+import { createPortal } from 'react-dom';
import jsyaml from 'js-yaml';
import { ResourceDetails } from 'shared/components/ResourceDetails/ResourceDetails';
@@ -35,6 +36,7 @@ import { Label } from 'shared/ResourceForm/components/Label';
import { cloneDeep } from 'lodash';
import { useCreateResource } from 'shared/ResourceForm/useCreateResource';
import { useNotification } from 'shared/contexts/NotificationContext';
+import { useDeleteResource } from 'shared/hooks/useDeleteResource';
import { PopoverBadge } from 'shared/components/PopoverBadge/PopoverBadge';
import { isFormOpenState } from 'state/formOpenAtom';
@@ -50,6 +52,11 @@ export function KymaModulesList(props) {
const setIsFormOpen = useSetRecoilState(isFormOpenState);
const { clusterUrl } = useUrl();
+ const [DeleteMessageBox, handleResourceDelete] = useDeleteResource({
+ resourceType: t('kyma-modules.title'),
+ forceConfirmDelete: true,
+ });
+
const { data: kymaResources, loading: kymaResourcesLoading } = useGet(
'/apis/operator.kyma-project.io/v1beta2/namespaces/kyma-system/kymas',
);
@@ -85,6 +92,7 @@ export function KymaModulesList(props) {
const { data: crds } = useGet(crdUrl, {
pollingInterval: 5000,
});
+ const [chosenModuleIndex, setChosenModuleIndex] = useState(null);
if (kymaResourcesLoading || modulesLoading || kymaResourceLoading) {
return ;
@@ -123,7 +131,7 @@ export function KymaModulesList(props) {
return kymaExt?.find(ext => {
const { resource: extensionResource } =
jsyaml.load(ext.data.general, { json: true }) || {};
- return extensionResource === resourceKind;
+ return extensionResource.kind === resourceKind;
});
};
const checkBeta = module => {
@@ -132,14 +140,7 @@ export function KymaModulesList(props) {
);
};
- // TODO: Remove this function and use newfindCrd instead
- const findCrd = moduleName =>
- crds?.items?.find(crd =>
- crd.metadata.name
- .toLocaleLowerCase()
- .includes(pluralize(moduleName.replace('-', '').toLocaleLowerCase())),
- );
- const newfindCrd = resourceKind => {
+ const findCrd = resourceKind => {
return crds?.items?.find(crd => crd.spec?.names?.kind === resourceKind);
};
@@ -162,7 +163,7 @@ export function KymaModulesList(props) {
const isError = moduleStatus?.state === 'Error';
const hasExtension = !!findExtension(resource?.resource?.kind);
- const hasCrd = !!findCrd(resource.name);
+ const hasCrd = !!findCrd(resource?.resource?.kind);
return (
(isInstalled || isDeletionFailed || !isError) &&
@@ -205,7 +206,8 @@ export function KymaModulesList(props) {
type={
moduleStatus?.state === 'Ready'
? 'Success'
- : moduleStatus?.state === 'Processing'
+ : moduleStatus?.state === 'Processing' ||
+ moduleStatus?.state === 'Deleting'
? 'None'
: moduleStatus?.state || 'None'
}
@@ -219,7 +221,8 @@ export function KymaModulesList(props) {
type={
moduleStatus?.state === 'Ready'
? 'Success'
- : moduleStatus?.state === 'Processing'
+ : moduleStatus?.state === 'Processing' ||
+ moduleStatus?.state === 'Deleting'
? 'None'
: moduleStatus?.state || 'None'
}
@@ -284,15 +287,21 @@ export function KymaModulesList(props) {
return kymaResourceModule.name === resource.name;
});
- selectedModules.splice(index, 1);
- setKymaResourceState({
- ...kymaResource,
- spec: {
- ...kymaResource.spec,
- modules: selectedModules,
+ setChosenModuleIndex(index);
+ handleResourceDelete({
+ deleteFn: () => {
+ selectedModules.splice(index, 1);
+
+ setKymaResourceState({
+ ...kymaResource,
+ spec: {
+ ...kymaResource.spec,
+ modules: selectedModules,
+ },
+ });
+ handleModuleUninstall();
},
});
- handleModuleUninstall();
},
},
];
@@ -300,6 +309,7 @@ export function KymaModulesList(props) {
const handleClickResource = (resourceName, resource) => {
const isExtension = !!findExtension(resource?.resource?.kind);
const moduleStatus = findStatus(resourceName);
+ const moduleCrd = findCrd(resource?.resource?.kind);
const skipRedirect = !hasDetailsLink(resource);
if (skipRedirect) {
@@ -315,9 +325,7 @@ export function KymaModulesList(props) {
? `${pluralize(
moduleStatus?.resource?.kind || '',
).toLowerCase()}/${moduleStatus?.resource?.metadata?.name}`
- : `${newfindCrd(resource?.resource?.kind)?.metadata?.name}/${
- moduleStatus?.resource?.metadata?.name
- }`
+ : `${moduleCrd?.metadata?.name}/${moduleStatus?.resource?.metadata?.name}`
}`,
)
: clusterUrl(
@@ -326,16 +334,14 @@ export function KymaModulesList(props) {
? `${pluralize(
moduleStatus?.resource?.kind || '',
).toLowerCase()}/${moduleStatus?.resource?.metadata?.name}`
- : `${newfindCrd(resource?.resource?.kind)?.metadata?.name}/${
- moduleStatus?.resource?.metadata?.name
- }`
+ : `${moduleCrd?.metadata?.name}/${moduleStatus?.resource?.metadata?.name}`
}`,
);
if (!isExtension) {
setLayoutColumn({
midColumn: {
- resourceType: findCrd(resourceName)?.metadata?.name,
+ resourceType: moduleCrd?.metadata?.name,
resourceName: moduleStatus?.resource?.metadata?.name,
namespaceId: moduleStatus?.resource?.metadata.namespace || '',
},
@@ -369,43 +375,63 @@ export function KymaModulesList(props) {
};
return (
-
- {t('common.buttons.add')}
- ,
- ]}
- customColumnLayout={customColumnLayout}
- enableColumnLayout
- hasDetailsView
- entries={resource?.status?.modules}
- headerRenderer={headerRenderer}
- rowRenderer={rowRenderer}
- noHideFields={['Name', '', 'Namespace']}
- displayArrow
- title={'Modules'}
- sortBy={{
- name: (a, b) => a.name?.localeCompare(b.name),
- }}
- emptyListProps={{
- image: 'TntComponents',
- titleText: `${t('common.labels.no')} ${t(
- 'kyma-modules.title',
- ).toLocaleLowerCase()}`,
- subtitleText: t('kyma-modules.no-modules-description'),
- url:
- 'https://help.sap.com/docs/btp/sap-business-technology-platform/kyma-s-modular-approach?locale=en-US&state=DRAFT&version=Cloud',
- buttonText: t('common.buttons.add'),
- showButton: true,
- onClick: handleShowAddModule,
- }}
- />
+ <>
+ {createPortal(
+ {
+ selectedModules.splice(chosenModuleIndex, 1);
+ setKymaResourceState({
+ ...kymaResource,
+ spec: {
+ ...kymaResource.spec,
+ modules: selectedModules,
+ },
+ });
+
+ handleModuleUninstall();
+ }}
+ />,
+ document.body,
+ )}
+
+ {t('common.buttons.add')}
+ ,
+ ]}
+ customColumnLayout={customColumnLayout}
+ enableColumnLayout
+ hasDetailsView
+ entries={resource?.status?.modules}
+ headerRenderer={headerRenderer}
+ rowRenderer={rowRenderer}
+ noHideFields={['Name', '', 'Namespace']}
+ displayArrow
+ title={'Modules'}
+ sortBy={{
+ name: (a, b) => a.name?.localeCompare(b.name),
+ }}
+ emptyListProps={{
+ image: 'TntComponents',
+ titleText: `${t('common.labels.no')} ${t(
+ 'kyma-modules.title',
+ ).toLocaleLowerCase()}`,
+ subtitleText: t('kyma-modules.no-modules-description'),
+ url:
+ 'https://help.sap.com/docs/btp/sap-business-technology-platform/kyma-s-modular-approach?locale=en-US&state=DRAFT&version=Cloud',
+ buttonText: t('common.buttons.add'),
+ showButton: true,
+ onClick: handleShowAddModule,
+ }}
+ />
+ >
);
};
diff --git a/src/shared/hooks/useDeleteResource.js b/src/shared/hooks/useDeleteResource.js
index 434404beea..53d928c1d4 100644
--- a/src/shared/hooks/useDeleteResource.js
+++ b/src/shared/hooks/useDeleteResource.js
@@ -30,6 +30,7 @@ export function useDeleteResource({
layoutNumber,
redirectBack = true,
parentCrdName,
+ forceConfirmDelete = false,
}) {
const { t } = useTranslation();
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
@@ -148,7 +149,7 @@ export function useDeleteResource({
};
const handleResourceDelete = ({ resource, resourceUrl, deleteFn }) => {
- if (dontConfirmDelete) {
+ if (dontConfirmDelete && !forceConfirmDelete) {
performDelete(resource, resourceUrl, deleteFn);
} else {
setShowDeleteDialog(true);
@@ -218,12 +219,14 @@ export function useDeleteResource({
},
)}
- setDontConfirmDelete(prevState => !prevState)}
- text={t('common.delete-dialog.delete-confirm')}
- />
- {dontConfirmDelete && (
+ {!forceConfirmDelete && (
+ setDontConfirmDelete(prevState => !prevState)}
+ text={t('common.delete-dialog.delete-confirm')}
+ />
+ )}
+ {dontConfirmDelete && !forceConfirmDelete && (
{t('common.delete-dialog.information')}