diff --git a/frontend-project/src/components/Modals/Confirmation/index.tsx b/frontend-project/src/components/Modals/Confirmation/index.tsx new file mode 100644 index 000000000..cfe038ce4 --- /dev/null +++ b/frontend-project/src/components/Modals/Confirmation/index.tsx @@ -0,0 +1,106 @@ +import React, { useEffect, useState } from 'react'; +import { Modal, Button } from 'antd'; +import { localeKeys } from '@/locales/pl-PL'; +import { formatMessage } from 'umi-plugin-react/locale'; + +type ConfirmationProps = { + title?: string; + onSuccess?: () => void; + onFailure?: (args: T) => void; +}; + +type ConfirmationModalProps = ConfirmationProps & { + title: string; + submitArgs: T; + hideModal: () => void; + onSubmit: () => void; +}; + +const ConfirmationModal = ({ + onSubmit, + title, + onSuccess, + onFailure, + hideModal, + submitArgs, +}: ConfirmationModalProps) => { + const [isModalVisible, setIsModalVisible] = useState(true); + const [isInProgress, setIsInProgress] = useState(false); + + useEffect(() => { + if (!isModalVisible) { + hideModal(); + } + }, [isModalVisible]); + + const handleOk = async () => { + setIsInProgress(true); + try { + await onSubmit(); + setIsModalVisible(false); + onSuccess(); + } catch (error) { + if (onFailure) { + onFailure(submitArgs); + } + } finally { + setIsInProgress(false); + } + }; + + const handleCancel = () => { + setIsModalVisible(false); + }; + + return ( + <> + + {formatMessage({ id: localeKeys.modal.cancel })} + , + , + ]} + > +

{formatMessage({ id: localeKeys.modal.description })}

