Skip to content
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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ jobs:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install pnpm
run: npm install -g pnpm
- uses: pnpm/action-setup@v4
name: Install pnpm

- uses: actions/setup-node@v4
with:
Expand Down
19 changes: 19 additions & 0 deletions app/Root/config/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,22 @@ const editDocument: RouteConfig = {
load: () => import('#views/Documents/DocumentsForm'),
visibility: 'is-authenticated',
};
const pmer: RouteConfig = {
index: true,
path: '/pmer',
load: () => import('#views/Pmer'),
visibility: 'is-authenticated',
};
const createPmer: RouteConfig = {
path: '/pmer/new',
load: () => import('#views/Pmer/PmerForm'),
visibility: 'is-authenticated',
};
const editPmer: RouteConfig = {
path: '/pmer/:id/edit',
load: () => import('#views/Pmer/PmerForm'),
visibility: 'is-authenticated',
};
const onlineInteractive: RouteConfig = {
index: true,
path: '/online-interactive',
Expand Down Expand Up @@ -274,6 +290,9 @@ const routes = {
documents,
createDocument,
editDocument,
pmer,
createPmer,
editPmer,
onlineInteractive,
createOnlineInteractive,
editOnlineInteractive,
Expand Down
2 changes: 2 additions & 0 deletions app/Root/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ function RootContent() {
dashboardPage: globalEnumsData?.enums.DashboardPage,
reportContentType: globalEnumsData?.enums.ReportContentType,
reportVisibility: globalEnumsData?.enums.ReportVisibility,
pmerReportCategory: globalEnumsData?.enums.PmerReportCategory,
pmerReportDocumentType: globalEnumsData?.enums.PmerReportDocumentType,
}), [globalEnumsData]);

