diff --git a/src/entities/transfer/api/hooks/index.ts b/src/entities/transfer/api/hooks/index.ts index 0f1dadc5..78f095cd 100644 --- a/src/entities/transfer/api/hooks/index.ts +++ b/src/entities/transfer/api/hooks/index.ts @@ -1 +1,2 @@ export * from './useGetTransfer'; +export * from './useDeleteTransfer'; diff --git a/src/entities/transfer/api/hooks/useDeleteTransfer/index.ts b/src/entities/transfer/api/hooks/useDeleteTransfer/index.ts new file mode 100644 index 00000000..629f32a7 --- /dev/null +++ b/src/entities/transfer/api/hooks/useDeleteTransfer/index.ts @@ -0,0 +1,25 @@ +import { useMutation, UseMutationResult, useQueryClient } from '@tanstack/react-query'; +import { notification } from 'antd'; +import { getErrorMessage } from '@shared/config'; + +import { transferService } from '../../transferService'; +import { TransferQueryKey } from '../../keys'; +import { DeleteTransferRequest } from '../../types'; + +/** Hook for deleting transfer */ +export const useDeleteTransfer = (data: DeleteTransferRequest): UseMutationResult => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: () => transferService.deleteTransfer(data), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: [TransferQueryKey.GET_TRANSFERS] }); + queryClient.removeQueries({ queryKey: [TransferQueryKey.GET_TRANSFER, data.id] }); + }, + onError: (error) => { + notification.error({ + message: getErrorMessage(error), + }); + }, + }); +}; diff --git a/src/entities/transfer/api/transferService.ts b/src/entities/transfer/api/transferService.ts index dfdf9548..0ff59eb2 100644 --- a/src/entities/transfer/api/transferService.ts +++ b/src/entities/transfer/api/transferService.ts @@ -1,7 +1,7 @@ import { axiosInstance } from '@shared/config'; import { PaginationResponse } from '@shared/types'; -import { GetTransferRequest, GetTransfersRequest, Transfer } from './types'; +import { DeleteTransferRequest, GetTransferRequest, GetTransfersRequest, Transfer } from './types'; export const transferService = { getTransfers: (params: GetTransfersRequest): Promise> => { @@ -11,4 +11,8 @@ export const transferService = { getTransfer: ({ id }: GetTransferRequest): Promise => { return axiosInstance.get(`transfers/${id}`); }, + + deleteTransfer: ({ id }: DeleteTransferRequest): Promise => { + return axiosInstance.delete(`transfers/${id}`); + }, }; diff --git a/src/entities/transfer/api/types.ts b/src/entities/transfer/api/types.ts index bb04b138..ccd20f8a 100644 --- a/src/entities/transfer/api/types.ts +++ b/src/entities/transfer/api/types.ts @@ -79,3 +79,7 @@ export interface GetTransfersRequest extends PaginationRequest { export interface GetTransferRequest { id: number; } + +export interface DeleteTransferRequest { + id: number; +} diff --git a/src/features/transfer/DeleteTransfer/index.tsx b/src/features/transfer/DeleteTransfer/index.tsx new file mode 100644 index 00000000..27746a19 --- /dev/null +++ b/src/features/transfer/DeleteTransfer/index.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { ControlButtons } from '@shared/ui'; +import { Typography } from 'antd'; +import { WarningOutlined } from '@ant-design/icons'; +import { useDeleteTransfer } from '@entities/transfer'; + +import classes from './styles.module.less'; +import { DeleteTransferProps } from './types'; + +const { Text } = Typography; + +export const DeleteTransfer = ({ transfer, onSuccess, onCancel }: DeleteTransferProps) => { + const { mutate: deleteTransfer, isPending } = useDeleteTransfer({ id: transfer.id }); + + const handleSubmit = () => { + deleteTransfer(null, { onSuccess }); + }; + + return ( +
+
+ + + Do you really want to delete transfer «{transfer.name}»? + +
+ +
+ ); +}; diff --git a/src/features/transfer/DeleteTransfer/styles.module.less b/src/features/transfer/DeleteTransfer/styles.module.less new file mode 100644 index 00000000..4341ad51 --- /dev/null +++ b/src/features/transfer/DeleteTransfer/styles.module.less @@ -0,0 +1,20 @@ +.root { + display: flex; + flex-direction: column; + gap: 24px; + + .main { + display: flex; + align-items: flex-start; + gap: 24px; + + .icon { + color: @red-6; + + svg { + width: 24px; + height: 24px; + } + } + } +} diff --git a/src/features/transfer/DeleteTransfer/types.ts b/src/features/transfer/DeleteTransfer/types.ts new file mode 100644 index 00000000..0e18012e --- /dev/null +++ b/src/features/transfer/DeleteTransfer/types.ts @@ -0,0 +1,7 @@ +import { Transfer } from '@entities/transfer'; + +export interface DeleteTransferProps { + transfer: Transfer; + onSuccess: () => void; + onCancel: () => void; +} diff --git a/src/features/transfer/TransferList/index.tsx b/src/features/transfer/TransferList/index.tsx index 8459cebd..d19ac180 100644 --- a/src/features/transfer/TransferList/index.tsx +++ b/src/features/transfer/TransferList/index.tsx @@ -7,7 +7,7 @@ import { TransferQueryKey, transferService } from '@entities/transfer'; import { TRANSFER_LIST_COLUMNS } from './constants'; import { TransferListProps } from './types'; -export const TransferList = memo(({ group }: TransferListProps) => { +export const TransferList = memo(({ group, onDeleteRowClick }: TransferListProps) => { return ( { columns={TRANSFER_LIST_COLUMNS} isRenderUpdateRowAction={() => hasAccessByUserRole(UserRole.Developer, group.role)} isRenderDeleteRowAction={() => hasAccessByUserRole(UserRole.Maintainer, group.role)} + onDeleteRowClick={onDeleteRowClick} rowKey="id" /> ); diff --git a/src/features/transfer/TransferList/types.ts b/src/features/transfer/TransferList/types.ts index b7a1f643..5ec6e968 100644 --- a/src/features/transfer/TransferList/types.ts +++ b/src/features/transfer/TransferList/types.ts @@ -1,5 +1,7 @@ import { Group } from '@entities/group'; +import { Transfer } from '@entities/transfer'; export interface TransferListProps { group: Group; + onDeleteRowClick: (transfer: Transfer) => void; } diff --git a/src/features/transfer/index.ts b/src/features/transfer/index.ts index ead941e9..de2c2a4a 100644 --- a/src/features/transfer/index.ts +++ b/src/features/transfer/index.ts @@ -1,2 +1,3 @@ export * from './TransferList'; export * from './TransferDetailInfo'; +export * from './DeleteTransfer'; diff --git a/src/widgets/transfer/TransferDetail/components/DeleteTransferButton/index.tsx b/src/widgets/transfer/TransferDetail/components/DeleteTransferButton/index.tsx new file mode 100644 index 00000000..7b8efe88 --- /dev/null +++ b/src/widgets/transfer/TransferDetail/components/DeleteTransferButton/index.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { DEFAULT_MODAL_DELETE_WIDTH } from '@shared/constants'; +import { useModalState } from '@shared/hooks'; +import { ModalWrapper } from '@shared/ui'; +import { Button } from 'antd'; +import { useNavigate } from 'react-router-dom'; +import { DeleteTransfer } from '@features/transfer'; + +import { DeleteTransferButtonProps } from './types'; + +export const DeleteTransferButton = ({ transfer }: DeleteTransferButtonProps) => { + const navigate = useNavigate(); + + const { isOpened: isOpenedModal, handleOpen: handleOpenModal, handleClose: handleCloseModal } = useModalState(); + + const handleSuccessDeleteTransfer = () => { + navigate('/transfers'); + handleCloseModal(); + }; + + return ( + <> + + + + + + ); +}; diff --git a/src/widgets/transfer/TransferDetail/components/DeleteTransferButton/types.ts b/src/widgets/transfer/TransferDetail/components/DeleteTransferButton/types.ts new file mode 100644 index 00000000..efff9b42 --- /dev/null +++ b/src/widgets/transfer/TransferDetail/components/DeleteTransferButton/types.ts @@ -0,0 +1,5 @@ +import { Transfer } from '@entities/transfer'; + +export interface DeleteTransferButtonProps { + transfer: Transfer; +} diff --git a/src/widgets/transfer/TransferDetail/components/index.ts b/src/widgets/transfer/TransferDetail/components/index.ts new file mode 100644 index 00000000..be55a2f9 --- /dev/null +++ b/src/widgets/transfer/TransferDetail/components/index.ts @@ -0,0 +1 @@ +export * from './DeleteTransferButton'; diff --git a/src/widgets/transfer/TransferDetail/index.tsx b/src/widgets/transfer/TransferDetail/index.tsx index 292e59d4..8303f8bb 100644 --- a/src/widgets/transfer/TransferDetail/index.tsx +++ b/src/widgets/transfer/TransferDetail/index.tsx @@ -1,19 +1,28 @@ import React from 'react'; -import { PageContentWrapper } from '@shared/ui'; +import { AccessWrapper, PageContentWrapper } from '@shared/ui'; import { TransferDetailInfo } from '@features/transfer'; +import { UserRole } from '@shared/types'; import { TransferDetailProps } from './types'; +import { DeleteTransferButton } from './components'; +import classes from './styles.module.less'; export const TransferDetail = ({ transfer, group, connectionSource, connectionTarget, queue }: TransferDetailProps) => { return ( - {/* //TODO: [DOP-20065] add update and delete actions for transfer */} +
+ +
+ + } />
); diff --git a/src/widgets/transfer/TransferDetail/styles.module.less b/src/widgets/transfer/TransferDetail/styles.module.less new file mode 100644 index 00000000..f0c745a4 --- /dev/null +++ b/src/widgets/transfer/TransferDetail/styles.module.less @@ -0,0 +1,5 @@ +.actions { + display: flex; + align-items: center; + gap: 16px; +} diff --git a/src/widgets/transfer/TransferListWrapper/index.tsx b/src/widgets/transfer/TransferListWrapper/index.tsx index a6a051a5..661cc032 100644 --- a/src/widgets/transfer/TransferListWrapper/index.tsx +++ b/src/widgets/transfer/TransferListWrapper/index.tsx @@ -1,9 +1,46 @@ -import React from 'react'; -import { TransferList } from '@features/transfer'; +import React, { useCallback, useState } from 'react'; +import { DeleteTransfer, TransferList } from '@features/transfer'; +import { Transfer } from '@entities/transfer'; +import { useModalState } from '@shared/hooks'; +import { ModalWrapper } from '@shared/ui'; +import { DEFAULT_MODAL_DELETE_WIDTH } from '@shared/constants'; import { TransferListWrapperProps } from './types'; export const TransferListWrapper = ({ group }: TransferListWrapperProps) => { - //TODO: [DOP-20065] add update and delete actions for transfer - return ; + const [selectedTransfer, setSelectedTransfer] = useState(); + + const { + isOpened: isOpenedDeleteTransferModal, + handleOpen: handleOpenDeleteTransferModal, + handleClose: handleCloseDeleteTransferModal, + } = useModalState(); + + const handleDeleteUserClick = useCallback( + (transfer: Transfer) => { + setSelectedTransfer(transfer); + handleOpenDeleteTransferModal(); + }, + [handleOpenDeleteTransferModal], + ); + + return ( + <> + {selectedTransfer && ( + + + + )} + ; + + ); };