diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e7f2c819..9896a00f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## 2.0.0-RC2 + +### Change + +- Technical Integration: updated connector registration overlay + + ### Bugfix + +- Company Subscriptions + - added missing translations +- Connector overlay + - updated overlay content with dynamic data +- Sticky header + - disabled focus effect on button +- User Management + - fixed app roles section +- My Account + - changed account page access role + ## 2.0.0-RC1 ### Change diff --git a/DEPENDENCIES b/DEPENDENCIES index 92dd449f3..975b6cc72 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -94,7 +94,7 @@ npm/npmjs/-/dayjs/1.11.10, MIT, approved, #9149 npm/npmjs/-/debug/3.2.7, MIT, approved, clearlydefined npm/npmjs/-/debug/4.3.4, MIT, approved, clearlydefined npm/npmjs/-/decimal.js/10.4.3, MIT, approved, clearlydefined -npm/npmjs/-/dedent/1.5.1, MIT, approved, clearlydefined +npm/npmjs/-/dedent/1.5.1, MIT, approved, #14381 npm/npmjs/-/deep-equal/2.2.3, MIT, approved, #8406 npm/npmjs/-/deep-is/0.1.4, MIT, approved, #2130 npm/npmjs/-/deepmerge/4.3.1, MIT, approved, #7032 @@ -406,7 +406,7 @@ npm/npmjs/-/proxy-from-env/1.1.0, MIT, approved, clearlydefined npm/npmjs/-/psl/1.9.0, MIT AND CC0-1.0, approved, #3080 npm/npmjs/-/punycode/2.3.1, MIT, approved, #6373 npm/npmjs/-/pure-rand/6.0.4, MIT AND (BSD-2-Clause AND ISC AND MIT), approved, #8423 -npm/npmjs/-/qs/6.12.0, BSD-3-Clause, approved, clearlydefined +npm/npmjs/-/qs/6.12.0, BSD-3-Clause, approved, #14380 npm/npmjs/-/querystringify/2.2.0, MIT, approved, clearlydefined npm/npmjs/-/queue-microtask/1.2.3, MIT, approved, clearlydefined npm/npmjs/-/react-dom/18.2.0, MIT, approved, clearlydefined diff --git a/package.json b/package.json index 2d81d20ff..f8c9250f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@catena-x/portal-frontend", - "version": "v2.0.0-RC1", + "version": "v2.0.0-RC2", "description": "Catena-X Portal Frontend", "author": "Catena-X Contributors", "license": "Apache-2.0", diff --git a/src/assets/locales/de/main.json b/src/assets/locales/de/main.json index ea27103f9..e79478566 100644 --- a/src/assets/locales/de/main.json +++ b/src/assets/locales/de/main.json @@ -387,6 +387,25 @@ } }, "organization": { + "unsubscribe": { + "title": "Geschäftsanwendung/Dienst abbestellen", + "descriptionNote": "Bitte beachten Sie: Die Abmeldung ist nicht rückgängig zu machen", + "description": "Alle möglicherweise verbundenen Objekte (in der folgenden Tabelle aufgeführt) werden ebenfalls deaktiviert", + "table": { + "listOfConnectedObjects": "Liste der verbundenen Objekte:", + "app": "Bewerbungs-/Diensttitel:", + "status": "Aktueller Status:", + "connector": "Verbinder:", + "techUser": "Technischer Benutzer:" + }, + "subscribed": "Gezeichnet", + "checkBoxLabel": "Ja, ich bin damit einverstanden, mich von dieser Anwendung/diesem Dienst abzumelden.", + "checkBoxLabelDescription": "Ich verstehe die Auswirkungen einer Abmeldung und würde den Vorgang dennoch gerne fortsetzen.", + "buttonText": "Abbestellen", + "unsubscribeSuccess": "Das Abmelden des Abonnements ist erfolgreich", + "unsubscribeError": "Die Abmeldung konnte nicht durchgeführt werden. Bitte versuchen Sie es erneut oder kommen Sie später noch einmal vorbei.", + "unsubscriptionOnProgress": "Abmeldung bei Fortschritt" + }, "companyDetails": { "title": "Company Details", "companyName": "Company Name", @@ -540,18 +559,28 @@ "managed": "Managed" }, "configurationDetails": { - "title": "Connector Configuration for authentication flow", - "description": "Your edc instance need to get connected to the catena-x identity provider for the technical user authentication flow to fetch the user token and authenticate against the MIW. Additionally the MIW endpoint, authority BPN and your technical user need to get configured/set to ensure that the connection works correctly.", - "orderList": { - "title": "Below you can find the relevant details regarding all those values", - "centralAuth": "* central auth url: https:{{env}}/realms/CX-Central/protocol/openid-connect/token", - "clientId": "* client id: client id of your existing or newly created tech user - details how to: ", - "clientIdLink": "/documentation/?path=user%2F03.+User+Management%2F03.+Technical+User%2F02.+Create+Technical+User.md", - "clientSecret": "* client secret: client id of your existing or newly created tech user - details how to: ", - "clientSecretLink": "/documentation/?path=user%2F03.+User+Management%2F03.+Technical+User%2F02.+Create+Technical+User.md", - "authorityBpn": "* authority bpn: {{bpn}}", - "miwUrl": "* miw url: https:{{managedIdentityWalletApiBase}}", - "clickhere": "click here" + "title": "How to Configure Your Connector", + "description": "Dies Beschreibung bietet schrittweise Anweisungen zur Konfiguration Ihres Connectors. Bitte befolgen Sie die unten stehenden Anweisungen, um die erforderlichen Konfigurationswerte einzustellen. Stellen Sie sicher, dass Sie die richtigen Werte für jede Konfigurationseinstellung eingeben. Sobald Sie diese Werte eingestellt haben, ist Ihr Connector ordnungsgemäß konfiguriert und einsatzbereit.", + "section": { + "part1": { + "title": "iatp.sts.oauth.token_url: ", + "description": "Der Token-Endpunkt der dezentralen Identitätsverwaltungsinstanz ist " + }, + "part2": { + "title": "iatp.sts.oauth.client.id: ", + "description1": "Technische Benutzer-Client-ID Ihres technischen Benutzers für den spezifischen Connector. Stellen Sie sicher, dass Sie die technischen Benutzer trennen – jeder Connector ist ein technischer Benutzer. Technische Benutzer können im gefunden und angefragt werden ", + "key": "technical user self-service.", + "description2": " Sie können den technischen Benutzer auch im Rahmen der Connector-Registrierung erstellen." + }, + "part3": { + "title": "iatp.sts.oauth.client.secret_alias: ", + "description": "Alias, unter dem Sie Ihr DIM-Client-Geheimnis im Tresor gespeichert haben. Im Tresor sollte das Geheimnis des oben definierten technischen Benutzers gespeichert werden. Sie können das Geheimnis im Inneren sehen ", + "key": "technical user self-service." + }, + "part4": { + "title": "iatp.sts.dim.url: ", + "description": "Base-URL Ihrer dezentralen Identitätsverwaltungsinstanz. Bitte verwenden Sie die folgenden Angaben für Connectors, die unter Ihrer Firmenidentität laufen: " + } } }, "helpText": "Get some help", @@ -580,9 +609,11 @@ } }, "modal": { + "title": "Firmenstecker anschließen", + "intro": "Registrierung eines Company Connectoren welcher im eigenen Firmennetz implementiert ist.", "company": { - "title": "Connect company connector", - "intro": "Registrierung eines Company Connectoren welcher im eigenen Firmennetz implementiert ist.", + "title": "Connector registrieren", + "intro": "Um mit Ihrem Connector innerhalb des Datenraums kommunizieren zu können, muss der Connector-Endpunkt registriert werden. Für den Connector ist zwingend ein technischer Benutzer erforderlich. Dieser Benutzer wird verwendet, um die Kommunikation zwischen Ihrem Connector und dem Firmen-Wallet (Identitätsmanagement) zu ermöglichen. Wenn der technische Benutzer noch nicht erstellt wurde, erstellen Sie bitte zuerst den technischen Benutzer und fahren Sie anschließend mit der Connector-Registrierung fort. Beachten Sie, dass die technische Benutzererstellung ein asynchroner Prozess ist und bis zu 5 Minuten dauern kann.", "disableDescription": "Diese Option ist nur verfügbar, wenn Ihr Unternehmen aktiver Teilnehmer ist. Unternehmensrollen können vom Unternehmensadministrator /company-role geändert werden" }, "managed": { @@ -592,21 +623,23 @@ }, "companyconnectorlabel": "Verbinden Sie den Unternehmenskonnektor", "connectorasaservice": "Connector-as-a-service", + "technicalUser": "Technischer Benutzer", + "connectorRegistrationDetails": "Details zur Connector-Registrierung", + "connectAlreadyExistingTechnicalUser": "Verbinden Sie einen bereits vorhandenen technischen Benutzer", + "createNewTechnicalUser": "Erstellen Sie einen neuen technischen Benutzer", "insertform": { "name": { "label": "Name*", "placeholder": "Connector Name", - "patternError": { - "lengthError": "Connector name length should be between 2 and 20.", - "otherError": "Connector name can not start with special character or empty space. Allowed special characters are @_:;.-%&?,'!." - }, - "error": "Connector name is mandatory.", - "tooltipMsg": "Own selected connector name for verification" + "mandatoryError": "Der Connector-Name ist obligatorisch.", + "tooltipMsg": "Eigener ausgewählter Connector-Name zur Überprüfung", + "patternError": "Der Connector-Name darf nicht mit Sonderzeichen oder Leerzeichen beginnen. Erlaubte Sonderzeichen sind @_:;%&?,'!." }, "url": { - "label": "Connector URL*", + "label": "Connector-Katalog-Endpunkt*", "placeholder": "Connector URL", - "error": "Enter a valid url - eg: https://catena-x.net", + "mandatoryError": "Die Connector-URL ist obligatorisch.", + "patternError": "Geben Sie eine gültige URL ein – z. B.: https://catena-x.net", "tooltipMsg": "URL of the connector endpoint. Only https:// endpoints are allowed" }, "bpn": { @@ -618,7 +651,8 @@ "country": { "label": "Location*", "placeholder": "Two digit country code", - "error": "Valid code eg: DE, US", + "mandatoryError": "Der Standort ist obligatorisch", + "patternError": "Gültiger Code zB: DE, US", "tooltipMsg": "Connector Location - Message to be added" }, "doc": { @@ -631,7 +665,29 @@ "placeholder": "Select the related subscription", "tooltipMsg": "Select the related subscription", "error": "Customer link is mandatory" - } + }, + "technicalUser": { + "label": "Technischer Benutzer*", + "placeholder": "Wählen Sie den vorhandenen technischen Benutzer aus", + "tooltipMsg": "Wählen Sie den vorhandenen technischen Benutzer aus", + "error": "Technischer Benutzer ist obligatorisch" + }, + "UserName": { + "label": "Nutzername*", + "placeholder": "Nutzername", + "tooltipMsg": "Benutzername für neuen technischen Benutzer", + "mandatoryError": "Der Benutzername ist obligatorisch", + "patternError": "Der Benutzername sollte mit einem Buchstaben beginnen. Zulässige Sonderzeichen sind #. '!=()&“ zusammen mit Zahlen und Leerzeichen" + }, + "description": { + "label": "Beschreibung*", + "placeholder": "Beschreibung", + "tooltipMsg": "Beschreibung für neue technische Benutzer", + "mandatoryError": "Beschreibung ist obligatorisch", + "patternError": "Der Benutzername sollte mit einem Buchstaben beginnen. Zulässige Sonderzeichen sind #. '!=()&“ zusammen mit Zahlen und Leerzeichen" + }, + "minLength": "Minlength ist", + "maxLength": "Maxlength ist" }, "create": { "successTitle": "Create connector successfully completed", @@ -736,12 +792,14 @@ "userRoleErrorMsg": "Etwas ist schief gelaufen. Benutzerrollen wurden nicht aktualisiert.", "header": { "title": "App Rollen", - "subtitle": "Für die App stehen folgende Rollen zur Verfügung. Über das Feld 'Rollenbeschreibung' können sie detailierte Informationen zu den Rechten der Rollen erhalten. Um eine Rolle einem User hinzuzufügen, nutzen Sie bitte den Button 'Add Role' unter den Rollenbeschreibungen" + "subtitle": "Für die App stehen folgende Rollen zur Verfügung. Über das Feld 'Rollenbeschreibung' können sie detailierte Informationen zu den Rechten der Rollen erhalten. Um eine Rolle einem User hinzuzufügen, nutzen Sie bitte den Button 'Add Role' unter den Rollenbeschreibungen", + "noRoles": "Derzeit sind keine App-Rollen vorhanden. Keine Zuordnung möglich." }, "table": { "headline": "Benutzermanagement", "title": "Benutzer Liste", "add": "Benutzerrolle hinzufügen", + "buttonTooltip": "Funktion deaktiviert, da keine App-Rollen verfügbar sind", "noRowsMsg": "No users assigned till now. Start to assign by clicking on Add Role" }, "roles": { diff --git a/src/assets/locales/en/main.json b/src/assets/locales/en/main.json index d4f9a0856..236556af5 100644 --- a/src/assets/locales/en/main.json +++ b/src/assets/locales/en/main.json @@ -386,6 +386,25 @@ } }, "organization": { + "unsubscribe": { + "title": "Unsubscribe Business Application / Service", + "descriptionNote": "Please note: the unsubscription is not revertible", + "description": "all possibly connected objects (mentioned in below table) will get deactivated as well", + "table": { + "listOfConnectedObjects": "List of connected objects:", + "app": "Application / Service title:", + "status": "Current Status:", + "connector": "Connector:", + "techUser": "Technical User:" + }, + "subscribed": "Subscribed", + "checkBoxLabel": "Yes, I agree to unsubscribe from this application / service.", + "checkBoxLabelDescription": "I understand the implications of unsubscribing and would still like to continue the process.", + "buttonText": "Unsubscribe", + "unsubscribeSuccess": "Unsubscribe subscription is successful", + "unsubscribeError": "Unsubscription could not be executed. Please try again or come back later.", + "unsubscriptionOnProgress": "Unsubscription on progress" + }, "companyDetails": { "title": "Company Details", "companyName": "Company Name", @@ -539,18 +558,28 @@ "managed": "Managed" }, "configurationDetails": { - "title": "Connector Configuration for authentication flow", - "description": "Your edc instance need to get connected to the catena-x identity provider for the technical user authentication flow to fetch the user token and authenticate against the MIW. Additionally the MIW endpoint, authority BPN and your technical user need to get configured/set to ensure that the connection works correctly.", - "orderList": { - "title": "Below you can find the relevant details regarding all those values", - "centralAuth": "* central auth url: https:{{env}}/realms/CX-Central/protocol/openid-connect/token", - "clientId": "* client id: client id of your existing or newly created tech user - details how to: ", - "clientIdLink": "/documentation/?path=user%2F03.+User+Management%2F03.+Technical+User%2F02.+Create+Technical+User.md", - "clientSecret": "* client secret: client id of your existing or newly created tech user - details how to: ", - "clientSecretLink": "/documentation/?path=user%2F03.+User+Management%2F03.+Technical+User%2F02.+Create+Technical+User.md", - "authorityBpn": "* authority bpn: {{bpn}}", - "miwUrl": "* miw url: https:{{managedIdentityWalletApiBase}}", - "clickhere": "click here" + "title": "How to Configure Your Connector", + "description": "This description provides step-by-step instructions on how to configure your connector. Please follow the instructions below to set the necessary configuration values. Please ensure that you enter the correct values for each configuration setting. Once you have set these values, your connector will be properly configured and ready to use.", + "section": { + "part1": { + "title": "iatp.sts.oauth.token_url: ", + "description": "the token endpoint of the decentral identity management instance is: " + }, + "part2": { + "title": "iatp.sts.oauth.client.id: ", + "description1": "technical user client ID of your technical user for the specific connector. Ensure you separate the technical users - each connector one technical user. Technical users can get found and requested inside the ", + "key": "technical user self-service.", + "description2": " You can also create the technical user as part of the connector registration." + }, + "part3": { + "title": "iatp.sts.oauth.client.secret_alias: ", + "description": "alias under which you saved your DIM client secret in the vault. Inside the vault the secret of the technical user defined above should be stored. You can view the secret inside the ", + "key": "technical user self-service." + }, + "part4": { + "title": "iatp.sts.dim.url: ", + "description": "base url of you decentral identity management instance. Please use the following details for connectors running under your company identity: " + } } }, "helpText": "Get some help", @@ -579,9 +608,11 @@ } }, "modal": { + "title": "Connect company connector", + "intro": "Registration of a company connector which is implemented in your own company network.", "company": { - "title": "Connect company connector", - "intro": "Registration of a company connector which is implemented in your own company network.", + "title": "Register Connector", + "intro": "To be able to communicate with your connector inside the dataspace, the connector endpoint needs to get registered. For the connector, a technical user is mandatorily needed. This user is used to enable the communication between your connector and the company wallet (identity management). If the technical user is not created already, please create the technical user first and proceed with the connector registration afterwards. Note, the technical user creation is a asynchrony process and might take up to 5 minutes.", "disableDescription": "This option is only available if your company is Active Participant. Company roles can get changed by the company admin /company-role" }, "managed": { @@ -591,21 +622,23 @@ }, "companyconnectorlabel": "Connect company connector", "connectorasaservice": "Connector-as-a-service", + "technicalUser": "Technical User", + "connectorRegistrationDetails": "Connector Registration Details", + "connectAlreadyExistingTechnicalUser": "Connect an already existing technical user", + "createNewTechnicalUser": "Create a new technical user", "insertform": { "name": { "label": "Name*", "placeholder": "Connector Name", - "patternError": { - "lengthError": "Connector name length should be between 2 and 20.", - "otherError": "Connector name can not start with special character or empty space. Allowed special characters are @_:;.-%&?,'!." - }, - "error": "Connector name is mandatory.", - "tooltipMsg": "Own selected connector name for verification" + "mandatoryError": "Connector name is mandatory.", + "tooltipMsg": "Own selected connector name for verification", + "patternError": "Connector name can not start with special character or empty space. Allowed special characters are @_:;.-%&?,'!." }, "url": { - "label": "Connector URL/Endpoint*", + "label": "Connector Catalogue Endpoint*", "placeholder": "Connector URL", - "error": "Enter a valid url - eg: https://catena-x.net", + "mandatoryError": "Connector URL is mandatory.", + "patternError": "Enter a valid url - eg: https://catena-x.net", "tooltipMsg": "URL of the connector endpoint. Only https:// endpoints are allowed" }, "bpn": { @@ -617,7 +650,8 @@ "country": { "label": "Location*", "placeholder": "Two digit country code", - "error": "Valid code eg: DE, US", + "mandatoryError": "Location is mandatory", + "patternError": "Valid code eg: DE, US", "tooltipMsg": "Connector Location Country Code - e.g. DE, US, etc." }, "doc": { @@ -630,6 +664,26 @@ "placeholder": "Select the related subscription", "tooltipMsg": "Select the related subscription", "error": "Customer link is mandatory" + }, + "technicalUser": { + "label": "Technical User*", + "placeholder": "Select existing technical user", + "tooltipMsg": "Select existing technical user", + "error": "Technical User is mandatory" + }, + "UserName": { + "label": "Username*", + "placeholder": "Username", + "tooltipMsg": "Username for new technical user", + "mandatoryError": "Username is mandatory", + "patternError": "Username should start with a letter. Allowed special characters are #. '!=()&” along with numbers and spaces" + }, + "description": { + "label": "Description*", + "placeholder": "Description", + "tooltipMsg": "Description for new technical user", + "mandatoryError": "Description is mandatory", + "patternError": "Username should start with a letter. Allowed special characters are #. '!=()&” along with numbers and spaces" } }, "create": { @@ -643,7 +697,9 @@ "successDescription": "Delete connector successfully completed.", "errorTitle": "Something went wrong", "errorDescription": "Something went wrong. Please try it later again or contact your administrator." - } + }, + "minLength": "Minlength is", + "maxLength": "Maxlength is" } }, "partnernetwork": { @@ -735,12 +791,14 @@ "userRoleErrorMsg": "Roles have not got updated.", "header": { "title": "App Roles", - "subtitle": "Below you can find an overview of the available app roles as well as a role description by selectiong the 'Role Description' field. To add the user role to an existing active company user, please use the 'add role' button below the 'Available Role' area." + "subtitle": "Below you can find an overview of the available app roles as well as a role description by selectiong the 'Role Description' field. To add the user role to an existing active company user, please use the 'add role' button below the 'Available Role' area.", + "noRoles": "No app roles are currently existing. No assignment possible." }, "table": { "headline": "Identity Management", "title": "App Users", "add": "Add Role", + "buttonTooltip": "Function disabled since no app roles are available", "noRowsMsg": "No users assigned till now. Start to assign by clicking on Add Role" }, "roles": { diff --git a/src/components/pages/Admin/components/RegistrationRequests/CompanyDetailOverlay/index.tsx b/src/components/pages/Admin/components/RegistrationRequests/CompanyDetailOverlay/index.tsx index e1bee2c50..cabd586ca 100644 --- a/src/components/pages/Admin/components/RegistrationRequests/CompanyDetailOverlay/index.tsx +++ b/src/components/pages/Admin/components/RegistrationRequests/CompanyDetailOverlay/index.tsx @@ -38,7 +38,6 @@ import ArticleOutlinedIcon from '@mui/icons-material/ArticleOutlined' import { type ApplicationRequest, useFetchCheckListDetailsQuery, - useFetchCompanySearchQuery, } from 'features/admin/applicationRequestApiSlice' import { download } from 'utils/downloadUtils' import CheckListFullButtons from '../components/CheckList/CheckListFullButtons' @@ -47,12 +46,14 @@ import { useFetchNewDocumentByIdMutation } from 'features/appManagement/apiSlice interface CompanyDetailOverlayProps { openDialog?: boolean + selectedRequest?: ApplicationRequest selectedRequestId?: string handleOverlayClose: React.MouseEventHandler } const CompanyDetailOverlay = ({ openDialog = false, + selectedRequest, selectedRequestId, handleOverlayClose, }: CompanyDetailOverlayProps) => { @@ -69,22 +70,10 @@ const CompanyDetailOverlay = ({ const [height, setHeight] = useState('') const { data: checklistData } = useFetchCheckListDetailsQuery(selectedRequestId) - const { data } = useFetchCompanySearchQuery({ - page: 0, - args: { - expr: selectedCompany?.name, - }, - }) useEffect(() => { - if (data) { - const selected = data?.content?.filter( - (company: { bpn: string }) => - !company.bpn || selectedCompany.bpn === company.bpn - ) - setCompany(selected[0]) - } - }, [data, selectedCompany]) + if (selectedRequest) setCompany(selectedRequest) + }, [selectedRequest]) const getLocaleStr = (str: string) => { if (str === 'ACTIVE_PARTICIPANT') { diff --git a/src/components/pages/Admin/components/RegistrationRequests/index.tsx b/src/components/pages/Admin/components/RegistrationRequests/index.tsx index a282680fb..f73827670 100644 --- a/src/components/pages/Admin/components/RegistrationRequests/index.tsx +++ b/src/components/pages/Admin/components/RegistrationRequests/index.tsx @@ -28,6 +28,7 @@ import type { GridCellParams } from '@mui/x-data-grid' import CompanyDetailOverlay from './CompanyDetailOverlay' import ConfirmationOverlay from './ConfirmationOverlay/ConfirmationOverlay' import { + type ApplicationRequest, useApproveRequestMutation, useDeclineChecklistMutation, useFetchCompanySearchQuery, @@ -54,6 +55,7 @@ export default function RegistrationRequests() { const [confirmModalOpen, setConfirmModalOpen] = useState(false) const [selectedRequestId, setSelectedRequestId] = useState() + const [selectedRequest, setSelectedRequest] = useState() const [actionType, setActionType] = useState('approve') const [approveRequest] = useApproveRequestMutation() @@ -83,6 +85,7 @@ export default function RegistrationRequests() { // Show overlay only when detail field clicked if (params.field === 'detail') { setSelectedRequestId(params.row.applicationId) + setSelectedRequest(params.row) dispatch(fetchCompanyDetail(params.row.applicationId)) setOverlayOpen(true) } @@ -181,6 +184,7 @@ export default function RegistrationRequests() { { setOverlayOpen(false) diff --git a/src/components/pages/AppUserManagement/components/AppUserDetailsHeader/AppUserDetailsHeader.scss b/src/components/pages/AppUserManagement/components/AppUserDetailsHeader/AppUserDetailsHeader.scss index 460673de6..a1b2b9a59 100644 --- a/src/components/pages/AppUserManagement/components/AppUserDetailsHeader/AppUserDetailsHeader.scss +++ b/src/components/pages/AppUserManagement/components/AppUserDetailsHeader/AppUserDetailsHeader.scss @@ -30,6 +30,11 @@ max-width: 1200px; height: max-content; margin: 80px auto 0px auto; + .no-roles { + text-align: center; + display: inline-block; + width: 100%; + } } .app-user-details-header-role { diff --git a/src/components/pages/AppUserManagement/components/AppUserDetailsHeader/index.tsx b/src/components/pages/AppUserManagement/components/AppUserDetailsHeader/index.tsx index 8f48ad5da..cd952cd17 100644 --- a/src/components/pages/AppUserManagement/components/AppUserDetailsHeader/index.tsx +++ b/src/components/pages/AppUserManagement/components/AppUserDetailsHeader/index.tsx @@ -28,7 +28,7 @@ import type { AppRole } from 'features/admin/appuserApiSlice' import './AppUserDetailsHeader.scss' export interface AppUserDetailsHeaderProps { - roles: AppRole[] + roles?: AppRole[] error: string } @@ -55,23 +55,29 @@ export default function AppUserDetailsHeader({
- {roles?.map((role) => { - return ( -
-
- - {role.role} - - - {role.description} - + {roles?.length ? ( + roles.map((role) => { + return ( +
+
+ + {role.role} + + + {role.description} + +
-
- ) - })} + ) + }) + ) : ( + + {t('content.usermanagement.appUserDetails.header.noRoles')} + + )}
{error && ( diff --git a/src/components/pages/AppUserManagement/components/AppUserDetailsTable/index.tsx b/src/components/pages/AppUserManagement/components/AppUserDetailsTable/index.tsx index 427081680..7990bed2e 100644 --- a/src/components/pages/AppUserManagement/components/AppUserDetailsTable/index.tsx +++ b/src/components/pages/AppUserManagement/components/AppUserDetailsTable/index.tsx @@ -24,14 +24,21 @@ import { useState } from 'react' import { UserList } from 'components/shared/frame/UserList' import { show } from 'features/control/overlay' import { OVERLAYS } from 'types/Constants' -import { useFetchAppUsersSearchQuery } from 'features/admin/appuserApiSlice' +import { + type AppRole, + useFetchAppUsersSearchQuery, +} from 'features/admin/appuserApiSlice' import type { TenantUser } from 'features/admin/userApiSlice' +import { useTranslation } from 'react-i18next' export const AppUserDetailsTable = ({ + roles, userRoleResponse, }: { + roles?: AppRole[] userRoleResponse: string }) => { + const { t } = useTranslation() const dispatch = useDispatch() const { appId } = useParams() const [expr, setExpr] = useState('') @@ -41,6 +48,12 @@ export const AppUserDetailsTable = ({ sectionTitle={'content.usermanagement.appUserDetails.subheadline'} addButtonLabel={'content.usermanagement.appUserDetails.table.add'} addButtonClick={() => dispatch(show(OVERLAYS.ADD_APP_USER_ROLES, appId))} + addButtonDisabled={!roles} + addButtonTooltip={ + !roles + ? t('content.usermanagement.appUserDetails.table.buttonTooltip') + : '' + } tableLabel={'content.usermanagement.appUserDetails.table.title'} fetchHook={useFetchAppUsersSearchQuery} fetchHookArgs={{ appId, expr, userRoleResponse, role: true }} diff --git a/src/components/pages/AppUserManagement/index.tsx b/src/components/pages/AppUserManagement/index.tsx index a47034840..6d9c3fa05 100644 --- a/src/components/pages/AppUserManagement/index.tsx +++ b/src/components/pages/AppUserManagement/index.tsx @@ -82,13 +82,11 @@ export default function AppUserManagement() { > - {data && ( - - )} - + + {/* success or error dialog/overlay */} {userRoleResponse && ( { @@ -116,17 +124,6 @@ any) => { <> { - let errortext = helperText - if (rules.pattern.test(value)) { - errortext = '' - } else if ( - (value.length <= 2 || value.length > 20) && - patternError - ) { - errortext = patternError.lengthError - } else if (!rules.pattern.test(value) && patternError) { - errortext = patternError.otherError - } return ( { paddingTop: '10px', }} error={!!errors[name]} - helperText={errortext} + helperText={errors?.[name]?.message} label={label} placeholder={placeholder} onChange={(event) => { @@ -142,12 +139,30 @@ any) => { onChange(event) }} value={value} + disabled={disable} /> ) }} name={name} control={control} - rules={rules} + rules={{ + required: { + value: true, + message: rules.required, + }, + minLength: { + value: minLength, + message: rules.minLength, + }, + pattern: { + value: pattern, + message: rules.pattern, + }, + maxLength: { + value: maxLength, + message: rules.maxLength, + }, + }} /> )} @@ -200,7 +215,11 @@ any) => { label={''} placeholder={placeholder} onChangeItem={(e) => { - onChange(e ? e.subscriptionId : '') + onChange( + name === 'ConnectorTechnicalUser' + ? e.serviceAccountId + : e.subscriptionId + ) }} keyTitle={keyTitle} /> @@ -225,149 +244,357 @@ const ConnectorInsertForm = ({ trigger, selectedService, subscriptions, + fetchServiceAccountUsers, + setNewTechnicalUSer, + onFormSubmitt, + newUserLoading, + newUserSuccess, }: // Add an ESLint exception until there is a solution // eslint-disable-next-line any) => { const { t } = useTranslation() - const theme = useTheme() - const { spacing } = theme + const [selectedValue, setSelectedValue] = useState() - return ( - - - -
-
{ + if ( + selectedValue === t('content.edcconnector.modal.createNewTechnicalUser') + ) { + if (newUserLoading) { + return ( + + { + // do nothing }} + sx={{ marginLeft: '10px', textTransform: 'none' }} + /> + + ) + } else + return ( + +
-
- -
-
+ + {selectedValue === + t( + 'content.edcconnector.modal.connectAlreadyExistingTechnicalUser' + ) && ( -
- {selectedService && - selectedService.type === ConnectType.MANAGED_CONNECTOR && ( -
- + { + setSelectedValue(event.target.value) + setNewTechnicalUSer(true) + }} + size="small" + sx={{ + display: 'flex !important', + }} + /> + + {selectedValue === + t('content.edcconnector.modal.createNewTechnicalUser') && ( + <> + + -
- )} -
-
-
+ }, + label: t( + 'content.edcconnector.modal.insertform.description.label' + ), + placeholder: t( + 'content.edcconnector.modal.insertform.description.placeholder' + ), + tooltipMsg: t( + 'content.edcconnector.modal.insertform.description.tooltipMsg' + ), + disable: newUserSuccess ?? false, + }} + /> + + )} + {handleTechnicalUserSubmit()} + + + 2 + + + + {t('content.edcconnector.modal.connectorRegistrationDetails')} + + + )} + + + + {selectedService && + selectedService.type === ConnectType.MANAGED_CONNECTOR && ( + + )} +
) } diff --git a/src/components/pages/EdcConnector/AddConnectorOverlay/components/ConnectorTypeSelection.tsx b/src/components/pages/EdcConnector/AddConnectorOverlay/components/ConnectorTypeSelection.tsx index 044c2b586..5c59a4e8f 100644 --- a/src/components/pages/EdcConnector/AddConnectorOverlay/components/ConnectorTypeSelection.tsx +++ b/src/components/pages/EdcConnector/AddConnectorOverlay/components/ConnectorTypeSelection.tsx @@ -26,6 +26,8 @@ import { type CompanyDetails, CompanyRoleEnum, } from 'features/admin/userApiSlice' +import { ConnectType } from 'features/connector/connectorApiSlice' + // Static content // Add Connector Button action modal first step content const ConnectorTypeSelection = ({ @@ -41,8 +43,8 @@ const ConnectorTypeSelection = ({ const checkBoxSelector = [ { title: t('content.edcconnector.modal.companyconnectorlabel'), - type: 'COMPANY_CONNECTOR', - descritpion: t('content.edcconnector.modal.company.intro'), + type: ConnectType.COMPANY_CONNECTOR, + descritpion: t('content.edcconnector.modal.intro'), id: 1, disable: !ownCompanyDetails?.companyRole || @@ -53,7 +55,7 @@ const ConnectorTypeSelection = ({ }, { title: t('content.edcconnector.modal.connectorasaservice'), - type: 'MANAGED_CONNECTOR', + type: ConnectType.MANAGED_CONNECTOR, descritpion: t('content.edcconnector.modal.managed.intro'), id: 2, disable: diff --git a/src/components/pages/EdcConnector/AddConnectorOverlay/components/EdcComponentStyles.scss b/src/components/pages/EdcConnector/AddConnectorOverlay/components/EdcComponentStyles.scss index 2fd053b6b..c703e7ee5 100644 --- a/src/components/pages/EdcConnector/AddConnectorOverlay/components/EdcComponentStyles.scss +++ b/src/components/pages/EdcConnector/AddConnectorOverlay/components/EdcComponentStyles.scss @@ -26,3 +26,12 @@ background-color: rgba(241, 38, 19, 0.1); border-radius: 8px; } + +.stepNumber { + width: 25px; + border-radius: 50%; + color: #0f71cb; + border: 2px solid; + text-align: center; + height: 25px; +} diff --git a/src/components/pages/EdcConnector/AddConnectorOverlay/index.tsx b/src/components/pages/EdcConnector/AddConnectorOverlay/index.tsx index b8d4d01ca..1338bed48 100644 --- a/src/components/pages/EdcConnector/AddConnectorOverlay/index.tsx +++ b/src/components/pages/EdcConnector/AddConnectorOverlay/index.tsx @@ -27,6 +27,7 @@ import { DialogActions, DialogHeader, CircleProgress, + Typography, } from '@catena-x/portal-shared-components' import ConnectorTypeSelection from './components/ConnectorTypeSelection' import ConnectorInsertForm from './components/ConnectorInsertForm' @@ -34,9 +35,11 @@ import { useForm } from 'react-hook-form' import { type ConnectorType, useFetchOfferSubscriptionsQuery, + ConnectType, } from 'features/connector/connectorApiSlice' import Box from '@mui/material/Box' import { useFetchOwnCompanyDetailsQuery } from 'features/admin/userApiSlice' +import { useFetchServiceAccountUsersQuery } from 'features/admin/serviceApiSlice' interface AddCollectorOverlayProps { openDialog?: boolean @@ -46,6 +49,9 @@ interface AddCollectorOverlayProps { onFormConfirmClick: (data: FormFieldsType) => void loading?: boolean onStepChange: () => void + onSubmitClick: (data: FormFieldsType) => void + newUserLoading?: boolean + newUserSuccess?: boolean } export type FormFieldsType = { @@ -53,6 +59,9 @@ export type FormFieldsType = { ConnectorURL: string ConnectorSubscriptionId: string ConnectorLocation: string + ConnectorTechnicalUser: string + TechnicalUserName: string + TechnicalUserDescription: string } const formFields = { @@ -60,6 +69,9 @@ const formFields = { ConnectorURL: '', ConnectorLocation: '', ConnectorSubscriptionId: '', + ConnectorTechnicalUser: '', + TechnicalUserName: '', + TechnicalUserDescription: '', } const AddConnectorOverlay = ({ @@ -70,10 +82,16 @@ const AddConnectorOverlay = ({ onFormConfirmClick, loading, onStepChange, + onSubmitClick, + newUserLoading, + newUserSuccess, }: AddCollectorOverlayProps) => { const { t } = useTranslation() const { data } = useFetchOfferSubscriptionsQuery() const { data: ownCompanyDetails } = useFetchOwnCompanyDetailsQuery() + const fetchServiceAccountUsers = useFetchServiceAccountUsersQuery().data + const [newTechnicalUSer, setNewTechnicalUSer] = useState(false) + const { handleSubmit, getValues, @@ -93,14 +111,20 @@ const AddConnectorOverlay = ({ }, [openDialog, reset]) const onFormSubmit = async () => { - const validateFields = await trigger([ - 'ConnectorName', - 'ConnectorURL', - 'ConnectorLocation', - 'ConnectorSubscriptionId', - ]) + const validateFields = + newTechnicalUSer && !newUserSuccess + ? await trigger(['TechnicalUserName', 'TechnicalUserDescription']) + : await trigger([ + 'ConnectorName', + 'ConnectorURL', + 'ConnectorLocation', + 'ConnectorSubscriptionId', + 'ConnectorTechnicalUser', + ]) if (validateFields) { - onFormConfirmClick(getValues() as FormFieldsType) + newTechnicalUSer && !newUserSuccess + ? onSubmitClick(getValues() as FormFieldsType) + : onFormConfirmClick(getValues() as FormFieldsType) } } @@ -108,25 +132,50 @@ const AddConnectorOverlay = ({ setSelected(service) } + const getTitle = () => { + if (connectorStep === 1 && selected.type === 'MANAGED_CONNECTOR') + return t('content.edcconnector.modal.managed.title') + else if ( + connectorStep === 1 && + selected.type === ConnectType.COMPANY_CONNECTOR + ) { + return t('content.edcconnector.modal.company.title') + } else return t('content.edcconnector.modal.title') + } + const getIntro = () => { + if ( + connectorStep === 1 && + selected.type === ConnectType.MANAGED_CONNECTOR + ) { + return t('content.edcconnector.modal.managed.intro') + } else if ( + connectorStep === 1 && + selected.type === ConnectType.COMPANY_CONNECTOR + ) { + return ( + + {t('content.edcconnector.modal.company.intro')} + + ) + } else { + return t('content.edcconnector.modal.intro') + } + } return (
{ setSelected({}) @@ -150,6 +199,11 @@ const AddConnectorOverlay = ({ diff --git a/src/components/pages/EdcConnector/ConfigurationDetailsOverlay.tsx b/src/components/pages/EdcConnector/ConfigurationDetailsOverlay.tsx index e7c6d6901..673cf3d7a 100644 --- a/src/components/pages/EdcConnector/ConfigurationDetailsOverlay.tsx +++ b/src/components/pages/EdcConnector/ConfigurationDetailsOverlay.tsx @@ -18,16 +18,16 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -import { Trans, useTranslation } from 'react-i18next' +import { useTranslation } from 'react-i18next' import { Dialog, DialogContent, DialogHeader, Typography, } from '@catena-x/portal-shared-components' -import { useFetchOperatorBpnQuery } from 'features/connector/connectorApiSlice' -import { getCentralIdp, getMiwBase } from 'services/EnvironmentService' +import { useFetchDecentralIdentityUrlsQuery } from 'features/connector/connectorApiSlice' import './EdcConnector.scss' +import { PAGES } from 'types/Constants' interface ConfigurationDetailsOverlayProps { openDialog: boolean @@ -39,7 +39,7 @@ const ConfigurationDetailsOverlay = ({ handleOverlayClose, }: ConfigurationDetailsOverlayProps) => { const { t } = useTranslation() - const { data } = useFetchOperatorBpnQuery() + const { data } = useFetchDecentralIdentityUrlsQuery() return (
@@ -62,92 +62,79 @@ const ConfigurationDetailsOverlay = ({ padding: '0px 120px 40px 120px', }} > - - {t('content.edcconnector.configurationDetails.orderList.title')} - - - + + {t( - 'content.edcconnector.configurationDetails.orderList.centralAuth' + 'content.edcconnector.configurationDetails.section.part1.title' )} - - - + + {t( + 'content.edcconnector.configurationDetails.section.part1.description' + )} + + {data?.decentralIdentityManagementAuthUrl} + + - {t('content.edcconnector.configurationDetails.orderList.clientId')}{' '} + + {t( + 'content.edcconnector.configurationDetails.section.part2.title' + )} + + {t( + 'content.edcconnector.configurationDetails.section.part2.description1' + )} - window.open( - t( - 'content.edcconnector.configurationDetails.orderList.clientSecretLink' - ), - '_blank' - ) - } + style={{ + textDecoration: 'underline', + }} + onClick={() => window.open(PAGES.TECHUSER_MANAGEMENT, '_blank')} onKeyUp={() => { // do nothing }} > - {t( - 'content.edcconnector.configurationDetails.orderList.clickhere' - )} + {t('content.edcconnector.configurationDetails.section.part2.key')} + {t( + 'content.edcconnector.configurationDetails.section.part2.description2' + )} + + {t( + 'content.edcconnector.configurationDetails.section.part3.title' + )} + {t( - 'content.edcconnector.configurationDetails.orderList.clientSecret' - )}{' '} + 'content.edcconnector.configurationDetails.section.part3.description' + )} - window.open( - t( - 'content.edcconnector.configurationDetails.orderList.clientSecretLink' - ), - '_blank' - ) - } + style={{ + textDecoration: 'underline', + }} + onClick={() => window.open(PAGES.TECHUSER_MANAGEMENT, '_blank')} onKeyUp={() => { // do nothing }} > + {t('content.edcconnector.configurationDetails.section.part3.key')} + + + + {t( - 'content.edcconnector.configurationDetails.orderList.clickhere' + 'content.edcconnector.configurationDetails.section.part4.title' )} + + {t( + 'content.edcconnector.configurationDetails.section.part4.description' + )} + + {data?.decentralIdentityManagementServiceUrl} - {data && ( - - - {t( - 'content.edcconnector.configurationDetails.orderList.authorityBpn' - )} - - - )} - - - {t('content.edcconnector.configurationDetails.orderList.miwUrl')} - -
diff --git a/src/components/pages/EdcConnector/EdcConnector.scss b/src/components/pages/EdcConnector/EdcConnector.scss index 3b230cf91..47f3f5052 100644 --- a/src/components/pages/EdcConnector/EdcConnector.scss +++ b/src/components/pages/EdcConnector/EdcConnector.scss @@ -46,12 +46,6 @@ } } -.connector-insert-form { - .form-input { - margin-bottom: 0px; - } -} - .detailsBodyText { margin-bottom: 10px !important; margin-left: 20px !important; diff --git a/src/components/pages/EdcConnector/index.tsx b/src/components/pages/EdcConnector/index.tsx index 4d339c932..8588624c4 100644 --- a/src/components/pages/EdcConnector/index.tsx +++ b/src/components/pages/EdcConnector/index.tsx @@ -52,6 +52,11 @@ import { SuccessErrorType } from 'features/admin/appuserApiSlice' import { ManagedConnectorTableColumns } from './edcManagedConnectorTableColumns' import { OwnConnectorTableColumns } from './edcOwnConnectorTableColumns' import ConfigurationDetailsOverlay from './ConfigurationDetailsOverlay' +import { + ServiceAccountType, + useAddServiceAccountMutation, + useFetchServiceAccountRolesQuery, +} from 'features/admin/serviceApiSlice' const EdcConnector = () => { const { t } = useTranslation() @@ -98,6 +103,20 @@ const EdcConnector = () => { viewConfigurationDetailsOverlayOpen, setViewConfigurationDetailsOverlayOpen, ] = useState(false) + const [addServiceAccount] = useAddServiceAccountMutation() + const roles = useFetchServiceAccountRolesQuery().data + const [role, setRole] = useState('') + const [newUserLoading, setNewUserLoading] = useState(false) + const [newUserSuccess, setNewUserSuccess] = useState(false) + const [serviceAccId, setServiceAccId] = useState('') + + useEffect(() => { + if (roles && roles.length > 0) + setRole( + roles?.filter((i) => i.roleName === 'Identity Wallet Management')[0] + .roleId + ) + }, [roles]) const onStepChange = () => { setAddConnectorOverlayCurrentStep(0) @@ -148,6 +167,10 @@ const EdcConnector = () => { body.append('Status', ConnectorStatusType.PENDING) setLoading(true) if (selectedService.type === ConnectType.COMPANY_CONNECTOR) { + body.append( + 'TechnicalUserId', + serviceAccId === '' ? data.ConnectorTechnicalUser : serviceAccId + ) await createConnector(body) .unwrap() .then(() => { @@ -166,11 +189,35 @@ const EdcConnector = () => { showOverlay(true) }) .catch(() => { - showOverlay(false) + !setNewUserSuccess && showOverlay(false) }) } } + const onSubmitClick = async (data: FormFieldsType) => { + const body = new FormData() + body.append('name', data.TechnicalUserName) + body.append('description', data.TechnicalUserDescription) + body.append('authenticationType', ServiceAccountType.SECRET) + body.append('roleIds', role) + setNewUserLoading(true) + await addServiceAccount({ + name: data.TechnicalUserName, + description: data.TechnicalUserDescription, + authenticationType: ServiceAccountType.SECRET, + roleIds: [role], + }) + .unwrap() + .then((res) => { + setServiceAccId(res.serviceAccountId) + setNewUserSuccess(true) + }) + .catch(() => { + showOverlay(false) + }) + setNewUserLoading(false) + } + const showOverlay = (result: boolean) => { setLoading(false) closeAndResetModalState() @@ -272,7 +319,10 @@ const EdcConnector = () => { connectorStep={addConnectorOverlayCurrentStep} handleConfirmClick={onConfirmClick} onFormConfirmClick={(data) => void onFormSubmit(data)} + onSubmitClick={(data) => void onSubmitClick(data)} loading={loading} + newUserLoading={newUserLoading} + newUserSuccess={newUserSuccess} onStepChange={onStepChange} /> ))} diff --git a/src/components/shared/frame/UserList/index.tsx b/src/components/shared/frame/UserList/index.tsx index 0a3c5caee..0e603e22f 100644 --- a/src/components/shared/frame/UserList/index.tsx +++ b/src/components/shared/frame/UserList/index.tsx @@ -52,6 +52,8 @@ export const UserList = ({ sectionTitle, addButtonLabel, addButtonClick, + addButtonDisabled, + addButtonTooltip, addMultipleButtonLabel, onMultipleButtonClick, tableLabel, @@ -65,6 +67,8 @@ export const UserList = ({ sectionTitle: string addButtonLabel: string addButtonClick: () => void + addButtonDisabled?: boolean + addButtonTooltip?: string addMultipleButtonLabel?: string onMultipleButtonClick?: () => void tableLabel: string @@ -99,6 +103,8 @@ export const UserList = ({ autoFocus={false} onButtonClick={addButtonClick} buttonLabel={t(addButtonLabel)} + buttonDisabled={addButtonDisabled} + buttonTooltip={addButtonTooltip} secondButtonLabel={addMultipleButtonLabel && t(addMultipleButtonLabel)} onSecondButtonClick={onMultipleButtonClick} toolbarVariant="premium" diff --git a/src/components/shared/templates/Templates.scss b/src/components/shared/templates/Templates.scss index 3ed9bfc09..6b47ba9d2 100644 --- a/src/components/shared/templates/Templates.scss +++ b/src/components/shared/templates/Templates.scss @@ -50,6 +50,12 @@ .subNavigationContainer button:hover { background-color: transparent !important; + box-shadow: none !important; +} + +.subNavigationContainer button:focus { + background-color: transparent !important; + box-shadow: none !important; } //tab layout diff --git a/src/features/admin/serviceApiSlice.ts b/src/features/admin/serviceApiSlice.ts index ed669bab3..b9cbd5d13 100644 --- a/src/features/admin/serviceApiSlice.ts +++ b/src/features/admin/serviceApiSlice.ts @@ -165,6 +165,10 @@ export const apiSlice = createApi({ method: 'POST', }), }), + fetchServiceAccountUsers: builder.query({ + query: () => + '/api/administration/serviceaccount/owncompany/serviceaccounts?page=0&size=10&filterForInactive=false', + }), }), }) @@ -175,4 +179,5 @@ export const { useFetchServiceAccountDetailQuery, useFetchServiceAccountRolesQuery, useResetCredentialMutation, + useFetchServiceAccountUsersQuery, } = apiSlice diff --git a/src/features/connector/connectorApiSlice.ts b/src/features/connector/connectorApiSlice.ts index f87522ff9..480ac5566 100644 --- a/src/features/connector/connectorApiSlice.ts +++ b/src/features/connector/connectorApiSlice.ts @@ -74,6 +74,11 @@ export interface OperatorBpnType { bpn: string } +export interface DecentralIdentityUrlsType { + decentralIdentityManagementServiceUrl: string + decentralIdentityManagementAuthUrl: string +} + export const apiSlice = createApi({ reducerPath: 'rtk/admin/connector', baseQuery: fetchBaseQuery(apiBaseQuery()), @@ -126,8 +131,8 @@ export const apiSlice = createApi({ return obj }, }), - fetchOperatorBpn: builder.query({ - query: () => '/api/administration/staticdata/operator-bpn', + fetchDecentralIdentityUrls: builder.query({ + query: () => 'api/administration/companydata/decentralidentity/urls', }), }), }) @@ -139,5 +144,5 @@ export const { useFetchConnectorsQuery, useFetchManagedConnectorsQuery, useFetchOfferSubscriptionsQuery, - useFetchOperatorBpnQuery, + useFetchDecentralIdentityUrlsQuery, } = apiSlice diff --git a/src/types/Config.tsx b/src/types/Config.tsx index a03bfdcad..da7cafc56 100644 --- a/src/types/Config.tsx +++ b/src/types/Config.tsx @@ -185,7 +185,7 @@ export const ALL_PAGES: IPage[] = [ }, { name: PAGES.ACCOUNT, - role: ROLES.MY_USER_ACCOUNT, + role: ROLES.MY_ACCOUNT, element: , }, { diff --git a/src/types/Constants.ts b/src/types/Constants.ts index 229270098..1c386322e 100644 --- a/src/types/Constants.ts +++ b/src/types/Constants.ts @@ -224,6 +224,7 @@ export enum ROLES { UPLOAD_COMPANY_CERTIFICATE = 'upload_certificates', VIEW_SUBSCRIPTION = 'view_subscription', DELETE_CERTIFICATES = 'delete_certificates', + MY_ACCOUNT = 'view_own_user_account', } export enum HINTS { diff --git a/src/types/Patterns.ts b/src/types/Patterns.ts index bf0cdd39d..1be0f92ed 100644 --- a/src/types/Patterns.ts +++ b/src/types/Patterns.ts @@ -88,6 +88,8 @@ export const Patterns = { connectors: { NAME: /^[^-\s()'"#@.&](?!.*[%&?,';:!\s-]{2}).{1,19}$/, COUNTRY: /^[A-Z]{2}$/, + TECHNICAL_USER_NAME: /^[A-Za-z]+[a-zA-Z0-9 =.!&#'"()]{2,80}$/, + TECHNICAL_USER_DESCRIPTION: /^[A-Za-z]+[a-zA-Z0-9 =.!&#'"()]{2,120}$/, }, CANCEL_INPUT: /^[a-z0-9 ?*%$#@!-](?=)/i, techuser: {