return (
Expand Down
8 changes: 8 additions & 0 deletions app/Root/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ export const GLOBAL_ENUMS = gql`
key
label
}
PmerReportCategory {
key
label
}
PmerReportDocumentType {
key
label
}
}
}
`;
50 changes: 45 additions & 5 deletions app/components/CategoryModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ function CategoryModal(props: Props) {

const [categoryName, setCategoryName] = useState<string | undefined>();
const [editingId, setEditingId] = useState<string | undefined>();
const [deletingId, setDeletingId] = useState<string | undefined>();

const [{ fetching, data, error }, reExecuteQuery] = useThematicAreasQuery({
variables: {
Expand Down Expand Up @@ -201,13 +202,25 @@ function CategoryModal(props: Props) {
setCategoryName(undefined);
}, []);

const handleDelete = useCallback((id: string) => {
deleteThematicArea({ id }).then((resp) => {
const handleDeleteClick = useCallback((id: string) => {
setDeletingId(id);
}, []);

const handleDeleteCancel = useCallback(() => {
setDeletingId(undefined);
}, []);

const handleDeleteConfirm = useCallback(() => {
if (isNotDefined(deletingId)) {
return;
}
setDeletingId(undefined);
deleteThematicArea({ id: deletingId }).then((resp) => {
handleResult(resp.data?.deleteThematicArea, 'Category deleted successfully');
}).catch(() => {
alert.show(errorMessage, { variant: 'danger' });
});
}, [deleteThematicArea, handleResult, alert]);
}, [deletingId, deleteThematicArea, handleResult, alert]);

const columns = useMemo(() => [
createStringColumn<ThematicArea, string | number>(
Expand All @@ -222,12 +235,12 @@ function CategoryModal(props: Props) {
(_, datum) => ({
id: datum.id,
onEdit: handleEdit,
onDelete: handleDelete,
onDelete: handleDeleteClick,
disabled: actionPending,
}),
{ columnWidth: 100 },
),
], [handleEdit, handleDelete, actionPending]);
], [handleEdit, handleDeleteClick, actionPending]);

const isEditing = isDefined(editingId);

Expand Down Expand Up @@ -292,6 +305,33 @@ function CategoryModal(props: Props) {
onActivePageChange={setPage}
/>
</ListView>
{isDefined(deletingId) && (
<Modal
heading="Delete category?"
size="sm"
onClose={handleDeleteCancel}
closeOnEscape
footerActions={(
<ListView spacing="sm">
<Button
name={undefined}
onClick={handleDeleteCancel}
>
Cancel
</Button>
<Button
name={undefined}
styleVariant="filled"
onClick={handleDeleteConfirm}
>
Delete
</Button>
</ListView>
)}
>
{`Are you sure you want to delete "${categories?.find((item) => item.id === deletingId)?.name || 'this category'}"? This action cannot be undone.`}
</Modal>
)}
</Modal>
);
}
Expand Down
25 changes: 21 additions & 4 deletions app/components/EditDeleteActions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,22 @@ export interface Props {
onDelete: (id: string) => void;
itemTitle: string;
to: keyof RoutesMap;
deleteMode?: 'delete' | 'deactivate';
}

const deleteCopy = {
delete: {
actionLabel: 'Delete',
heading: 'Delete item?',
message: (title: string) => `Are you sure you want to delete "${title}"? This action cannot be undone.`,
},
deactivate: {
actionLabel: 'Deactivate',
heading: 'Deactivate user?',
message: (title: string) => `Are you sure you want to deactivate "${title}"? They will lose access, and you can reactivate them later.`,
},
};

function EditDeleteActions(props: Props) {
const {
id,
Expand All @@ -33,8 +47,11 @@ function EditDeleteActions(props: Props) {
to,
member,
dashboard,
deleteMode = 'delete',
} = props;

const copy = deleteCopy[deleteMode];

const navigate = useRouting();

const [showDeleteModal, setShowDeleteModal] = useState(false);
Expand Down Expand Up @@ -77,14 +94,14 @@ function EditDeleteActions(props: Props) {
<Button
name={undefined}
onClick={handleDeleteClick}
title="Delete"
title={copy.actionLabel}
styleVariant="action"
>
<DeleteBinLineIcon />
</Button>
{showDeleteModal && (
<Modal
heading="Delete item?"
heading={copy.heading}
size="sm"
onClose={handleDeleteCancel}
closeOnEscape
Expand All @@ -101,12 +118,12 @@ function EditDeleteActions(props: Props) {
styleVariant="filled"
onClick={handleDeleteConfirm}
>
Delete
{copy.actionLabel}
</Button>
</ListView>
)}
>
{`Are you sure you want to delete "${itemTitle || 'this item'}"? This action cannot be undone.`}
{copy.message(itemTitle || 'this item')}
</Modal>
)}
</TableActions>
Expand Down
6 changes: 6 additions & 0 deletions app/contexts/GlobalEnumsContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { createContext } from 'react';
import type {
AppEnumCollectionDashboardPage,
AppEnumCollectionLinkType,
AppEnumCollectionPmerReportCategory,
AppEnumCollectionPmerReportDocumentType,
AppEnumCollectionReportContentType,
AppEnumCollectionReportType,
AppEnumCollectionReportVisibility,
Expand All @@ -18,6 +20,8 @@ export interface GlobalEnumsContextInterface {
dashboardPage: AppEnumCollectionDashboardPage[] | undefined;
reportContentType: AppEnumCollectionReportContentType[] | undefined;
reportVisibility: AppEnumCollectionReportVisibility[] | undefined;
pmerReportCategory: AppEnumCollectionPmerReportCategory[] | undefined;
pmerReportDocumentType: AppEnumCollectionPmerReportDocumentType[] | undefined;
}

const GlobalEnumsContext = createContext<GlobalEnumsContextInterface>({
Expand All @@ -28,6 +32,8 @@ const GlobalEnumsContext = createContext<GlobalEnumsContextInterface>({
dashboardPage: undefined,
reportContentType: undefined,
reportVisibility: undefined,
pmerReportCategory: undefined,
pmerReportDocumentType: undefined,
});

export default GlobalEnumsContext;
1 change: 1 addition & 0 deletions app/utils/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export function getReadableFileSize(bytes: number | null | undefined): string {
}

export const ACCEPTED_REPORT_FILE_TYPES = '.pdf,.doc,.docx,.png,.jpg,.jpeg';
export const ACCEPTED_PMER_FILE_TYPES = '.docx,.pdf,.xls,.xlsx,.csv,.png';
export const ACCEPTED_IMAGE_TYPES = 'image/*';
export const ACCEPTED_IMPORT_FILE_TYPES = '.xlsx,.xlsm';
export const MAX_REPORT_FILE_SIZE = 5 * 1024 * 1024; // 5MB
Expand Down
79 changes: 79 additions & 0 deletions app/views/Pmer/PmerFilters/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {
Button,
SelectInput,
TextInput,
} from '@ifrc-go/ui';
import { type EntriesAsList } from '@togglecorp/toggle-form';

import RegionSelectInput from '#components/RegionSelectInput';
import { AdminAreaLevel } from '#generated/types/graphql';
import useGlobalEnums from '#hooks/useGlobalEnums';
import {
keySelector,
labelSelector,
} from '#utils/common';

import type { PmerFilterType } from '..';

export interface Props {
value: PmerFilterType;
onChange: (...args: EntriesAsList<PmerFilterType>) => void;
onReset: () => void;
filtered: boolean;
}

function PmerFilters({
value, onChange, onReset, filtered,
}: Props) {
const {
pmerReportCategory: categoryOptions,
pmerReportDocumentType: reportTypeOptions,
} = useGlobalEnums();

return (
<>
<TextInput
name="search"
placeholder="Search by title"
value={value.search}
onChange={onChange}
/>
<RegionSelectInput
name="region"
placeholder="Region"
level={AdminAreaLevel.Region}
value={value.region}
onChange={onChange}
/>
<SelectInput
name="category"
placeholder="Report Category"
value={value.category}
onChange={onChange}
options={categoryOptions}
keySelector={keySelector}
labelSelector={labelSelector}
/>
<SelectInput
name="reportType"
placeholder="Report Type"
value={value.reportType}
onChange={onChange}
options={reportTypeOptions}
keySelector={keySelector}
labelSelector={labelSelector}
/>

<Button
name={undefined}
onClick={onReset}
title="Reset"
disabled={!filtered}
>
Reset
</Button>
</>
);
}

export default PmerFilters;
Loading
Loading