Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/staging table actions #1213

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/renderer/api/cadt/v1/staging/staging.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,22 @@ const stagingApi = cadtApi.injectEndpoints({
},
providesTags: [stagedUnitsTag],
}),

deleteStagedItem: builder.mutation<any, { uuid: string }>({
query: ({ uuid }) => {
return {
url: `/v1/staging`,
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
body: { uuid },
};
},
invalidatesTags: [stagedUnitsTag, stagedProjectsTag],
}),
}),
});

const invalidateStagingApiTag = stagingApi.util.invalidateTags;
export { invalidateStagingApiTag };

export const { useGetStagedProjectsQuery, useGetStagedUnitsQuery } = stagingApi;
export const { useGetStagedProjectsQuery, useGetStagedUnitsQuery, useDeleteStagedItemMutation } = stagingApi;
3 changes: 2 additions & 1 deletion src/renderer/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from './cadt/v1/units';
export * from './cadt/v1/projects';
export * from './cadt/v1/audit';
export * from './cadt/v1/issuances';
export * from './cadt/v1/governance';
export * from './cadt/v1/governance';
export * from './cadt/v1/staging';
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { Button, Modal } from '@/components';
import { FormattedMessage } from 'react-intl';
import { useDeleteProjectMutation, useDeleteUnitMutation } from '@/api';
import { invalidateStagingApiTag } from '@/api/cadt/v1/staging/staging.api';
import { invalidateStagingApiTag } from '@/api/cadt/v1/staging/';
import { stagedProjectsTag, stagedUnitsTag } from '@/api/cadt/v1';
import { useDispatch } from 'react-redux';

Expand All @@ -12,7 +12,7 @@ interface ConfirmDeleteModalProps {
onClose: () => void;
}

