From 0c342093df305cebb026a2837d7e4f4d2bd310be Mon Sep 17 00:00:00 2001 From: Kenil Date: Mon, 30 Sep 2024 20:19:17 +0530 Subject: [PATCH] Add Stop functionality for Applications --- .../KillScheduleRunModal.interface.ts | 20 +++ .../KillScheduleRun/KillScheduleRunModal.tsx | 76 ++++++++++ .../AppRunsHistory.component.tsx | 130 ++++++++++-------- .../resources/ui/src/rest/applicationAPI.ts | 4 + 4 files changed, 176 insertions(+), 54 deletions(-) create mode 100644 openmetadata-ui/src/main/resources/ui/src/components/Modals/KillScheduleRun/KillScheduleRunModal.interface.ts create mode 100644 openmetadata-ui/src/main/resources/ui/src/components/Modals/KillScheduleRun/KillScheduleRunModal.tsx diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Modals/KillScheduleRun/KillScheduleRunModal.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/Modals/KillScheduleRun/KillScheduleRunModal.interface.ts new file mode 100644 index 000000000000..01cdf947b317 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/Modals/KillScheduleRun/KillScheduleRunModal.interface.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2022 Collate. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface KillScheduleRunModalProps { + appName: string; + isModalOpen: boolean; + displayName: string; + onClose: () => void; + onKillWorkflowsUpdate?: () => void; +} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Modals/KillScheduleRun/KillScheduleRunModal.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Modals/KillScheduleRun/KillScheduleRunModal.tsx new file mode 100644 index 000000000000..ec6e08441fdc --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/Modals/KillScheduleRun/KillScheduleRunModal.tsx @@ -0,0 +1,76 @@ +/* + * Copyright 2022 Collate. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Modal, Typography } from 'antd'; +import { AxiosError } from 'axios'; +import React, { FC, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { killApp } from '../../../rest/applicationAPI'; +import { showErrorToast, showSuccessToast } from '../../../utils/ToastUtils'; +import { KillScheduleRunModalProps } from './KillScheduleRunModal.interface'; + +const KillScheduleModal: FC = ({ + appName, + isModalOpen, + displayName, + onClose, + onKillWorkflowsUpdate, +}) => { + const { t } = useTranslation(); + const [isLoading, setIsLoading] = useState(false); + + const handleConfirm = async () => { + setIsLoading(true); + try { + const { status } = await killApp(appName); + if (status === 200) { + showSuccessToast( + t('message.pipeline-killed-successfully', { + pipelineName: displayName, + }) + ); + onKillWorkflowsUpdate?.(); + } + } catch (error) { + // catch block error is unknown type so we have to cast it to respective type + showErrorToast(error as AxiosError); + } finally { + onClose(); + setIsLoading(false); + } + }; + + return ( + + + {t('message.are-you-sure-action-property', { + action: 'Kill', + propertyName: displayName, + })} + + + ); +}; + +export default KillScheduleModal; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Applications/AppRunsHistory/AppRunsHistory.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Applications/AppRunsHistory/AppRunsHistory.component.tsx index aecccc6167c0..f7d424e66740 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Applications/AppRunsHistory/AppRunsHistory.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Applications/AppRunsHistory/AppRunsHistory.component.tsx @@ -55,6 +55,7 @@ import { PagingHandlerParams } from '../../../common/NextPrevious/NextPrevious.i import StatusBadge from '../../../common/StatusBadge/StatusBadge.component'; import { StatusType } from '../../../common/StatusBadge/StatusBadge.interface'; import Table from '../../../common/Table/Table'; +import KillScheduleModal from '../../../Modals/KillScheduleRun/KillScheduleRunModal'; import AppLogsViewer from '../AppLogsViewer/AppLogsViewer.component'; import { AppRunRecordWithId, @@ -73,6 +74,7 @@ const AppRunsHistory = forwardRef( AppRunRecordWithId[] >([]); const [expandedRowKeys, setExpandedRowKeys] = useState([]); + const [isKillModalOpen, setIsKillModalOpen] = useState(false); const { currentPage, @@ -127,29 +129,34 @@ const AppRunsHistory = forwardRef( const getActionButton = useCallback( (record: AppRunRecordWithId, index: number) => { - if (appData?.appType === AppType.Internal) { + if ( + appData?.appType === AppType.Internal || + (isExternalApp && index === 0) + ) { return ( - - ); - } else if (isExternalApp && index === 0) { - return ( - + <> + + {/* For status running and supportsInterrupt is true, show kill button */} + {record.status === Status.Running && + Boolean(appData?.supportsInterrupt) && ( + + )} + ); } else { return NO_DATA_PLACEHOLDER; @@ -281,41 +288,56 @@ const AppRunsHistory = forwardRef( }, [fqn, pageSize]); return ( - - - , - showExpandColumn: false, - rowExpandable: (record) => !showLogAction(record), - expandedRowKeys, + <> + + +
, + showExpandColumn: false, + rowExpandable: (record) => !showLogAction(record), + expandedRowKeys, + }} + loading={isLoading} + locale={{ + emptyText: , + }} + pagination={false} + rowKey="id" + size="small" + /> + + + {showPagination && paginationVisible && ( + + )} + + + {isKillModalOpen && ( + { + setIsKillModalOpen(false); }} - loading={isLoading} - locale={{ - emptyText: , + onKillWorkflowsUpdate={() => { + fetchAppHistory(); }} - pagination={false} - rowKey="id" - size="small" /> - - - {showPagination && paginationVisible && ( - - )} - - + )} + ); } ); diff --git a/openmetadata-ui/src/main/resources/ui/src/rest/applicationAPI.ts b/openmetadata-ui/src/main/resources/ui/src/rest/applicationAPI.ts index 4b84e71786a0..f6b9e274d82c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/rest/applicationAPI.ts +++ b/openmetadata-ui/src/main/resources/ui/src/rest/applicationAPI.ts @@ -135,3 +135,7 @@ export const restoreApp = async (id: string) => { return response.data; }; + +export const killApp = async (name: string) => { + return await APIClient.post(`${BASE_URL}/stop/${getEncodedFqn(name)}`); +};