Skip to content

Commit

Permalink
add permissions for PDU module frontend (#4169)
Browse files Browse the repository at this point in the history
* add permissions for PDU module frontend

* display permission denied

---------

Co-authored-by: Maciej Szewczyk <[email protected]>
  • Loading branch information
mmaciekk and Maciej Szewczyk authored Aug 30, 2024
1 parent 2e7b5de commit 695395a
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BaseSection } from '@components/core/BaseSection';
import { Box, Tab, Tabs, Button, Fade } from '@mui/material';
import { Box, Tab, Tabs, Fade } from '@mui/material';
import { useState } from 'react';
import { Link } from 'react-router-dom';
import AddIcon from '@mui/icons-material/Add';
Expand All @@ -8,11 +8,20 @@ import { PeriodicDataUpdatesUpdatesList } from './PeriodicDataUpdatesUpdatesList
import { useBaseUrl } from '@hooks/useBaseUrl';
import { PeriodDataUpdatesUploadDialog } from './PeriodicDataUpdatesUploadDialog';
import { useProgramContext } from 'src/programContext';
import { usePermissions } from '@hooks/usePermissions';
import { hasPermissions, PERMISSIONS } from 'src/config/permissions';
import { ButtonTooltip } from '@components/core/ButtonTooltip';

export const PeriodicDataUpdates = (): React.ReactElement => {
const [value, setValue] = useState(0);
const { baseUrl } = useBaseUrl();
const { isSocialDctType } = useProgramContext();
const permissions = usePermissions();

const canCreatePDUTemplate = hasPermissions(
PERMISSIONS.PDU_TEMPLATE_CREATE,
permissions,
);

const handleChange = (
_event: React.ChangeEvent<object>,
Expand All @@ -35,24 +44,25 @@ export const PeriodicDataUpdates = (): React.ReactElement => {
onChange={handleChange}
aria-label="periodic data updates tabs"
>
<Tab label="Templates" data-cy="pdu-templates"/>
<Tab label="Updates" data-cy="pdu-updates"/>
<Tab label="Templates" data-cy="pdu-templates" />
<Tab label="Updates" data-cy="pdu-updates" />
</Tabs>
</Box>
}
buttons={
<Box display="flex" align-items="center">
<Box mr={2}>
<Button
<ButtonTooltip
variant="contained"
color="primary"
component={Link}
to={newTemplatePath}
startIcon={<AddIcon />}
data-cy="new-template-button"
disabled={!canCreatePDUTemplate}
>
New Template
</Button>
</ButtonTooltip>
</Box>
<Box>
<PeriodDataUpdatesUploadDialog />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useBaseUrl } from '@hooks/useBaseUrl';
import GetAppIcon from '@mui/icons-material/GetApp';
import UploadIcon from '@mui/icons-material/Upload';
import VisibilityIcon from '@mui/icons-material/Visibility';
import { Button, IconButton, TableCell, Tooltip } from '@mui/material';
import { IconButton, TableCell, Tooltip } from '@mui/material';
import { useQuery } from '@tanstack/react-query';
import { ReactElement, useEffect, useState } from 'react';
import { PeriodicDataUpdatesTemplateDetailsDialog } from './PeriodicDataUpdatesTemplateDetailsDialog';
Expand All @@ -19,6 +19,9 @@ import { StatusBox } from '@core/StatusBox';
import { periodicDataUpdateTemplateStatusToColor } from '@utils/utils';
import { useSnackbar } from '@hooks/useSnackBar';
import { useTranslation } from 'react-i18next';
import { ButtonTooltip } from '@components/core/ButtonTooltip';
import { usePermissions } from '@hooks/usePermissions';
import { hasPermissions, PERMISSIONS } from 'src/config/permissions';

export interface Template {
id: number;
Expand Down Expand Up @@ -87,6 +90,7 @@ export const PeriodicDataUpdatesTemplatesList = (): ReactElement => {
const { t } = useTranslation();
const { businessArea: businessAreaSlug, programId } = useBaseUrl();
const [isDialogOpen, setIsDialogOpen] = useState(false);
const permissions = usePermissions();
const [selectedTemplateId, setSelectedTemplateId] = useState<number | null>(
null,
);
Expand Down Expand Up @@ -161,6 +165,11 @@ export const PeriodicDataUpdatesTemplatesList = (): ReactElement => {
(template) => template.id === selectedTemplateId,
);

const canExportOrDownloadTemplate = hasPermissions(
PERMISSIONS.PDU_TEMPLATE_DOWNLOAD,
permissions,
);

const renderTemplateRow = (row: Template): ReactElement => (
<ClickableTableRow key={row.id} data-cy={`template-row-${row.id}`}>
<TableCell data-cy={`template-id-${row.id}`}>{row.id}</TableCell>
Expand Down Expand Up @@ -194,28 +203,31 @@ export const PeriodicDataUpdatesTemplatesList = (): ReactElement => {
}
>
<span>
<Button
<ButtonTooltip
variant="contained"
color="primary"
onClick={() => handleDownloadClick(row.id)}
startIcon={<GetAppIcon />}
data-cy={`download-btn-${row.id}`}
disabled={row?.number_of_records === 0}
disabled={
row?.number_of_records === 0 || !canExportOrDownloadTemplate
}
>
Download
</Button>
</ButtonTooltip>
</span>
</Tooltip>
) : row.can_export ? (
<Button
<ButtonTooltip
variant="contained"
color="primary"
onClick={() => handleExportClick(row.id)}
startIcon={<UploadIcon />}
data-cy={`export-btn-${row.id}`}
disabled={!canExportOrDownloadTemplate}
>
Export
</Button>
</ButtonTooltip>
) : null}
</TableCell>
</ClickableTableRow>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
import { DialogTitleWrapper } from '@containers/dialogs/DialogTitleWrapper';
//TODO MS: display errors
// import { ImportErrors } from '@containers/tables/payments/VerificationRecordsTable/errors/ImportErrors';
import { useSnackbar } from '@hooks/useSnackBar';

import { DropzoneField } from '@core/DropzoneField';
import { LoadingButton } from '@core/LoadingButton';
import { useProgramContext } from 'src/programContext';
import { useUploadPeriodicDataUpdateTemplate } from './PeriodicDataUpdatesTemplatesListActions';
import { useBaseUrl } from '@hooks/useBaseUrl';
import { usePermissions } from '@hooks/usePermissions';
import { hasPermissions, PERMISSIONS } from 'src/config/permissions';
import { ButtonTooltip } from '@components/core/ButtonTooltip';

const Error = styled.div`
color: ${({ theme }) => theme.palette.error.dark};
Expand All @@ -31,12 +32,14 @@ const DisabledUploadIcon = styled(Publish)`
export const PeriodDataUpdatesUploadDialog = (): React.ReactElement => {
const { showMessage } = useSnackbar();
const { businessArea, programId } = useBaseUrl();
const permissions = usePermissions();
const [open, setOpenImport] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [fileToImport, setFileToImport] = useState<File | null>(null);
const { isActiveProgram } = useProgramContext();
const { t } = useTranslation();
const { mutate, error } = useUploadPeriodicDataUpdateTemplate();
const canPDUUpload = hasPermissions(PERMISSIONS.PDU_UPLOAD, permissions);

const handleFileUpload = (): void => {
if (fileToImport) {
Expand Down Expand Up @@ -65,11 +68,7 @@ export const PeriodDataUpdatesUploadDialog = (): React.ReactElement => {
}
};
let errorMessage = null;
// @ts-ignore
if (error && error?.data?.error) {
// @ts-ignore
errorMessage = <Error data-cy="pdu-upload-error">{error?.data?.error}</Error>;
} else if (error) {
if (error) {
errorMessage = (
<Error data-cy="pdu-upload-error">
{t('Error uploading file:')} {error.message}
Expand All @@ -80,15 +79,15 @@ export const PeriodDataUpdatesUploadDialog = (): React.ReactElement => {
return (
<>
<Box key="import">
<Button
<ButtonTooltip
startIcon={!isActiveProgram ? <DisabledUploadIcon /> : <UploadIcon />}
color="primary"
data-cy="button-import"
onClick={() => setOpenImport(true)}
disabled={!isActiveProgram}
disabled={!isActiveProgram || !canPDUUpload}
>
{t('Upload Data')}
</Button>
</ButtonTooltip>
</Box>
<Dialog
open={open}
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/config/permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ export const PERMISSIONS = {
TARGETING_UNLOCK: 'TARGETING_UNLOCK',
TARGETING_SEND: 'TARGETING_SEND',

// PDU
PDU_VIEW_LIST_AND_DETAILS: 'PDU_VIEW_LIST_AND_DETAILS',
PDU_TEMPLATE_CREATE: 'PDU_TEMPLATE_CREATE',
PDU_TEMPLATE_DOWNLOAD: 'PDU_TEMPLATE_DOWNLOAD',
PDU_UPLOAD: 'PDU_UPLOAD',

// Payment Verification
PAYMENT_VERIFICATION_VIEW_LIST: 'PAYMENT_VERIFICATION_VIEW_LIST',
PAYMENT_VERIFICATION_VIEW_DETAILS: 'PAYMENT_VERIFICATION_VIEW_DETAILS',
Expand Down
46 changes: 33 additions & 13 deletions frontend/src/containers/pages/population/HouseholdMembersPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,23 @@ export const HouseholdMembersPage = (): React.ReactElement => {
isNewTemplateJustCreated ? 1 : 0,
);

const canViewPDUListAndDetails = hasPermissions(
PERMISSIONS.PDU_VIEW_LIST_AND_DETAILS,
permissions,
);

const canViewHouseholdMembersPage = hasPermissions(
PERMISSIONS.POPULATION_VIEW_INDIVIDUALS_LIST,
permissions,
);

if (householdChoicesLoading || individualChoicesLoading)
return <LoadingComponent />;

if (!individualChoicesData || !householdChoicesData || permissions === null)
return null;

if (
!hasPermissions(PERMISSIONS.POPULATION_VIEW_INDIVIDUALS_LIST, permissions)
)
return <PermissionDenied />;
if (!canViewHouseholdMembersPage) return <PermissionDenied />;

return (
<>
Expand All @@ -84,26 +91,37 @@ export const HouseholdMembersPage = (): React.ReactElement => {
}}
>
<Tab data-cy="tab-individuals" label="Individuals" />
{!programHasPdu ? (
{programHasPdu ? (
canViewPDUListAndDetails ? (
<Tab
data-cy="tab-periodic-data-updates"
label="Periodic Data Updates"
/>
) : (
<Tooltip title={t('Permission Denied')}>
<span>
<Tab
disabled
data-cy="tab-periodic-data-updates"
label="Periodic Data Updates"
/>
</span>
</Tooltip>
)
) : (
<Tooltip
title={t(
'Programme does not have defined fields for periodic updates',
)}
>
<span>
<Tab
disabled={!programHasPdu}
disabled
data-cy="tab-periodic-data-updates"
label="Periodic Data Updates"
/>
</span>
</Tooltip>
) : (
<Tab
disabled={!programHasPdu}
data-cy="tab-periodic-data-updates"
label="Periodic Data Updates"
/>
)}
</Tabs>
}
Expand Down Expand Up @@ -136,8 +154,10 @@ export const HouseholdMembersPage = (): React.ReactElement => {
/>
</Box>
</>
) : (
) : canViewPDUListAndDetails ? (
<PeriodicDataUpdates />
) : (
<PermissionDenied />
)}
</Box>
</Fade>
Expand Down

0 comments on commit 695395a

Please sign in to comment.