Skip to content

Commit

Permalink
[VAS-1070] feat; Change station and channel detail view on pending up…
Browse files Browse the repository at this point in the history
…date (#586)

* [VAS-1070] improved station API and removed wrapper status value from body

* [VAS-1070] integrated new station and channel detail API and removed unused ones.

* [VAS-1070] fix unit tests

* [VAS-1070] handled station and channel with pending update

* [VAS-1070] added common component for alert in station and channel detail page

* [VAS-1070] removed created by when undefined

* [VAS-1070] fix unit tests

* [VAS-1070] fix title

* [VAS-1070] rename variable
  • Loading branch information
gioelemella authored Jul 2, 2024
1 parent a27f297 commit c331f88
Show file tree
Hide file tree
Showing 34 changed files with 1,208 additions and 1,232 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"clean:api-portal": "rimraf src/api/generated/portal && rimraf openApi/generated",
"generate:api-portal": "wget https://raw.githubusercontent.com/pagopa/pagopa-selfcare-ms-backoffice-backend/main/openapi/openapi.json -O ./openApi/portal-api-docs.json && npm run generate:client",
"generate:api-portal-next": "wget https://raw.githubusercontent.com/pagopa/pagopa-selfcare-ms-backoffice-backend/next/openapi/openapi.json -O ./openApi/portal-api-docs.json && npm run generate:client",
"generate:api-portal-pr": "wget https://raw.githubusercontent.com/pagopa/pagopa-selfcare-ms-backoffice-backend/VAS-1103-bundle-pspName/openapi/openapi.json -O ./openApi/portal-api-docs.json && npm run generate:client",
"generate:api-portal-pr": "wget https://raw.githubusercontent.com/pagopa/pagopa-selfcare-ms-backoffice-backend/VAS-1070-change-station-channel-detail-view-on-update/openapi/openapi.json -O ./openApi/portal-api-docs.json && npm run generate:client",
"generate:api-portal-local": "npm run generate:client",
"generate:client": "jq 'walk(if type == \"object\" and has(\"parameters\") then .parameters |= map(select(.name != \"X-Request-Id\")) else . end)' ./openApi/portal-api-docs.json > ./openApi/portal-api-docs.json.temp && mv ./openApi/portal-api-docs.json.temp ./openApi/portal-api-docs.json && yarn run clean:api-portal && mkdirp openApi/generated && gen-api-models --api-spec openApi/portal-api-docs.json --out-dir src/api/generated/portal --no-strict --request-types --response-decoders --client && node openApi/scripts/api-portal_fixPostGen.js"
},
Expand Down
114 changes: 55 additions & 59 deletions src/api/BackofficeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import { ConfigurationStatus, StationOnCreation } from '../model/Station';
import { store } from '../redux/store';
import { extractResponse } from '../utils/client-utils';
import { ENV } from '../utils/env';
import { WithDefaultsT as WithCustomDefaultsT, createClient as createCustomClient } from './custom/client';
import {
WithDefaultsT as WithCustomDefaultsT,
createClient as createCustomClient,
} from './custom/client';
import { AvailableCodes } from './generated/portal/AvailableCodes';
import { BrokerAndEcDetailsResource } from './generated/portal/BrokerAndEcDetailsResource';
import { BrokerDto } from './generated/portal/BrokerDto';
Expand Down Expand Up @@ -75,7 +78,7 @@ import { PspChannelsResource } from './generated/portal/PspChannelsResource';
import { PublicBundleRequest } from './generated/portal/PublicBundleRequest';
import { StationCodeResource } from './generated/portal/StationCodeResource';
import { StationDetailResource } from './generated/portal/StationDetailResource';
import { StationDetailsDto, StatusEnum } from './generated/portal/StationDetailsDto';
import { StationDetailsDto } from './generated/portal/StationDetailsDto';
import { TestStationTypeEnum } from './generated/portal/StationTestDto';
import { TavoloOpDto } from './generated/portal/TavoloOpDto';
import { TavoloOpOperations } from './generated/portal/TavoloOpOperations';
Expand All @@ -91,7 +94,6 @@ import {
Redirect_protocolEnum,
WrapperChannelDetailsDto,
} from './generated/portal/WrapperChannelDetailsDto';
import { WrapperChannelDetailsResource } from './generated/portal/WrapperChannelDetailsResource';
import { WrapperChannelsResource } from './generated/portal/WrapperChannelsResource';
import { WrapperEntities } from './generated/portal/WrapperEntities';
import { WrapperStationDetailsDto } from './generated/portal/WrapperStationDetailsDto';
Expand Down Expand Up @@ -400,9 +402,17 @@ export const BackofficeApi = {
return extractResponse(result, 200, onRedirectToLogin);
},

