diff --git a/src/api/eservice/eservice.mutations.ts b/src/api/eservice/eservice.mutations.ts index 146aa967c..c447a5a0e 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,31 @@ 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: unknown) => + t('outcome.success', { + attributeKind: tAttribute( + `${(variables as { attributeKey: AttributeKey }).attributeKey}_other` + ), + }), + errorToastLabel: (_: unknown, variables: unknown) => + t('outcome.error', { + attributeKind: tAttribute( + `${(variables as { attributeKey: AttributeKey }).attributeKey}_other` + ), + }), + loadingLabel: t('loading'), + }, + }) +} + export const EServiceMutations = { useCreateDraft, useUpdateDraft, @@ -326,4 +352,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..3b921fc87 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,22 @@ async function importVersion({ eserviceFile }: { eserviceFile: File }) { }) } +async function updateDescriptorAttributes({ + eserviceId, + descriptorId, + attributeKey: _attributeKey, + ...payload +}: { + eserviceId: string + descriptorId: string + attributeKey: AttributeKey +} & DescriptorAttributesSeed) { + return axiosInstance.post( + `${BACKEND_FOR_FRONTEND_URL}/eservices/${eserviceId}/descriptors/${descriptorId}/attributes/update`, + payload + ) +} + export const EServiceServices = { getCatalogList, getProviderList, @@ -420,4 +438,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..49bed1baf 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,26 @@ 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 ( - + = ({ descriptorAttributes, }) => { - const { t: tAttribute } = useTranslation('attribute') - const { mode } = useCurrentRoute() - - const providerOrConsumer = mode as ProviderOrConsumer - - const getSubtitle = (attributeKey: AttributeKey) => { - return ( - }} - > - {tAttribute(`${attributeKey}.description`)} - - ) - } - return ( <> ) } type AttributeGroupsListSectionProps = { - attributeGroups: Array> - title: string - subtitle: React.ReactNode - emptyLabel: string + descriptorAttributes: DescriptorAttributes + attributeKey: AttributeKey + topSideActions?: Array } -const AttributeGroupsListSection: React.FC = ({ - attributeGroups, - title, - subtitle, - emptyLabel, +export const AttributeGroupsListSection: React.FC = ({ + descriptorAttributes, + attributeKey, + topSideActions, }) => { + const { t: tAttribute } = useTranslation('attribute') + + const { mode } = useCurrentRoute() + + const providerOrConsumer = mode as ProviderOrConsumer + + const attributeGroups = descriptorAttributes[attributeKey] + return ( - + }} + > + {tAttribute(`${attributeKey}.description`)} + + } + topSideActions={topSideActions} + > {attributeGroups.length > 0 && ( {attributeGroups.map((attributeGroup, index) => ( @@ -88,7 +78,14 @@ const AttributeGroupsListSection: React.FC = ({ ))} )} - {attributeGroups.length === 0 && } + {attributeGroups.length === 0 && ( + + )} ) } diff --git a/src/pages/ProviderEServiceCreatePage/components/EServiceCreateStepAttributes/AddAttributesToEServiceForm/AttributeGroup.tsx b/src/pages/ProviderEServiceCreatePage/components/EServiceCreateStepAttributes/AddAttributesToEServiceForm/AttributeGroup.tsx index e4df7784e..2a7776ebf 100644 --- a/src/pages/ProviderEServiceCreatePage/components/EServiceCreateStepAttributes/AddAttributesToEServiceForm/AttributeGroup.tsx +++ b/src/pages/ProviderEServiceCreatePage/components/EServiceCreateStepAttributes/AddAttributesToEServiceForm/AttributeGroup.tsx @@ -5,8 +5,10 @@ import { Box, Stack } from '@mui/material' import { useTranslation } from 'react-i18next' import AddIcon from '@mui/icons-material/Add' import { ButtonNaked } from '@pagopa/mui-italia' -import { AttributeAutocomplete } from './AttributeAutocomplete' +import { AttributeAutocomplete } from '../../../../../components/shared/AttributeAutocomplete' import type { DescriptorAttribute } from '@/api/api.generatedTypes' +import { useFormContext } from 'react-hook-form' +import type { EServiceCreateStepAttributesFormValues } from '../EServiceCreateStepAttributes' export type AttributeGroupProps = { group: Array @@ -36,7 +38,13 @@ export const AttributeGroup: React.FC = ({ onRemoveAttributeFromGroup(attributeId, groupIndex) } - const handleHideAutocomplete = () => { + const { watch, setValue } = useFormContext() + const attributeGroups = watch(`attributes.${attributeKey}`) + + const handleAddAttributeToGroup = (attribute: DescriptorAttribute) => { + const newAttributeGroups = [...attributeGroups] + newAttributeGroups[groupIndex].push(attribute) + setValue(`attributes.${attributeKey}`, newAttributeGroups) setIsAttributeAutocompleteShown(false) } @@ -63,9 +71,12 @@ export const AttributeGroup: React.FC = ({ <> {isAttributeAutocompleteShown ? ( [...acc, ...group.map(({ id }) => id)], + [] as Array + )} /> ) : ( { const { t } = useTranslation('eservice', { keyPrefix: 'read.sections.attributes' }) + const { t: tCommon } = useTranslation('common') const { eserviceId, descriptorId } = useParams<'PROVIDE_ESERVICE_MANAGE'>() const { data: descriptorAttributes } = useSuspenseQuery({ @@ -15,10 +21,51 @@ export const ProviderEServiceDescriptorAttributes: React.FC = () => { select: (d) => d.attributes, }) + const [editAttributeDrawerState, setEditAttributeDrawerState] = useState<{ + kind: AttributeKey + isOpen: boolean + }>({ isOpen: false, kind: 'certified' }) + + const getAttributeSectionActions = (kind: AttributeKey): Array | undefined => { + if (descriptorAttributes[kind].length === 0) return + + return [ + { + action: () => setEditAttributeDrawerState({ kind, isOpen: true }), + label: tCommon('actions.edit'), + icon: EditIcon, + }, + ] + } + return ( - - - + <> + + + + + + + + setEditAttributeDrawerState({ ...editAttributeDrawerState, isOpen: false })} + attributeKey={editAttributeDrawerState.kind} + descriptorAttributes={descriptorAttributes} + /> + ) } diff --git a/src/pages/ProviderEServiceDetailsPage/components/ProviderEServiceDetailsTab/ProviderEServiceUpdateDescriptorAttributesDrawer.tsx b/src/pages/ProviderEServiceDetailsPage/components/ProviderEServiceDetailsTab/ProviderEServiceUpdateDescriptorAttributesDrawer.tsx new file mode 100644 index 000000000..6d02f10b6 --- /dev/null +++ b/src/pages/ProviderEServiceDetailsPage/components/ProviderEServiceDetailsTab/ProviderEServiceUpdateDescriptorAttributesDrawer.tsx @@ -0,0 +1,155 @@ +import { Drawer } from '@/components/shared/Drawer' +import React from 'react' +import type { AttributeKey } from '@/types/attribute.types' +import type { DescriptorAttribute, DescriptorAttributes } from '@/api/api.generatedTypes' +import { Box, Stack } from '@mui/material' +import { AttributeContainer, AttributeGroupContainer } from '@/components/layout/containers' +import { useTranslation } from 'react-i18next' +import { ButtonNaked } from '@pagopa/mui-italia' +import AddIcon from '@mui/icons-material/Add' +import { AttributeAutocomplete } from '@/components/shared/AttributeAutocomplete' +import cloneDeep from 'lodash/cloneDeep' +import { EServiceMutations } from '@/api/eservice' +import { remapDescriptorAttributesToDescriptorAttributesSeed } from '@/utils/attribute.utils' +import { useParams } from '@/router' + +type ProviderEServiceUpdateDescriptorAttributesDrawerProps = { + isOpen: boolean + onClose: () => void + attributeKey: AttributeKey + descriptorAttributes: DescriptorAttributes +} + +export const ProviderEServiceUpdateDescriptorAttributesDrawer: React.FC< + ProviderEServiceUpdateDescriptorAttributesDrawerProps +> = ({ isOpen, onClose, descriptorAttributes, attributeKey }) => { + const { t } = useTranslation('eservice', { + keyPrefix: 'read.drawers.updateDescriptorAttributesDrawer', + }) + const { t: tAttribute } = useTranslation('attribute') + const { t: tCommon } = useTranslation('common') + + const { eserviceId, descriptorId } = useParams<'PROVIDE_ESERVICE_MANAGE'>() + + const [selectedDescriptorAttributes, setSelectedDescriptorAttributes] = + React.useState(() => cloneDeep(descriptorAttributes)) + + const { mutate: updateAttributes } = EServiceMutations.useUpdateDescriptorAttributes() + + const attributeGroups = selectedDescriptorAttributes[attributeKey] + const [isAttributeAutocompleteShown, setIsAttributeAutocompleteShown] = React.useState(false) + + const alreadySelectedAttributeIds = React.useMemo( + () => + attributeGroups.reduce( + (acc, group) => [...acc, ...group.map(({ id }) => id)], + [] as Array + ), + [attributeGroups] + ) + + const handleAddAttributeToGroup = (groupdIdx: number, attribute: DescriptorAttribute) => { + setSelectedDescriptorAttributes((prev) => { + const newAttributeGroups = [...prev[attributeKey]] + newAttributeGroups[groupdIdx].push(attribute) + return { + ...prev, + [attributeKey]: newAttributeGroups, + } + }) + setIsAttributeAutocompleteShown(false) + } + + const handleRemoveAttributeFromGroup = (groupIdx: number, attributeId: string) => { + setSelectedDescriptorAttributes((prev) => { + const newAttributeGroups = [...prev[attributeKey]] + newAttributeGroups[groupIdx] = newAttributeGroups[groupIdx].filter( + ({ id }) => id !== attributeId + ) + return { + ...prev, + [attributeKey]: newAttributeGroups, + } + }) + } + + const canAttributeBeRemoved = (groupIdx: number, descriptorAttribute: DescriptorAttribute) => { + return !descriptorAttributes[attributeKey][groupIdx].some( + (att) => att.id === descriptorAttribute.id + ) + } + + const handleSubmit = () => { + updateAttributes( + { + eserviceId, + descriptorId, + attributeKey, + ...remapDescriptorAttributesToDescriptorAttributesSeed(selectedDescriptorAttributes), + }, + { onSuccess: onClose } + ) + } + + return ( + setSelectedDescriptorAttributes(cloneDeep(descriptorAttributes))} + title={t('title', { attributeKind: tAttribute(`type.${attributeKey}_other`) })} + subtitle={t('subtitle')} + buttonAction={{ + label: tCommon('actions.saveEdits'), + action: handleSubmit, + }} + > + + {attributeGroups.map((group, groupIdx) => ( + + + {group.map((attribute) => ( + + handleRemoveAttributeFromGroup(groupIdx, attribute) + : undefined + } + /> + + ))} + + {isAttributeAutocompleteShown ? ( + handleAddAttributeToGroup(groupIdx, attribute)} + direction="column" + /> + ) : ( + } + onClick={() => setIsAttributeAutocompleteShown(true)} + > + {tAttribute('group.addBtn')} + + )} + + ))} + + + ) +} diff --git a/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceAttributeVersionSummary.tsx b/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceAttributeVersionSummary.tsx index 044fd7a3b..4f6bda7a0 100644 --- a/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceAttributeVersionSummary.tsx +++ b/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceAttributeVersionSummary.tsx @@ -2,12 +2,12 @@ import React from 'react' import { ReadOnlyDescriptorAttributes } from '@/components/shared/ReadOnlyDescriptorAttributes' import { EServiceQueries } from '@/api/eservice' import { useParams } from '@/router' -import { useQuery } from '@tanstack/react-query' +import { useSuspenseQuery } from '@tanstack/react-query' export const ProviderEServiceAttributeVersionSummary: React.FC = () => { const params = useParams<'PROVIDE_ESERVICE_SUMMARY'>() - const { data: descriptor } = useQuery( + const { data: descriptor } = useSuspenseQuery( EServiceQueries.getDescriptorProvider(params.eserviceId, params.descriptorId) ) diff --git a/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceDocumentationSummary.tsx b/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceDocumentationSummary.tsx index 9fd825b05..87e8f2c12 100644 --- a/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceDocumentationSummary.tsx +++ b/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceDocumentationSummary.tsx @@ -7,13 +7,13 @@ import AttachFileIcon from '@mui/icons-material/AttachFile' import { EServiceDownloads, EServiceQueries } from '@/api/eservice' import { getDownloadDocumentName } from '@/utils/eservice.utils' import { useParams } from '@/router' -import { useQuery } from '@tanstack/react-query' +import { useSuspenseQuery } from '@tanstack/react-query' export const ProviderEServiceDocumentationSummary: React.FC = () => { const { t } = useTranslation('eservice', { keyPrefix: 'summary.documentationSummary' }) const params = useParams<'PROVIDE_ESERVICE_SUMMARY'>() - const { data: descriptor } = useQuery( + const { data: descriptor } = useSuspenseQuery( EServiceQueries.getDescriptorProvider(params.eserviceId, params.descriptorId) ) diff --git a/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceGeneralInfoSummary.tsx b/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceGeneralInfoSummary.tsx index 7d8801225..5004cdb3f 100644 --- a/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceGeneralInfoSummary.tsx +++ b/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceGeneralInfoSummary.tsx @@ -4,9 +4,9 @@ import { InformationContainer } from '@pagopa/interop-fe-commons' import { useTranslation } from 'react-i18next' import { EServiceQueries } from '@/api/eservice' import { useParams } from '@/router' -import { useQuery } from '@tanstack/react-query' +import { useSuspenseQuery } from '@tanstack/react-query' import { STAGE } from '@/config/env' -import { PagoPAEnvVars } from '@/types/common.types' +import type { PagoPAEnvVars } from '@/types/common.types' export const ProviderEServiceGeneralInfoSummary: React.FC = () => { const signalHubFlagDisabledStage: PagoPAEnvVars['STAGE'][] = ['PROD', 'UAT'] @@ -14,12 +14,10 @@ export const ProviderEServiceGeneralInfoSummary: React.FC = () => { const { t } = useTranslation('eservice', { keyPrefix: 'summary.generalInfoSummary' }) const params = useParams<'PROVIDE_ESERVICE_SUMMARY'>() - const { data: descriptor } = useQuery( + const { data: descriptor } = useSuspenseQuery( EServiceQueries.getDescriptorProvider(params.eserviceId, params.descriptorId) ) - if (!descriptor) return null - return ( () - const { data: descriptor } = useQuery( + const { data: descriptor } = useSuspenseQuery( EServiceQueries.getDescriptorProvider(params.eserviceId, params.descriptorId) ) @@ -70,7 +70,7 @@ export const ProviderEServiceRiskAnalysisSummary: React.FC< return answers }, [riskAnalysisTemplate, riskAnalysisConfig, currentLanguage]) - if (!descriptor || !riskAnalysisTemplate) return null + if (!riskAnalysisTemplate) return null return ( <> diff --git a/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceRiskAnalysisSummaryList.tsx b/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceRiskAnalysisSummaryList.tsx index a2ff932ce..897dc0c1c 100644 --- a/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceRiskAnalysisSummaryList.tsx +++ b/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceRiskAnalysisSummaryList.tsx @@ -4,18 +4,16 @@ import { Divider, Stack, Typography } from '@mui/material' import React from 'react' import { ProviderEServiceRiskAnalysisSummary } from './ProviderEServiceRiskAnalysisSummary' import { useTranslation } from 'react-i18next' -import { useQuery } from '@tanstack/react-query' +import { useSuspenseQuery } from '@tanstack/react-query' export const ProviderEServiceRiskAnalysisSummaryList: React.FC = () => { const { t } = useTranslation('eservice', { keyPrefix: 'summary.riskAnalysisSummaryList' }) const params = useParams<'PROVIDE_ESERVICE_SUMMARY'>() - const { data: descriptor } = useQuery( + const { data: descriptor } = useSuspenseQuery( EServiceQueries.getDescriptorProvider(params.eserviceId, params.descriptorId) ) - if (!descriptor) return null - const riskAnalysisList = descriptor.eservice.riskAnalysis return ( diff --git a/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceVersionInfoSummary.tsx b/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceVersionInfoSummary.tsx index 4d712a7ae..44dda87af 100644 --- a/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceVersionInfoSummary.tsx +++ b/src/pages/ProviderEServiceSummaryPage/components/ProviderEServiceVersionInfoSummary.tsx @@ -5,19 +5,17 @@ import { useTranslation } from 'react-i18next' import { formatThousands, secondsToMinutes } from '@/utils/format.utils' import { EServiceQueries } from '@/api/eservice' import { useParams } from '@/router' -import { useQuery } from '@tanstack/react-query' +import { useSuspenseQuery } from '@tanstack/react-query' export const ProviderEServiceVersionInfoSummary: React.FC = () => { const { t } = useTranslation('eservice', { keyPrefix: 'summary.versionInfoSummary' }) const { t: tCommon } = useTranslation('common') const params = useParams<'PROVIDE_ESERVICE_SUMMARY'>() - const { data: descriptor } = useQuery( + const { data: descriptor } = useSuspenseQuery( EServiceQueries.getDescriptorProvider(params.eserviceId, params.descriptorId) ) - if (!descriptor) return null - const voucherLifespan = secondsToMinutes(descriptor.voucherLifespan) const hasManualApproval = descriptor.agreementApprovalPolicy === 'MANUAL' diff --git a/src/static/locales/en/common.json b/src/static/locales/en/common.json index 38ec4438f..78ff979b9 100644 --- a/src/static/locales/en/common.json +++ b/src/static/locales/en/common.json @@ -38,7 +38,8 @@ "insert": "Insert", "revoke": "Revoke", "upload": "Upload", - "import": "Import" + "import": "Import", + "saveEdits": "Save edits" }, "table": { "headData": { diff --git a/src/static/locales/en/eservice.json b/src/static/locales/en/eservice.json index df05622b7..8a9126d5f 100644 --- a/src/static/locales/en/eservice.json +++ b/src/static/locales/en/eservice.json @@ -431,6 +431,10 @@ "noOptionsText": "No keychain found" }, "noKeychainAlert": "There are no keychain available. <1>Create your first keychain." + }, + "updateDescriptorAttributesDrawer": { + "title": "Edit {{attributeKind}} attributes", + "subtitle": "The requirements already entered cannot be modified" } } }, diff --git a/src/static/locales/en/mutations-feedback.json b/src/static/locales/en/mutations-feedback.json index ed7f40bde..f521ce53a 100644 --- a/src/static/locales/en/mutations-feedback.json +++ b/src/static/locales/en/mutations-feedback.json @@ -184,6 +184,13 @@ "success": "The list has been downloaded successfully", "error": "The list could not be downloaded. Please try again" } + }, + "updateDescriptorAttributes": { + "loading": "Saving new attributes", + "outcome": { + "success": "The {{attributeKind}} attributes have been modified correctly", + "error": "It was not possible to modify the {{attributeKind}} attributes. Please, try again!" + } } }, "attribute": { diff --git a/src/static/locales/it/common.json b/src/static/locales/it/common.json index aacef2329..e739ee2a8 100644 --- a/src/static/locales/it/common.json +++ b/src/static/locales/it/common.json @@ -38,7 +38,8 @@ "insert": "Inserisci", "revoke": "Revoca", "upload": "Carica", - "import": "Importa" + "import": "Importa", + "saveEdits": "Salva modifiche" }, "table": { "headData": { diff --git a/src/static/locales/it/eservice.json b/src/static/locales/it/eservice.json index cacc2c5c6..ebaa49ab0 100644 --- a/src/static/locales/it/eservice.json +++ b/src/static/locales/it/eservice.json @@ -431,6 +431,10 @@ "noOptionsText": "Nessun portachiavi trovato" }, "noKeychainAlert": "Non ci sono portachiavi disponibili. <1>Crea il tuo primo portachiavi." + }, + "updateDescriptorAttributesDrawer": { + "title": "Modifica attributi {{attributeKind}}", + "subtitle": "I requisiti già inseriti non possono essere modificati" } } }, diff --git a/src/static/locales/it/mutations-feedback.json b/src/static/locales/it/mutations-feedback.json index e4f1740eb..73327944b 100644 --- a/src/static/locales/it/mutations-feedback.json +++ b/src/static/locales/it/mutations-feedback.json @@ -184,6 +184,13 @@ "success": "L’elenco è stato scaricato correttamente", "error": "Non è stato possibile scaricare l’elenco. Per favore, riprova!" } + }, + "updateDescriptorAttributes": { + "loading": "Stiamo aggiornando gli attributi", + "outcome": { + "success": "Gli attributi {{attributeKind}} sono stati modificati correttamente!", + "error": "Non è stato possibile modificare gli attributi {{attributeKind}}. Per favore, riprova!" + } } }, "attribute": {