Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release UAT #824

Merged
merged 10 commits into from
Oct 31, 2024
Merged
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"@mui/x-data-grid": "^5.0.1",
"@mui/x-data-grid-generator": "^5.0.1",
"@pagopa/mui-italia": "^1.5.0",
"@pagopa/selfcare-common-frontend": "^1.34.43",
"@pagopa/selfcare-common-frontend": "^1.34.44",
"@types/react": "^18.2.22",
"@types/react-dom": "^18.2.7",
"@types/react-router-dom": "^5.3.3",
Expand Down
6 changes: 3 additions & 3 deletions src/components/DashboardHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const DashboardHeader = ({ onExit, loggedUser, parties }: Props) => {

const hasMoreThanOneInteropEnv = authorizedInteropProducts.length > 1;

const onboardedPartyProducts = party?.products.filter(
const authorizedPartyProducts = party?.products.filter(
(pp) =>
pp.productOnBoardingStatus === 'ACTIVE' &&
(hasPermission(pp.productId ?? '', Actions.AccessProductBackoffice) ||
Expand All @@ -72,8 +72,8 @@ const DashboardHeader = ({ onExit, loggedUser, parties }: Props) => {

const activeProducts: Array<Product> = useMemo(
() =>
products?.filter((p) => onboardedPartyProducts?.some((op) => op.productId === p.id)) ?? [],
[onboardedPartyProducts]
products?.filter((p) => authorizedPartyProducts?.some((op) => op.productId === p.id)) ?? [],
[authorizedPartyProducts]
);

// eslint-disable-next-line functional/immutable-data
Expand Down
25 changes: 17 additions & 8 deletions src/hooks/useProductsRolesMap.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { usePermissions } from '@pagopa/selfcare-common-frontend/lib';
import useReduxCachedValue from '@pagopa/selfcare-common-frontend/lib/hooks/useReduxCachedValue';
import { Actions } from '@pagopa/selfcare-common-frontend/lib/utils/constants';
import { useMemo } from 'react';
import { Party } from '../model/Party';
import {
Expand All @@ -15,26 +17,33 @@ export const useProductsRolesMap = (): (() => Promise<ProductsRolesMap>) => {
const party = useAppSelector(partiesSelectors.selectPartySelected);
const products = useAppSelector(partiesSelectors.selectPartySelectedProducts);
const productsRolesMap = useAppSelector(partiesSelectors.selectPartySelectedProductsRolesMap);
const { hasPermission } = usePermissions();

const activeProducts = useMemo(
const activeAndAccessibleProducts = useMemo(
() =>
products?.filter((p) =>
party?.products.some(
(us) => us.productId === p.id && us.productOnBoardingStatus === 'ACTIVE'
(us) =>
us.productId === p.id &&
us.productOnBoardingStatus === 'ACTIVE' &&
hasPermission(us.productId ?? '', Actions.AccessProductBackoffice)
)
),
[products, party?.products]
);

const fetchProductRolesNotYetCached = async (): Promise<ProductsRolesMap> => {
if (!activeProducts) {
return new Promise((resolve) => resolve(productsRolesMap));
if (!activeAndAccessibleProducts) {
return Promise.resolve(productsRolesMap);
}

const promises: Array<Promise<[string, ProductRolesLists]>> = activeProducts
const promises: Array<Promise<[string, ProductRolesLists]>> = activeAndAccessibleProducts
.filter((p) => !productsRolesMap[p.id])
.map((p) =>
fetchProductRoles(p, party as Party).then((roles) => [p.id, productRoles2ProductRolesList(roles)])
fetchProductRoles(p, party as Party).then((roles) => [
p.id,
productRoles2ProductRolesList(roles),
])
);
const fetched: Array<[string, ProductRolesLists]> = await Promise.all(promises);

Expand All @@ -45,9 +54,9 @@ export const useProductsRolesMap = (): (() => Promise<ProductsRolesMap>) => {
'PRODUCTS_ROLES',
fetchProductRolesNotYetCached,
(state: RootState) =>
!activeProducts ||
!activeAndAccessibleProducts ||
(state.parties.selectedProductsRolesMap &&
!activeProducts.find(
!activeAndAccessibleProducts.find(
(p) => !(state.parties.selectedProductsRolesMap as ProductsRolesMap)[p.id]
))
? state.parties.selectedProductsRolesMap
Expand Down
4 changes: 2 additions & 2 deletions src/model/Party.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { InstitutionResource } from '../api/generated/b4f-dashboard/InstitutionR
import { ProductOnBoardingStatusEnum } from '../api/generated/b4f-dashboard/OnboardedProductResource';
import { ENV } from '../utils/env';

export type UserRole = 'ADMIN' | 'LIMITED';
export type PartyRole = 'DELEGATE' | 'MANAGER' | 'OPERATOR' | 'SUB_DELEGATE';
export type UserRole = 'ADMIN' | 'LIMITED' | 'ADMIN_EA';
export type PartyRole = 'DELEGATE' | 'MANAGER' | 'OPERATOR' | 'SUB_DELEGATE' | 'ADMIN_EA';
export type UserStatus = 'PENDING' | 'ACTIVE' | 'SUSPENDED' | 'TOBEVALIDATED';

type OnboardedProduct = {
Expand Down
7 changes: 4 additions & 3 deletions src/model/ProductRole.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { UserRole, PartyRole } from './Party';
import { PartyRole, UserRole } from "./Party";


export type ProductRole = {
productId: string;
Expand All @@ -20,9 +21,9 @@ export type ProductRolesLists = {

export const buildEmptyProductRolesLists = (): ProductRolesLists => ({
list: [],
groupBySelcRole: { ADMIN: [], LIMITED: [] },
groupBySelcRole: { ADMIN: [], LIMITED: [], ADMIN_EA: [] },
groupByProductRole: {},
groupByPartyRole: { MANAGER: [], DELEGATE: [], SUB_DELEGATE: [], OPERATOR: [] },
groupByPartyRole: { MANAGER: [], DELEGATE: [], SUB_DELEGATE: [], OPERATOR: [], ADMIN_EA: [] },
});

export type ProductRolesByProductRoleType = { [productRole: string]: ProductRole };
Expand Down
34 changes: 18 additions & 16 deletions src/model/__tests__/ProductRole.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { mockedProductRoles } from '../../services/__mocks__/productService';
import { ProductRole, productRoles2ProductRolesList } from '../ProductRole';
import { productRoles2ProductRolesList } from '../ProductRole';

test('Test productRoles2ProductRolesList', () => {
const rolesList = productRoles2ProductRolesList(mockedProductRoles);
Expand All @@ -15,7 +15,7 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'referente-legale',
title: 'Referente Legale',
description: 'Descrizione referente-legale',
phasesAdditionAllowed: ['dashboard']
phasesAdditionAllowed: ['dashboard'],
},
{
productId: 'PRODID',
Expand All @@ -25,7 +25,7 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'referente-amministrativo',
title: 'Amministratore',
description: 'Descrizione referente-amministrativo',
phasesAdditionAllowed: ['dashboard']
phasesAdditionAllowed: ['dashboard'],
},
{
productId: 'PRODID',
Expand All @@ -35,7 +35,7 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'incaricato-ente-creditore',
title: 'Incaricato Ente Creditore',
description: 'Descrizione incaricato-ente-creditore',
phasesAdditionAllowed: ['dashboard-async']
phasesAdditionAllowed: ['dashboard-async'],
},
],
LIMITED: [
Expand All @@ -47,7 +47,7 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'referente-dei-pagamenti',
title: 'Referente dei Pagamenti',
description: 'Descrizione referente-dei-pagamenti',
phasesAdditionAllowed: ['dashboard']
phasesAdditionAllowed: ['dashboard'],
},
{
productId: 'PRODID',
Expand All @@ -57,9 +57,10 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'referente-tecnico',
title: 'Referente Tecnico',
description: 'Descrizione referente-tecnico',
phasesAdditionAllowed: ['dashboard']
phasesAdditionAllowed: ['dashboard'],
},
],
ADMIN_EA: [],
},
groupByPartyRole: {
DELEGATE: [
Expand All @@ -71,7 +72,7 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'referente-amministrativo',
selcRole: 'ADMIN',
title: 'Amministratore',
phasesAdditionAllowed: ['dashboard']
phasesAdditionAllowed: ['dashboard'],
},
],
MANAGER: [
Expand All @@ -83,7 +84,7 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'referente-legale',
selcRole: 'ADMIN',
title: 'Referente Legale',
phasesAdditionAllowed: ['dashboard']
phasesAdditionAllowed: ['dashboard'],
},
],
OPERATOR: [
Expand All @@ -95,7 +96,7 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'referente-dei-pagamenti',
selcRole: 'LIMITED',
title: 'Referente dei Pagamenti',
phasesAdditionAllowed: ['dashboard']
phasesAdditionAllowed: ['dashboard'],
},
{
description: 'Descrizione referente-tecnico',
Expand All @@ -105,7 +106,7 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'referente-tecnico',
selcRole: 'LIMITED',
title: 'Referente Tecnico',
phasesAdditionAllowed: ['dashboard']
phasesAdditionAllowed: ['dashboard'],
},
],
SUB_DELEGATE: [
Expand All @@ -117,9 +118,10 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'incaricato-ente-creditore',
selcRole: 'ADMIN',
title: 'Incaricato Ente Creditore',
phasesAdditionAllowed: ['dashboard-async']
phasesAdditionAllowed: ['dashboard-async'],
},
],
ADMIN_EA: [],
},
groupByProductRole: {
'referente-legale': {
Expand All @@ -130,7 +132,7 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'referente-legale',
title: 'Referente Legale',
description: 'Descrizione referente-legale',
phasesAdditionAllowed: ['dashboard']
phasesAdditionAllowed: ['dashboard'],
},
'referente-amministrativo': {
productId: 'PRODID',
Expand All @@ -140,7 +142,7 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'referente-amministrativo',
title: 'Amministratore',
description: 'Descrizione referente-amministrativo',
phasesAdditionAllowed: ['dashboard']
phasesAdditionAllowed: ['dashboard'],
},
'incaricato-ente-creditore': {
productId: 'PRODID',
Expand All @@ -150,7 +152,7 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'incaricato-ente-creditore',
title: 'Incaricato Ente Creditore',
description: 'Descrizione incaricato-ente-creditore',
phasesAdditionAllowed: ['dashboard-async']
phasesAdditionAllowed: ['dashboard-async'],
},
'referente-dei-pagamenti': {
productId: 'PRODID',
Expand All @@ -160,7 +162,7 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'referente-dei-pagamenti',
title: 'Referente dei Pagamenti',
description: 'Descrizione referente-dei-pagamenti',
phasesAdditionAllowed: ['dashboard']
phasesAdditionAllowed: ['dashboard'],
},
'referente-tecnico': {
productId: 'PRODID',
Expand All @@ -170,7 +172,7 @@ test('Test productRoles2ProductRolesList', () => {
productRole: 'referente-tecnico',
title: 'Referente Tecnico',
description: 'Descrizione referente-tecnico',
phasesAdditionAllowed: ['dashboard']
phasesAdditionAllowed: ['dashboard'],
},
},
});
Expand Down
32 changes: 15 additions & 17 deletions src/pages/dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,8 @@ const Dashboard = () => {
)
);

const authorizedDelegableProducts: Array<Product> = activeProducts.filter((ap) =>
party?.products.some(
(p) =>
p.productId === ap.id &&
hasPermission(p.productId, Actions.AccessProductBackoffice) &&
ap.delegable
)
const authorizedDelegableProducts: Array<Product> = delegableProducts.filter((ap) =>
hasPermission(ap.id ?? '', Actions.AccessProductBackoffice)
);

const canAggregatorSeeHandleDelegations = useMemo(() => {
Expand Down Expand Up @@ -164,19 +159,22 @@ const Dashboard = () => {
getAllProductsWithPermission(Actions.ViewDelegations).length > 0;

const isHandleDelegationsVisible = useMemo(() => {
const hasPermissionForManagedInstitutions =
const canDelegateSeeHandleDelegations =
delegableProducts.length > 0 &&
(isPT || hasDelegation) &&
getAllProductsWithPermission(Actions.ViewManagedInstitutions).length > 0;
const canShowDelegations = delegableProducts.length > 0 && (isPT || hasDelegation);

return (
(hasPermissionForManagedInstitutions && canShowDelegations) ||
canAggregatorSeeHandleDelegations
);
}, [authorizedDelegableProducts, isPT, hasDelegation, canAggregatorSeeHandleDelegations]);
return canDelegateSeeHandleDelegations || canAggregatorSeeHandleDelegations;
}, [
authorizedDelegableProducts,
isPT,
hasDelegation,
canAggregatorSeeHandleDelegations,
delegableProducts,
]);

// Check if the current route matches any path in the array
// TODO `${ENV.ROUTES.USERS}/add` add after release in PROD
const paths = [DASHBOARD_ROUTES.ADD_DELEGATE.path];
const paths = [DASHBOARD_ROUTES.ADD_DELEGATE.path, `${ENV.ROUTES.USERS}/add`];

const match = matchPath(location.pathname, {
path: paths,
Expand Down Expand Up @@ -346,7 +344,7 @@ const Dashboard = () => {
/>
</Route>
<Route path={DASHBOARD_ROUTES.TECHPARTNER.path} exact={true}>
<DashboardTechnologyPartnerPage party={party} ptProducts={activeProducts} />
<DashboardTechnologyPartnerPage party={party} />
</Route>
{buildRoutes(party, products, activeProducts, productsMap, decorators, DASHBOARD_ROUTES)}
</Switch>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default function DashboardSideMenu({
isHandleDelegationsVisible,
setDrawerOpen,
hideLabels,
}: Props) {
}: Readonly<Props>) {
const { t } = useTranslation();
const history = useHistory();
const onExit = useUnloadEventOnExit();
Expand All @@ -55,7 +55,7 @@ export default function DashboardSideMenu({
const ptRoute = DASHBOARD_ROUTES.TECHPARTNER.path;
const { getAllProductsWithPermission } = usePermissions();

const canSeeUsers = getAllProductsWithPermission(Actions.ManageProductUsers).length > 0;
const canSeeUsers = getAllProductsWithPermission(Actions.ListProductUsers).length > 0;
const canSeeGroups = getAllProductsWithPermission(Actions.ManageProductGroups).length > 0;

const overviewPath = resolvePathVariables(overviewRoute, {
Expand Down
Loading