+
+ + ); +}; + +export const useConfirmationModal = ( + props: ConfirmationProps, + onSubmit: (args: T) => void, +) => { + const [modal, setModal] = useState(null); + + const hideModal = () => setModal(null); + + const showModal = (args: T, title?: string) => { + setModal( + onSubmit(args)} + hideModal={hideModal} + />, + ); + }; + + return [modal, showModal]; +}; + +export default ConfirmationModal; diff --git a/frontend-project/src/locales/en-US.ts b/frontend-project/src/locales/en-US.ts index 0e948b58e..4920ebae2 100644 --- a/frontend-project/src/locales/en-US.ts +++ b/frontend-project/src/locales/en-US.ts @@ -1,3 +1,4 @@ +import { tagsLocale } from '@/pages/tags/locales/en-US'; import component from './en-US/component'; import globalHeader from './en-US/globalHeader'; import { menuLocale } from './en-US/menu'; @@ -8,7 +9,6 @@ import BaseLocales from './pl-PL'; import { structuredLocale } from '../utils/structedLocale'; import { casesLocale } from '../pages/cases/locales/en-US'; import { globalsLocale } from './en-US/globals'; -import { tagsLocale } from '@/pages/tags/locales/en-US'; const [labels] = structuredLocale({ ...menuLocale, diff --git a/frontend-project/src/locales/en-US/globals.ts b/frontend-project/src/locales/en-US/globals.ts index 1310a53b8..fe0d8a104 100644 --- a/frontend-project/src/locales/en-US/globals.ts +++ b/frontend-project/src/locales/en-US/globals.ts @@ -1,5 +1,5 @@ export const globalsLocale = { - error: 'Błąd', + error: 'Error', lists: { edit: 'Edit', delete: 'Delete', @@ -12,4 +12,9 @@ export const globalsLocale = { save: 'Save', reset: 'Reset', }, + modal: { + confirm: 'Confirm', + cancel: 'Cancel', + description: 'Are you sure you want to proceed?', + }, }; diff --git a/frontend-project/src/locales/pl-PL.ts b/frontend-project/src/locales/pl-PL.ts index ec9e1b2a6..8644ce2d7 100644 --- a/frontend-project/src/locales/pl-PL.ts +++ b/frontend-project/src/locales/pl-PL.ts @@ -1,3 +1,4 @@ +import { tagsLocale } from '@/pages/tags/locales/pl-PL'; import component from './pl-PL/component'; import globalHeader from './pl-PL/globalHeader'; import pwa from './pl-PL/pwa'; @@ -7,7 +8,6 @@ import { menuLocale } from './pl-PL/menu'; import { structuredLocale } from '../utils/structedLocale'; import { casesLocale } from '../pages/cases/locales/pl-PL'; import { globalsLocale } from './pl-PL/globals'; -import { tagsLocale } from '@/pages/tags/locales/pl-PL'; const [labels, keys] = structuredLocale({ ...menuLocale, diff --git a/frontend-project/src/locales/pl-PL/globals.ts b/frontend-project/src/locales/pl-PL/globals.ts index 0f0e22d11..ec16dc771 100644 --- a/frontend-project/src/locales/pl-PL/globals.ts +++ b/frontend-project/src/locales/pl-PL/globals.ts @@ -12,4 +12,9 @@ export const globalsLocale = { save: 'Zapisz', reset: 'Wyczyść', }, + modal: { + confirm: 'Potwierdź', + cancel: 'Anuluj', + description: 'Czy chcesz kontynuować?', + }, }; diff --git a/frontend-project/src/models/letters.ts b/frontend-project/src/models/letters.ts new file mode 100644 index 000000000..7ce85b8e0 --- /dev/null +++ b/frontend-project/src/models/letters.ts @@ -0,0 +1,8 @@ +import { Letter } from '@/services/definitions'; +import { LettersService } from '@/services/letters'; +import { ReadWriteReduxResource } from '@/utils/reduxModel'; + +export default ReadWriteReduxResource({ + namespace: 'letters', + service: LettersService, +}); diff --git a/frontend-project/src/pages/cases/CasesDetailView.tsx b/frontend-project/src/pages/cases/CasesDetailView.tsx index d2b18d53a..2db41aab8 100644 --- a/frontend-project/src/pages/cases/CasesDetailView.tsx +++ b/frontend-project/src/pages/cases/CasesDetailView.tsx @@ -6,11 +6,11 @@ import { formatMessage, FormattedMessage } from 'umi-plugin-react/locale'; import { Institution, User, Tag, Case, Feature } from '@/services/definitions'; import { ReduxResourceState } from '@/utils/reduxModel'; import router from 'umi/router'; -import { localeKeys } from '../../locales/pl-PL'; import { RouterTypes } from 'umi'; import { ServiceResponse } from '@/services/service'; import smallEodSDK from '@/utils/sdk'; import { openNotificationWithIcon } from '@/models/global'; +import { localeKeys } from '../../locales/pl-PL'; interface CasesDetailViewProps { cases: ReduxResourceState; diff --git a/frontend-project/src/pages/letters/list/index.tsx b/frontend-project/src/pages/letters/list/index.tsx index fa247a958..c1925c60c 100644 --- a/frontend-project/src/pages/letters/list/index.tsx +++ b/frontend-project/src/pages/letters/list/index.tsx @@ -1,16 +1,66 @@ -import { ProColumns } from '@ant-design/pro-table'; -import React, { FC } from 'react'; +import { ActionType, ProColumns } from '@ant-design/pro-table'; +import React, { FC, useRef } from 'react'; import { formatMessage } from 'umi-plugin-react/locale'; -import { fetchLettersPage } from '@/services/letters'; import { Letter } from '@/services/definitions'; import Table from '@/components/Table'; import ChannelName from '@/components/Table/ChannelName'; import InstitutionName from '@/components/Table/InstitutionName'; import CaseName from '@/components/Table/CaseName'; import DocumentTypeName from '@/components/Table/DocumentTypeName'; +import { Button, Space, Tooltip } from 'antd'; +import { DeleteOutlined } from '@ant-design/icons'; +import { useDispatch } from 'dva'; +import { openNotificationWithIcon } from '@/models/global'; +import { ServiceResponse } from '@/services/service'; +import { PaginationParams, PaginationResponse } from '@/services/common'; +import { LettersService } from '@/services/letters'; +import { localeKeys } from '@/locales/pl-PL'; +import { useConfirmationModal } from '@/components/Modals/Confirmation'; const TableList: FC<{}> = () => { + const dispatch = useDispatch(); + const tableActionRef = useRef(); + + function onRemove(id: number): Promise { + return new Promise((resolve, reject) => { + dispatch({ + type: 'letters/remove', + payload: { + id, + onResponse: (response: ServiceResponse) => + response.status === 'failed' ? reject() : resolve(), + }, + }); + }); + } + + const [modal, showModal] = useConfirmationModal( + { + onSuccess: () => tableActionRef.current.reload(), + onFailure: id => + openNotificationWithIcon( + 'error', + formatMessage({ id: localeKeys.error }), + `${formatMessage({ id: 'letters-list.table.notification.remove' })} ${id}`, + ), + }, + onRemove, + ); + + async function fetchPage(props: PaginationParams): Promise> { + const response = await LettersService.fetchPage(props); + if (response.status === 'failed') { + openNotificationWithIcon( + 'error', + formatMessage({ id: localeKeys.error }), + formatMessage({ id: localeKeys.lists.failedDownload }), + ); + return { data: [], total: 0 }; + } + return response.data; + } + const columns: ProColumns[] = [ { title: formatMessage({ id: 'letters-list.table.columns.documentType.title' }), @@ -70,9 +120,43 @@ const TableList: FC<{}> = () => { dataIndex: 'attachments', render: (attachments: []) => attachments.length, }, + { + title: formatMessage({ id: localeKeys.lists.actions }), + dataIndex: 'id', + render: (_, { id, referenceNumber }: Letter) => ( + + +