@pagopa/selfcare-common-frontend 1.5.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +36 -11
- package/build.info +2 -2
- package/decorators/withRetrievedValue.d.ts +13 -3
- package/decorators/withRetrievedValue.js +12 -2
- package/decorators/withRetrievedValue.js.map +1 -1
- package/hooks/useReduxCachedValue.d.ts +1 -1
- package/hooks/useReduxCachedValue.js +11 -1
- package/hooks/useReduxCachedValue.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,8 +4,14 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
#### [v1.5.1](https://github.com/pagopa/selfcare-common-frontend/compare/v1.5.0...v1.5.1)
|
|
8
|
+
|
|
9
|
+
- withRetrievedValue will accept a component to show while loading [`#25`](https://github.com/pagopa/selfcare-common-frontend/pull/25)
|
|
10
|
+
|
|
7
11
|
#### [v1.5.0](https://github.com/pagopa/selfcare-common-frontend/compare/v1.4.1...v1.5.0)
|
|
8
12
|
|
|
13
|
+
> 11 February 2022
|
|
14
|
+
|
|
9
15
|
- Toast autoclosable in UserNotifyHandle and ErrorBoundaryfeatures [`#24`](https://github.com/pagopa/selfcare-common-frontend/pull/24)
|
|
10
16
|
- Customhook cached redux [`#23`](https://github.com/pagopa/selfcare-common-frontend/pull/23)
|
|
11
17
|
- fixed readme [`#22`](https://github.com/pagopa/selfcare-common-frontend/pull/22)
|
package/README.md
CHANGED
|
@@ -57,16 +57,16 @@ Modal used to show a list of values from which to choose a single value
|
|
|
57
57
|
| Prop | Type | Mandatory | Description |
|
|
58
58
|
|------|------|-----------|-------------|
|
|
59
59
|
| open | boolean | Y | If the popup is to be displayed |
|
|
60
|
-
| handleClose | React.MouseEventHandler
|
|
60
|
+
| handleClose | React.MouseEventHandler`<HTMLButtonElement>` | Y | The function to be invoked when clicking on exit button or selecting a value |
|
|
61
61
|
| title | string | Y | The popup title |
|
|
62
|
-
| filterModalConfig | FilterModalConfig
|
|
62
|
+
| filterModalConfig | FilterModalConfig`<any, any>` | N | See below |
|
|
63
63
|
| height | string | N | The popup height |
|
|
64
64
|
| minHeight | string | N | The popup minHeight |
|
|
65
65
|
|
|
66
66
|
FilterModalConfig fields:
|
|
67
67
|
| Field | Type | Mandatory | Description |
|
|
68
68
|
|-------|------|-----------|-------------|
|
|
69
|
-
| data | Array
|
|
69
|
+
| data | Array`<T>` | Y | The list of values between to which choose |
|
|
70
70
|
| getLabel | (e: T) => string | Y | A function that will select the label to show |
|
|
71
71
|
| getValue | (e: T) => string | Y | A function that will select the value to return when selecting an item |
|
|
72
72
|
| onFilterChange | (v: V) => void | Y | The function invoked when selecting a value |
|
|
@@ -79,10 +79,10 @@ Selfcare's popup
|
|
|
79
79
|
| open | boolean | Y | If this component should be displayed or not |
|
|
80
80
|
| title | string | Y | The title to show in the popup |
|
|
81
81
|
| message | React.ReactNode | Y | The body to show in the popup |
|
|
82
|
-
| onConfirm | React.MouseEventHandler
|
|
82
|
+
| onConfirm | React.MouseEventHandler`<HTMLButtonElement>` | N | If defined, it will render a confirm button using this function as behavior |
|
|
83
83
|
| onConfirmLabel | string | N | The confirm label text |
|
|
84
|
-
| handleClose | React.MouseEventHandler
|
|
85
|
-
| handleExit | React.MouseEventHandler
|
|
84
|
+
| handleClose | React.MouseEventHandler`<HTMLButtonElement>` | Y | The function invoked when clicking on close button or in the showed X icon |
|
|
85
|
+
| handleExit | React.MouseEventHandler`<HTMLButtonElement>` | N | If defined, it allow to set a different behavior when clicking on X icon |
|
|
86
86
|
| onCloseLabel | string | N | Close button text |
|
|
87
87
|
| height | string | N | The popup height |
|
|
88
88
|
| minHeight | string | N | The popup minHeight |
|
|
@@ -132,7 +132,7 @@ To show an error popup to inform of the not valid session
|
|
|
132
132
|
### buildFetchApi = (timeoutMs: number = 300000) => fetch
|
|
133
133
|
Return the implementation of fetch configured with a timeout
|
|
134
134
|
|
|
135
|
-
### extractResponse
|
|
135
|
+
### extractResponse `<R>`(response: t.Validation`<TypeofApiResponse<any>>`, successHttpStatus: number, onRedirectToLogin: () => void, notValidTokenHttpStatus: number | null = 401, notAuthorizedTokenHttpStatus: number | null = 403, emptyResponseHttpStatus: number | null = 404): Promise`<R>`
|
|
136
136
|
Extract the response of a @pagopa/openapi-codegen-ts generated client rest invocation having status code successHttpStatus.
|
|
137
137
|
If notValidTokenHttpStatus is not null and the returned status is equal to notValidTokenHttpStatus, it will call the onRedirectToLogin function and will schedule the redirect towards logout path.
|
|
138
138
|
If notAuthorizedTokenHttpStatus is not null and the returned status is equal to notAuthorizedTokenHttpStatus, it will throw an Error with message "Operation not allowed".
|
|
@@ -179,8 +179,23 @@ It's possible to modify the login path changing the value in [CONFIG.URL_FE.LOGI
|
|
|
179
179
|
|
|
180
180
|
## withRetrievedValue
|
|
181
181
|
Decorator to retrieve a value and serve it once ready to the decorated component.
|
|
182
|
-
|
|
183
|
-
See withRetrievedValue.test.tsx file for an
|
|
182
|
+
Using it together with [useReduxCachedValue](#usereduxcachedvalue) will allow to build a component which will use centralized and cached data
|
|
183
|
+
See withRetrievedValue.test.tsx file for an example.
|
|
184
|
+
|
|
185
|
+
Given the following type parameters:
|
|
186
|
+
* ENTITY_TYPE extends Record`<string, any>`,
|
|
187
|
+
* PROP_NAME extends string,
|
|
188
|
+
* PROPS extends Record`<PROP_NAME, ENTITY_TYPE>`
|
|
189
|
+
|
|
190
|
+
The arguments to provide to the decorator are the following:
|
|
191
|
+
|
|
192
|
+
| Prop | Type | Mandatory | Description |
|
|
193
|
+
|------|------|-----------|-------------|
|
|
194
|
+
| propEntityName | PROP_NAME | Y | The name of the prop to which serve the value when available |
|
|
195
|
+
| getRetrieverService | () => () => Promise`<ENTITY_TYPE>` | Y | A function that will return an other function to retrieve the expected value. This for allow the use of custom hook |
|
|
196
|
+
| WrappedComponent | React.ComponentType`<PROPS>` | Y | The component to decore |
|
|
197
|
+
| onError | (appError: AppError) => void | N | What to do in case of error. As default, it will use the feature ErrorBoundary |
|
|
198
|
+
| onLoading | ReactNode | N | A component to show while waiting for the value |
|
|
184
199
|
|
|
185
200
|
# Custom Hooks
|
|
186
201
|
## useFakePagination
|
|
@@ -190,7 +205,17 @@ The sorting actually is applied using string representation
|
|
|
190
205
|
|
|
191
206
|
## useReduxCachedValue
|
|
192
207
|
It will return a method that only at the very first invocation it will call the retrieverService only the first time, storing the obtained values, and returning always cached values.
|
|
193
|
-
See useReduxCachedValue.test.tsx file for an example
|
|
208
|
+
See useReduxCachedValue.test.tsx file for an example.
|
|
209
|
+
|
|
210
|
+
The arguments to provide to the custom hook are the following:
|
|
211
|
+
|
|
212
|
+
| Prop | Type | Mandatory | Description |
|
|
213
|
+
|------|------|-----------|-------------|
|
|
214
|
+
| entity | string | Y | The name of the entity, used just for logging purpose |
|
|
215
|
+
| retrieverService | () => Promise`<T>` | Y | The service that will retrieve the value |
|
|
216
|
+
| reduxSelector | (state: any) => T | undefined | Y | The selector to verify if a value already exists |
|
|
217
|
+
| reduxSetterAction | PayloadActionCreator`<T>` | Y | The action to store the value |
|
|
218
|
+
| alwaysRetrieve | boolean | N | If true, it will always retrieve and store the new value |
|
|
194
219
|
|
|
195
220
|
# Features
|
|
196
221
|
## LoadingOverlay
|
|
@@ -285,7 +310,7 @@ This feature can be configured with the following keys of the [CONFIG](#Configur
|
|
|
285
310
|
| PERSISTENCE | string | Where to store session data, possible values are cookie or localStorage | localStorage |
|
|
286
311
|
| LOG_IP | boolean | If the ip should be sent | false |
|
|
287
312
|
| LOG_IP | boolean | If the ip should be sent | false |
|
|
288
|
-
| PROPERTY_BLACKLIST | Array
|
|
313
|
+
| PROPERTY_BLACKLIST | Array`<string>` | If the ip should be sent | ["$current_url", "$initial_referrer", "$referrer"] |
|
|
289
314
|
| ADDITIONAL_PROPERTIES | {[key: string]: string} | An object containing a fixed set of properties to send every time, overridden if the actual event will report the same properties | {} |
|
|
290
315
|
| ADDITIONAL_PROPERTIES_IMPORTANT | {[key: string]: string} | As ADDITIONAL_PROPERTIES, but these properties will take the precedence overriding events conflicting properties | {} |
|
|
291
316
|
|
package/build.info
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
20220214.1 - selfcare-common-frontend.deploy(20316)
|
|
2
|
+
remotes/origin/dependabot/npm_and_yarn/follow-redirects-1.14.8 7ef79dc222e49dd330354ff6868d6735ab4861bf
|
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
import { AppError } from '../
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { AppError } from '../model/AppError';
|
|
3
3
|
/** Decorator to retrieve a value and serve it once ready to the decorated component */
|
|
4
|
-
export default function withRetrievedValue<ENTITY_TYPE extends Record<string, any>, PROP_NAME extends string, PROPS extends Record<PROP_NAME, ENTITY_TYPE>>(
|
|
4
|
+
export default function withRetrievedValue<ENTITY_TYPE extends Record<string, any>, PROP_NAME extends string, PROPS extends Record<PROP_NAME, ENTITY_TYPE>>(
|
|
5
|
+
/** The name of the prop to which serve the value when available */
|
|
6
|
+
propEntityName: PROP_NAME,
|
|
7
|
+
/** A function that will return an other function to retrieve the expected value. This for allow the use of custom hook */
|
|
8
|
+
getRetrieverService: () => () => Promise<ENTITY_TYPE>,
|
|
9
|
+
/** The component to decore */
|
|
10
|
+
WrappedComponent: React.ComponentType<PROPS>,
|
|
11
|
+
/** What to do in case of error. As default, it will use the feature ErrorBoundary */
|
|
12
|
+
onError?: (appError: AppError) => void,
|
|
13
|
+
/** A component to show while waiting for the value */
|
|
14
|
+
onLoading?: ReactNode): import("react").ComponentType<Omit<PROPS, PROP_NAME>>;
|
|
@@ -5,7 +5,17 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const useErrorDispatcher_1 = (0, tslib_1.__importDefault)(require("../hooks/useErrorDispatcher"));
|
|
7
7
|
/** Decorator to retrieve a value and serve it once ready to the decorated component */
|
|
8
|
-
function withRetrievedValue(
|
|
8
|
+
function withRetrievedValue(
|
|
9
|
+
/** The name of the prop to which serve the value when available */
|
|
10
|
+
propEntityName,
|
|
11
|
+
/** A function that will return an other function to retrieve the expected value. This for allow the use of custom hook */
|
|
12
|
+
getRetrieverService,
|
|
13
|
+
/** The component to decore */
|
|
14
|
+
WrappedComponent,
|
|
15
|
+
/** What to do in case of error. As default, it will use the feature ErrorBoundary */
|
|
16
|
+
onError,
|
|
17
|
+
/** A component to show while waiting for the value */
|
|
18
|
+
onLoading) {
|
|
9
19
|
const displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component';
|
|
10
20
|
const ComponentWithParties = (props) => {
|
|
11
21
|
const [value, setValue] = (0, react_1.useState)();
|
|
@@ -28,7 +38,7 @@ function withRetrievedValue(propEntityName, getRetrieverService, WrappedComponen
|
|
|
28
38
|
doRetrieve();
|
|
29
39
|
}
|
|
30
40
|
}, []);
|
|
31
|
-
return
|
|
41
|
+
return value !== undefined ? ((0, jsx_runtime_1.jsx)(WrappedComponent, Object.assign({}, props, { [propEntityName]: value }), void 0)) : (onLoading !== null && onLoading !== void 0 ? onLoading : (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}, void 0));
|
|
32
42
|
};
|
|
33
43
|
// eslint-disable-next-line functional/immutable-data
|
|
34
44
|
ComponentWithParties.displayName = `withRetrieve${propEntityName}(${displayName})`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"withRetrievedValue.js","sourceRoot":"","sources":["../../src/lib/decorators/withRetrievedValue.tsx"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"withRetrievedValue.js","sourceRoot":"","sources":["../../src/lib/decorators/withRetrievedValue.tsx"],"names":[],"mappings":";;;;AAAA,iCAAuD;AACvD,kGAA6D;AAG7D,uFAAuF;AACvF,SAAwB,kBAAkB;AAKxC,mEAAmE;AACnE,cAAyB;AACzB,2HAA2H;AAC3H,mBAAqD;AACrD,8BAA8B;AAC9B,gBAA4C;AAC5C,qFAAqF;AACrF,OAAsC;AACtC,sDAAsD;AACtD,SAAqB;IAErB,MAAM,WAAW,GAAG,gBAAgB,CAAC,WAAW,IAAI,gBAAgB,CAAC,IAAI,IAAI,WAAW,CAAC;IAEzF,MAAM,oBAAoB,GAAG,CAAC,KAAY,EAAE,EAAE;QAC5C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,GAAe,CAAC;QAClD,MAAM,cAAc,GAAG,mBAAmB,EAAE,CAAC;QAE7C,MAAM,QAAQ,GAAG,IAAA,4BAAkB,GAAE,CAAC;QAEtC,MAAM,UAAU,GAAG,GAAS,EAAE;YAC5B,cAAc,EAAE;iBACb,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;iBACxB,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAChB,CAAC,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,QAAQ,CAAC,CAAC;gBACpB,EAAE,EAAE,kBAAkB,cAAc,EAAE;gBACtC,QAAQ,EAAE,KAAK;gBACf,eAAe,EAAE,yCAAyC,cAAc,EAAE;gBAC1E,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,MAAM;gBACb,OAAO,EAAE,UAAU;aACpB,CAAC,CACH,CAAC;QACN,CAAC,CAAC;QAEF,IAAA,iBAAS,EAAC,GAAG,EAAE;YACb,IAAI,CAAC,KAAK,EAAE;gBACV,UAAU,EAAE,CAAC;aACd;QACH,CAAC,EAAE,EAAE,CAAC,CAAC;QAEP,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAC3B,uBAAC,gBAAgB,oBAAM,KAAe,EAAM,EAAE,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,UAAI,CAC5E,CAAC,CAAC,CAAC,CACF,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,0DAAK,CACnB,CAAC;IACJ,CAAC,CAAC;IAEF,qDAAqD;IACrD,oBAAoB,CAAC,WAAW,GAAG,eAAe,cAAc,IAAI,WAAW,GAAG,CAAC;IAEnF,OAAO,oBAAmE,CAAC;AAC7E,CAAC;AAxDD,qCAwDC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { PayloadActionCreator } from '@reduxjs/toolkit';
|
|
2
2
|
/** It will return a method that only at the very first invocation it will call the retrieverService only the first time, storing the obtained values, and returning always cached values */
|
|
3
|
-
declare const useReduxCachedValue: <T extends any[] | Record<string, any>>(entity: string, retrieverService: () => Promise<T>, reduxSelector: (state: any) => T, reduxSetterAction: import("@reduxjs/toolkit/dist/tsHelpers").IsAny<T, import("@reduxjs/toolkit").ActionCreatorWithPayload<any, string>, import("@reduxjs/toolkit/dist/tsHelpers").IsUnknown<T, import("@reduxjs/toolkit").ActionCreatorWithNonInferrablePayload<string>, import("@reduxjs/toolkit/dist/tsHelpers").IfVoid<T, import("@reduxjs/toolkit").ActionCreatorWithoutPayload<string>, import("@reduxjs/toolkit/dist/tsHelpers").IfMaybeUndefined<T, import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<T, string>, import("@reduxjs/toolkit").ActionCreatorWithPayload<T, string>>>>>, alwaysRetrieve?: boolean | undefined) => () => Promise<T>;
|
|
3
|
+
declare const useReduxCachedValue: <T extends any[] | Record<string, any>>(entity: string, retrieverService: () => Promise<T>, reduxSelector: (state: any) => T | undefined, reduxSetterAction: import("@reduxjs/toolkit/dist/tsHelpers").IsAny<T, import("@reduxjs/toolkit").ActionCreatorWithPayload<any, string>, import("@reduxjs/toolkit/dist/tsHelpers").IsUnknown<T, import("@reduxjs/toolkit").ActionCreatorWithNonInferrablePayload<string>, import("@reduxjs/toolkit/dist/tsHelpers").IfVoid<T, import("@reduxjs/toolkit").ActionCreatorWithoutPayload<string>, import("@reduxjs/toolkit/dist/tsHelpers").IfMaybeUndefined<T, import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<T, string>, import("@reduxjs/toolkit").ActionCreatorWithPayload<T, string>>>>>, alwaysRetrieve?: boolean | undefined) => () => Promise<T>;
|
|
4
4
|
export default useReduxCachedValue;
|
|
@@ -5,7 +5,17 @@ const react_redux_1 = require("react-redux");
|
|
|
5
5
|
const constants_1 = require("../utils/constants");
|
|
6
6
|
const useLoading_1 = (0, tslib_1.__importDefault)(require("./useLoading"));
|
|
7
7
|
/** It will return a method that only at the very first invocation it will call the retrieverService only the first time, storing the obtained values, and returning always cached values */
|
|
8
|
-
const useReduxCachedValue = (
|
|
8
|
+
const useReduxCachedValue = (
|
|
9
|
+
/** The name of the entity, used just for logging purpose */
|
|
10
|
+
entity,
|
|
11
|
+
/** The service that will retrieve the value */
|
|
12
|
+
retrieverService,
|
|
13
|
+
/** The selector to verify if a value already exists */
|
|
14
|
+
reduxSelector,
|
|
15
|
+
/** The action to store the value */
|
|
16
|
+
reduxSetterAction,
|
|
17
|
+
/** If true, it will always retrieve and store the new value */
|
|
18
|
+
alwaysRetrieve) => {
|
|
9
19
|
const dispatch = (0, react_redux_1.useDispatch)();
|
|
10
20
|
const entities = (0, react_redux_1.useSelector)(reduxSelector);
|
|
11
21
|
const setEntities = (value) => dispatch(reduxSetterAction(value));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useReduxCachedValue.js","sourceRoot":"","sources":["../../src/lib/hooks/useReduxCachedValue.tsx"],"names":[],"mappings":";;;AACA,6CAAuD;AACvD,kDAAyE;AACzE,2EAAsC;AAEtC,4LAA4L;AAC5L,MAAM,mBAAmB,GAAG,
|
|
1
|
+
{"version":3,"file":"useReduxCachedValue.js","sourceRoot":"","sources":["../../src/lib/hooks/useReduxCachedValue.tsx"],"names":[],"mappings":";;;AACA,6CAAuD;AACvD,kDAAyE;AACzE,2EAAsC;AAEtC,4LAA4L;AAC5L,MAAM,mBAAmB,GAAG;AAC1B,4DAA4D;AAC5D,MAAc;AACd,+CAA+C;AAC/C,gBAAkC;AAClC,uDAAuD;AACvD,aAA4C;AAC5C,oCAAoC;AACpC,iBAA0C;AAC1C,+DAA+D;AAC/D,cAAwB,EACJ,EAAE;IACtB,MAAM,QAAQ,GAAG,IAAA,yBAAW,GAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,IAAA,yBAAW,EAAC,aAAa,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,CAAC,KAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;IAErE,MAAM,UAAU,GAAG,IAAA,oBAAU,EAAC,GAAG,+CAAmC,IAAI,MAAM,EAAE,CAAC,CAAC;IAElF,OAAO,GAAe,EAAE;QACtB,IAAI,cAAc,IAAI,CAAC,QAAQ,EAAE;YAC/B,UAAU,CAAC,IAAI,CAAC,CAAC;YACjB,OAAO,gBAAgB,EAAE;iBACtB,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;gBACV,WAAW,CAAC,CAAC,CAAC,CAAC;gBACf,OAAO,CAAC,CAAC;YACX,CAAC,CAAC;iBACD,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;SACrC;aAAM;YACL,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;SACpD;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,mBAAmB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pagopa/selfcare-common-frontend",
|
|
3
3
|
"description": "Shared React components for the pagopa selfcare project",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "https://github.com/pagopa/selfcare-common-frontend",
|
|
7
7
|
"author": "https://www.pagopa.gov.it",
|