diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee9b6388b..075cbc74d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -33,6 +33,11 @@
- IDP Config
- Implementation of displaying metadata details
+### Feature
+
+- Onboarding Service Provider
+ - created new UI
+
## 1.8.0-RC6
### Change
diff --git a/src/assets/locales/de/registration.json b/src/assets/locales/de/registration.json
new file mode 100644
index 000000000..fc548b2a8
--- /dev/null
+++ b/src/assets/locales/de/registration.json
@@ -0,0 +1,47 @@
+{
+ "osp": {
+ "heading": "Registrierungszusammenfassung",
+ "companyHeading": "Firmendetails",
+ "companyMessage": "Unten finden Sie die Registrierungsdaten Ihres Unternehmens, die Ihnen von Ihrem Onboarding-Anbieter mitgeteilt wurden. Bitte überprüfen Sie die Details und fahren Sie mit der Auswahl der Unternehmensrolle unten fort, bevor Sie Ihre Registrierung absenden.",
+ "companyName": "Name der Firma",
+ "bmw": "BMW AG",
+ "street": "Hausnummer",
+ "zip": "Postleitzahl",
+ "city": "Stadt",
+ "region": "Region",
+ "country": "Land",
+ "companyRole": {
+ "title": "Rollenauswahl",
+ "subTitle": "Hinweis: Bitte wählen Sie mindestens eine Rolle aus und akzeptieren Sie die zugehörigen Geschäftsbedingungen.",
+ "TermsAndCondSpan1": "Ja, ich stimme den",
+ "TermsAndCondSpan2": "Geschäftsbedingungen",
+ "TermsAndCondSpan3": "der ausgewählten Rolle zu.",
+ "TermsAndCond2Span1": "Ja, ich stimme den",
+ "TermsAndCond2Span2": "Sicherheitsvorschriften",
+ "TermsAndCond2Span3": "der ausgewählten Rolle zu.",
+ "ACTIVE_PARTICIPANT": "Aktiver Teilnehmer",
+ "APP_PROVIDER": "App-Anbieter",
+ "SERVICE_PROVIDER": "Service-Anbieter",
+ "ONBOARDING_SERVICE_PROVIDER": "Onboarding-Anbieter",
+ "NoRolesError1": "Es ist ein Fehler aufgetreten. Keine Rollen gefunden.",
+ "NoRolesError2": " oder wenden Sie sich an den Systemadministrator.",
+ "NoRolesError": "Es ist ein Fehler aufgetreten. Keine Rollen gefunden. Bitte {{ retry }} oder wenden Sie sich an den Systemadministrator.",
+ "Please": "Bitte",
+ "Retry": "versuchen Sie es erneut"
+ },
+ "success": {
+ "heading": "Herzlichen Glückwunsch, Ihre Registrierung war erfolgreich!",
+ "description": "Wir werden Ihre Registrierung nun validieren. Der Vorgang kann ein paar Stunden dauern. In der Zwischenzeit haben Sie bereits die Möglichkeit sich umzusehen und einige Einführungsseiten zu besuchen. Beachten Sie jedoch bitte, dass der volle Zugang zum Dataspace erst verfügbar ist, sobald die Registrierung erfolgreich abgeschlossen wurde. Wenn Sie Fragen zum Registrierungsstatus haben, finden Sie den aktuellen Status unten.",
+ "stepTitle": "Status:",
+ "homepage": "Startseite"
+ },
+ "error": {
+ "heading": "Fehler 500: Serverfehler",
+ "description": "Auf unserer Seite ist etwas schief gelaufen. Es liegen technische Schwierigkeiten vor. Bitte versuchen Sie es in ein paar Augenblicken noch einmal. Wenn das Problem weiterhin besteht, wenden Sie sich bitte an unser Support-Team.
Alle Details und mögliche erneute Auslöser finden Sie unten:",
+ "retry": "Bestätigung erneut versuchen",
+ "back": "zurück zur vorherigen Seite"
+ },
+ "submitError": "Bitte stimmen Sie allen Geschäftsbedingungen der ausgewählten Unternehmensrolle(n) zu, bevor Sie mit dem nächsten Schritt fortfahren.",
+ "helpText": "Wenn Sie Fragen zu Ihrer Registrierung haben, wenden Sie sich bitte an unseren Helpdesk: help@catena-x.com oder an den Plattformadministrator: “xxx.xxxx@catena-x-operator.net"
+ }
+}
diff --git a/src/assets/locales/en/registration.json b/src/assets/locales/en/registration.json
new file mode 100644
index 000000000..d976d48bd
--- /dev/null
+++ b/src/assets/locales/en/registration.json
@@ -0,0 +1,47 @@
+{
+ "osp": {
+ "heading": "Registration Summary",
+ "companyHeading": "Company Details",
+ "companyMessage": "Below you can find your company registration details shared by your onboarding provider. Please review the details and proceed to the Company Role selection below before submitting your registration.",
+ "companyName": "Company Name",
+ "bmw": "BMW AG",
+ "street": "Street & Number",
+ "zip": "ZIP",
+ "city": "City",
+ "region": "Region",
+ "country": "Country",
+ "companyRole": {
+ "title": "Role Selection",
+ "subTitle": "Note: Please select at least one role and accept the associated terms and conditions.",
+ "TermsAndCondSpan1": "Yes, I agree to the",
+ "TermsAndCondSpan2": "terms and conditions",
+ "TermsAndCondSpan3": "of the selected role.",
+ "TermsAndCond2Span1": "Yes, I agree to the",
+ "TermsAndCond2Span2": "security regulations",
+ "TermsAndCond2Span3": "of the selected role.",
+ "ACTIVE_PARTICIPANT": "Active Participant",
+ "APP_PROVIDER": "App Provider",
+ "SERVICE_PROVIDER": "Service Provider",
+ "ONBOARDING_SERVICE_PROVIDER": "Onboarding Service Provider",
+ "NoRolesError1": "An error occured. No roles found.",
+ "NoRolesError2": " or contact the system administrator.",
+ "NoRolesError": "An error occured. No roles found. Please {{ retry }} or contact the system administrator.",
+ "Please": "Please",
+ "Retry": "retry"
+ },
+ "success": {
+ "heading": "Congratulations, your registration has been successfull!",
+ "description": "We will now validate your registration. The process might take a couple of hours, in the meantime you might wanna check out some introduction pages already, but note that the complete dataspace functions will only be available as soon as the registration is successfully finished. If you are corrious about the registration state, you can find the current status below.",
+ "stepTitle": "Status:",
+ "homepage": "Get to home"
+ },
+ "error": {
+ "heading": "Error 500 : Server Error",
+ "description": "Something went wrong on our side. We’re experiencing technical difficulities. Please try the call once again in a couple of moments. If the problem persists, feel free to reach out to our support team for assistance.
All details and possible retriggers are shared below:",
+ "retry": "Retry confirmation",
+ "back": "Back to previous page"
+ },
+ "submitError": "Please agree to all Terms & Conditions of the selected company role(s) before proceeding to the next step.",
+ "helpText": "If you have any questions regarding your registration please contact our helpdesk: help@catena-x.com or contact the platform administrator: “xxx.xxxx@catena-x-operator.net"
+ }
+}
diff --git a/src/components/Main.tsx b/src/components/Main.tsx
index 7623e8bdf..1f7a77692 100644
--- a/src/components/Main.tsx
+++ b/src/components/Main.tsx
@@ -28,7 +28,7 @@ import { useTranslation } from 'react-i18next'
import AccessService from '../services/AccessService'
import MainOverlay from './MainOverlay'
import { show } from 'features/control/overlay'
-import { OVERLAYS, PAGES } from 'types/Constants'
+import { type OVERLAYS, PAGES } from 'types/Constants'
import MainNotify from './MainNotify'
import MainSearchOverlay from './shared/frame/SearchOverlay'
import { MenuInfo } from './pages/Home/components/MenuInfo'
@@ -41,6 +41,7 @@ import './styles/main.scss'
import RegistrationStatus from './pages/RegistrationStatus'
import Logout from './pages/Logout'
import Redirect from './actions/Redirect'
+import { OSPConsent } from './pages/OSPConsent'
export default function Main() {
document.title = useTranslation().t('title')
@@ -50,6 +51,14 @@ export default function Main() {
const { data, isLoading } = useFetchApplicationsQuery()
const companyData = data?.[0]
+ const renderSection = () => {
+ return companyData?.applicationType === ApplicationType.INTERNAL ? (
+
+ ) : (
+
+ )
+ }
+
useEffect(() => {
const overlay = searchParams.get('overlay')?.split(':')
overlay && dispatch(show(overlay[0] as OVERLAYS, overlay[1]))
@@ -70,21 +79,15 @@ export default function Main() {
].includes(companyData.applicationStatus) &&
!location.search.includes('overlay=consent_osp')
) {
- if (companyData.applicationType === ApplicationType.INTERNAL) {
- return (
- <>
-
-
- {window.location.pathname === '/logout' ? (
-
- ) : (
-
- )}
-
-
- >
- )
- } else dispatch(show(OVERLAYS.CONSENT_OSP))
+ return (
+ <>
+
+
+ {location.pathname === '/logout' ? : renderSection()}
+
+
+ >
+ )
}
return (
diff --git a/src/components/pages/OSPConsent/CompanyDetails.tsx b/src/components/pages/OSPConsent/CompanyDetails.tsx
new file mode 100644
index 000000000..e1153a5c0
--- /dev/null
+++ b/src/components/pages/OSPConsent/CompanyDetails.tsx
@@ -0,0 +1,306 @@
+/********************************************************************************
+ * Copyright (c) 2021, 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 { Trans, useTranslation } from 'react-i18next'
+import { useMediaQuery, useTheme } from '@mui/material'
+import { uniqueId } from 'lodash'
+import {
+ StaticTable,
+ type TableType,
+ Typography,
+ Button,
+ Checkbox,
+ LoadingButton,
+} from '@catena-x/portal-shared-components'
+import {
+ useFetchCompanyDetailsWithAddressQuery,
+ useFetchAgreementDataQuery,
+ type companyRole,
+ useFetchAgreementConsentsQuery,
+ type AgreementData,
+} from 'features/registration/registrationApiSlice'
+import { getApiBase } from 'services/EnvironmentService'
+import UserService from 'services/UserService'
+import { download } from 'utils/downloadUtils'
+import './style.scss'
+
+interface CompanyDetailsProps {
+ applicationId: string
+ loading: boolean
+ handleSubmit: () => void
+ submitError: boolean
+}
+
+export const CompanyDetails = ({
+ applicationId,
+ loading,
+ handleSubmit,
+ submitError,
+}: CompanyDetailsProps) => {
+ const tm = useTranslation().t
+ const { t } = useTranslation('registration')
+ const theme = useTheme()
+ const isMobile = useMediaQuery(theme.breakpoints.down('md'), {
+ defaultMatches: true,
+ })
+
+ const [companyRoleChecked, setCompanyRoleChecked] = useState<{
+ [key: string]: boolean
+ }>({})
+ const [agreementChecked, setAgreementChecked] = useState<{
+ [key: string]: boolean
+ }>({})
+
+ const { data: companyDetails } = useFetchCompanyDetailsWithAddressQuery(
+ applicationId ?? ''
+ )
+ const { data: allConsentData } = useFetchAgreementDataQuery()
+ const { data: consentData } = useFetchAgreementConsentsQuery(
+ applicationId ?? ''
+ )
+
+ useEffect(() => {
+ updateSelectedRolesAndAgreement()
+ }, [consentData])
+
+ const updateSelectedRolesAndAgreement = () => {
+ consentData &&
+ setCompanyRoleChecked(
+ consentData?.companyRoles.reduce((prev, next) => {
+ return { ...prev, [next]: true }
+ }, {})
+ )
+
+ consentData &&
+ setAgreementChecked(
+ consentData?.agreements.reduce((prev, next) => {
+ return { ...prev, [next.agreementId]: true }
+ }, {})
+ )
+ }
+
+ const handleAgreementCheck = (id: string) => {
+ const updatedMap = { ...agreementChecked }
+ updatedMap[id] = !updatedMap[id]
+ setAgreementChecked(updatedMap)
+ }
+
+ const handleCompanyRoleCheck = (id: string) => {
+ const updatedMap = { ...companyRoleChecked }
+ updatedMap[id] = !updatedMap[id]
+
+ if (!updatedMap[id]) {
+ const companyRoleIndex =
+ allConsentData?.companyRoles.findIndex(
+ (item) => item.companyRole === id
+ ) ?? 0
+
+ const updatedAgreementIds = allConsentData?.companyRoles[
+ companyRoleIndex
+ ].agreementIds.reduce((prev: {}, next: string) => {
+ return { ...prev, [next]: false }
+ }, {})
+
+ setAgreementChecked((prevState: { [key: string]: boolean }) => ({
+ ...prevState,
+ ...updatedAgreementIds,
+ }))
+ }
+
+ setCompanyRoleChecked(updatedMap)
+ }
+
+ const handleDownloadClick = (documentId: string, documentName: string) => {
+ if (!documentId) return
+ try {
+ fetch(
+ `${getApiBase()}/api/registration/registrationDocuments/${documentId}`,
+ {
+ method: 'GET',
+ headers: {
+ authorization: `Bearer ${UserService.getToken()}`,
+ },
+ }
+ )
+ .then(async (res) => {
+ const fileType = res.headers.get('content-type') ?? ''
+ const file = await res.blob()
+ download(file, fileType, documentName)
+ })
+ .catch((error) => {
+ console.log(error)
+ })
+ } catch (error) {
+ console.error(error, 'ERROR WHILE FETCHING DOCUMENT')
+ }
+ }
+
+ const renderTermsText = (agreement: AgreementData) => {
+ return (
+ <>
+ {t('osp.companyRole.TermsAndCondSpan1')}
+ {
+ handleDownloadClick(agreement.documentId, agreement.name)
+ }}
+ onKeyDown={() => {
+ // do nothing
+ }}
+ >
+ {agreement.name}
+ {' '}
+ {t('osp.companyRole.TermsAndCondSpan3')}
+ >
+ )
+ }
+
+ const renderTermsSection = (role: companyRole) => {
+ if (role.agreementIds.length === 0) return null
+ return (
+