diff --git a/CHANGELOG.md b/CHANGELOG.md index d6bf70349..8ecb96b18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +### Feature + +- **Clearinghouse Self-Description** + - Admin UI for Managing SD Document Retriggering [#1141](https://github.com/eclipse-tractusx/portal-frontend/pull/1141) + ### Technical Support - **Injection of environment variables to Docker image** diff --git a/src/assets/locales/de/main.json b/src/assets/locales/de/main.json index a2721ea37..f193e4f1e 100644 --- a/src/assets/locales/de/main.json +++ b/src/assets/locales/de/main.json @@ -624,7 +624,7 @@ "configureYourConnectorDetails": "Konfigurieren Sie die Connector-Details", "learnMore": "Learn More", "noDocumentAvailable": "Kein Dokument verfügbar", - "selfDescriptionDocument": "Selbstbeschreibungsdokument", + "selfDescriptionDocument": "Eigenerklärungsdokument", "deleteConnector": "Connector löschen", "urlUpdatedSuccessfully": "URL erfolgreich aktualisiert", "note": "Bitte beachten Sie:", @@ -676,7 +676,7 @@ "deletemodal": { "title": "EDC-Connector Löschen", "description": "Möchten Sie den ausgewählten Connector wirklich löschen? Die Löschung kann nicht rückgängig gemacht werden.", - "techUserdescription": "Möchten Sie den Connector wirklich löschen? Mit der Löschung wird der Connector automatisch vom Endpunkt „Connector Discovery“ gelöscht und das Selbstbeschreibungsdokument auf inaktiv gesetzt.\n Bitte beachten Sie, dass mit dem Connector ein technischer Benutzer verbunden ist. Der technische Benutzer kann gelöscht werden, wenn Sie das Kontrollkästchen unten aktivieren. Andernfalls wird nur die Zuordnung zwischen Connector und technischem Benutzer gelöscht.", + "techUserdescription": "Möchten Sie den Connector wirklich löschen? Mit der Löschung wird der Connector automatisch vom Endpunkt „Connector Discovery“ gelöscht und das Eigenerklärungsdokument auf inaktiv gesetzt.\n Bitte beachten Sie, dass mit dem Connector ein technischer Benutzer verbunden ist. Der technische Benutzer kann gelöscht werden, wenn Sie das Kontrollkästchen unten aktivieren. Andernfalls wird nur die Zuordnung zwischen Connector und technischem Benutzer gelöscht.", "techUserCheckBoxLabel": "Ja, ich möchte den Connector löschen, wodurch automatisch auch der erwähnte technische Benutzer gelöscht wird.", "techDetails": { "title": "Technical Details", @@ -1066,6 +1066,18 @@ "metadata_url_required_error": "Metadaten-URL ist erforderlich", "metadata_url_invalid_error": "Bitte geben Sie eine gültige Metadaten-URL ein" }, + "clearinghouseSelfDescription": { + "heading": "Status der Eigenerklärung", + "description": "Diese Seite bietet einen Überblick über den aktuellen Stand der Eigenerklärungen für Administratoren.", + "reprocess": "Nachverarbeiten", + "complianceStatus": "Compliance-Status:", + "legalPerson": "Juristische Person", + "legalPersonDesc": "Übersicht über Unternehmen mit fehlender Eigenerklärung einer juristischen Person", + "connectors": "Connectors", + "connectorsDesc": "Übersicht über Unternehmen mit fehlender Eigenerklärung der Konnektoren", + "errorMsg": "Fehler! Etwas ist schief gelaufen", + "noDataMsg": "Keine Datensätze gefunden." + }, "addUser": { "headline": "Erstelle einen neuen User", "subheadline": "Fügen Sie ein neues Benutzerkonto hinzu, indem Sie den Vor- und Nachnamen des Benutzers sowie die E-Mail-Adresse hinterlegen. Wählen Sie unterhalb der Eingabefelder die jeweiligen Benutzerrollen aus, die der Benutzer haben soll. Eine Rolle ist mindestens erforderlich, um dem Benutzer den Zugriff auf das Netzwerk zu ermöglichen.", @@ -1842,7 +1854,7 @@ }, "SKIPPED": { "title": "Von Ihrer Seite sind keine Maßnahmen erforderlich", - "description": "Die Erstellung der Selbstbeschreibung wurde absichtlich übersprungen. Dieser Prozess wird vom CX-Operator so bald wie möglich wieder ausgelöst." + "description": "Die Erstellung der Eigenerklärung wurde absichtlich übersprungen. Dieser Prozess wird vom CX-Operator so bald wie möglich wieder ausgelöst." } } }, diff --git a/src/assets/locales/en/main.json b/src/assets/locales/en/main.json index b03a4f90e..2a7e6ea43 100644 --- a/src/assets/locales/en/main.json +++ b/src/assets/locales/en/main.json @@ -21,6 +21,7 @@ "technicalSetup": "Technical Integration", "connectorManagement": "Connector Management", "applicationRequests": "Application Requests", + "clearinghouseSelfDescription": "Clearinghouse Self-Description", "admin": "Administration", "developer": "Development", "invite": "Invite Business Partner", @@ -1070,6 +1071,18 @@ "metadata_url_required_error": "Metadata url is required", "metadata_url_invalid_error": "Please enter valid metadata url" }, + "clearinghouseSelfDescription": { + "heading": "Self-Description Document Status", + "description": "This page provides an overview of the current status of self-descriptions for administrators.", + "reprocess": "Reprocess", + "complianceStatus": "Compliance Status:", + "legalPerson": "Legal Person", + "legalPersonDesc": "Overview of companies with missing legal person self-description", + "connectors": "Connectors", + "connectorsDesc": "Overview of companies with missing connector self-description", + "errorMsg": "Error! Something went wrong", + "noDataMsg": "No records found." + }, "addUser": { "headline": "Add User Account", "subheadline": "Add a new user account by adding the user first and last name as well as the email address. Below the input fields select the respective user roles which the user should have. One role is minimum needed to enable the user to access the network.", diff --git a/src/components/pages/AdminClearingHouseSD/AdminClearingHouseSD.scss b/src/components/pages/AdminClearingHouseSD/AdminClearingHouseSD.scss new file mode 100644 index 000000000..5734acbbd --- /dev/null +++ b/src/components/pages/AdminClearingHouseSD/AdminClearingHouseSD.scss @@ -0,0 +1,107 @@ +/******************************************************************************** + * Copyright (c) 2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +.admin-container { + padding: 50px 15px; + + .loading-progress { + display: flex; + justify-content: center; + align-items: center; + height: 50vh; + } + + .heading { + text-align: center; + } + + .description { + text-align: center; + margin: 34px auto 64px; + width: 70%; + } + + .company-list-container { + max-height: 350px; + overflow-y: auto; + scrollbar-width: none; + -ms-overflow-style: none; + } + + .section { + margin-bottom: 20px; + + ul { + margin-top: 24px; + list-style-type: none; + padding-left: 0; + + li { + margin-bottom: 5px; + } + } + + .connectors-list { + gap: 10px; + margin-top: 24px; + max-height: 350px; + overflow-y: auto; + scrollbar-width: none; + -ms-overflow-style: none; + + .connector { + display: flex; + gap: 80px; + padding: 5px; + border-radius: 5px; + } + } + + .btn-container { + display: flex; + margin-top: 20px; + align-items: flex-end; + justify-content: flex-end; + } + } + + .compliance-status { + display: flex; + align-items: center; + margin-bottom: 40px; + margin-top: 50px; + + label { + margin-right: 10px; + font-weight: bold; + } + + .switch-container { + display: flex; + align-items: center; + margin-left: 5px; + } + } + + .no-data-msg { + text-align: center; + margin-top: 24px; + margin-bottom: 24px; + } +} diff --git a/src/components/pages/AdminClearingHouseSD/AdminClearingHouseSDElements.tsx b/src/components/pages/AdminClearingHouseSD/AdminClearingHouseSDElements.tsx new file mode 100644 index 000000000..f37786ad9 --- /dev/null +++ b/src/components/pages/AdminClearingHouseSD/AdminClearingHouseSDElements.tsx @@ -0,0 +1,350 @@ +/******************************************************************************** + * Copyright (c) 2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +import { useEffect, useState } from 'react' +import './AdminClearingHouseSD.scss' +import { Trans } from 'react-i18next' +import { t } from 'i18next' +import { + Button, + CircleProgress, + ToggleSwitch, + Typography, +} from '@catena-x/portal-shared-components' +import { + type ComapnyDataType, + useFetchCompanyDataQuery, + useFetchConnectorsQuery, + useTriggerCompanyDataMutation, + useTriggerConnectorsMutation, + PAGE_SIZE, +} from 'features/adminClearingHouseSD/adminClearingHouseSDApiSlice' +import { error } from 'services/NotifyService' +import { isClearinghouseConnectDisabled } from 'services/EnvironmentService' + +const AdminclearinghouseSDElements = () => { + const [checked, setChecked] = useState(isClearinghouseConnectDisabled()) + const [triggerCompanyData] = useTriggerCompanyDataMutation() + const [triggerConnectors] = useTriggerConnectorsMutation() + const [triggerCDLoading, setTriggerCDLoading] = useState(false) + const [triggerConnectorsLoading, setTriggerConnectorsLoading] = + useState(false) + const [currentCompanyPage, setCurrentCompanyPage] = useState(0) + const [currentConnectorPage, setCurrentConnectorPage] = useState(0) + const [isFetchingMoreCompanies, setIsFetchingMoreCompanies] = useState(false) + const [isFetchingMoreConnectors, setIsFetchingMoreConnectors] = + useState(false) + + const handleChange = (newChecked: boolean) => { + setChecked(newChecked) + } + + const { + data: companyData, + isFetching: isFetchingCompanyData, + refetch: refetchCompanyData, + } = useFetchCompanyDataQuery({ page: currentCompanyPage }) + + const { + data: connectors, + isFetching: isFetchingConnectors, + refetch: refetchConnectors, + } = useFetchConnectorsQuery({ page: currentConnectorPage }) + + const isCompanyDataAvailable = + !isFetchingCompanyData && (companyData?.content?.length ?? 0) > 0 + const isConnectorsDataAvailable = + !isFetchingConnectors && (connectors?.content?.length ?? 0) > 0 + + // Load more companies + const loadMoreCompanies = () => { + if ( + !isFetchingMoreCompanies && + (companyData?.meta?.page ?? 0) < (companyData?.meta?.totalPages ?? 1) - 1 + ) { + const currentItemCount = companyData?.content?.length ?? 0 + if (currentItemCount % PAGE_SIZE === 0) { + setIsFetchingMoreCompanies(true) + setCurrentCompanyPage((prev) => prev + 1) + } + } + } + + // Load more connectors + const loadMoreConnectors = () => { + if ( + !isFetchingMoreConnectors && + (connectors?.meta?.page ?? 0) < (connectors?.meta?.totalPages ?? 1) - 1 + ) { + const currentItemCount = connectors?.content?.length ?? 0 + if (currentItemCount % PAGE_SIZE === 0) { + setIsFetchingMoreConnectors(true) + setCurrentConnectorPage((prev) => prev + 1) + } + } + } + + useEffect(() => { + if (isFetchingMoreCompanies) { + refetchCompanyData().then(() => { + setIsFetchingMoreCompanies(false) + }) + } + }, [currentCompanyPage, isFetchingMoreCompanies]) + + useEffect(() => { + if (isFetchingMoreConnectors) { + refetchConnectors().then(() => { + setIsFetchingMoreConnectors(false) + }) + } + }, [currentConnectorPage, isFetchingMoreConnectors]) + + // Scroll event to load more data for company list + useEffect(() => { + const companyContainer = document.querySelector('.company-list-container') + + const handleCompanyScroll = () => { + if (companyContainer) { + const bottom = + companyContainer.scrollTop + companyContainer.clientHeight >= + companyContainer.scrollHeight - 10 + + if (bottom) { + loadMoreCompanies() + } + } + } + + companyContainer?.addEventListener('scroll', handleCompanyScroll) + + return () => + companyContainer?.removeEventListener('scroll', handleCompanyScroll) + }, [companyData]) + + // Scroll event to load more data for connector list + useEffect(() => { + const connectorContainer = document.querySelector('.connectors-list') + + const handleConnectorScroll = () => { + if (connectorContainer) { + const bottom = + connectorContainer.scrollHeight - connectorContainer.scrollTop <= + connectorContainer.clientHeight + 10 + if (bottom) { + loadMoreConnectors() + } + } + } + + connectorContainer?.addEventListener('scroll', handleConnectorScroll) + + return () => + connectorContainer?.removeEventListener('scroll', handleConnectorScroll) + }, [connectors]) + + const handleTriggerCompanyData = async () => { + setTriggerCDLoading(true) + try { + await triggerCompanyData().unwrap() + refetchCompanyData() + setTriggerCDLoading(false) + } catch (err) { + setTriggerCDLoading(false) + error( + t('content.clearinghouseSelfDescription.errorMsg'), + '', + err as object + ) + } + } + + const handleTriggerConnectors = async () => { + setTriggerConnectorsLoading(true) + try { + await triggerConnectors().unwrap() + refetchConnectors() + setTriggerConnectorsLoading(false) + } catch (err) { + setTriggerConnectorsLoading(false) + error( + t('content.clearinghouseSelfDescription.errorMsg'), + '', + err as object + ) + } + } + + const renderCompanyDataContent = () => { + return ( + <> + {isCompanyDataAvailable ? ( + + ) : ( + + {t('content.clearinghouseSelfDescription.noDataMsg')} + + )} + + ) + } + + const renderConnectorsContent = () => { + return ( + <> + {isConnectorsDataAvailable ? ( +
+ {connectors?.content?.map((connector) => ( +
+ {connector?.name} + {connector?.companyName} +
+ ))} +
+ ) : ( + + {t('content.clearinghouseSelfDescription.noDataMsg')} + + )} + + ) + } + + return ( +
+ + {t('content.clearinghouseSelfDescription.heading')} + + + + {t('content.clearinghouseSelfDescription.description')} + + + +
+ + {t('content.clearinghouseSelfDescription.complianceStatus')} + + +
+ +
+
+ +
+ + {t('content.clearinghouseSelfDescription.legalPerson')} + + + {t('content.clearinghouseSelfDescription.legalPersonDesc')} + + {isFetchingCompanyData ? ( +
+ +
+ ) : ( + renderCompanyDataContent() + )} +
+ +
+
+ +
+ + {t('content.clearinghouseSelfDescription.connectors')} + + + {t('content.clearinghouseSelfDescription.connectorsDesc')} + + + {isFetchingConnectors ? ( +
+ +
+ ) : ( + renderConnectorsContent() + )} +
+ +
+
+
+ ) +} + +export default AdminclearinghouseSDElements diff --git a/src/components/pages/AdminClearingHouseSD/index.tsx b/src/components/pages/AdminClearingHouseSD/index.tsx new file mode 100644 index 000000000..6343b20f1 --- /dev/null +++ b/src/components/pages/AdminClearingHouseSD/index.tsx @@ -0,0 +1,32 @@ +/******************************************************************************** + * Copyright (c) 2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +import AdminclearinghouseSDElements from './AdminClearingHouseSDElements' + +export default function AdminclearinghouseSD() { + return ( +
+
+
+ +
+
+
+ ) +} diff --git a/src/features/adminClearingHouseSD/adminClearingHouseSDApiSlice.tsx b/src/features/adminClearingHouseSD/adminClearingHouseSDApiSlice.tsx new file mode 100644 index 000000000..c7d3aaaa3 --- /dev/null +++ b/src/features/adminClearingHouseSD/adminClearingHouseSDApiSlice.tsx @@ -0,0 +1,97 @@ +/******************************************************************************** + * Copyright (c) 2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' +import { apiBaseQuery } from 'utils/rtkUtil' + +export const PAGE_SIZE = 15 + +export type PaginationData = { + totalElements: number + page: number + totalPages: number +} + +export type ComapnyDataType = { + companyId: string + name: string +} + +export type ConnectorsType = { + connectorId: string + name: string + companyId: string + companyName: string +} + +export type CompanyDataResponse = { + content: Array + meta: PaginationData +} + +export interface CompanyDataRequestType { + page: number +} + +export type ConnectorsResponse = { + content: Array + meta: PaginationData +} + +export interface ConnectorsRequestType { + page: number +} + +export const apiSlice = createApi({ + reducerPath: 'rtk/admin/clearingHouseSD', + baseQuery: fetchBaseQuery(apiBaseQuery()), + endpoints: (builder) => ({ + fetchCompanyData: builder.query< + CompanyDataResponse, + CompanyDataRequestType + >({ + query: ({ page }) => + `/api/administration/companyData/missing-sd-document?page=${page}&size=${PAGE_SIZE}`, + keepUnusedDataFor: 5, + }), + fetchConnectors: builder.query({ + query: ({ page }) => + `/api/administration/connectors/missing-sd-document?page=${page}&size=${PAGE_SIZE}`, + }), + triggerCompanyData: builder.mutation({ + query: () => ({ + url: '/api/administration/companyData/trigger-self-description', + method: 'POST', + }), + }), + triggerConnectors: builder.mutation({ + query: () => ({ + url: '/api/administration/connectors/trigger-self-description', + method: 'POST', + }), + }), + }), +}) + +export const { + useFetchConnectorsQuery, + useFetchCompanyDataQuery, + useTriggerCompanyDataMutation, + useTriggerConnectorsMutation, +} = apiSlice diff --git a/src/features/store.ts b/src/features/store.ts index 0c44cc82c..3145ed305 100644 --- a/src/features/store.ts +++ b/src/features/store.ts @@ -51,6 +51,7 @@ import { apiSlice as serviceMarketplaceApiSlice } from './serviceMarketplace/ser import { apiSlice as serviceProviderApiSlice } from './serviceProvider/serviceProviderApiSlice' import { apiSlice as appSubscriptionApiSlice } from './appSubscription/appSubscriptionApiSlice' import { apiSlice as adminBoardApiSlice } from './adminBoard/adminBoardApiSlice' +import { apiSlice as adminClearingHouseSDApiSlice } from './adminClearingHouseSD/adminClearingHouseSDApiSlice' import { apiSlice as inviteApiSlice } from './admin/inviteApiSlice' import { apiSlice as networkApiSlice } from './admin/networkApiSlice' import { apiSlice as applicationRequestApiSlice } from './admin/applicationRequestApiSlice' @@ -110,6 +111,8 @@ export const reducers = { [serviceProviderApiSlice.reducerPath]: serviceProviderApiSlice.reducer, [appSubscriptionApiSlice.reducerPath]: appSubscriptionApiSlice.reducer, [adminBoardApiSlice.reducerPath]: adminBoardApiSlice.reducer, + [adminClearingHouseSDApiSlice.reducerPath]: + adminClearingHouseSDApiSlice.reducer, [inviteApiSlice.reducerPath]: inviteApiSlice.reducer, [networkApiSlice.reducerPath]: networkApiSlice.reducer, [applicationRequestApiSlice.reducerPath]: applicationRequestApiSlice.reducer, @@ -148,6 +151,7 @@ export const store = configureStore({ .concat(serviceProviderApiSlice.middleware) .concat(appSubscriptionApiSlice.middleware) .concat(adminBoardApiSlice.middleware) + .concat(adminClearingHouseSDApiSlice.middleware) .concat(inviteApiSlice.middleware) .concat(networkApiSlice.middleware) .concat(applicationRequestApiSlice.middleware) diff --git a/src/services/EnvironmentService.ts b/src/services/EnvironmentService.ts index af8b34c6b..5fe93a9ff 100644 --- a/src/services/EnvironmentService.ts +++ b/src/services/EnvironmentService.ts @@ -19,11 +19,11 @@ declare const ENV: Record -export const getRequireHttpsUrlPattern = () => - ENV.REQUIRE_HTTPS_URL_PATTERN ?? 'true' +export const isRequireHttpsUrlPattern = () => + ENV.REQUIRE_HTTPS_URL_PATTERN !== 'false' -export const getClearinghouseConnectDisabled = () => - ENV.CLEARINGHOUSE_CONNECT_DISABLED ?? 'false' +export const isClearinghouseConnectDisabled = () => + ENV.CLEARINGHOUSE_CONNECT_DISABLED === 'true' export const getRealm = () => ENV.REALM ?? '' @@ -58,8 +58,8 @@ export const getMiwBase = () => ENV.MANAGED_IDENTITY_WALLETS_NEW_URL ?? '' export const getSSICredentialBase = () => ENV.SSI_CREDENTIAL_URL ?? '' const EnvironmentService = { - getRequireHttpsUrlPattern, - getClearinghouseConnectDisabled, + isRequireHttpsUrlPattern, + isClearinghouseConnectDisabled, getRealm, getClientId, getClientIdRegistration, diff --git a/src/types/Config.tsx b/src/types/Config.tsx index ec79e4e27..aba7be626 100644 --- a/src/types/Config.tsx +++ b/src/types/Config.tsx @@ -95,6 +95,7 @@ import { userHasSsiCredentialRole, } from 'services/AccessService' import OnboardingServiceProvider from 'components/pages/OnboardingServiceProvider/OnboardingServiceProvider' +import AdminclearinghouseSD from 'components/pages/AdminClearingHouseSD' /** * ALL_PAGES @@ -397,6 +398,11 @@ export const ALL_PAGES: IPage[] = [ allowTo: () => userHasPortalRole(ROLES.SUBMITTED_APPLICATION), element: , }, + { + name: PAGES.CLEARINGHOUSE_SELF_DESCRIPTION, + allowTo: () => userHasPortalRole(ROLES.APPROVE_NEW_PARTNER), + element: , + }, { name: PAGES.CONTACT, element: }, { name: PAGES.IMPRINT, element: }, { name: PAGES.PRIVACY, element: }, @@ -830,6 +836,7 @@ export const userMenuFull = [ PAGES.IDP_MANAGEMENT, PAGES.CONNECTOR_MANAGEMENT, PAGES.APPLICATION_REQUESTS, + PAGES.CLEARINGHOUSE_SELF_DESCRIPTION, PAGES.INVITE, PAGES.COMPANY_ROLE, PAGES.USECASE_PARTICIPATION, @@ -850,6 +857,7 @@ export const userMenuCompany = [ PAGES.IDP_MANAGEMENT, PAGES.CONNECTOR_MANAGEMENT, PAGES.APPLICATION_REQUESTS, + PAGES.CLEARINGHOUSE_SELF_DESCRIPTION, PAGES.INVITE, PAGES.COMPANY_ROLE, PAGES.USECASE_PARTICIPATION, diff --git a/src/types/Constants.ts b/src/types/Constants.ts index 0a1ede6c5..3f3628bb0 100644 --- a/src/types/Constants.ts +++ b/src/types/Constants.ts @@ -49,6 +49,7 @@ export enum PAGES { TECH_USER_DETAILS = 'techUserDetails', IDP_MANAGEMENT = 'idpManagement', APPLICATION_REQUESTS = 'applicationRequests', + CLEARINGHOUSE_SELF_DESCRIPTION = 'clearinghouseSelfDescription', APP_USER_MANAGEMENT = 'appUserManagement', INVITE = 'invite', ADMINISTRATION = 'admin', @@ -233,6 +234,7 @@ export enum ROLES { REVOKE_CREDENTIALS_ISSUER = 'revoke_credentials_issuer', VIEW_REGISTRATION = 'view_registration', READ_PARTNER = 'read_partner', + APPROVE_NEW_PARTNER = 'approve_new_partner', CONFIGURE_PARTNER_REGISTRATION = 'configure_partner_registration', } diff --git a/src/types/Patterns.ts b/src/types/Patterns.ts index 168946180..5449c77bd 100644 --- a/src/types/Patterns.ts +++ b/src/types/Patterns.ts @@ -18,16 +18,13 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -import { getRequireHttpsUrlPattern } from '../services/EnvironmentService' - -// check the REQUIRE_HTTPS_URL_PATTERN environment variable, defaulting to !== 'false' if not set -const requireHttpsUrlPattern = getRequireHttpsUrlPattern() !== 'false' +import { isRequireHttpsUrlPattern } from '../services/EnvironmentService' const DOMAIN = /([a-z0-9]|[a-z0-9][a-z0-9-]{0,61}[a-z0-9])(\.([a-z0-9]|[a-z0-9][a-z0-9-]{0,61}[a-z0-9])){1,10}/i const URLPATH = /(\/[a-z0-9-._~:/?#[\]@!$&'()*+,;=%]{0,500}){0,20}/ // construct regex patterns for URL based on the REQUIRE_HTTPS_URL_PATTERN environment variable -const urlProtocol = requireHttpsUrlPattern ? 'https' : 'https?' +const urlProtocol = isRequireHttpsUrlPattern() ? 'https' : 'https?' const urlPattern = new RegExp( `^(${urlProtocol})://(${DOMAIN.source})(:\\d{1,5})?(${URLPATH.source})?$`, 'i'