Skip to content

Commit 02167d5

Browse files
Merge pull request #1440 from pagopa/feature/PIN-7581-add-personal-data-field-create-and-summary-page
Feature/pin 7581 7860 add personal data field create and summary page
2 parents 7761e68 + 177af25 commit 02167d5

File tree

9 files changed

+182
-50
lines changed

9 files changed

+182
-50
lines changed

src/components/shared/CreateStepPurposeRiskAnalysisForm.tsx

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,21 @@ import { RHFTextField } from '@/components/shared/react-hook-form-inputs'
1010
import { useTranslation } from 'react-i18next'
1111
import { RiskAnalysisFormComponents } from '@/components/shared/RiskAnalysisFormComponents'
1212
import { useRiskAnalysisForm } from '@/hooks/useRiskAnalysisForm'
13+
import { InformationContainer } from '@pagopa/interop-fe-commons'
14+
import { FEATURE_FLAG_ESERVICE_PERSONAL_DATA } from '@/config/env'
1315

1416
type CreateStepPurposeRiskAnalysisFormProps = {
1517
defaultName?: string | undefined
1618
defaultAnswers?: Record<string, string[]>
1719
riskAnalysis: RiskAnalysisFormConfig
20+
personalData?: boolean | undefined
1821
onSubmit: (name: string, answers: Record<string, string[]>) => void
1922
onCancel: VoidFunction
2023
}
2124

