Skip to content

Commit 1f569bb

Browse files
committed
feat: working step two eservice creation
1 parent c1015d0 commit 1f569bb

File tree

12 files changed

+558
-10
lines changed

12 files changed

+558
-10
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/layout/containers/AttributeContainer.tsx

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
Skeleton,
1212
Stack,
1313
Typography,
14+
Button,
1415
} from '@mui/material'
1516
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
1617
import { ButtonNaked } from '@pagopa/mui-italia'
@@ -21,7 +22,9 @@ import { InformationContainer } from '@pagopa/interop-fe-commons'
2122
import { useTranslation } from 'react-i18next'
2223
import { useQuery, useQueryClient } from '@tanstack/react-query'
2324

24-
type AttributeContainerProps<TAttribute extends { id: string; name: string }> = {
25+
type AttributeContainerProps<
26+
TAttribute extends { id: string; name: string; dailyCallsPerConsumer?: number },
27+
> = {
2528
attribute: TAttribute
2629
actions?: Array<{
2730
label: React.ReactNode
@@ -31,14 +34,18 @@ type AttributeContainerProps<TAttribute extends { id: string; name: string }> =
3134
chipLabel?: string
3235
checked?: boolean
3336
onRemove?: (id: string, name: string) => void
37+
onCustomizeThreshold?: VoidFunction
3438
}
3539

36-
export const AttributeContainer = <TAttribute extends { id: string; name: string }>({
40+
export const AttributeContainer = <
41+
TAttribute extends { id: string; name: string; dailyCallsPerConsumer?: number },
42+
>({
3743
attribute,
3844
actions,
3945
chipLabel,
4046
checked,
4147
onRemove,
48+
onCustomizeThreshold,
4249
}: AttributeContainerProps<TAttribute>) => {
4350
const { t } = useTranslation('shared-components', { keyPrefix: 'attributeContainer' })
4451
const panelContentId = React.useId()
@@ -83,7 +90,43 @@ export const AttributeContainer = <TAttribute extends { id: string; name: string
8390
aria-controls={panelContentId}
8491
id={headerId}
8592
>
86-
<Typography fontWeight={600}>{attribute.name}</Typography>
93+
<Stack>
94+
<Typography fontWeight={600}>{attribute.name}</Typography>
95+
<Stack direction={'row'} spacing={2} alignItems={'center'}>
96+
{attribute.dailyCallsPerConsumer && (
97+
<Stack direction={'row'} spacing={1}>
98+
<Typography
99+
sx={{
100+
fontSize: 16,
101+
}}
102+
>
103+
{t('thresholdLabel')}
104+
</Typography>
105+
<Typography
106+
sx={{
107+
fontSize: 16,
108+
fontWeight: 700,
109+
}}
110+
>
111+
{attribute.dailyCallsPerConsumer}
112+
</Typography>
113+
</Stack>
114+
)}
115+
<Button
116+
sx={{
117+
justifyContent: 'start',
118+
px: 1,
119+
width: 'fit-content',
120+
}}
121+
onClick={(e) => {
122+
e.stopPropagation()
123+
onCustomizeThreshold?.()
124+
}}
125+
>
126+
{attribute.dailyCallsPerConsumer ? t('changeBtn') : t('customizeBtn')}
127+
</Button>
128+
</Stack>
129+
</Stack>
87130
</AccordionSummary>
88131
<AccordionDetails>
89132
{hasExpandedOnce && <AttributeDetails attributeId={attribute.id} />}

src/components/shared/AddAttributesToForm/AddAttributesToForm.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,30 @@ import { SectionContainer } from '@/components/layout/containers'
66
import { Box, Button, Link, Stack } from '@mui/material'
77
import { attributesHelpLink } from '@/config/constants'
88
import { AttributeGroup } from './AttributeGroup'
9-
import type { CreateStepAttributesFormValues } from '@/pages/ProviderEServiceCreatePage/components/EServiceCreateStepAttributes'
9+
import { type DescriptorAttribute } from '@/api/api.generatedTypes'
10+
import { type CreateStepThresholdsFormValues } from '@/pages/ProviderEServiceCreatePage/components/EServiceCreateStepThresholds'
1011

1112
export type AddAttributesToFormProps = {
1213
attributeKey: AttributeKey
1314
readOnly: boolean
1415
openCreateAttributeDrawer?: VoidFunction
16+
openCustomizeThresholdDrawer?: (
17+
attribute: DescriptorAttribute,
18+
attributeKey: AttributeKey,
19+
attributeGroupIndex: number
20+
) => void
1521
}
1622

1723
export const AddAttributesToForm: React.FC<AddAttributesToFormProps> = ({
1824
attributeKey,
1925
readOnly,
2026
openCreateAttributeDrawer,
27+
openCustomizeThresholdDrawer,
2128
}) => {
2229
const { t } = useTranslation('eservice', { keyPrefix: `create.step3` })
2330
const { t: tAttribute } = useTranslation('attribute')
2431

25-
const { watch, setValue } = useFormContext<CreateStepAttributesFormValues>()
32+
const { watch, setValue } = useFormContext<CreateStepThresholdsFormValues>()
2633

2734
const attributeGroups = watch(`attributes.${attributeKey}`)
2835

@@ -70,6 +77,7 @@ export const AddAttributesToForm: React.FC<AddAttributesToFormProps> = ({
7077
readOnly={readOnly}
7178
onRemoveAttributesGroup={handleRemoveAttributesGroup}
7279
onRemoveAttributeFromGroup={handleRemoveAttributeFromGroup}
80+
onOpenCustomizeThresholdDrawer={openCustomizeThresholdDrawer}
7381
/>
7482
))}
7583
</Stack>

src/components/shared/AddAttributesToForm/AttributeGroup.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ export type AttributeGroupProps = {
1717
readOnly: boolean
1818
onRemoveAttributesGroup: (groupIndex: number) => void
1919
onRemoveAttributeFromGroup: (attributeId: string, groupIndex: number) => void
20+
onOpenCustomizeThresholdDrawer?: (
21+
attribute: DescriptorAttribute,
22+
attributeKey: AttributeKey,
23+
attributeGroupIndex: number
24+
) => void
2025
}
2126

2227
export const AttributeGroup: React.FC<AttributeGroupProps> = ({
@@ -26,6 +31,7 @@ export const AttributeGroup: React.FC<AttributeGroupProps> = ({
2631
readOnly,
2732
onRemoveAttributesGroup,
2833
onRemoveAttributeFromGroup,
34+
onOpenCustomizeThresholdDrawer,
2935
}) => {
3036
const { t } = useTranslation('attribute', { keyPrefix: 'group' })
3137
const [isAttributeAutocompleteShown, setIsAttributeAutocompleteShown] = React.useState(false)
@@ -63,6 +69,9 @@ export const AttributeGroup: React.FC<AttributeGroupProps> = ({
6369
onRemove={
6470
!readOnly ? handleDeleteAttributeFromGroup.bind(null, attribute.id) : undefined
6571
}
72+
onCustomizeThreshold={() =>
73+
onOpenCustomizeThresholdDrawer?.(attribute, attributeKey, groupIndex)
74+
}
6675
/>
6776
</Box>
6877
))}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
import React, { useEffect } from 'react'
2+
import { FormProvider, type SubmitHandler, useForm } from 'react-hook-form'
3+
import { Drawer } from '@/components/shared/Drawer'
4+
import { Alert, Stack, Button, Typography } from '@mui/material'
5+
import { RHFTextField } from './react-hook-form-inputs'
6+
import { useTranslation } from 'react-i18next'
7+
import { type DescriptorAttribute } from '@/api/api.generatedTypes'
8+
import { type AttributeKey } from '@/types/attribute.types'
9+
import { WarningAmber } from '@mui/icons-material'
10+
11+
export type CustomizeThresholdDrawerProps = {
12+
isOpen: boolean
13+
onClose: VoidFunction
14+
attribute?: DescriptorAttribute
15+
attributeKey?: AttributeKey
16+
attributeGroupIndex?: number
17+
dailyCallsPerConsumer?: number
18+
dailyCallsTotal?: number
19+
onSubmit: (threshold: number) => void
20+
}
21+
22+
type CustomizeThresholdFormValues = {
23+
threshold: number
24+
}
25+
26+
export const CustomizeThresholdDrawer: React.FC<CustomizeThresholdDrawerProps> = ({
27+
isOpen,
28+
onClose,
29+
onSubmit,
30+
attribute,
31+
attributeKey,
32+
dailyCallsPerConsumer,
33+
dailyCallsTotal,
34+
}) => {
35+
const { t } = useTranslation('eservice', {
36+
keyPrefix: 'create.step2.attributes.customizeThresholdDrawer',
37+
})
38+
const formMethods = useForm<CustomizeThresholdFormValues>({
39+
defaultValues: {
40+
threshold: attribute?.dailyCallsPerConsumer,
41+
},
42+
})
43+
44+
const handleFormSubmit: SubmitHandler<CustomizeThresholdFormValues> = (values) => {
45+
onSubmit(values.threshold)
46+
}
47+
48+
useEffect(() => {
49+
if (isOpen) {
50+
formMethods.reset({
51+
threshold: attribute?.dailyCallsPerConsumer,
52+
})
53+
}
54+
}, [isOpen, formMethods, attribute])
55+
return (
56+
<FormProvider {...formMethods}>
57+
<Drawer
58+
isOpen={isOpen}
59+
title={t('title')}
60+
subtitle={t('subtitle', { type: attributeKey, name: attribute?.name })}
61+
onTransitionExited={formMethods.reset}
62+
onClose={onClose}
63+
>
64+
<Stack
65+
justifyContent={'space-between'}
66+
sx={{ height: '100%', pb: 5 }}
67+
component={'form'}
68+
noValidate
69+
onSubmit={formMethods.handleSubmit(handleFormSubmit)}
70+
id="threshold-form"
71+
>
72+
<Stack spacing={5}>
73+
<RHFTextField
74+
sx={{ mt: 2, mb: 0 }}
75+
name="threshold"
76+
label={t('field.placeholder')}
77+
infoLabel={t('field.info')}
78+
type="number"
79+
rules={{
80+
required: true,
81+
min: 1,
82+
}}
83+
/>
84+
<Alert icon={false} color="info">
85+
<Stack>
86+
<Typography
87+
sx={{
88+
fontSize: 14,
89+
fontWeight: 700,
90+
textTransform: 'uppercase',
91+
}}
92+
>
93+
{t('limitAlert.title')}
94+
</Typography>
95+
<Stack direction={'row'} alignItems={'center'} justifyContent={'space-between'}>
96+
<Typography
97+
sx={{
98+
fontSize: 16,
99+
}}
100+
>
101+
{t('limitAlert.totalLimit')}
102+
</Typography>
103+
{dailyCallsTotal ? (
104+
<Typography
105+
sx={{
106+
fontSize: 16,
107+
fontWeight: 600,
108+
}}
109+
>
110+
{t('limitAlert.label', { threshold: dailyCallsTotal })}
111+
</Typography>
112+
) : (
113+
<Stack direction={'row'} alignItems={'center'} spacing={1}>
114+
<WarningAmber color="warning" />
115+
<Typography
116+
sx={{
117+
fontSize: 16,
118+
fontWeight: 600,
119+
}}
120+
>
121+
{t('limitAlert.toInsert')}
122+
</Typography>
123+
</Stack>
124+
)}
125+
</Stack>
126+
<Stack direction={'row'} alignItems={'center'} justifyContent={'space-between'}>
127+
<Typography
128+
sx={{
129+
fontSize: 16,
130+
}}
131+
>
132+
{t('limitAlert.consumerLimit')}
133+
</Typography>
134+
{dailyCallsPerConsumer ? (
135+
<Typography
136+
sx={{
137+
fontSize: 16,
138+
fontWeight: 600,
139+
}}
140+
>
141+
{t('limitAlert.label', { threshold: dailyCallsPerConsumer })}
142+
</Typography>
143+
) : (
144+
<Stack direction={'row'} alignItems={'center'} spacing={1}>
145+
<WarningAmber color="warning" />
146+
<Typography
147+
sx={{
148+
fontSize: 16,
149+
fontWeight: 600,
150+
}}
151+
>
152+
{t('limitAlert.toInsert')}
153+
</Typography>
154+
</Stack>
155+
)}
156+
</Stack>
157+
</Stack>
158+
</Alert>
159+
</Stack>
160+
<Stack spacing={5}>
161+
<Alert severity="info">{t('alert')}</Alert>
162+
<Button type={'submit'} form="threshold-form" variant="contained">
163+
{t('submitBtnLabel')}
164+
</Button>
165+
</Stack>
166+
</Stack>
167+
</Drawer>
168+
</FormProvider>
169+
)
170+
}

src/pages/ProviderEServiceCreatePage/ProviderEServiceCreate.page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import type { EServiceMode } from '@/api/api.generatedTypes'
3333
import { useQuery } from '@tanstack/react-query'
3434
import { EServiceCreateFromTemplateStepPurpose } from './components/EServiceCreateStepPurpose/EServiceCreateFromTemplateStepPurpose'
3535
import { EServiceTemplateQueries } from '@/api/eserviceTemplate'
36+
import { EServiceCreateStepThresholds } from './components/EServiceCreateStepThresholds'
3637

3738
const ProviderEServiceCreatePage: React.FC = () => {
3839
const { t } = useTranslation('eservice')
@@ -76,7 +77,7 @@ const ProviderEServiceCreatePage: React.FC = () => {
7677
eserviceMode === 'DELIVER'
7778
? [
7879
{ label: t('create.stepper.step1Label'), component: EServiceCreateStepGeneral },
79-
{ label: t('create.stepper.step2Label'), component: EServiceCreateStepVersion },
80+
{ label: t('create.stepper.step2Label'), component: EServiceCreateStepThresholds },
8081
{ label: t('create.stepper.step3Label'), component: EServiceCreateStepAttributes },
8182
{ label: t('create.stepper.step4Label'), component: CreateStepDocuments },
8283
]

0 commit comments

Comments
 (0)