From 4ff96472ac6f94f127c68337506e00e1c1fa931e Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 30 Jul 2024 15:31:04 -0400 Subject: [PATCH 1/2] Add form validation for GDAP invite wizard Remove the ability to have duplicate roleDefinitionIds selected --- .../administration/GDAPInviteWizard.jsx | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/views/tenant/administration/GDAPInviteWizard.jsx b/src/views/tenant/administration/GDAPInviteWizard.jsx index 5f303a3c827f..e46c6b7180e7 100644 --- a/src/views/tenant/administration/GDAPInviteWizard.jsx +++ b/src/views/tenant/administration/GDAPInviteWizard.jsx @@ -28,7 +28,7 @@ const Error = ({ name }) => ( render={({ meta: { touched, error } }) => touched && error ? ( - + {error} ) : null @@ -40,7 +40,31 @@ Error.propTypes = { name: PropTypes.string.isRequired, } -const requiredArray = (value) => (value && value.length !== 0 ? undefined : 'Required') +const requiredArray = (value) => { + if (value && value.length !== 0) { + /// group each item in value by roleDefinitionId and select Role name where count is greater than 1 + const duplicateRoles = value + .map((item) => item.roleDefinitionId) + .filter((item, index, self) => index !== self.indexOf(item)) + console.log(duplicateRoles) + + if (duplicateRoles.length > 0) { + var duplicates = value.filter((item) => duplicateRoles.includes(item.roleDefinitionId)) + /// get unique list of duplicate roles + duplicates = duplicates + .filter( + (role, index, self) => + index === self.findIndex((t) => t.roleDefinitionId === role.roleDefinitionId), + ) + .map((role) => role.RoleName) + return `Duplicate GDAP Roles selected, remove one of the mapped groups for the listed roles to continue: ${duplicates}` + } else { + return undefined + } + } else { + return 'You must select at least one GDAP Role' + } +} const GDAPInviteWizard = () => { const defaultRolesArray = [ From da771ee9d0414d95c18b6e70313e7e3a246e53be Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 30 Jul 2024 16:22:26 -0400 Subject: [PATCH 2/2] Add GDAP invite page --- src/_nav.jsx | 7 ++- src/importsMap.jsx | 3 +- src/routes.json | 8 ++- .../tenant/administration/ListGDAPInvites.jsx | 63 +++++++++++++++++++ 4 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 src/views/tenant/administration/ListGDAPInvites.jsx diff --git a/src/_nav.jsx b/src/_nav.jsx index c0faa91279c0..c83f7f179148 100644 --- a/src/_nav.jsx +++ b/src/_nav.jsx @@ -326,7 +326,12 @@ const _nav = [ { component: CNavItem, name: 'Invite Wizard', - to: '/tenant/administration/gdap-invite', + to: '/tenant/administration/gdap-invite-wizard', + }, + { + component: CNavItem, + name: 'Invite List', + to: '/tenant/administration/gdap-invites', }, { component: CNavItem, diff --git a/src/importsMap.jsx b/src/importsMap.jsx index eaa260ad4dbd..21174e32a0f2 100644 --- a/src/importsMap.jsx +++ b/src/importsMap.jsx @@ -147,7 +147,8 @@ import React from 'react' "/cipp/setup": React.lazy(() => import('./views/cipp/Setup')), "/tenant/administration/securescore": React.lazy(() => import('./views/tenant/administration/SecureScore')), "/tenant/administration/gdap": React.lazy(() => import('./views/tenant/administration/GDAPWizard')), - "/tenant/administration/gdap-invite": React.lazy(() => import('./views/tenant/administration/GDAPInviteWizard')), + "/tenant/administration/gdap-invite-wizard": React.lazy(() => import('./views/tenant/administration/GDAPInviteWizard')), + "/tenant/administration/gdap-invites": React.lazy(() => import('./views/tenant/administration/ListGDAPInvites')), "/tenant/administration/gdap-role-wizard": React.lazy(() => import('./views/tenant/administration/GDAPRoleWizard')), "/tenant/administration/gdap-roles": React.lazy(() => import('./views/tenant/administration/ListGDAPRoles')), "/tenant/administration/gdap-relationships": React.lazy(() => import('././views/tenant/administration/ListGDAPRelationships')), diff --git a/src/routes.json b/src/routes.json index f5b6053359a7..c0a996610e41 100644 --- a/src/routes.json +++ b/src/routes.json @@ -999,11 +999,17 @@ "allowedRoles": ["admin"] }, { - "path": "/tenant/administration/gdap-invite", + "path": "/tenant/administration/gdap-invite-wizard", "name": "GDAP Invite Wizard", "component": "views/tenant/administration/GDAPInviteWizard", "allowedRoles": ["admin"] }, + { + "path": "/tenant/administration/gdap-invites", + "name": "GDAP Invites", + "component": "views/tenant/administration/ListGDAPInvites", + "allowedRoles": ["admin"] + }, { "path": "/tenant/administration/gdap-role-wizard", "name": "GDAP Role Wizard", diff --git a/src/views/tenant/administration/ListGDAPInvites.jsx b/src/views/tenant/administration/ListGDAPInvites.jsx new file mode 100644 index 000000000000..24a44e6b253f --- /dev/null +++ b/src/views/tenant/administration/ListGDAPInvites.jsx @@ -0,0 +1,63 @@ +import React from 'react' +import { CippPageList } from 'src/components/layout' +import { TitleButton } from 'src/components/buttons' +import { cellGenericFormatter } from 'src/components/tables/CellGenericFormat' +import { cellDateFormatter } from 'src/components/tables' + +const ListGDAPInvites = () => { + const columns = [ + { + name: 'Created', + selector: (row) => row['Timestamp'], + sortable: true, + exportSelector: 'Timestamp', + cell: cellDateFormatter({ format: 'short' }), + }, + { + name: 'Relationship ID', + selector: (row) => row['RowKey'], + sortable: true, + exportSelector: 'RowKey', + cell: cellGenericFormatter(), + }, + { + name: 'Invite URL', + selector: (row) => row['InviteUrl'], + exportSelector: 'InviteUrl', + cell: cellGenericFormatter(), + }, + { + name: 'Onboarding URL', + selector: (row) => row['OnboardingUrl'], + exportSelector: 'OnboardingUrl', + cell: cellGenericFormatter(), + }, + { + name: 'Role Mapping', + selector: (row) => row['RoleMappings'], + exportSelector: 'RoleMappings', + cell: cellGenericFormatter(), + }, + ] + return ( +
+ +
+ ) +} + +export default ListGDAPInvites