const ConfirmDeleteModal: React.FC<ConfirmDeleteModalProps> = ({
const ConfirmDeleteCommittedItemModal: React.FC<ConfirmDeleteModalProps> = ({
type,
warehouseId,
onClose,
Expand Down Expand Up @@ -41,9 +41,14 @@ const ConfirmDeleteModal: React.FC<ConfirmDeleteModalProps> = ({
<FormattedMessage id="confirm-delete" />
</Modal.Header>
<Modal.Body>
<p>
<FormattedMessage id="this-action-cannot-be-undone" />
</p>
<div className="space-y-2">
<p>
<FormattedMessage id="deleting-this-item-will-add-a-corresponding-delete-entry-to-the-staging-table" />.
</p>
<p>
<FormattedMessage id="no-items-will-be-deleted-until-staged-changes-are-committed" />.
</p>
</div>
</Modal.Body>
<Modal.Footer>
<Button color="gray" onClick={handleClickClose} disabled={projectDeletionLoading || unitDeletionLoading}>
Expand All @@ -61,4 +66,4 @@ const ConfirmDeleteModal: React.FC<ConfirmDeleteModalProps> = ({
);
};

export { ConfirmDeleteModal };
export { ConfirmDeleteCommittedItemModal };
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import { Button, Modal } from '@/components';
import { FormattedMessage } from 'react-intl';
import { useDeleteStagedItemMutation } from '@/api/cadt/v1/staging';

interface ConfirmDeleteModalProps {
uuid: string;
onClose: () => void;
}

const ConfirmDeleteStagedItemModal: React.FC<ConfirmDeleteModalProps> = ({
uuid,
onClose,
}: ConfirmDeleteModalProps) => {
const [triggerDeleteStagedItem, { isLoading: stagedItemDeletionLoading }] = useDeleteStagedItemMutation();
const handleConfirm = async () => {
await triggerDeleteStagedItem({ uuid });
onClose();
};

const handleClickClose = async () => {
onClose();
};

return (
<Modal show={true} onClose={onClose}>
<Modal.Header>
<FormattedMessage id="confirm-delete" />
</Modal.Header>
<Modal.Body>
<p>
<FormattedMessage id="deleting-a-staged-item-is-a-permanent-action" />.
</p>
</Modal.Body>
<Modal.Footer>
<Button color="gray" onClick={handleClickClose} disabled={stagedItemDeletionLoading}>
<FormattedMessage id="cancel" />
</Button>
<Button onClick={handleConfirm} isProcessing={stagedItemDeletionLoading} disabled={stagedItemDeletionLoading}>
<FormattedMessage id="delete" />
</Button>
</Modal.Footer>
</Modal>
);
};

export { ConfirmDeleteStagedItemModal };
2 changes: 1 addition & 1 deletion src/renderer/components/blocks/modals/StagingDiffModal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useMemo } from 'react';
import { DiffViewer, Modal } from '@/components';
import { FormattedMessage } from 'react-intl';
import { useGetStagedProjectsQuery } from '@/api/cadt/v1/staging/staging.api';
import { useGetStagedProjectsQuery } from '@/api/cadt/v1/staging';

interface ProjectModalProps {
stagingUuid: string;
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/components/blocks/modals/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ export * from './UnitModal';
export * from './StagingDiffModal';
export * from './UpsertProjectModal';
export * from './UpsertUnitModal';
export * from './ConfirmDeleteCommittedItemModal';
export * from './ConfirmDeleteStagedItemModal';
export * from './StagedProjectSuccessModal';
export * from './ConfirmDeleteModal';
7 changes: 4 additions & 3 deletions src/renderer/components/blocks/tables/ProjectsListTable.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useMemo } from 'react';
import { FormattedMessage } from 'react-intl';
import { DebouncedFunc } from 'lodash';
import { DataTable, PageCounter, Pagination, ProjectAndUnitActions, Tooltip } from '@/components';
import { Column, DataTable, PageCounter, Pagination, ProjectAndUnitActions, Tooltip } from '@/components';
import { Project } from '@/schemas/Project.schema';
import { Badge } from 'flowbite-react';

Expand Down Expand Up @@ -31,16 +31,17 @@ const ProjectsListTable: React.FC<TableProps> = ({
totalCount,
}) => {
const columns = useMemo(() => {
const editColumn: any = [
const editColumn: Column[] = [
{
title: '',
key: 'actionColumn',
ignoreChildEvents: true,
ignoreOrderChange: true,
render: (row: Project) => <ProjectAndUnitActions type="project" warehouseId={row?.warehouseProjectId || ''} />,
},
];

const staticColumns: any = [
const staticColumns: Column[] = [
{
title: <FormattedMessage id={'current-registry'} />,
key: 'currentRegistry',
Expand Down
10 changes: 9 additions & 1 deletion src/renderer/components/blocks/tables/StagingTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,26 @@ import React, { useMemo } from 'react';
import { FormattedMessage } from 'react-intl';
import { Badge, DataTable } from '@/components';
import dayjs from 'dayjs';
import { StagedItemActions } from '@/components/blocks/widgets/StagedItemActions';

interface TableProps {
data: any[];
type: 'staged' | 'pending' | 'failed';
isLoading: boolean;
setOrder: (sort: string) => void;
onRowClick: (row: any) => void;
order: string;
}

const StagingTable: React.FC<TableProps> = ({ data, isLoading, onRowClick, setOrder, order }) => {
const StagingTable: React.FC<TableProps> = ({ data, type, isLoading, onRowClick, setOrder, order }: TableProps) => {
const columns = useMemo(
() => [
{
title: '',
key: 'actionColumn',
ignoreChildEvents: true,
render: (row: any) => <StagedItemActions type={type} stagedItem={row} />,
},
{
title: <FormattedMessage id={'table'} />,
key: 'table',
Expand Down
7 changes: 4 additions & 3 deletions src/renderer/components/blocks/tables/UnitsListTable.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useMemo } from 'react';
import { FormattedMessage } from 'react-intl';
import { DebouncedFunc } from 'lodash';
import { DataTable, PageCounter, Pagination, ProjectAndUnitActions } from '@/components';
import { Column, DataTable, PageCounter, Pagination, ProjectAndUnitActions } from '@/components';
import { Unit } from '@/schemas/Unit.schema';

interface TableProps {
Expand Down Expand Up @@ -30,16 +30,17 @@ const UnitsListTable: React.FC<TableProps> = ({
totalCount,
}) => {
const columns = useMemo(() => {
const editColumn: any = [
const editColumn: Column[] = [
{
title: '',
key: 'actionColumn',
ignoreChildEvents: true,
ignoreOrderChange: true,
render: (row: Unit) => <ProjectAndUnitActions type="unit" warehouseId={row.warehouseUnitId} />,
},
];

const staticColumns: any = [
const staticColumns: Column[] = [
{
title: <FormattedMessage id={'unit-owner'} />,
key: 'unitOwner',
Expand Down
4 changes: 3 additions & 1 deletion src/renderer/components/blocks/tabs/StagingTableTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import React from 'react';
import { useColumnOrderHandler, useQueryParamState, useWildCardUrlHash } from '@/hooks';

interface PageTabProps {
type: 'staged' | 'pending' | 'failed';
stagingData: any[];
showLoading: boolean;
}

const StagingTableTab: React.FC<PageTabProps> = ({ stagingData, showLoading }: PageTabProps) => {
const StagingTableTab: React.FC<PageTabProps> = ({ stagingData, showLoading, type }: PageTabProps) => {
const [order, setOrder] = useQueryParamState('order', undefined);
const handleSetOrder = useColumnOrderHandler(order, setOrder);
const [stagingDiffFragment, stagingDiffModalActive, setStagingDiffModalActive] = useWildCardUrlHash('staging');
Expand All @@ -28,6 +29,7 @@ const StagingTableTab: React.FC<PageTabProps> = ({ stagingData, showLoading }: P
) : (
<StagingTable
data={stagingData}
type={type}
isLoading={showLoading}
setOrder={handleSetOrder}
order={order}
Expand Down
18 changes: 10 additions & 8 deletions src/renderer/components/blocks/widgets/ProjectAndUnitActions.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { HiDotsVertical } from 'react-icons/hi';
import { Button, ConfirmDeleteModal, Tooltip, UpsertProjectModal, UpsertUnitModal } from '@/components';
import { Button, ConfirmDeleteCommittedItemModal, Tooltip } from '@/components';
import { useWildCardUrlHash } from '@/hooks';
import { FormattedMessage } from 'react-intl';

Expand All @@ -13,8 +13,8 @@ const ProjectAndUnitActions: React.FC<ProjectAndUnitActionsProps> = ({
type,
warehouseId,
}: ProjectAndUnitActionsProps) => {
const [, editProjectModalActive, setEditProjectModalActive] = useWildCardUrlHash('edit-project');
const [, editUnitModalActive, setEditUnitModalActive] = useWildCardUrlHash('edit-unit');
const [, , setEditProjectModalActive] = useWildCardUrlHash('edit-project');
const [, , setEditUnitModalActive] = useWildCardUrlHash('edit-unit');
const [showDeleteModal, setShowDeleteModal] = useState<boolean>(false);

const handleClickDelete = () => {
Expand All @@ -37,21 +37,23 @@ const ProjectAndUnitActions: React.FC<ProjectAndUnitActionsProps> = ({
placement="right"
content={
<Button.Group>
<Button onClick={handleClickEdit}>
<Button onClick={handleClickEdit} outline>
<FormattedMessage id="edit" />
</Button>
<Button color="gray" onClick={handleClickDelete}>
<Button onClick={handleClickDelete} outline>
<FormattedMessage id="delete" />
</Button>
</Button.Group>
}
>
<HiDotsVertical size="25" />
</Tooltip>
{editProjectModalActive && <UpsertProjectModal onClose={() => setEditProjectModalActive(false)} />}
{editUnitModalActive && <UpsertUnitModal onClose={() => setEditUnitModalActive(false)} />}
{showDeleteModal && (
<ConfirmDeleteModal type={type} warehouseId={warehouseId} onClose={() => setShowDeleteModal(false)} />
<ConfirmDeleteCommittedItemModal
type={type}
warehouseId={warehouseId}
onClose={() => setShowDeleteModal(false)}
/>
)}
</>
);
Expand Down
72 changes: 72 additions & 0 deletions src/renderer/components/blocks/widgets/StagedItemActions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React, { useState } from 'react';
import { HiDotsVertical } from 'react-icons/hi';
import { Button, ConfirmDeleteStagedItemModal, Tooltip } from '@/components';
import { useWildCardUrlHash } from '@/hooks';
import { FormattedMessage } from 'react-intl';

interface ActionsProps {
type: 'staged' | 'pending' | 'failed';
stagedItem: any;
}

const StagedItemActions: React.FC<ActionsProps> = ({ type, stagedItem }: ActionsProps) => {
const [, , setEditProjectModalActive] = useWildCardUrlHash('edit-project');
const [, , setEditUnitModalActive] = useWildCardUrlHash('edit-unit');
const [showDeleteModal, setShowDeleteModal] = useState<boolean>(false);

const handleClickDelete = () => {
setShowDeleteModal(true);
};

const handleClickEdit = () => {
if (stagedItem?.table === 'Projects') {
setEditProjectModalActive(true, ''); //todo: need a way to get staged data into form without using warehouseId
} else {
setEditUnitModalActive(true, ''); //todo: need a way to get staged data into form without using warehouseId
}
};

return (
<>
{type !== 'pending' && (
<Tooltip
style="light"
trigger="click"
placement="right"
content={
<>
<Button onClick={handleClickDelete} outline>
<FormattedMessage id="delete" />
</Button>
{/*todo: delete the above button and encasing fragment and make this div
visible when a solution to editing a staged item is complete */}
<div className="hidden">
{stagedItem?.action === 'DELETE' || type === 'failed' ? (
<Button onClick={handleClickDelete} outline>
<FormattedMessage id="delete" />
</Button>
) : (
<Button.Group>
<Button onClick={handleClickEdit} outline>
<FormattedMessage id="edit" />
</Button>
<Button onClick={handleClickDelete} outline>
<FormattedMessage id="delete" />
</Button>
</Button.Group>
)}
</div>
</>
}
>
<HiDotsVertical size="25" />
</Tooltip>
)}
{showDeleteModal && stagedItem?.uuid && (
<ConfirmDeleteStagedItemModal uuid={stagedItem.uuid} onClose={() => setShowDeleteModal(false)} />
)}
</>
);
};

export { StagedItemActions };
1 change: 1 addition & 0 deletions src/renderer/components/blocks/widgets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './ThemeSelector';
export * from './UnitSummary';
export * from './DiffViewer';
export * from './ProjectAndUnitActions';
export * from './StagedItemActions';
5 changes: 3 additions & 2 deletions src/renderer/components/layout/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import 'simplebar/dist/simplebar.min.css';
import { AiOutlineSortAscending, AiOutlineSortDescending } from 'react-icons/ai';
import React from 'react';

interface Column {
export interface Column {
key: string;
title: string | JSX.Element;
ignoreChildEvents?: boolean;
ignoreOrderChange?: boolean;
render?: (row: any) => JSX.Element;
renderHeader?: (column: any) => JSX.Element;
width?: string;
Expand Down Expand Up @@ -103,7 +104,7 @@ const DataTable: React.FC<DataTableProps> = ({
? 'bg-gray-200 dark:bg-gray-600 text-gray-800 dark:text-white'
: 'text-gray-500 dark:text-gray-400'
}`}
onClick={() => onChangeOrder && onChangeOrder(column.key)}
onClick={() => !column.ignoreOrderChange && onChangeOrder && onChangeOrder(column.key)}
>
<div className="flex items-center justify-between">
<span>{column.renderHeader ? column.renderHeader(column) : column.title}</span>
Expand Down
Loading