// retrive of channel detail before on db and then on the node
getChannelDetail: async (channelcode: string): Promise<ChannelDetailsResource> => {
const result = await backofficeClient.getChannelDetail({ 'channel-code': channelcode });
getChannelDetail: async ({
channelCode,
status,
}: {
channelCode: string;
status: ConfigurationStatus;
}): Promise<ChannelDetailsResource> => {
const result = await backofficeClient.getChannelDetails({
'channel-code': channelCode,
status,
});
return extractResponse(result, 200, onRedirectToLogin);
},

Expand Down Expand Up @@ -432,7 +442,7 @@ export const BackofficeApi = {
return extractResponse(result, 200, onRedirectToLogin);
},

createChannel: async (channel: ChannelDetailsDto): Promise<WrapperChannelDetailsResource> => {
createChannel: async (channel: ChannelDetailsDto): Promise<ChannelDetailsResource> => {
const channelBody2Send = channelBody(channel);
const result = await backofficeClient.createChannel({
body: channelBody2Send,
Expand Down Expand Up @@ -695,12 +705,13 @@ export const BackofficeApi = {
return extractResponse(result, 200, onRedirectToLogin);
},

getWrapperEntities: async (code: string): Promise<WrapperEntities> => {
const result = await backofficeClient.getStation({ 'station-code': code });
return extractResponse(result, 200, onRedirectToLogin);
},

createWrapperStation: async (station: WrapperStationDetailsDto): Promise<WrapperEntities> => {
createWrapperStation: async ({
station,
validationUrl,
}: {
station: WrapperStationDetailsDto;
validationUrl: string;
}): Promise<WrapperEntities> => {
const result = await backofficeClient.createWrapperStationDetails({
body: {
brokerCode: station.brokerCode,
Expand All @@ -720,36 +731,24 @@ export const BackofficeApi = {
targetHostPof: station.targetHostPof,
targetPathPof: station.targetPathPof,
targetPortPof: station.targetPortPof,
validationUrl: station.validationUrl,
validationUrl,
},
});
return extractResponse(result, 201, onRedirectToLogin);
},

updateWrapperStationToCheck: async (
stationCode: string,
station: StationDetailsDto
): Promise<WrapperEntities> => {
const result = await backofficeClient.updateWrapperStationDetails({
'station-code': stationCode,
body: {
...station,
status: StatusEnum.TO_CHECK,
},
});
return extractResponse(result, 200, onRedirectToLogin);
},

updateWrapperStationToCheckUpdate: async (
stationCode: string,
station: StationDetailsDto
): Promise<WrapperEntities> => {
updateWrapperStationDetails: async ({
stationCode,
station,
validationUrl,
}: {
stationCode: string;
station: StationDetailsDto;
validationUrl: string;
}): Promise<WrapperEntities> => {
const result = await backofficeClient.updateWrapperStationDetails({
'station-code': stationCode,
body: {
...station,
status: StatusEnum.TO_CHECK_UPDATE,
},
body: { ...station, validationUrl },
});
return extractResponse(result, 200, onRedirectToLogin);
},
Expand All @@ -773,34 +772,31 @@ export const BackofficeApi = {
return extractResponse(result, 200, onRedirectToLogin);
},

updateStation: async (
station: StationDetailsDto,
stationcode: string
): Promise<StationDetailResource> => {
updateStation: async ({
stationCode,
station,
}: {
stationCode: string;
station: StationDetailsDto;
}): Promise<StationDetailResource> => {
const result = await backofficeClient.updateStation({
body: {
...station,
status: StatusEnum.APPROVED,
},
'station-code': stationcode,
body: station,
'station-code': stationCode,
});
return extractResponse(result, 200, onRedirectToLogin);
},

getWrapperEntitiesStation: async (code: string): Promise<WrapperEntities> => {
const result = await backofficeClient.getWrapperEntitiesStation({ 'station-code': code });
return extractResponse(result, 200, onRedirectToLogin);
},

// before tries to get the detail from the DB, if it doesn't find anything, will try to get the detail form apim
getStationDetail: async (stationId: string): Promise<StationDetailResource> => {
const result = await backofficeClient.getStationDetail({ 'station-code': stationId });
return extractResponse(result, 200, onRedirectToLogin);
},

// get the detail directly from apim
getStation: async (stationId: string): Promise<StationDetailResource> => {
const result = await backofficeClient.getStation({ 'station-code': stationId });
getStationDetails: async ({
stationCode,
status,
}: {
stationCode: string;
status: ConfigurationStatus;
}): Promise<StationDetailResource> => {
const result = await backofficeClient.getStationDetails({
'station-code': stationCode,
status,
});
return extractResponse(result, 200, onRedirectToLogin);
},

Expand Down
98 changes: 98 additions & 0 deletions src/components/WrapperCommon/GetAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { Alert, Typography } from '@mui/material';
import { Box } from '@mui/system';
import { useTranslation } from 'react-i18next';
import { WrapperStatusEnum } from '../../api/generated/portal/ChannelDetailsResource';
import { useUserRole } from '../../hooks/useUserRole';

type Props = {
componentPath: string;
wrapperStatus: WrapperStatusEnum;
note: string;
pendingUpdate: boolean;
};

// eslint-disable-next-line sonarjs/cognitive-complexity
export default function GetAlert({
componentPath,
wrapperStatus,
note,
pendingUpdate,
}: Readonly<Props>) {
const { t } = useTranslation();
const { userIsPagopaOperator } = useUserRole();

if (wrapperStatus !== WrapperStatusEnum.APPROVED) {
const isToBeValidated =
wrapperStatus === WrapperStatusEnum.TO_CHECK ||
wrapperStatus === WrapperStatusEnum.TO_CHECK_UPDATE;
const isToBeFixed =
wrapperStatus === WrapperStatusEnum.TO_FIX ||
wrapperStatus === WrapperStatusEnum.TO_FIX_UPDATE;

const userHasToTakeAction =
(isToBeValidated && userIsPagopaOperator) || (isToBeFixed && !userIsPagopaOperator);
return (
<Box my={2} data-testId="on-validation-alert-test-id">
<Alert
severity={userHasToTakeAction ? 'warning' : 'info'}
variant="outlined"
sx={{ py: 2 }}
>
<GetAlertContent
isToBeFixed={isToBeFixed}
isToBeValidated={isToBeValidated}
userIsPagopaOperator={userIsPagopaOperator}
componentPath={componentPath}
note={note}
t={t}
/>
</Alert>
</Box>
);
} else if (pendingUpdate) {
return (
<Box my={2} data-testId="pending-update-alert-test-id">
<Alert severity="warning" variant="outlined" sx={{ py: 2 }}>
<Typography fontWeight={'fontWeightMedium'} sx={{ whiteSpace: 'pre-line' }}>
{t(`${componentPath}.alert.pendingUpdate`)}
</Typography>
</Alert>
</Box>
);
}
return null;
}

function GetAlertContent({
isToBeFixed,
isToBeValidated,
userIsPagopaOperator,
componentPath,
note,
t,
}: Readonly<{
isToBeFixed: boolean;
isToBeValidated: boolean;
userIsPagopaOperator: boolean;
componentPath: string;
note: string;
t: (key: string) => string;
}>) {
if (isToBeFixed) {
return (
<>
<Typography fontWeight={'fontWeightMedium'} data-testId="to-fix-alert-test-id">
{t(`${componentPath}.alert.toFixTitle`)}
</Typography>
<Typography>{note.trim() ? note : t(`${componentPath}.alert.toFixMessage`)}</Typography>
</>
);
}
if (isToBeValidated && userIsPagopaOperator) {
return <Typography data-testId="to-check-alert-test-id">{t(`${componentPath}.alert.toCheckMessage`)}</Typography>;
}
if (isToBeValidated && !userIsPagopaOperator) {
return <Typography data-testId="waiting-for-review-alert-test-id">{t(`${componentPath}.alert.waitingForRevision`)}</Typography>;
}
return null;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Chip} from '@mui/material';
import {useTranslation} from 'react-i18next';
import {useUserRole} from '../hooks/useUserRole';
import {WrapperStatusEnum} from '../api/generated/portal/WrapperStationResource';
import { Chip } from '@mui/material';
import { useTranslation } from 'react-i18next';
import { WrapperStatusEnum } from '../../api/generated/portal/StationDetailResource';
import { useUserRole } from '../../hooks/useUserRole';

type Props = {
status: string;
Expand Down
Loading

0 comments on commit c331f88

Please sign in to comment.