2225
export const CreateStepPurposeRiskAnalysisForm: React.FC<
2326
CreateStepPurposeRiskAnalysisFormProps
24-
> = ({ defaultName, defaultAnswers, riskAnalysis, onSubmit, onCancel }) => {
27+
> = ({ defaultName, defaultAnswers, riskAnalysis, onSubmit, onCancel, personalData }) => {
2528
const { t } = useTranslation('shared-components', { keyPrefix: 'create.stepPurpose' })
2629

2730
const riskAnalysisForm = useRiskAnalysisForm({
@@ -30,7 +33,30 @@ export const CreateStepPurposeRiskAnalysisForm: React.FC<
3033
extraFields: { name: defaultName ?? '' },
3134
})
3235

36+
const [incompatibleAnswerValue, setIncompatibleAnswerValue] = React.useState<boolean>(false)
37+
38+
const checkIncompatibleAnswerValue = (validAnswers: Record<string, string[]>) => {
39+
const userAnswer = validAnswers['usesPersonalData']?.[0]
40+
const isYes = userAnswer === 'YES'
41+
const isNo = userAnswer === 'NO'
42+
43+
const incompatible = (isYes && personalData !== true) || (isNo && personalData !== false)
44+
45+
setIncompatibleAnswerValue(incompatible)
46+
return incompatible
47+
}
48+
3349
const handleSubmit = riskAnalysisForm.handleSubmit(({ validAnswers, name }) => {
50+
if (checkIncompatibleAnswerValue(validAnswers)) {
51+
riskAnalysisForm.setError('answers.usesPersonalData', {
52+
type: 'manual',
53+
message: t(
54+
'riskAnalysis.riskAnalysisSection.personalDataValuesAlert.labelForEserviceCreateStep2'
55+
),
56+
})
57+
return
58+
}
59+
3460
onSubmit(name, validAnswers)
3561
})
3662

@@ -54,13 +80,26 @@ export const CreateStepPurposeRiskAnalysisForm: React.FC<
5480
title={t('riskAnalysis.riskAnalysisSection.title')}
5581
description={t('riskAnalysis.riskAnalysisSection.description')}
5682
>
83+
{FEATURE_FLAG_ESERVICE_PERSONAL_DATA && (
84+
<InformationContainer
85+
label={t('riskAnalysis.riskAnalysisSection.personalDataFlag.label')}
86+
content={t(`riskAnalysis.riskAnalysisSection.personalDataFlag.${personalData}`)}
87+
/>
88+
)}
5789
<Alert sx={{ mt: 2, mb: -1 }} severity="warning">
5890
{t('riskAnalysis.riskAnalysisSection.personalDataAlert')}
5991
</Alert>
6092
</SectionContainer>
6193
<Stack spacing={2}>
6294
<RiskAnalysisFormComponents questions={riskAnalysisForm.questions} />
6395
</Stack>
96+
{FEATURE_FLAG_ESERVICE_PERSONAL_DATA && incompatibleAnswerValue && (
97+
<Alert sx={{ mt: 2 }} severity="warning">
98+
{t(
99+
'riskAnalysis.riskAnalysisSection.personalDataValuesAlert.alertForIncompatibleAnswer'
100+
)}
101+
</Alert>
102+
)}
64103
<StepActions
65104
back={{
66105
label: t('backWithoutSaveBtn'),

src/components/shared/RiskAnalysisFormComponents/RiskAnalysisFormComponents.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,20 @@ import { match } from 'ts-pattern'
2424
* @param questions - the actual updated questions visible to the user
2525
* @returns Array of components that should be rendered inside the form
2626
* */
27-
export const RiskAnalysisFormComponents: React.FC<{ questions: RiskAnalysisQuestions }> = ({
28-
questions,
29-
}) => {
27+
export const RiskAnalysisFormComponents: React.FC<{
28+
questions: RiskAnalysisQuestions
29+
}> = ({ questions }) => {
3030
return Object.entries(questions).map(([questionId, question]) => (
3131
<RiskAnalysisQuestion key={questionId} question={question} />
3232
))
3333
}
3434

35-
function RiskAnalysisQuestion({ question }: { question: FormConfigQuestion }) {
35+
function RiskAnalysisQuestion({
36+
question,
37+
}: {
38+
question: FormConfigQuestion
39+
personalData?: boolean
40+
}) {
3641
const lang = useCurrentLanguage()
3742
const answers = useFormContext<{ answers: RiskAnalysisAnswers }>().watch('answers')
3843

src/components/shared/RiskAnalysisFormComponents/RiskAnalysisRadioGroup.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export const RiskAnalysisRadioGroup: React.FC<RiskAnalysisRadioGroupProps> = ({
3737
const { t } = useTranslation()
3838
const labelId = useId()
3939

40-
const name = `answers.${questionId}`
40+
const name = `answers.${questionId}` as const
4141

4242
const error = formState.errors.answers?.[questionId]?.message as string | undefined
4343

src/hooks/useGetProviderEServiceActions.ts

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ export function useGetProviderEServiceActions(
2828
eserviceName: string | undefined,
2929
isNewTemplateVersionAvailable: boolean,
3030
isTemplateInstance: boolean,
31-
delegation?: DelegationWithCompactTenants
31+
delegation?: DelegationWithCompactTenants,
32+
hasPersonalData?: boolean,
33+
where?: 'tableRow' | 'detailsPage'
3234
): { actions: Array<ActionItemButton> } {
3335
const { t } = useTranslation('common', { keyPrefix: 'actions' })
3436
const { t: tDialogApproveDelegatedVersionDraft } = useTranslation('shared-components', {
@@ -936,9 +938,12 @@ export function useGetProviderEServiceActions(
936938
DEPRECATED: isDelegator ? [] : [suspendAction],
937939
DRAFT: draftActions,
938940
SUSPENDED: fromTemplateSuspendActions,
939-
WAITING_FOR_APPROVAL: isDelegator
940-
? [approveDelegatedVersionDraftAction, rejectDelegatedVersionDraftAction]
941-
: [],
941+
WAITING_FOR_APPROVAL:
942+
isDelegator && where !== 'tableRow'
943+
? [approveDelegatedVersionDraftAction, rejectDelegatedVersionDraftAction]
944+
: isDelegator && where === 'tableRow' && !hasPersonalData
945+
? [rejectDelegatedVersionDraftAction]
946+
: [],
942947
}
943948

944949
const EServiceFromTemplateOperatorAPIActions: Record<
@@ -950,9 +955,12 @@ export function useGetProviderEServiceActions(
950955
DEPRECATED: [],
951956
DRAFT: draftActions,
952957
SUSPENDED: fromTemplateSuspendActions,
953-
WAITING_FOR_APPROVAL: isDelegator
954-
? [approveDelegatedVersionDraftAction, rejectDelegatedVersionDraftAction]
955-
: [],
958+
WAITING_FOR_APPROVAL:
959+
isDelegator && where !== 'tableRow'
960+
? [approveDelegatedVersionDraftAction, rejectDelegatedVersionDraftAction]
961+
: isDelegator && where === 'tableRow' && !hasPersonalData
962+
? [rejectDelegatedVersionDraftAction]
963+
: [],
956964
}
957965

958966
const adminActions: Record<EServiceDescriptorState, Array<ActionItemButton>> = {
@@ -961,9 +969,12 @@ export function useGetProviderEServiceActions(
961969
DEPRECATED: isDelegator ? [] : [suspendAction],
962970
DRAFT: draftActions,
963971
SUSPENDED: suspendedActions,
964-
WAITING_FOR_APPROVAL: isDelegator
965-
? [approveDelegatedVersionDraftAction, rejectDelegatedVersionDraftAction]
966-
: [],
972+
WAITING_FOR_APPROVAL:
973+
isDelegator && where !== 'tableRow'
974+
? [approveDelegatedVersionDraftAction, rejectDelegatedVersionDraftAction]
975+
: isDelegator && where === 'tableRow' && !hasPersonalData
976+
? [rejectDelegatedVersionDraftAction]
977+
: [],
967978
}
968979

969980
const operatorAPIActions: Record<EServiceDescriptorState, Array<ActionItemButton>> = {
@@ -972,9 +983,12 @@ export function useGetProviderEServiceActions(
972983
DEPRECATED: [],
973984
DRAFT: draftActions,
974985
SUSPENDED: suspendedActions,
975-
WAITING_FOR_APPROVAL: isDelegator
976-
? [approveDelegatedVersionDraftAction, rejectDelegatedVersionDraftAction]
977-
: [],
986+
WAITING_FOR_APPROVAL:
987+
isDelegator && where !== 'tableRow'
988+
? [approveDelegatedVersionDraftAction, rejectDelegatedVersionDraftAction]
989+
: isDelegator && where === 'tableRow' && !hasPersonalData
990+
? [rejectDelegatedVersionDraftAction]
991+
: [],
978992
}
979993

980994
const availableClassicEServiceAction = isAdmin ? adminActions[state] : operatorAPIActions[state]

src/pages/ProviderEServiceCreatePage/components/EServiceCreateStepGeneral/EServiceCreateStepGeneral.tsx

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,17 @@ import {
3434
import { trackEvent } from '@/config/tracking'
3535
import { AuthHooks } from '@/api/auth'
3636
import { EServiceTemplateMutations } from '@/api/eserviceTemplate'
37-
import { SIGNALHUB_PERSONAL_DATA_PROCESS_URL } from '@/config/env'
37+
import {
38+
FEATURE_FLAG_ESERVICE_PERSONAL_DATA,
39+
SIGNALHUB_PERSONAL_DATA_PROCESS_URL,
40+
} from '@/config/env'
3841

3942
export type EServiceCreateStepGeneralFormValues = {
4043
name: string
4144
description: string
4245
technology: EServiceTechnology
4346
mode: EServiceMode
47+
personalData: boolean | undefined
4448
isSignalHubEnabled: boolean
4549
isConsumerDelegable: boolean
4650
isClientAccessDelegable: boolean
@@ -231,6 +235,37 @@ export const EServiceCreateStepGeneral: React.FC = () => {
231235
sx={{ mb: 0, mt: 3 }}
232236
onValueChange={(mode) => onEserviceModeChange!(mode as EServiceMode)}
233237
/>
238+
{FEATURE_FLAG_ESERVICE_PERSONAL_DATA && (
239+
<>
240+
<RHFRadioGroup
241+
name="personalData"
242+
row
243+
label={t(`create.step1.eservicePersonalDataField.${eserviceMode}.label`)}
244+
options={[
245+
{
246+
label: t(`create.step1.eservicePersonalDataField.${eserviceMode}.options.true`),
247+
value: 'true',
248+
},
249+
{
250+
label: t(
251+
`create.step1.eservicePersonalDataField.${eserviceMode}.options.false`
252+
),
253+
value: 'false',
254+
},
255+
]}
256+
disabled={!areEServiceGeneralInfoEditable || isEserviceFromTemplate}
257+
rules={{ required: true }}
258+
sx={{ mb: 3, mt: 3 }}
259+
/>
260+
{isEserviceFromTemplate && !eserviceTemplate?.personalData && (
261+
<Alert severity="error">
262+
{t('create.step1.eservicePersonalDataField.alertMissingPersonalData', {
263+
tenantName: eserviceTemplate?.creator.name,
264+
})}
265+
</Alert>
266+
)}
267+
</>
268+
)}
234269
</SectionContainer>
235270

236271
{/* Signalhub switch can be editable also if coming from a eservice eserviceTemplate */}
@@ -380,6 +415,7 @@ function evaluateFormDefaultValues(
380415
description: descriptor?.eservice.description ?? '',
381416
technology: descriptor?.eservice.technology ?? 'REST',
382417
mode: eserviceMode,
418+
personalData: descriptor?.eservice.personalData,
383419
isSignalHubEnabled: descriptor?.eservice.isSignalHubEnabled ?? false,
384420
isConsumerDelegable: descriptor?.eservice.isConsumerDelegable ?? false,
385421
isClientAccessDelegable: descriptor?.eservice.isClientAccessDelegable ?? false,
@@ -390,6 +426,7 @@ function evaluateFormDefaultValues(
390426
description: eserviceTemplate?.description,
391427
technology: eserviceTemplate?.technology,
392428
mode: eserviceTemplate?.mode,
429+
personalData: eserviceTemplate?.personalData,
393430
isSignalHubEnabled: eserviceTemplate?.isSignalHubEnabled ?? false,
394431
isConsumerDelegable: false,
395432
isClientAccessDelegable: false,

src/pages/ProviderEServiceCreatePage/components/EServiceCreateStepPurpose/EServiceCreateStepPurposeRiskAnalysis/EServiceCreateStepPurposeRiskAnalysis.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { useQuery } from '@tanstack/react-query'
1111
export const EServiceCreateStepPurposeRiskAnalysis: React.FC = () => {
1212
const { riskAnalysisFormState, closeRiskAnalysisForm, descriptor } = useEServiceCreateContext()
1313

14+
const personalData = descriptor?.eservice.personalData
15+
1416
const { mutate: addEServiceRiskAnalysis } = EServiceMutations.useAddEServiceRiskAnalysis()
1517
const { mutate: updateEServiceRiskAnalysis } = EServiceMutations.useUpdateEServiceRiskAnalysis()
1618

@@ -80,6 +82,7 @@ export const EServiceCreateStepPurposeRiskAnalysis: React.FC = () => {
8082
riskAnalysis={riskAnalysisLatest}
8183
onSubmit={handleSubmit}
8284
onCancel={handleCancel}
85+
personalData={personalData}
8386
/>
8487
)
8588
}

src/pages/ProviderEServiceListPage/components/EServiceTableRow.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { useGetProviderEServiceActions } from '@/hooks/useGetProviderEServiceAct
1010
import { TableRow } from '@pagopa/interop-fe-commons'
1111
import type { EServiceDescriptorState, ProducerEService } from '@/api/api.generatedTypes'
1212
import { AuthHooks } from '@/api/auth'
13-
import { useQueryClient } from '@tanstack/react-query'
13+
import { useQuery, useQueryClient } from '@tanstack/react-query'
1414
import { ByDelegationChip } from '@/components/shared/ByDelegationChip'
1515

1616
type EServiceTableRow = {
@@ -30,6 +30,9 @@ export const EServiceTableRow: React.FC<EServiceTableRow> = ({ eservice }) => {
3030
eservice.delegation && eservice.delegation?.delegator.id === jwt?.organizationId
3131
)
3232

33+
const { data: eserviceWithPersonalData } = useQuery(EServiceQueries.getSingle(eservice.id))
34+
const hasPersonalData = eserviceWithPersonalData?.personalData !== undefined
35+
3336
const { actions } = useGetProviderEServiceActions(
3437
eservice.id,
3538
eservice.activeDescriptor?.state,
@@ -40,7 +43,9 @@ export const EServiceTableRow: React.FC<EServiceTableRow> = ({ eservice }) => {
4043
eservice.name,
4144
eservice.isNewTemplateVersionAvailable ?? false,
4245
eservice.isTemplateInstance,
43-
eservice.delegation
46+
eservice.delegation,
47+
hasPersonalData,
48+
'tableRow'
4449
)
4550

4651
const hasActiveDescriptor = eservice.activeDescriptor

0 commit comments

Comments
 (0)