From 3d8a077b783a4890c0e262e853f359b68e57c5fb Mon Sep 17 00:00:00 2001 From: Carmine Porricelli Date: Fri, 6 Dec 2024 15:02:49 +0100 Subject: [PATCH 1/4] Added in-add attributes drawer --- src/api/eservice/eservice.mutations.ts | 19 +++ src/api/eservice/eservice.services.ts | 20 +++ .../layout/containers/AttributeContainer.tsx | 3 +- .../containers/AttributeGroupContainer.tsx | 14 +- .../shared}/AttributeAutocomplete.tsx | 32 ++-- .../shared/ReadOnlyDescriptorAttributes.tsx | 87 +++++----- .../AttributeGroup.tsx | 19 ++- .../ProviderEServiceDescriptorAttributes.tsx | 57 ++++++- ...erviceUpdateDescriptorAttributesDrawer.tsx | 153 ++++++++++++++++++ ...roviderEServiceAttributeVersionSummary.tsx | 4 +- .../ProviderEServiceDocumentationSummary.tsx | 4 +- .../ProviderEServiceGeneralInfoSummary.tsx | 8 +- .../ProviderEServiceRiskAnalysisSummary.tsx | 6 +- ...roviderEServiceRiskAnalysisSummaryList.tsx | 6 +- .../ProviderEServiceVersionInfoSummary.tsx | 6 +- src/static/locales/en/common.json | 3 +- src/static/locales/en/eservice.json | 4 + src/static/locales/en/mutations-feedback.json | 7 + src/static/locales/it/common.json | 3 +- src/static/locales/it/eservice.json | 4 + src/static/locales/it/mutations-feedback.json | 7 + 21 files changed, 366 insertions(+), 100 deletions(-) rename src/{pages/ProviderEServiceCreatePage/components/EServiceCreateStepAttributes/AddAttributesToEServiceForm => components/shared}/AttributeAutocomplete.tsx (75%) create mode 100644 src/pages/ProviderEServiceDetailsPage/components/ProviderEServiceDetailsTab/ProviderEServiceUpdateDescriptorAttributesDrawer.tsx diff --git a/src/api/eservice/eservice.mutations.ts b/src/api/eservice/eservice.mutations.ts index 146aa967c..881082206 100644 --- a/src/api/eservice/eservice.mutations.ts +++ b/src/api/eservice/eservice.mutations.ts @@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next' import type { EServiceRiskAnalysisSeed, UpdateEServiceDescriptorSeed } from '../api.generatedTypes' import { EServiceServices } from './eservice.services' import { EServiceQueries } from './eservice.queries' +import type { AttributeKey } from '@/types/attribute.types' function useCreateDraft() { const { t } = useTranslation('mutations-feedback', { keyPrefix: 'eservice.createDraft' }) @@ -306,6 +307,23 @@ function useUpdateEServiceDescription() { }) } +function useUpdateDescriptorAttributes() { + const { t } = useTranslation('mutations-feedback', { + keyPrefix: 'eservice.updateDescriptorAttributes', + }) + const { t: tAttribute } = useTranslation('attribute', { keyPrefix: 'type' }) + return useMutation({ + mutationFn: EServiceServices.updateDescriptorAttributes, + meta: { + successToastLabel: (_: unknown, variables: { attributeKey: AttributeKey }) => + t('outcome.success', { attributeKind: tAttribute(`${variables.attributeKey}_other`) }), + errorToastLabel: (_: unknown, variables: { attributeKey: AttributeKey }) => + t('outcome.error', { attributeKind: tAttribute(`${variables.attributeKey}_other`) }), + loadingLabel: t('loading'), + }, + }) +} + export const EServiceMutations = { useCreateDraft, useUpdateDraft, @@ -326,4 +344,5 @@ export const EServiceMutations = { useUpdateEServiceDescription, useUpdateVersionDraftDocumentDescription, useImportVersion, + useUpdateDescriptorAttributes, } diff --git a/src/api/eservice/eservice.services.ts b/src/api/eservice/eservice.services.ts index 324be0fda..92a4e842c 100644 --- a/src/api/eservice/eservice.services.ts +++ b/src/api/eservice/eservice.services.ts @@ -7,6 +7,7 @@ import type { CreatedEServiceDescriptor, CreatedResource, CreateEServiceDocumentPayload, + DescriptorAttributesSeed, EServiceDescriptionSeed, EServiceDoc, EServiceRiskAnalysis, @@ -26,6 +27,7 @@ import type { UpdateEServiceDescriptorSeed, UpdateEServiceSeed, } from '../api.generatedTypes' +import type { AttributeKey } from '@/types/attribute.types' async function getCatalogList(params: GetEServicesCatalogParams) { const response = await axiosInstance.get( @@ -389,6 +391,23 @@ async function importVersion({ eserviceFile }: { eserviceFile: File }) { }) } +async function updateDescriptorAttributes({ + eserviceId, + descriptorId, + attributeKey: _attributeKey, + ...payload +}: { + eserviceId: string + descriptorId: string + attributeKey: AttributeKey +} & DescriptorAttributesSeed) { + const response = await axiosInstance.post( + `${BACKEND_FOR_FRONTEND_URL}/eservices/${eserviceId}/descriptors/${descriptorId}/attributes/update`, + payload + ) + return response.data +} + export const EServiceServices = { getCatalogList, getProviderList, @@ -420,4 +439,5 @@ export const EServiceServices = { updateEServiceDescription, exportVersion, importVersion, + updateDescriptorAttributes, } diff --git a/src/components/layout/containers/AttributeContainer.tsx b/src/components/layout/containers/AttributeContainer.tsx index a805c1e2c..8153329c5 100644 --- a/src/components/layout/containers/AttributeContainer.tsx +++ b/src/components/layout/containers/AttributeContainer.tsx @@ -55,7 +55,7 @@ export const AttributeContainer = + {checked && } {onRemove && ( @@ -130,6 +130,7 @@ const AttributeDetails: React.FC<{ attributeId: string }> = ({ attributeId }) => {attribute.description} void subheader?: React.ReactNode children?: React.ReactNode color?: 'primary' | 'success' | 'error' | 'warning' | 'gray' + cardContentSx?: SxProps } const containerColors = { @@ -50,13 +52,18 @@ export const AttributeGroupContainer: React.FC = ( onRemove, children, subheader, + cardContentSx, color = 'primary', + ...cardProps }) => { const { t } = useTranslation('shared-components', { keyPrefix: 'attributeGroupContainer' }) const { headerColor, borderColor, bodyColor, textColor } = containerColors[color] return ( - + = ( sx={{ p: 2, '&:last-child': { - paddingBottom: 2, + pb: 2, }, + ...cardContentSx, }} > {children} diff --git a/src/pages/ProviderEServiceCreatePage/components/EServiceCreateStepAttributes/AddAttributesToEServiceForm/AttributeAutocomplete.tsx b/src/components/shared/AttributeAutocomplete.tsx similarity index 75% rename from src/pages/ProviderEServiceCreatePage/components/EServiceCreateStepAttributes/AddAttributesToEServiceForm/AttributeAutocomplete.tsx rename to src/components/shared/AttributeAutocomplete.tsx index 5b8c6b178..81cad16d0 100644 --- a/src/pages/ProviderEServiceCreatePage/components/EServiceCreateStepAttributes/AddAttributesToEServiceForm/AttributeAutocomplete.tsx +++ b/src/components/shared/AttributeAutocomplete.tsx @@ -3,32 +3,30 @@ import { AttributeQueries } from '@/api/attribute' import { RHFAutocompleteSingle } from '@/components/shared/react-hook-form-inputs' import type { AttributeKey } from '@/types/attribute.types' import { Button, Stack } from '@mui/material' -import { FormProvider, useForm, useFormContext } from 'react-hook-form' +import { FormProvider, useForm } from 'react-hook-form' import { useTranslation } from 'react-i18next' import type { AttributeKind, DescriptorAttribute } from '@/api/api.generatedTypes' import { useAutocompleteTextInput } from '@pagopa/interop-fe-commons' -import type { EServiceCreateStepAttributesFormValues } from '..' import { keepPreviousData, useQuery } from '@tanstack/react-query' export type AttributeAutocompleteProps = { - groupIndex: number attributeKey: AttributeKey - handleHideAutocomplete: VoidFunction + onAddAttribute: (attribute: DescriptorAttribute) => void + alreadySelectedAttributeIds: string[] + direction?: 'column' | 'row' } type AttributeAutocompleteFormValues = { attribute: null | DescriptorAttribute } export const AttributeAutocomplete: React.FC = ({ - groupIndex, attributeKey, - handleHideAutocomplete, + onAddAttribute, + alreadySelectedAttributeIds, + direction = 'row', }) => { const { t } = useTranslation('attribute', { keyPrefix: 'group' }) const [attributeSearchParam, setAttributeSearchParam] = useAutocompleteTextInput() - const { watch, setValue } = useFormContext() - const attributeGroups = watch(`attributes.${attributeKey}`) - const attributeAutocompleteFormMethods = useForm({ defaultValues: { attribute: null }, }) @@ -62,29 +60,22 @@ export const AttributeAutocomplete: React.FC = ({ const handleAddAttributeToGroup = handleSubmit(({ attribute }) => { if (!attribute) return - const newAttributeGroups = [...attributeGroups] - newAttributeGroups[groupIndex].push(attribute) - setValue(`attributes.${attributeKey}`, newAttributeGroups) - handleHideAutocomplete() + onAddAttribute(attribute) }) const options = React.useMemo(() => { const attributes = data?.results ?? [] - const attributesAlreadyInGroups = attributeGroups.reduce( - (acc, group) => [...acc, ...group.map(({ id }) => id)], - [] as Array - ) return attributes - .filter((att) => !attributesAlreadyInGroups.includes(att.id)) + .filter((att) => !alreadySelectedAttributeIds.includes(att.id)) .map((att) => ({ label: att.name, value: att, })) - }, [data?.results, attributeGroups]) + }, [data?.results, alreadySelectedAttributeIds]) return ( - + = ({ />