diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c9310441c..8d4cbaa51 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -89,7 +89,7 @@ jobs: type=raw,value=${{ github.sha }} - name: Build and push Docker image - uses: docker/build-push-action@16ebe778df0e7752d2cfcbd924afdbbd89c1a755 # v6.6.1 + uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 with: context: . file: .conf/Dockerfile.prebuilt diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f1cfa7edb..8b12ca748 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -75,7 +75,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa # v2.227 + uses: github/codeql-action/init@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v2.227 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -89,7 +89,7 @@ jobs: # Automates dependency installation for Python, Ruby, and JavaScript, optimizing the CodeQL analysis setup. # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa # v2.227 + uses: github/codeql-action/autobuild@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v2.227 # ℹ️ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -102,6 +102,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa # v2.227 + uses: github/codeql-action/analyze@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v2.227 with: category: '/language:${{matrix.language}}' diff --git a/.github/workflows/dependencies.yaml b/.github/workflows/dependencies.yaml index bd73e7a17..7f9c4396f 100644 --- a/.github/workflows/dependencies.yaml +++ b/.github/workflows/dependencies.yaml @@ -65,7 +65,7 @@ jobs: if: steps.dependencies-changed.outputs.changed == 'true' - name: Upload DEPENDENCIES file - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: path: DEPENDENCIES if: steps.dependencies-changed.outputs.changed == 'true' diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 2bfe68a5b..89ea9a7e4 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -45,7 +45,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: KICS scan - uses: checkmarx/kics-github-action@252e73959bd4809a14863cbfbb42d7a90d5a4860 # v2.1.1 + uses: checkmarx/kics-github-action@530ac1f8efe6202b0f12c9a6e952597ae707b755 # v2.1.2 with: # Scanning directory . path: '.' @@ -67,6 +67,6 @@ jobs: # Upload findings to GitHub Advanced Security Dashboard - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa # v3.26.0 + uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/release-release_candidate.yml b/.github/workflows/release-release_candidate.yml index f06587034..d3ad2ff0e 100644 --- a/.github/workflows/release-release_candidate.yml +++ b/.github/workflows/release-release_candidate.yml @@ -111,7 +111,7 @@ jobs: type=semver,pattern=v{{major}}.{{minor}} - name: Build and push Docker image - uses: docker/build-push-action@16ebe778df0e7752d2cfcbd924afdbbd89c1a755 # v6.6.1 + uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 with: context: . file: .conf/Dockerfile.prebuilt diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cceeb24a5..48ce0e90a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -112,7 +112,7 @@ jobs: type=semver,pattern=v{{major}}.{{minor}} - name: Build and push Docker image - uses: docker/build-push-action@16ebe778df0e7752d2cfcbd924afdbbd89c1a755 # v6.6.1 + uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 with: context: . file: .conf/Dockerfile.prebuilt diff --git a/.github/workflows/release_candidate.yml b/.github/workflows/release_candidate.yml index 1d40771b5..bfec1ede7 100644 --- a/.github/workflows/release_candidate.yml +++ b/.github/workflows/release_candidate.yml @@ -86,7 +86,7 @@ jobs: type=raw,value=${{ github.sha }} - name: Build and push Docker image - uses: docker/build-push-action@16ebe778df0e7752d2cfcbd924afdbbd89c1a755 # v6.6.1 + uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 with: context: . file: .conf/Dockerfile.prebuilt diff --git a/.github/workflows/trivy-main.yml b/.github/workflows/trivy-main.yml index 48e934c93..77ff0b96f 100644 --- a/.github/workflows/trivy-main.yml +++ b/.github/workflows/trivy-main.yml @@ -63,7 +63,7 @@ jobs: vuln-type: 'os,library' - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa # v3.26.0 + uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 if: always() with: sarif_file: 'trivy-results1.sarif' @@ -96,6 +96,6 @@ jobs: - name: Upload Trivy scan results to GitHub Security tab if: always() - uses: github/codeql-action/upload-sarif@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa # v3.26.0 + uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 with: sarif_file: 'trivy-results2.sarif' diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index 09b306425..09d2dd01f 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -63,7 +63,7 @@ jobs: vuln-type: 'os,library' - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa # v3.26.0 + uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 if: always() with: sarif_file: 'trivy-results1.sarif' @@ -96,6 +96,6 @@ jobs: - name: Upload Trivy scan results to GitHub Security tab if: always() - uses: github/codeql-action/upload-sarif@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa # v3.26.0 + uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 with: sarif_file: 'trivy-results2.sarif' diff --git a/CHANGELOG.md b/CHANGELOG.md index 1454fc9e7..3088bc5f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,43 @@ # Changelog +## Unreleased + +### Feature + +- **Customer Detail Data Overlay** + - implement new UI design for customer detail data overlay +- **Company Subscription Management** + - extended the subscription detail page for customer to include more app-related information [#1051](https://github.com/eclipse-tractusx/portal-frontend/pull/1051) + +### Change + +- **Company Subscriptions** + - Update and bind API with filter options [#1062](https://github.com/eclipse-tractusx/portal-frontend/pull/1062) + +### Bugfixes + +- **Connector Management** + - fixed technical user selection +- **IDP management** + - Fixed IDP management page title & description +- **Technical User** + - Show appropriate error message. + - Fix closing page notification bar issue +- **IDP management** + - Fixed statusTag color in status column [#978](https://github.com/eclipse-tractusx/portal-frontend/pull/978) +- **Connector Management** + - Updated SD document download API to fix downloading SD document issue [#1038](https://github.com/eclipse-tractusx/portal-frontend/pull/1038) +- **Service Release Process** + - Fixed back button navigation to service management instead of navigating to home page[#1038](https://github.com/eclipse-tractusx/portal-frontend/pull/1038) +- **Application Requests** + - Fixed 'activeTab' conditions to load data for Tab-2(Registration Process) [#1050](https://github.com/eclipse-tractusx/portal-frontend/pull/1050) +- **App Release Process**: + - Fixed role upload does not work using Firefox [#1003](https://github.com/eclipse-tractusx/portal-frontend/pull/1003) +- **Technical User Management** + - Display technicalUserManagement button based on role validation [#1073](https://github.com/eclipse-tractusx/portal-frontend/pull/1073) +- **OSP Consent form** + - Display invited company name in OSP consent form (Previously hard coded with 'BMW') [#1083](https://github.com/eclipse-tractusx/portal-frontend/pull/1083) + ## 2.2.0-RC3 ### Change @@ -73,6 +111,8 @@ - removed unnecessary condition in semantic hub page's table [#979](https://github.com/eclipse-tractusx/portal-frontend/pull/979) - fixed unchanged text of button when user requests subscription [#985](https://github.com/eclipse-tractusx/portal-frontend/pull/985) - fixed height for "Admin Service Detail" page content [#1001](https://github.com/eclipse-tractusx/portal-frontend/pull/1001) +- fixed onClick of "Overview My Apps" button in App Release Process screen [#1022](https://github.com/eclipse-tractusx/portal-frontend/issues/1022) +- Fix 400 Bad Request error in App Access Management -> Add Role search filter [#1057](https://github.com/eclipse-tractusx/portal-frontend/issues/1057) ## 2.1.0 diff --git a/DEPENDENCIES b/DEPENDENCIES index 918a799f0..c17562ff9 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -64,7 +64,7 @@ npm/npmjs/-/ci-info/3.9.0, MIT, approved, clearlydefined npm/npmjs/-/cjs-module-lexer/1.2.3, MIT, approved, #9069 npm/npmjs/-/classnames/2.5.1, MIT, approved, clearlydefined npm/npmjs/-/cliui/8.0.1, ISC AND Artistic-2.0, approved, #3753 -npm/npmjs/-/clsx/2.1.0, MIT, approved, clearlydefined +npm/npmjs/-/clsx/2.1.1, MIT, approved, clearlydefined npm/npmjs/-/co/4.6.0, MIT, approved, clearlydefined npm/npmjs/-/collect-v8-coverage/1.0.2, MIT, approved, clearlydefined npm/npmjs/-/color-convert/1.9.3, MIT, approved, clearlydefined @@ -90,7 +90,7 @@ npm/npmjs/-/data-view-buffer/1.0.1, MIT, approved, clearlydefined npm/npmjs/-/data-view-byte-length/1.0.1, MIT, approved, clearlydefined npm/npmjs/-/data-view-byte-offset/1.0.0, MIT, approved, clearlydefined npm/npmjs/-/date-fns/3.6.0, MIT, approved, #14000 -npm/npmjs/-/dayjs/1.11.12, MIT, approved, #9149 +npm/npmjs/-/dayjs/1.11.13, 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 @@ -389,7 +389,7 @@ npm/npmjs/-/path-is-absolute/1.0.1, MIT, approved, clearlydefined npm/npmjs/-/path-key/3.1.1, MIT, approved, clearlydefined npm/npmjs/-/path-parse/1.0.7, MIT, approved, clearlydefined npm/npmjs/-/path-type/4.0.0, MIT, approved, clearlydefined -npm/npmjs/-/phone/3.1.49, MIT, approved, #10500 +npm/npmjs/-/phone/3.1.50, MIT, approved, #10500 npm/npmjs/-/picocolors/1.0.0, ISC, approved, #14718 npm/npmjs/-/picomatch/2.3.1, MIT, approved, clearlydefined npm/npmjs/-/pirates/4.0.6, MIT, approved, #680 @@ -416,7 +416,7 @@ npm/npmjs/-/react-hook-form/7.51.5, MIT, approved, #13909 npm/npmjs/-/react-i18next/14.1.3, MIT AND Apache-2.0, approved, #13870 npm/npmjs/-/react-is/16.13.1, MIT, approved, clearlydefined npm/npmjs/-/react-is/17.0.2, MIT, approved, clearlydefined -npm/npmjs/-/react-is/18.2.0, MIT, approved, clearlydefined +npm/npmjs/-/react-is/18.3.1, MIT, approved, clearlydefined npm/npmjs/-/react-player/2.15.1, MIT, approved, #13914 npm/npmjs/-/react-redux/9.1.2, MIT AND (BSD-2-Clause AND ISC AND MIT) AND BSD-3-Clause, approved, #13913 npm/npmjs/-/react-refresh/0.14.0, MIT, approved, clearlydefined @@ -678,14 +678,14 @@ npm/npmjs/@jridgewell/sourcemap-codec/1.4.15, MIT, approved, clearlydefined npm/npmjs/@jridgewell/trace-mapping/0.3.25, MIT, approved, #9904 npm/npmjs/@jridgewell/trace-mapping/0.3.9, MIT, approved, #9904 npm/npmjs/@mui/base/5.0.0-beta.40, MIT, approved, #2992 -npm/npmjs/@mui/core-downloads-tracker/5.15.15, MIT, approved, clearlydefined -npm/npmjs/@mui/icons-material/5.15.15, MIT AND CC-BY-3.0, approved, #13171 -npm/npmjs/@mui/material/5.15.15, MIT AND CC-BY-3.0, approved, #13175 -npm/npmjs/@mui/private-theming/5.15.14, MIT AND CC-BY-3.0, approved, #13174 -npm/npmjs/@mui/styled-engine/5.15.14, MIT AND CC-BY-3.0, approved, #13173 -npm/npmjs/@mui/system/5.15.15, MIT, approved, #13170 -npm/npmjs/@mui/types/7.2.14, MIT, approved, #16017 -npm/npmjs/@mui/utils/5.15.14, MIT AND OFL-1.1 AND CC-BY-3.0, approved, #13927 +npm/npmjs/@mui/core-downloads-tracker/5.16.7, MIT, approved, clearlydefined +npm/npmjs/@mui/icons-material/5.15.21, MIT AND CC-BY-3.0, approved, #13171 +npm/npmjs/@mui/material/5.15.21, MIT AND CC-BY-3.0, approved, #13175 +npm/npmjs/@mui/private-theming/5.16.6, MIT, approved, #15717 +npm/npmjs/@mui/styled-engine/5.16.6, MIT, approved, #15718 +npm/npmjs/@mui/system/5.16.7, MIT, approved, #15715 +npm/npmjs/@mui/types/7.2.15, MIT, approved, #16017 +npm/npmjs/@mui/utils/5.16.6, MIT, approved, #15716 npm/npmjs/@mui/x-data-grid/6.19.11, MIT, approved, #14027 npm/npmjs/@mui/x-date-pickers/6.19.9, MIT, approved, #14025 npm/npmjs/@nodelib/fs.scandir/2.1.5, MIT, approved, clearlydefined @@ -694,7 +694,7 @@ npm/npmjs/@nodelib/fs.walk/1.2.8, MIT, approved, clearlydefined npm/npmjs/@popperjs/core/2.11.8, MIT, approved, clearlydefined npm/npmjs/@react-hook/cache/1.1.1, MIT, approved, clearlydefined npm/npmjs/@react-hook/latest/1.0.3, MIT, approved, clearlydefined -npm/npmjs/@reduxjs/toolkit/2.2.6, MIT AND (BSD-2-Clause AND ISC AND MIT) AND Apache-2.0, approved, #14170 +npm/npmjs/@reduxjs/toolkit/2.2.7, MIT AND (BSD-2-Clause AND ISC AND MIT) AND Apache-2.0, approved, #14170 npm/npmjs/@remix-run/router/1.15.3, MIT, approved, clearlydefined npm/npmjs/@rollup/pluginutils/5.1.0, MIT, approved, clearlydefined npm/npmjs/@rollup/rollup-android-arm-eabi/4.17.2, MIT, approved, clearlydefined @@ -729,7 +729,7 @@ npm/npmjs/@svgr/core/8.1.0, MIT, approved, clearlydefined npm/npmjs/@svgr/hast-util-to-babel-ast/8.0.0, MIT, approved, clearlydefined npm/npmjs/@svgr/plugin-jsx/8.1.0, MIT, approved, clearlydefined npm/npmjs/@testing-library/dom/9.3.4, MIT AND (MIT AND WTFPL), approved, #9038 -npm/npmjs/@testing-library/jest-dom/6.4.6, MIT, approved, clearlydefined +npm/npmjs/@testing-library/jest-dom/6.4.8, MIT, approved, clearlydefined npm/npmjs/@testing-library/react/14.2.2, MIT, approved, #13316 npm/npmjs/@testing-library/user-event/14.5.2, MIT, approved, clearlydefined npm/npmjs/@tootallnate/once/2.0.0, MIT, approved, clearlydefined @@ -760,6 +760,7 @@ npm/npmjs/@types/node/20.11.30, MIT, approved, #13826 npm/npmjs/@types/papaparse/5.3.14, MIT, approved, #10964 npm/npmjs/@types/parse-json/4.0.2, MIT, approved, clearlydefined npm/npmjs/@types/prop-types/15.7.11, MIT, approved, clearlydefined +npm/npmjs/@types/prop-types/15.7.12, MIT, approved, clearlydefined npm/npmjs/@types/qs/6.9.15, MIT, approved, #14071 npm/npmjs/@types/react-dom/18.2.22, MIT, approved, #8256 npm/npmjs/@types/react-redux/7.1.33, MIT, approved, #10970 diff --git a/package.json b/package.json index 400a139b2..81b045c6d 100644 --- a/package.json +++ b/package.json @@ -38,15 +38,15 @@ "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", "@hookform/error-message": "^2.0.1", - "@mui/icons-material": "^5.15.14", - "@mui/material": "^5.15.14", + "@mui/icons-material": "^5.15.21", + "@mui/material": "^5.15.21", "@mui/x-data-grid": "^6.19.11", "@react-hook/cache": "^1.1.1", - "@reduxjs/toolkit": "^2.2.6", + "@reduxjs/toolkit": "^2.2.7", "autosuggest-highlight": "^3.3.4", "axios": "^1.6.8", "buffer": "^6.0.3", - "dayjs": "^1.11.12", + "dayjs": "^1.11.13", "i18next": "^23.10.1", "i18next-browser-languagedetector": "^7.2.1", "keycloak-js": "^23.0.7", @@ -54,7 +54,7 @@ "lodash.uniq": "^4.5.0", "nanoid": "^5.0.7", "papaparse": "^5.4.1", - "phone": "^3.1.49", + "phone": "^3.1.50", "qs": "^6.12.3", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -68,7 +68,7 @@ }, "devDependencies": { "@testing-library/dom": "^9.3.4", - "@testing-library/jest-dom": "^6.4.6", + "@testing-library/jest-dom": "^6.4.8", "@testing-library/react": "^14.2.2", "@testing-library/user-event": "^14.5.2", "@types/autosuggest-highlight": "^3.2.3", diff --git a/src/assets/locales/de/idp.json b/src/assets/locales/de/idp.json index 3906a3453..f5fd62b1a 100644 --- a/src/assets/locales/de/idp.json +++ b/src/assets/locales/de/idp.json @@ -45,8 +45,8 @@ "metadata_url_invalid_error": "Please enter valid metadata url" }, "page": { - "title": "Identity Provider Config", - "desc": "Here you can manage how the users of your company authenticate with Catena-X.

On registration we have created an IDP with one user entry for the admin (that's probably you ;).
Many companies already have their own IDP where users authenticate using their known company user id and a familiar login mask. In this case you will probably prefer to use your own company IDP and you can create and manage the federation on this page." + "title": "Konfiguration des Identitätsanbieters", + "desc": "Auf dieser Seite können Sie die Benutzerauthentifizierung für Ihr Unternehmen verwalten.

Bei der Registrierung haben wir einen Identity Provider (IDP) mit einem einzigen Benutzereintrag für den Administrator eingerichtet. Viele Organisationen unterhalten bereits ihren eigenen IDP, bei dem sich Benutzer mit ihren etablierten Unternehmensbenutzer-IDs und vertrauten Anmeldeoberflächen authentifizieren. In solchen Fällen möchten Sie möglicherweise Ihren vorhandenen Unternehmens-IDP nutzen. Auf dieser Seite können Sie die erforderliche Föderation erstellen und verwalten." }, "add": { "title": "Add your Identity Provider (IdP)", diff --git a/src/assets/locales/de/main.json b/src/assets/locales/de/main.json index 99dcbd5db..70c5b7200 100644 --- a/src/assets/locales/de/main.json +++ b/src/assets/locales/de/main.json @@ -39,7 +39,7 @@ "deactivate": "Deactivate", "appReleaseProcess": "App Release Process", "appSubscription": "App Subscription MGT", - "adminboard": "Admin Board", + "appAdminBoard": "Admin Board", "appUserManagement": "App Benutzer Verwaltung", "userdetails": "Benutzer Details", "technicalUserManagement": "Technische Benutzer Verwaltung", @@ -460,9 +460,38 @@ "action": "Aktion" }, "filter": { - "requested": "angefordert", + "pending": "ausstehend", "active": "aktiv", - "showAll": "zeige alles" + "inactive": "inaktiv", + "showAll": "Alles anzeigen" + } + }, + "companySubscriptionsDetail": { + "language": "Verfügbare App Sprachen", + "description": "Description", + "subscribed": "Gezeichnet", + "requested": "Angefordert", + "declined": "Abgelehnt", + "howtouse": { + "heading": "Nutzungsbedingungen", + "message": "Die Nutzungsbedingungen regeln das Verhältnis zwischen App Interessenten und App Anbieter. Die Nutzungsbedingungen, sowie die Datenmodelle und weitere Informationen können durch Anklicken der Hyperlinks eingesehen werden." + }, + "privacy": { + "heading": "Datenschutz", + "message": "Die Datenschutzerklärung gibt an, welche Daten die Geschäftsanwendungen erheben, handhaben und verarbeiten. Die nachstehenden Details zeigen explizit, welche Unternehmens-/Benutzerinformationen gesammelt/gespeichert werden.", + "notSupportedMessage": "Currently not yet supported", + "COMPANY_DATA": "Company Data", + "USER_DATA": "User Data", + "LOCATION": "Location", + "BROWSER_HISTORY": "Browser History", + "NONE": "None" + }, + "table": { + "connector": "Verbinder", + "technicalUser": "Technischer Benutzer" + }, + "technicalUser": { + "heading": "Technischer Details" } }, "appOverview": { @@ -923,7 +952,9 @@ "userDetails": "Technischer Benutzer Details", "description": "Beschreibung", "spoc": "SPOC", - "permission": "Berechtigungen" + "permission": "Berechtigungen", + "companyServiceAccountTypeID": "Firmenservicekontotyp", + "authenticationType": "Authentifizierungstyp" }, "status": { "ACTIVE": "AKTIV", @@ -1528,7 +1559,34 @@ "helpText": "For any questions regarding these change(s), please contact the Catena-X helpdesk:", "email": "xxx@xxxx.xxxx", "tenantUrlSuccessMsg": "App Tenant URL successfully updated", - "tenantUrlErrorMsg": "Error! Something went wrong" + "tenantUrlErrorMsg": "Error! Something went wrong", + "externalServices": { + "heading": "Details zum externen Dienst", + "trustedIssuer": { + "label": "Vertrauenswürdiger Aussteller", + "description": "Der vertrauenswürdige Aussteller, der für die Ausstellung der Identitätsnachweise verantwortlich ist." + }, + "participantId": { + "label": "Teilnehmer-ID", + "description": "Die eindeutige Kennung des Teilnehmers im externen System." + }, + "iatpId": { + "label": "IATP-ID", + "description": "Die eindeutige Kennung des IATP-Programms (Identity and Trust Protocol)." + }, + "didResolver": { + "label": "DID-Resolver", + "description": "Die URL des DID-Resolvers (Decentralized Identifier), der für die Auflösung der dezentralen Identitäten verwendet wird." + }, + "decentralIdentityManagementAuthUrl": { + "label": "Auth-URL für dezentrales Identitätsmanagement", + "description": "Die URL des Authentifizierungsendpunkts für das dezentrale Identitätsmanagement." + }, + "decentralIdentityManagementServiceUrl": { + "label": "Service-URL für dezentrales Identitätsmanagement", + "description": "Die URL des Dienstendpunkts für das dezentrale Identitätsmanagement." + } + } } }, "adminBoard": { diff --git a/src/assets/locales/de/notification.json b/src/assets/locales/de/notification.json index e9fc8600a..541814a1f 100644 --- a/src/assets/locales/de/notification.json +++ b/src/assets/locales/de/notification.json @@ -104,8 +104,8 @@ "appmanagementboard": "App Management Board öffnen", "servicemanagementboard": "Service Management Board öffnen", "appOverview": "Get there", - "appsubscription": "Get there", - "adminboard": "Get there", + "appSubscription": "Get there", + "appAdminBoard": "Get there", "technicaluser": "Get there", "companyRolesServiceProvider": "Get there", "usermanagement": "Get there", diff --git a/src/assets/locales/en/idp.json b/src/assets/locales/en/idp.json index 866939bee..ee41681bb 100644 --- a/src/assets/locales/en/idp.json +++ b/src/assets/locales/en/idp.json @@ -45,8 +45,8 @@ "metadata_url_invalid_error": "Please enter valid metadata url" }, "page": { - "title": "Identity Provider Config", - "desc": "Here you can manage how the users of your company authenticate with Catena-X.

On registration we have created an IDP with one user entry for the admin (that's probably you ;).
Many companies already have their own IDP where users authenticate using their known company user id and a familiar login mask. In this case you will probably prefer to use your own company IDP and you can create and manage the federation on this page." + "title": "Identity Provider configuration", + "desc": "This page provides the functionality to manage user authentication for your company.

Upon registration, we have established an Identity Provider (IDP) with a single user entry for the administrator. Many organizations already maintain their own IDP, where users authenticate using their established company user IDs and familiar login interfaces. In such cases, you may prefer to leverage your existing company IDP. You can create and manage the necessary federation on this page." }, "add": { "title": "Add your Identity Provider (IdP)", diff --git a/src/assets/locales/en/main.json b/src/assets/locales/en/main.json index 2bb92b6c7..5d9615025 100644 --- a/src/assets/locales/en/main.json +++ b/src/assets/locales/en/main.json @@ -38,7 +38,7 @@ "deactivate": "Deactivate", "appReleaseProcess": "App Release Process", "appSubscription": "App Subscription MGT", - "adminboard": "Admin Board", + "appAdminBoard": "Admin Board", "appUserManagement": "App User Management", "userdetails": "User Details", "technicalUserManagement": "Technical User Management", @@ -456,11 +456,41 @@ "action": "Action" }, "filter": { - "requested": "requested", + "pending": "pending", "active": "active", + "inactive": "inactive", "showAll": "show all" } }, + "companySubscriptionsDetail": { + "language": "Language", + "description": "Description", + "subscribed": "Subscribed", + "requested": "Requested", + "declined": "Declined", + "howtouse": { + "heading": "Documents", + "message": "The terms of use, as well as the data models and further information can be viewed by clicking on the documents shared below." + }, + "privacy": { + "heading": "Privacy Policy", + "message": "The Privacy Policy states which data the business applications collects, handles and processes. The details below explicitly show which company / user information are getting collected/stored.", + "notSupportedMessage": "Currently not yet supported", + "COMPANY_DATA": "Company Data", + "COMPANY_DATA_ICON": "ApartmentIcon", + "USER_DATA": "User Data", + "LOCATION": "Location", + "BROWSER_HISTORY": "Browser History", + "NONE": "None" + }, + "table": { + "connector": "Connector", + "technicalUser": "Technical User" + }, + "technicalUser": { + "heading": "Technical Details" + } + }, "datamanagement": { "message": "Contents of Data Management" }, @@ -927,7 +957,9 @@ "userDetails": "Technical User Details", "description": "Description", "spoc": "SPOC", - "permission": "Permission" + "permission": "Permission", + "companyServiceAccountTypeID": "Company Service Account Type", + "authenticationType": "Authentication Type" }, "status": { "ACTIVE": "ACTIVE", @@ -1495,7 +1527,34 @@ "helpText": "For any questions regarding these change(s), please contact the Catena-X helpdesk:", "email": "xxx@xxxx.xxxx", "tenantUrlSuccessMsg": "App Tenant URL successfully updated", - "tenantUrlErrorMsg": "Error! Something went wrong" + "tenantUrlErrorMsg": "Error! Something went wrong", + "externalServices": { + "heading": "External Service Details", + "trustedIssuer": { + "label": "Trusted Issuer", + "description": "The trusted issuer responsible for issuing the identity credentials." + }, + "participantId": { + "label": "Participant ID", + "description": "The unique identifier of the participant in the external system." + }, + "iatpId": { + "label": "IATP ID", + "description": "The unique identifier of the IATP (Identity and Trust Protocol)." + }, + "didResolver": { + "label": "DID Resolver", + "description": "The URL of the DID (Decentralized Identifier) resolver used for resolving decentralized identities." + }, + "decentralIdentityManagementAuthUrl": { + "label": "Decentralized Identity Management Auth URL", + "description": "The URL of the authentication endpoint for the decentralized identity management." + }, + "decentralIdentityManagementServiceUrl": { + "label": "Decentralized Identity Management Service URL", + "description": "The URL of the service endpoint for the decentralized identity management." + } + } } }, "adminBoard": { diff --git a/src/assets/locales/en/notification.json b/src/assets/locales/en/notification.json index 23c467580..b1caf5d9e 100644 --- a/src/assets/locales/en/notification.json +++ b/src/assets/locales/en/notification.json @@ -104,8 +104,8 @@ "appmanagementboard": "Get there", "servicemanagementboard": "Get there", "appOverview": "Get there", - "appsubscription": "Get there", - "adminboard": "Get there", + "appSubscription": "Get there", + "appAdminBoard": "Get there", "technicaluser": "Get there", "companyRolesServiceProvider": "Get there", "usermanagement": "Get there", diff --git a/src/components/overlays/ActivateServiceSubscription/index.tsx b/src/components/overlays/ActivateServiceSubscription/index.tsx index bace44311..1806fc8d1 100644 --- a/src/components/overlays/ActivateServiceSubscription/index.tsx +++ b/src/components/overlays/ActivateServiceSubscription/index.tsx @@ -93,45 +93,49 @@ export default function ActivateserviceSubscription({ const tableData: TableType = { head: [t('serviceSubscription.activation.tableheader'), ''], - body: [ - [ - t('serviceSubscription.activation.userId'), - techUserInfo?.technicalUserInfo[0]?.technicalClientId ?? '', - ], - [ - t('serviceSubscription.activation.sercret'), - techUserInfo?.technicalUserInfo[0]?.technicalUserSecret ?? '', - ], - [ - t('serviceSubscription.activation.url'), - techUserInfo?.clientInfo?.clientUrl ?? 'n/a', - ], - [ - t('serviceSubscription.activation.technicaluserType'), - techUserInfo?.technicalUserInfo[0]?.technicalUserPermissions?.join( - ', ' - ) ?? '', - ], - ], - edit: [ - [ - { - icon: false, - }, - { - icon: false, - }, - ], - [ - { - icon: false, - }, - { - icon: false, - copyValue: techUserInfo?.technicalUserInfo[0]?.technicalUserSecret, - }, - ], - ], + body: + techUserInfo?.technicalUserInfo + ?.map((userData) => [ + [ + t('serviceSubscription.activation.userId'), + userData.technicalClientId ?? '', + ], + [ + t('serviceSubscription.activation.sercret'), + userData.technicalUserSecret ?? '', + ], + [ + t('serviceSubscription.activation.url'), + techUserInfo?.clientInfo?.clientUrl ?? 'N/A', + ], + [ + t('serviceSubscription.activation.technicaluserType'), + userData.technicalUserPermissions.join(', ') ?? '', + ], + ]) + .flat(1) ?? [], + edit: + techUserInfo?.technicalUserInfo + ?.map((userData) => [ + [ + { + icon: false, + }, + { + icon: false, + }, + ], + [ + { + icon: false, + }, + { + icon: false, + copyValue: userData.technicalUserSecret, + }, + ], + ]) + .flat(1) ?? [], } return ( @@ -178,7 +182,10 @@ export default function ActivateserviceSubscription({ - + {techUserInfo?.technicalUserInfo && + techUserInfo?.technicalUserInfo?.length > 0 ? ( + + ) : null} - ) - else if (status === SubscriptionStatus.PENDING) - return ( - - ) - else - return ( - - ) - } + // Prevent API call when appId does not exist + const { data } = appId + ? useFetchSubscriptionAppQuery({ appId, subscriptionId }) + : { data: undefined } + const { data: fetchAppsData } = appId + ? useFetchAppDetailsQuery(appId) + : { data: undefined } return (
- - { - navigate(`/${PAGES.COMPANY_SUBSCRIPTIONS}`) - }} - /> - - {data && fetchAppsData && ( - - -
- {fetchAppsData.title} -
-
- - {renderStatusButton(fetchAppsData.isSubscribed)} - - {fetchAppsData.provider} - - - {fetchAppsData.title} - - -
-
- - {'Long description'} - - - {fetchAppsData.longDescription} - - - - {'Technical Details'} - - - + + + { + navigate(`/${PAGES.COMPANY_SUBSCRIPTIONS}`) + }} + /> - )} + {data && fetchAppsData && ( + <> + + + + + + + )} +
) } diff --git a/src/components/pages/CompanySubscriptions/CompanySubscriptions.scss b/src/components/pages/CompanySubscriptions/CompanySubscriptions.scss index 5704f5136..341a448bb 100644 --- a/src/components/pages/CompanySubscriptions/CompanySubscriptions.scss +++ b/src/components/pages/CompanySubscriptions/CompanySubscriptions.scss @@ -10,31 +10,69 @@ * * 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, eith er express or implied. See the + * 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 'src/components/styles/_breakpoints'; +@import 'src/components/styles/_colors'; + .company-subscription-detail { min-width: 1440px; + + @include media-breakpoint-up(xs) { + min-width: fit-content; + } + .company-subscription-back { - padding: 48px 256px 48px 160px; + padding: 80px 0 40px; + + @include media-breakpoint-up(md) { + padding: 70px 0 30px; + } + @include media-breakpoint-up(lg) { + transform: translateX(-75px); + } } .company-subscription-content { + width: 100%; + margin: 0 auto; - width: 620px; + + @include media-breakpoint-up(xs) { + max-width: 300px; + } + @include media-breakpoint-up(md) { + max-width: 620px; + } + @include media-breakpoint-up(lg) { + max-width: 970px; + } + .company-subscription-header { background-color: #ffffff; border-radius: 26px; - padding: 12px 0px 5px 12px; - margin-bottom: 55px; + padding: 12px; height: auto; box-shadow: 0px 2px 4px 0px #5050504d; - width: 606px; display: flex; flex-wrap: wrap; + flex-direction: column; + align-items: center; + width: 90%; + margin: 0 auto 55px; + + @include media-breakpoint-up(md) { + width: 100%; + margin-bottom: 55px; + flex-direction: row; + align-items: flex-start; + justify-content: space-between; + } + .lead-image > img { border-radius: 16px; width: 107px !important; @@ -44,6 +82,26 @@ flex: 1 1 0%; display: flex; flex-direction: column; + justify-content: space-between; + padding: 11px 12px; + gap: 10px; + + h5 { + color: color('text-tertiary'); + } + } + } + + #image-gallery { + max-width: calc(80% - 64px); + margin-left: auto; + margin-right: auto; + + @include media-breakpoint-up(md) { + max-width: calc(100% - 64px); + } + @include media-breakpoint-up(lg) { + max-width: 100%; } } } @@ -54,3 +112,9 @@ pointer-events: none !important; padding-left: 0 !important; } +.company-subscription-content-section:not(:last-of-type) { + margin-bottom: 40px; +} +.doc-list { + padding: 0 20px; +} diff --git a/src/components/pages/CompanySubscriptions/components/CompanySubscriptionContent/index.tsx b/src/components/pages/CompanySubscriptions/components/CompanySubscriptionContent/index.tsx new file mode 100644 index 000000000..d984d8c3a --- /dev/null +++ b/src/components/pages/CompanySubscriptions/components/CompanySubscriptionContent/index.tsx @@ -0,0 +1,58 @@ +/******************************************************************************** + * 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 { useTranslation } from 'react-i18next' +import { Box, useMediaQuery, useTheme } from '@mui/material' +import { ImageGallery, Typography } from '@catena-x/portal-shared-components' +import { type AppDetails } from 'features/apps/types' +import CommonService from 'services/CommonService' + +export default function CompanySubscriptionContent({ + detail, +}: Readonly<{ + detail: AppDetails +}>) { + const { t } = useTranslation() + const theme = useTheme() + const isMobile = useMediaQuery(theme.breakpoints.down('sm'), { + defaultMatches: true, + }) + return ( + <> + + + {t('content.companySubscriptionsDetail.description')} + + + {detail.longDescription} + + + + + + + ) +} diff --git a/src/components/pages/CompanySubscriptions/components/CompanySubscriptionDocument/index.tsx b/src/components/pages/CompanySubscriptions/components/CompanySubscriptionDocument/index.tsx new file mode 100644 index 000000000..c996573c0 --- /dev/null +++ b/src/components/pages/CompanySubscriptions/components/CompanySubscriptionDocument/index.tsx @@ -0,0 +1,101 @@ +/******************************************************************************** + * 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 { useTranslation } from 'react-i18next' +import { Box } from '@mui/material' +import ArticleOutlinedIcon from '@mui/icons-material/ArticleOutlined' +import { Typography } from '@catena-x/portal-shared-components' +import { DocumentTypeId } from 'features/appManagement/apiSlice' +import { useFetchDocumentByIdMutation } from 'features/apps/apiSlice' +import { type AppDetails, type Documents } from 'features/apps/types' +import { download } from 'utils/downloadUtils' +import 'components/styles/document.scss' + +export default function CompanySubscriptionDocument({ + detail, +}: Readonly<{ + detail: AppDetails +}>) { + const { t } = useTranslation() + + const [getDocumentById] = useFetchDocumentByIdMutation() + + const handleDownloadClick = async ( + documentId: string, + documentName: string + ) => { + try { + const response = await getDocumentById({ + appId: detail.id, + documentId, + }).unwrap() + const fileType = response.headers.get('content-type') + const file = response.data + download(file, fileType, documentName) + } catch (error) { + console.error(error, 'ERROR WHILE FETCHING DOCUMENT') + } + } + return ( + + + {t('content.companySubscriptionsDetail.howtouse.heading')} + + + {t('content.companySubscriptionsDetail.howtouse.message')} + + {detail.documents.hasOwnProperty( + DocumentTypeId.APP_TECHNICAL_INFORMATION + ) || + detail.documents.hasOwnProperty(DocumentTypeId.APP_CONTRACT) || + detail.documents.hasOwnProperty(DocumentTypeId.ADDITIONAL_DETAILS) ? ( + Object.keys(detail.documents).map( + (document) => + (document === DocumentTypeId.APP_TECHNICAL_INFORMATION || + document === DocumentTypeId.APP_CONTRACT || + document === DocumentTypeId.ADDITIONAL_DETAILS) && ( +
  • + + +
  • + ) + ) + ) : ( + + {t('global.errors.noDocumentsAvailable')} + + )} +
    + ) +} diff --git a/src/components/pages/CompanySubscriptions/components/CompanySubscriptionHeader/index.tsx b/src/components/pages/CompanySubscriptions/components/CompanySubscriptionHeader/index.tsx new file mode 100644 index 000000000..57ed54406 --- /dev/null +++ b/src/components/pages/CompanySubscriptions/components/CompanySubscriptionHeader/index.tsx @@ -0,0 +1,135 @@ +/******************************************************************************** + * 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 { + Button, + Image, + LogoGrayData, + Typography, +} from '@catena-x/portal-shared-components' +import { Box } from '@mui/material' +import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline' +import UnpublishedIcon from '@mui/icons-material/Unpublished' +import HourglassEmptyIcon from '@mui/icons-material/HourglassEmpty' +import { useTranslation } from 'react-i18next' +import { useEffect, useState } from 'react' +import { type AppDetails, SubscriptionStatus } from 'features/apps/types' +import CommonService from 'services/CommonService' +import { fetchImageWithToken } from 'services/ImageService' +import { getApiBase } from 'services/EnvironmentService' + +export default function CompanySubscriptionHeader({ + detail, +}: Readonly<{ + detail: AppDetails +}>) { + const { t } = useTranslation() + const [docId, setDocId] = useState('') + + useEffect(() => { + if (detail.leadPictureId) { + const id = CommonService.isValidPictureId(detail.leadPictureId) + setDocId(id) + } + }, [detail]) + + const renderStatusButton = (status: string) => { + if (status === SubscriptionStatus.ACTIVE) + return ( + + ) + else if (status === SubscriptionStatus.PENDING) + return ( + + ) + else + return ( + + ) + } + + return ( + +
    + {detail.title} +
    + +
    + {detail.provider} + {detail.title} +
    + + {t('content.companySubscriptionsDetail.language')}: + + {detail.languages.length + ? detail.languages.map((lang, index) => ( + + {` ${index ? ', ' : ''}${lang.toUpperCase()} `} + + )) + : ''} + + +
    + {renderStatusButton(detail.isSubscribed)} +
    + ) +} diff --git a/src/components/pages/CompanySubscriptions/components/CompanySubscriptionPrivacyContent/CompanySubscriptionPrivacyContent.scss b/src/components/pages/CompanySubscriptions/components/CompanySubscriptionPrivacyContent/CompanySubscriptionPrivacyContent.scss new file mode 100644 index 000000000..6df56b2cb --- /dev/null +++ b/src/components/pages/CompanySubscriptions/components/CompanySubscriptionPrivacyContent/CompanySubscriptionPrivacyContent.scss @@ -0,0 +1,43 @@ +/******************************************************************************** + * 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 + ********************************************************************************/ + +.company-subscription-detail-privacy { + .privacy-content { + margin-bottom: 32px; + } + .app-policies { + padding: 0 20px; + } + .policies-list { + display: flex; + flex-wrap: wrap; + max-width: none; + margin: 0; + .policy-name { + width: 50%; + display: flex; + align-items: center; + margin-bottom: 10px; + } + .policy-icon { + font-size: 20; + margin-right: 5px; + } + } +} diff --git a/src/components/pages/CompanySubscriptions/components/CompanySubscriptionPrivacyContent/index.tsx b/src/components/pages/CompanySubscriptions/components/CompanySubscriptionPrivacyContent/index.tsx new file mode 100644 index 000000000..f57347048 --- /dev/null +++ b/src/components/pages/CompanySubscriptions/components/CompanySubscriptionPrivacyContent/index.tsx @@ -0,0 +1,79 @@ +/******************************************************************************** + * 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 { uniqueId } from 'lodash' +import { Apartment, Person, LocationOn, Web, Info } from '@mui/icons-material' +import { useTranslation } from 'react-i18next' +import { Typography } from '@catena-x/portal-shared-components' +import { PrivacyPolicyType } from 'features/adminBoard/adminBoardApiSlice' +import { type AppDetails } from 'features/apps/types' +import './CompanySubscriptionPrivacyContent.scss' + +const policyIcons = { + [PrivacyPolicyType.COMPANY_DATA]: Apartment, + [PrivacyPolicyType.USER_DATA]: Person, + [PrivacyPolicyType.LOCATION]: LocationOn, + [PrivacyPolicyType.BROWSER_HISTORY]: Web, + [PrivacyPolicyType.NONE]: Info, +} + +export default function CompanySubscriptionPrivacy({ + detail, +}: Readonly<{ + detail: AppDetails +}>) { + const { t } = useTranslation('', { + keyPrefix: 'content.companySubscriptionsDetail.privacy', + }) + + const renderPrivacy = (policy: PrivacyPolicyType) => { + const IconComponent = policyIcons[policy] || Apartment + return + } + + return ( +
    +
    + {t('heading')} + {t('message')} +
    + {detail?.privacyPolicies?.length ? ( +
    + {detail.privacyPolicies.map((policy: PrivacyPolicyType) => ( + + {renderPrivacy(policy)} + {t(policy)} + + ))} +
    + ) : ( + + {t('notSupportedMessage')} + + )} +
    + ) +} diff --git a/src/components/pages/CompanySubscriptions/components/CompanySubscriptionTechnical/index.tsx b/src/components/pages/CompanySubscriptions/components/CompanySubscriptionTechnical/index.tsx new file mode 100644 index 000000000..40cfae42f --- /dev/null +++ b/src/components/pages/CompanySubscriptions/components/CompanySubscriptionTechnical/index.tsx @@ -0,0 +1,71 @@ +/******************************************************************************** + * 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 { Box } from '@mui/material' +import { useTranslation } from 'react-i18next' +import { StaticTable, Typography } from '@catena-x/portal-shared-components' +import { type ActiveSubscriptionDetails } from 'features/apps/types' +import { PAGES, ROLES } from 'types/Constants' +import UserService from 'services/UserService' + +export default function CompanySubscriptionTechnical({ + detail, +}: Readonly<{ + detail: ActiveSubscriptionDetails +}>) { + const { t } = useTranslation() + + const tableData = { + head: [ + t('content.companySubscriptionsDetail.table.connector'), + t('content.companySubscriptionsDetail.table.technicalUser'), + ], + body: [ + [ + !detail.connectorData.length ? '' : detail.connectorData[0].name, + !detail.technicalUserData.length + ? '' + : detail.technicalUserData[0].name, + ], + ], + edit: [ + [ + { + icon: false, + }, + { + icon: false, + clickableLink: + UserService.hasRole(ROLES.VIEW_USER_ACCOUNT) && + detail.technicalUserData.length + ? `/${PAGES.USER_DETAILS}/${detail.technicalUserData[0].id}` + : undefined, + }, + ], + ], + } + return ( + + + {t('content.companySubscriptionsDetail.technicalUser.heading')} + + + + ) +} diff --git a/src/components/pages/CompanySubscriptions/index.tsx b/src/components/pages/CompanySubscriptions/index.tsx index 097d5dd03..9c609877f 100644 --- a/src/components/pages/CompanySubscriptions/index.tsx +++ b/src/components/pages/CompanySubscriptions/index.tsx @@ -40,7 +40,7 @@ import { import { CompanySubscriptionsTableColumns } from './CompanySubscriptionsTableColumns' interface FetchHookArgsType { - statusFilter: string + statusId: string expr: string } @@ -50,7 +50,9 @@ export default function CompanySubscriptions() { const [refresh, setRefresh] = useState(0) const [searchExpr, setSearchExpr] = useState('') const [fetchHookArgs, setFetchHookArgs] = useState() - const [filterStatus, setFilterStatus] = useState('') + const [filterStatus, setFilterStatus] = useState( + CompanySubscriptionFilterType.SHOW_ALL + ) const searchInputData = useSelector(updateApplicationRequestSelector) const [group, setGroup] = useState( t('content.companySubscriptions.filter.showAll') @@ -72,8 +74,8 @@ export default function CompanySubscriptions() { const filterView = [ { - buttonText: t('content.companySubscriptions.filter.requested'), - buttonValue: CompanySubscriptionFilterType.REQUESTED, + buttonText: t('content.companySubscriptions.filter.pending'), + buttonValue: CompanySubscriptionFilterType.PENDING, onButtonClick: setView, }, { @@ -81,6 +83,11 @@ export default function CompanySubscriptions() { buttonValue: CompanySubscriptionFilterType.ACTIVE, onButtonClick: setView, }, + { + buttonText: t('content.companySubscriptions.filter.inactive'), + buttonValue: CompanySubscriptionFilterType.INACTIVE, + onButtonClick: setView, + }, { buttonText: t('content.companySubscriptions.filter.showAll'), buttonValue: CompanySubscriptionFilterType.SHOW_ALL, @@ -89,12 +96,10 @@ export default function CompanySubscriptions() { ] useEffect(() => { - if (onValidate(searchExpr)) { - setFetchHookArgs({ - statusFilter: filterStatus, - expr: searchExpr, - }) - } + setFetchHookArgs({ + statusId: filterStatus, + expr: searchExpr, + }) }, [filterStatus, searchExpr]) const onValidate = (expr: string) => { diff --git a/src/components/pages/EdcConnector/AddConnectorOverlay/components/ConnectorInsertForm.tsx b/src/components/pages/EdcConnector/AddConnectorOverlay/components/ConnectorInsertForm.tsx index b2157b8d2..63e0032d6 100644 --- a/src/components/pages/EdcConnector/AddConnectorOverlay/components/ConnectorInsertForm.tsx +++ b/src/components/pages/EdcConnector/AddConnectorOverlay/components/ConnectorInsertForm.tsx @@ -38,6 +38,7 @@ import { Dropzone } from '../../../../shared/basic/Dropzone' import { useEffect, useState } from 'react' import './EdcComponentStyles.scss' import { ConnectorFormFields } from '..' +import { type ServiceAccountListEntry } from 'features/admin/serviceApiSlice' export const ConnectorFormInput = ({ control, @@ -243,6 +244,7 @@ const ConnectorInsertForm = ({ errors, control, trigger, + getValues, selectedService, subscriptions, fetchServiceAccountUsers, @@ -256,6 +258,7 @@ any) => { const { t } = useTranslation() const [selectedValue, setSelectedValue] = useState() const [serviceAccountUsers, setServiceAccountUsers] = useState([]) + const [selectedTechnicalUser, setSelectedTechnicalUser] = useState('') useEffect(() => { if (fetchServiceAccountUsers) @@ -264,6 +267,17 @@ any) => { ) }, [fetchServiceAccountUsers]) + useEffect(() => { + const selectedConnectorTechnicalUser: ServiceAccountListEntry[] = + serviceAccountUsers?.filter( + (i: { serviceAccountId: string }) => + i.serviceAccountId === getValues().ConnectorTechnicalUser + ) + if (selectedConnectorTechnicalUser.length > 0) { + setSelectedTechnicalUser(selectedConnectorTechnicalUser[0]?.name) + } + }, [serviceAccountUsers]) + const handleTechnicalUserSubmit = () => { if ( selectedValue === t('content.edcconnector.modal.createNewTechnicalUser') @@ -374,7 +388,7 @@ any) => { 'content.edcconnector.modal.insertform.technicalUser.error' ), items: serviceAccountUsers, - defaultSelectValue: {}, + defaultSelectValue: selectedTechnicalUser ?? {}, keyTitle: 'name', }} /> diff --git a/src/components/pages/EdcConnector/AddConnectorOverlay/index.tsx b/src/components/pages/EdcConnector/AddConnectorOverlay/index.tsx index 7e79ebfdb..c0077f692 100644 --- a/src/components/pages/EdcConnector/AddConnectorOverlay/index.tsx +++ b/src/components/pages/EdcConnector/AddConnectorOverlay/index.tsx @@ -216,7 +216,7 @@ const AddConnectorOverlay = ({ setNewTechnicalUSer={setNewTechnicalUSer} newUserLoading={newUserLoading} newUserSuccess={newUserSuccess} - {...{ handleSubmit, control, errors, trigger }} + {...{ handleSubmit, control, errors, trigger, getValues }} /> )} diff --git a/src/components/pages/EdcConnector/ConnectorDetailsOverlay.tsx b/src/components/pages/EdcConnector/ConnectorDetailsOverlay.tsx index 525262a2a..e57624c8d 100644 --- a/src/components/pages/EdcConnector/ConnectorDetailsOverlay.tsx +++ b/src/components/pages/EdcConnector/ConnectorDetailsOverlay.tsx @@ -35,6 +35,7 @@ import { useDeleteConnectorMutation, useUpdateConnectorUrlMutation, useFetchConnectorDetailsQuery, + useFetchSdDocumentMutation, } from 'features/connector/connectorApiSlice' import { Box, Divider, Grid } from '@mui/material' import ArticleOutlinedIcon from '@mui/icons-material/ArticleOutlined' @@ -42,7 +43,6 @@ import { useEffect, useState } from 'react' import { error, success } from 'services/NotifyService' import EditIcon from '@mui/icons-material/Edit' import Patterns from 'types/Patterns' -import { useFetchDocumentMutation } from 'features/serviceManagement/apiSlice' import { download } from 'utils/downloadUtils' import UserService from 'services/UserService' import { ROLES } from 'types/Constants' @@ -59,7 +59,7 @@ const ConnectorDetailsOverlay = ({ overlayData, }: DeleteConfirmationOverlayProps) => { const { t } = useTranslation() - const [fetchDocumentById] = useFetchDocumentMutation() + const [fetchSDDocument] = useFetchSdDocumentMutation() const { data: fetchConnectorDetails, isFetching, @@ -135,10 +135,7 @@ const ConnectorDetailsOverlay = ({ const handleDownloadFn = async (documentId: string, documentName: string) => { if (fetchConnectorDetails?.id) { try { - const response = await fetchDocumentById({ - appId: fetchConnectorDetails.id, - documentId, - }).unwrap() + const response = await fetchSDDocument(documentId).unwrap() const fileType = response.headers.get('content-type') const file = response.data @@ -600,8 +597,8 @@ const ConnectorDetailsOverlay = ({ null ? ( t('content.edcconnector.details.noDocumentAvailable') ) : ( - <> - + + - + )} diff --git a/src/components/pages/EdcConnector/edcConnectorTableColumns.tsx b/src/components/pages/EdcConnector/edcConnectorTableColumns.tsx index d9dda7df3..829ca73e0 100644 --- a/src/components/pages/EdcConnector/edcConnectorTableColumns.tsx +++ b/src/components/pages/EdcConnector/edcConnectorTableColumns.tsx @@ -84,7 +84,6 @@ export const ConnectorTableColumns = ( { } } + const statusColorMap: Record = { + [IdpAccountStatus.ACTIVE]: 'confirmed', + [IdpAccountStatus.DISABLED]: 'declined', + [IdpAccountStatus.OPEN]: 'pending', + [IdpAccountStatus.IDP_CREATED]: 'pending', + } + const getStatus = (enabled: boolean, clientId: string | undefined) => { let status = `${ti('field.status1')}` if (enabled && !clientId) { @@ -135,7 +145,12 @@ export const IDPList = ({ isManagementOSP }: { isManagementOSP?: boolean }) => { } else if (enabled && clientId) { status = `${ti('field.status4')}` } - return + return ( + + ) } const renderMenu = (idp: IdentityProvider) => { diff --git a/src/components/pages/IDPManagement/index.tsx b/src/components/pages/IDPManagement/index.tsx index 7f71e40d7..a99d79fde 100644 --- a/src/components/pages/IDPManagement/index.tsx +++ b/src/components/pages/IDPManagement/index.tsx @@ -38,7 +38,7 @@ export default function IDPManagement() {
    - {t('idpManagement.title')} + {t('page.title')} diff --git a/src/components/pages/NotificationCenter/NotificationItem.tsx b/src/components/pages/NotificationCenter/NotificationItem.tsx index 60bd90892..e8e88c1dd 100644 --- a/src/components/pages/NotificationCenter/NotificationItem.tsx +++ b/src/components/pages/NotificationCenter/NotificationItem.tsx @@ -187,7 +187,9 @@ const NotificationConfig = ({ item }: { item: CXNotificationContent }) => { ) case NotificationType.APP_RELEASE_REQUEST: - return + return ( + + ) case NotificationType.APP_RELEASE_APPROVAL: return ( diff --git a/src/components/pages/OSPConsent/CompanyDetails.tsx b/src/components/pages/OSPConsent/CompanyDetails.tsx index c5348b7cd..4987cd026 100644 --- a/src/components/pages/OSPConsent/CompanyDetails.tsx +++ b/src/components/pages/OSPConsent/CompanyDetails.tsx @@ -207,7 +207,7 @@ export const CompanyDetails = ({ } const tableData: TableType = { - head: [t('osp.companyName'), t('osp.bmw')], + head: [t('osp.companyName'), companyDetails?.name ?? ''], body: [ [t('osp.street'), companyDetails?.streetName ?? ''], [t('osp.zip'), companyDetails?.zipCode ?? ''], diff --git a/src/components/pages/TechnicalUserDetails/TechnicalUserDetailsContent.tsx b/src/components/pages/TechnicalUserDetails/TechnicalUserDetailsContent.tsx index ce8978b9a..ecf4f4b8d 100644 --- a/src/components/pages/TechnicalUserDetails/TechnicalUserDetailsContent.tsx +++ b/src/components/pages/TechnicalUserDetails/TechnicalUserDetailsContent.tsx @@ -18,7 +18,11 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -import { Button, CircleProgress } from '@catena-x/portal-shared-components' +import { + Button, + CircleProgress, + StatusTag, +} from '@catena-x/portal-shared-components' import { useTranslation } from 'react-i18next' import { Box } from '@mui/material' import HighlightOffIcon from '@mui/icons-material/HighlightOff' @@ -32,8 +36,20 @@ import { useDispatch } from 'react-redux' import { show } from 'features/control/overlay' import { KeyValueView } from 'components/shared/basic/KeyValueView' import SyncIcon from '@mui/icons-material/Sync' -import { useState } from 'react' +import { type ComponentProps, useState } from 'react' import { error, success } from 'services/NotifyService' +import { ServiceAccountStatus } from 'features/admin/serviceApiSlice' + +export const statusColorMap: Record< + ServiceAccountStatus, + ComponentProps['color'] +> = { + [ServiceAccountStatus.ACTIVE]: 'confirmed', + [ServiceAccountStatus.INACTIVE]: 'declined', + [ServiceAccountStatus.DELETED]: 'deleted', + [ServiceAccountStatus.PENDING]: 'pending', + [ServiceAccountStatus.PENDING_DELETION]: 'pending', +} export default function TechnicalUserDetailsContent({ data, @@ -59,6 +75,16 @@ export default function TechnicalUserDetailsContent({ ] const displayData = [ + { + key: t('global.field.status'), + value: ( + + ), + copy: false, + }, { key: 'ID', value: newData.serviceAccountId, @@ -71,13 +97,22 @@ export default function TechnicalUserDetailsContent({ value: newData.name, copy: true, }, + { + key: t( + 'content.usermanagement.technicalUser.detailsPage.companyServiceAccountTypeID' + ), + value: newData.companyServiceAccountTypeId, + copy: false, + }, { key: t('global.field.clientId'), value: newData.clientId, copy: true, }, { - key: t('global.field.authType'), + key: t( + 'content.usermanagement.technicalUser.detailsPage.authenticationType' + ), value: newData.authenticationType, }, { diff --git a/src/components/pages/TechnicalUserManagement/index.tsx b/src/components/pages/TechnicalUserManagement/index.tsx index 06735fd0a..d9f945812 100644 --- a/src/components/pages/TechnicalUserManagement/index.tsx +++ b/src/components/pages/TechnicalUserManagement/index.tsx @@ -25,13 +25,16 @@ import SubHeaderTitle from 'components/shared/frame/SubHeaderTitle' import { Button, PageNotifications } from '@catena-x/portal-shared-components' import { show } from 'features/control/overlay' import UserService from 'services/UserService' -import { resetNotification } from 'features/notification/actions' -import { notificationSelector } from 'features/notification/slice' +import { + notificationSelector, + setNotification, +} from 'features/notification/slice' import { useTranslation } from 'react-i18next' import { useSelector, useDispatch } from 'react-redux' import './style.scss' import { TechnicalUserTable } from './TechnicalUserTable' import { getAssetBase } from 'services/EnvironmentService' +import { initServicetNotifications } from 'types/MainTypes' export default function TechnicalUserManagement() { const { t } = useTranslation() @@ -39,7 +42,7 @@ export default function TechnicalUserManagement() { const dispatch = useDispatch() const handleCloseNotification = () => { - dispatch(resetNotification()) + dispatch(setNotification(initServicetNotifications)) } return ( @@ -79,7 +82,7 @@ export default function TechnicalUserManagement() {
    - {notification.title && notification.description && ( + {notification?.title && notification?.description && ( { const { t } = useTranslation() @@ -44,9 +46,13 @@ export const StageSubNavigation = () => { return ( { - navigate('/technicalUserManagement') + navigate(`/${PAGES.TECH_USER_MANAGEMENT}`) }} link1Label={t('navigation.subNavigation.link1Label')} onLink1Click={() => { diff --git a/src/components/shared/basic/ReleaseProcess/OfferCard/index.tsx b/src/components/shared/basic/ReleaseProcess/OfferCard/index.tsx index 7c2970fe6..c41657f6d 100644 --- a/src/components/shared/basic/ReleaseProcess/OfferCard/index.tsx +++ b/src/components/shared/basic/ReleaseProcess/OfferCard/index.tsx @@ -65,6 +65,7 @@ import { ButtonLabelTypes } from '..' import RetryOverlay from '../components/RetryOverlay' import { success, error } from 'services/NotifyService' import { DocumentTypeId } from 'features/appManagement/apiSlice' +import { PAGES } from 'types/Constants' type FormDataType = { title: string @@ -458,9 +459,9 @@ export default function OfferCard() { ? getValues().shortDescriptionEN.length : getValues().shortDescriptionDE.length) + '/120' } - patternKey="shortDescriptionEN" - patternEN={Patterns.offerCard.shortDescriptionEN} - patternDE={Patterns.offerCard.shortDescriptionDE} + patternKey="shortDescription" + patternEN={Patterns.offerCard.shortDescription} + patternDE={Patterns.offerCard.shortDescription} isRequired={true} rules={{ required: @@ -471,11 +472,7 @@ export default function OfferCard() { )}`, pattern: `${t( 'serviceReleaseForm.validCharactersIncludes' - )} ${ - desc === 'shortDescriptionEN' - ? 'a-zA-Z0-9 !?@&#\'"()_-=/*.,;:' - : 'a-zA-ZÀ-ÿ0-9 !?@&#\'"()_-=/*.,;:' - }`, + )} ${'a-zA-ZÀ-ÿ0-9 !?@&#\'"()_-=/*.,;:'}`, maxLength: `${t('serviceReleaseForm.maximum')} 120 ${t( 'serviceReleaseForm.charactersAllowed' )}`, @@ -524,7 +521,7 @@ export default function OfferCard() { setServiceCardSnackbar(false) }} onBackIconClick={() => { - navigate('/home') + navigate(`/${PAGES.SERVICE_MANAGEMENT}`) }} // Add an ESLint exception until there is a solution // eslint-disable-next-line diff --git a/src/components/shared/basic/ReleaseProcess/OfferPage/index.tsx b/src/components/shared/basic/ReleaseProcess/OfferPage/index.tsx index c607d6594..65450105a 100644 --- a/src/components/shared/basic/ReleaseProcess/OfferPage/index.tsx +++ b/src/components/shared/basic/ReleaseProcess/OfferPage/index.tsx @@ -301,8 +301,8 @@ export default function OfferPage({ `/${longDescriptionMaxLength}` } patternKey="longDescriptionEN" - patternEN={Patterns.offerPage.longDescriptionEN} - patternDE={Patterns.offerPage.longDescriptionDE} + patternEN={Patterns.offerPage.longDescription} + patternDE={Patterns.offerPage.longDescription} rules={{ maxLength: `${t( 'serviceReleaseForm.maximum' @@ -317,11 +317,7 @@ export default function OfferPage({ )}`, pattern: `${t( 'serviceReleaseForm.validCharactersIncludes' - )} ${ - longDesc === 'longDescriptionEN' - ? 'a-zA-Z0-9 !?@&#\'"()[]_-+=<>/*.,;:' - : 'a-zA-ZÀ-ÿ0-9 !?@&#\'"()[]_-+=<>/*.,;:' - }`, + )} ${'a-zA-ZÀ-ÿ0-9 !?@&#\'"()[]_-+=<>/*.,;:'}`, }} maxLength={longDescriptionMaxLength} /> diff --git a/src/components/shared/basic/ReleaseProcess/TechnicalIntegration/index.tsx b/src/components/shared/basic/ReleaseProcess/TechnicalIntegration/index.tsx index cfa7520e4..ee5831849 100644 --- a/src/components/shared/basic/ReleaseProcess/TechnicalIntegration/index.tsx +++ b/src/components/shared/basic/ReleaseProcess/TechnicalIntegration/index.tsx @@ -263,7 +263,10 @@ export default function TechnicalIntegration() { const csvPreview = (files: File[]) => { files - .filter((file: File) => file.type === 'text/csv') + .filter( + (file: File) => + file.type === 'text/csv' || file.type === 'application/vnd.ms-excel' + ) .forEach((file: File) => { const reader = new FileReader() reader.onabort = () => { @@ -441,7 +444,10 @@ export default function TechnicalIntegration() { csvPreview(files) setUploadFileInfo(files) }} - acceptFormat={{ 'text/csv': ['.csv'] }} + acceptFormat={{ + 'text/csv': ['.csv'], + 'application/vnd.ms-excel': ['.csv'], + }} maxFilesToUpload={1} enableDeleteOverlay={true} deleteOverlayTranslation={{ diff --git a/src/components/shared/templates/AdminBoard/index.tsx b/src/components/shared/templates/AdminBoard/index.tsx index cddb13d8f..c54fdfd76 100644 --- a/src/components/shared/templates/AdminBoard/index.tsx +++ b/src/components/shared/templates/AdminBoard/index.tsx @@ -40,6 +40,7 @@ import type { import type { AppRequestBody } from 'features/adminBoard/adminBoardApiSlice' import { useNavigate } from 'react-router-dom' import SortImage from 'components/shared/frame/SortImage' +import { PAGES } from 'types/Constants' export interface TabButtonsType { buttonText: string @@ -235,7 +236,7 @@ export default function CommonAdminBoard({ fetchQuery, loadMoreButtonText = 'Load More', isDynamicSearchEnabled = false, - type = 'adminboarddetail', + type = PAGES.APP_ADMIN_BOARD_DETAIL, successApproveMsg, errorApproveMsg, successDeclineMsg, diff --git a/src/features/admin/applicationRequestApiSlice.ts b/src/features/admin/applicationRequestApiSlice.ts index 697d85e78..1dafa9550 100644 --- a/src/features/admin/applicationRequestApiSlice.ts +++ b/src/features/admin/applicationRequestApiSlice.ts @@ -43,6 +43,7 @@ export enum AppFilterType { export interface DocumentMapper { documentType: string documentId: string + documentSize?: number } export interface ApplicationChecklistType { @@ -88,6 +89,7 @@ interface Map { export const EndUrlMap: Map = { RETRIGGER_IDENTITY_WALLET: 'trigger-identity-wallet', + RETRIGGER_CREATE_DIM_WALLET: 'retrigger-create-dim-wallet', RETRIGGER_CLEARING_HOUSE: 'retrigger-clearinghouse', TRIGGER_OVERRIDE_CLEARING_HOUSE: 'override-clearinghouse', RETRIGGER_SELF_DESCRIPTION_LP: 'trigger-self-description', @@ -101,6 +103,7 @@ export const EndUrlMap: Map = { export enum RetriggerableProcessSteps { RETRIGGER_IDENTITY_WALLET = 'RETRIGGER_IDENTITY_WALLET', + RETRIGGER_CREATE_DIM_WALLET = 'RETRIGGER_CREATE_DIM_WALLET', RETRIGGER_CLEARING_HOUSE = 'RETRIGGER_CLEARING_HOUSE', TRIGGER_OVERRIDE_CLEARING_HOUSE = 'TRIGGER_OVERRIDE_CLEARING_HOUSE', RETRIGGER_SELF_DESCRIPTION_LP = 'RETRIGGER_SELF_DESCRIPTION_LP', diff --git a/src/features/admin/appuserApiSlice.ts b/src/features/admin/appuserApiSlice.ts index d99dd0913..8d19d5731 100644 --- a/src/features/admin/appuserApiSlice.ts +++ b/src/features/admin/appuserApiSlice.ts @@ -88,7 +88,7 @@ export const apiSlice = createApi({ fetchAppUsersSearch: builder.query, PaginFetchArgs>( { query: (fetchArgs) => { - const emailExpr = `email=${fetchArgs.args!.expr}` + const emailExpr = `&email=${fetchArgs.args!.expr}` return { url: `/api/administration/user/owncompany/apps/${ fetchArgs.args!.appId diff --git a/src/features/admin/idpApiSlice.ts b/src/features/admin/idpApiSlice.ts index 611e7c9e2..b0a2f2271 100644 --- a/src/features/admin/idpApiSlice.ts +++ b/src/features/admin/idpApiSlice.ts @@ -65,6 +65,13 @@ export enum SAMLAuthMethod { SECRET = 'SECRET', } +export enum IdpAccountStatus { + ACTIVE = 'active', + OPEN = 'open', + IDP_CREATED = 'Idp created', + DISABLED = 'disabled', +} + export interface IDPMapperConfig { syncMode: IDPSyncModeType } diff --git a/src/features/admin/serviceApiSlice.ts b/src/features/admin/serviceApiSlice.ts index 3c7047309..2df1ec815 100644 --- a/src/features/admin/serviceApiSlice.ts +++ b/src/features/admin/serviceApiSlice.ts @@ -77,6 +77,7 @@ export interface ServiceAccountDetail extends ServiceAccountListEntry { roles: ServiceAccountRole[] connector: ConnectedObject offer: ConnectedObject + companyServiceAccountTypeId: companyServiceAccountType } export type AppRoleCreate = { @@ -100,6 +101,11 @@ export enum ServiceAccountStatusFilter { OWNED = 'OWNED', } +export enum companyServiceAccountType { + MANAGED = 'MANAGED', + OWNED = 'OWN', +} + export const apiSlice = createApi({ reducerPath: 'rtk/admin/service', baseQuery: fetchBaseQuery(apiBaseQuery()), diff --git a/src/features/appSubscription/appSubscriptionApiSlice.ts b/src/features/appSubscription/appSubscriptionApiSlice.ts index c246bde06..c210fc365 100644 --- a/src/features/appSubscription/appSubscriptionApiSlice.ts +++ b/src/features/appSubscription/appSubscriptionApiSlice.ts @@ -63,6 +63,14 @@ export type SubscriptionDetailResponse = { technicalUserData: TechnicalUserData[] tenantUrl: string processStepTypeId: ProcessStep | null + externalService: { + trusted_issuer: string + participant_id: string + iatp_id: string + did_resolver: string + decentralIdentityManagementAuthUrl: string + decentralIdentityManagementServiceUrl: string + } } export type UserRoles = { diff --git a/src/features/apps/apiSlice.ts b/src/features/apps/apiSlice.ts index 61265b962..99393e63d 100644 --- a/src/features/apps/apiSlice.ts +++ b/src/features/apps/apiSlice.ts @@ -27,20 +27,22 @@ import i18next from 'i18next' import { getApiBase } from 'services/EnvironmentService' import { apiBaseQuery } from 'utils/rtkUtil' import { PAGE_SIZE } from 'types/Constants' -import type { - AppDetails, - AppMarketplaceApp, - SubscriptionStatusItem, - SubscriptionStatusDuplicateItem, - ActiveSubscriptionItem, - ProvidedApps, - DocumentRequestData, - SubscriptionAppRequest, - AgreementRequest, - ActiveSubscription, - ActiveSubscriptionDetails, - FetchSubscriptionAppQueryType, - SubscribedActiveApps, +import { + type AppDetails, + type AppMarketplaceApp, + type SubscriptionStatusItem, + type SubscriptionStatusDuplicateItem, + type ActiveSubscriptionItem, + type ProvidedApps, + type DocumentRequestData, + type SubscriptionAppRequest, + type AgreementRequest, + type ActiveSubscription, + type ActiveSubscriptionDetails, + type FetchSubscriptionAppQueryType, + type SubscribedActiveApps, + StatusIdEnum, + CompanySubscriptionFilterType, } from './types' export const apiSlice = createApi({ @@ -104,8 +106,16 @@ export const apiSlice = createApi({ return { data: subscriptionData } }, }), - fetchProvidedApps: builder.query({ - query: () => '/api/apps/provided', + fetchProvidedApps: builder.query({ + query: (fetchArgs) => { + const { page, args } = fetchArgs + const baseUrl = `/api/apps/provided?page=${page}&size=15` + const statusId = args?.statusFilter + ? args.statusFilter + : StatusIdEnum.All + const offerName = args?.expr ? `&offerName=${args.expr}` : '' + return `${baseUrl}&statusId=${statusId}${offerName}` + }, }), fetchBusinessApps: builder.query({ query: () => '/api/apps/business', @@ -155,9 +165,16 @@ export const apiSlice = createApi({ PaginResult, PaginFetchArgs >({ - query: (fetchArgs) => ({ - url: `/api/Apps/subscribed/subscription-status?size=${PAGE_SIZE}&page=${fetchArgs.page}`, - }), + query: (fetchArgs) => { + if ( + fetchArgs.args.statusId && + fetchArgs.args.statusId !== CompanySubscriptionFilterType.SHOW_ALL + ) { + return `/api/Apps/subscribed/subscription-status?size=${PAGE_SIZE}&page=${fetchArgs.page}&statusId=${fetchArgs.args.statusId}` + } else { + return `/api/Apps/subscribed/subscription-status?size=${PAGE_SIZE}&page=${fetchArgs.page}` + } + }, }), }), }) diff --git a/src/features/apps/types.ts b/src/features/apps/types.ts index b68a26c1e..899e1a203 100644 --- a/src/features/apps/types.ts +++ b/src/features/apps/types.ts @@ -251,8 +251,9 @@ export const initialState: AppsControlState = { } export enum CompanySubscriptionFilterType { - REQUESTED = 'requested', + PENDING = 'pending', ACTIVE = 'active', + INACTIVE = 'inactive', SHOW_ALL = 'show all', } @@ -264,3 +265,11 @@ export interface SubscribedActiveApps { subscriptionId: string image: string } + +export enum StatusIdEnum { + Active = 'Active', + Inactive = 'Inactive', + InReview = 'InReview', + WIP = 'WIP', + All = 'All', +} diff --git a/src/features/connector/connectorApiSlice.ts b/src/features/connector/connectorApiSlice.ts index 6fed4cc9f..f150e6f7c 100644 --- a/src/features/connector/connectorApiSlice.ts +++ b/src/features/connector/connectorApiSlice.ts @@ -173,6 +173,15 @@ export const apiSlice = createApi({ body: data.body, }), }), + fetchSdDocument: builder.mutation({ + query: (documentId) => ({ + url: `/api/administration/documents/selfDescription/${documentId}`, + responseHandler: async (response) => ({ + headers: response.headers, + data: await response.blob(), + }), + }), + }), }), }) @@ -186,4 +195,5 @@ export const { useFetchOfferSubscriptionsQuery, useFetchDecentralIdentityUrlsQuery, useUpdateConnectorUrlMutation, + useFetchSdDocumentMutation, } = apiSlice diff --git a/src/features/serviceManagement/apiSlice.ts b/src/features/serviceManagement/apiSlice.ts index 69a08758e..b152590e0 100644 --- a/src/features/serviceManagement/apiSlice.ts +++ b/src/features/serviceManagement/apiSlice.ts @@ -178,7 +178,7 @@ export type ActivateSubscriptionRequest = { } export type ActivateSubscriptionResponse = { - technicalUserInfo: TechnicalUserInfoType[] + technicalUserInfo: Array clientInfo: ClientInfoType } diff --git a/src/types/Config.tsx b/src/types/Config.tsx index 041a1f142..1918ea813 100644 --- a/src/types/Config.tsx +++ b/src/types/Config.tsx @@ -250,7 +250,7 @@ export const ALL_PAGES: IPage[] = [ element: , }, { - name: PAGES.ADMINBOARD, + name: PAGES.APP_ADMIN_BOARD, role: ROLES.APPROVE_APP_RELEASE || ROLES.DECLINE_APP_RELEASE, element: , }, @@ -260,13 +260,13 @@ export const ALL_PAGES: IPage[] = [ element: , }, { - name: PAGES.ADMINBOARD_DETAIL, + name: PAGES.APP_ADMIN_BOARD_DETAIL, role: ROLES.APPROVE_APP_RELEASE || ROLES.DECLINE_APP_RELEASE, isRoute: true, element: ( } > @@ -780,7 +780,7 @@ export const mainMenuFullTree = [ { name: PAGES.APP_OVERVIEW, hint: HINTS.NEW }, { name: PAGES.APP_RELEASE_PROCESS }, { name: PAGES.APP_SUBSCRIPTION, hint: HINTS.NEW }, - { name: PAGES.ADMINBOARD, hint: HINTS.NEW }, + { name: PAGES.APP_ADMIN_BOARD, hint: HINTS.NEW }, ], }, { diff --git a/src/types/Constants.ts b/src/types/Constants.ts index 4e1b491c6..ffe74bcc6 100644 --- a/src/types/Constants.ts +++ b/src/types/Constants.ts @@ -29,8 +29,8 @@ export enum PAGES { SWAGGER = 'swagger', STORYBOOK = 'storybook', APP_SUBSCRIPTION = 'appSubscription', - ADMINBOARD = 'adminboard', - ADMINBOARD_DETAIL = 'adminboardDetail', + APP_ADMIN_BOARD = 'appAdminBoard', + APP_ADMIN_BOARD_DETAIL = 'appAdminBoardDetail', MARKETPLACE = 'marketplace', APP_MARKETPLACE = 'appMarketplace', SERVICE_MARKETPLACE = 'serviceMarketplace', @@ -176,6 +176,7 @@ export enum ROLES { SETUP_CLIENT = 'setup_client', APPSTORE_VIEW = 'view_apps', APPSTORE_VIEW_SERVICES = 'view_service_marketplace', + SUBSCRIBE_APP_MARKETPLACE = 'subscribe_apps', SUBSCRIBE_SERVICE_MARKETPLACE = 'subscribe_service', APPSTORE_VIEW_DATASPACES = 'view_dataspaces', APPSTORE_ADD = 'add_app', @@ -185,7 +186,7 @@ export enum ROLES { APPMANAGEMENT_VIEW = 'add_apps', SERVICEMANAGEMENT_VIEW = 'add_service_offering', APP_MANAGEMENT = 'app_management', - SERVICE_SUBSCRIPTION_MANAGEMENT = 'activate_subscription', + SERVICE_SUBSCRIPTION_MANAGEMENT = 'service_management', APPOVERVIEW_VIEW = 'add_apps', SERVICEOVERVIEW_VIEW = 'add_service_offering', CONNECTOR_SETUP = 'setup_connector', diff --git a/src/types/Patterns.test.ts b/src/types/Patterns.test.ts index 602a1b53e..601842341 100644 --- a/src/types/Patterns.test.ts +++ b/src/types/Patterns.test.ts @@ -144,16 +144,23 @@ const TESTDATA = { 'BMW.Mini', 'BMW&Mini', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + '1234567890'.repeat(16), + 'Bayerische Motoren Werke Aktiengesellschaft', + '7-ELEVEN INTERNATIONAL LLC', + '5N Plus Lübeck GmbH', + 'Recht 24/7 Schröder Rechtsanwaltsgesellschaft mbH', + '+SEN Inc.', // leading special character + 'La Poste S.A.', + 'JPMORGAN ASIA-PACIFIC ADVANTAGE HYBRID FUND (QDII)', + 'Currency £$€¥¢', ], invalid: [ ' BMW', 'BMW TG', 'BMW ', - '123', - '!#@', - 'BMW/Mini]]', - 'BMW]]', - 'aaaaaaaaaaaa aaaaaaaaaaaaaaaaaa', + 'Bayerische Motoren Werke Aktiengesellschaft\n', // newline + 'W'.repeat(161), // 161 characters + '', // empty ], }, CNAMES: { diff --git a/src/types/Patterns.ts b/src/types/Patterns.ts index 901796d4b..130a733b6 100644 --- a/src/types/Patterns.ts +++ b/src/types/Patterns.ts @@ -50,7 +50,7 @@ export const Patterns = { UUID: /^[a-f0-9]{8}(-[a-f0-9]{4}){4}[a-f0-9]{8}$/i, EXTID: /^[a-z0-9]{6,36}$/i, COMPANY_NAME: - /^\d*?[a-zÀ-ÿ]\d?([a-z0-9À-ÿ!?@&_£$€¥\-.,:;'()*+#%=]\s?){2,40}$/i, + /^(?!.*\s$)([\wÀ-ÿ£$€¥¢@%*+\-/\\,.:;=<>!?&^#'\x22()[\]]\s?){1,160}$/, personName: personNamePattern, name: /^([A-Za-z\u00C0-\u017F-,.'](?!.*[-,.]{2})[A-Za-z\u00C0-\u017F-,.']{0,40} ?)[^ –]{1,40}$/, zipcode: /^[A-Z0-9-]{1,8}$/, @@ -81,14 +81,10 @@ export const Patterns = { offerCard: { serviceName: /^[^-\s()'"#@.&](?!.*[%&?,';:!\s-]{2}).{2,200}$/, serviceType: /^([A-Za-z])$/, - shortDescriptionEN: /^[^-\s()'"#@.&](?!.*[%&?,';:!\s-]{2}).{10,120}$/, - shortDescriptionDE: /^[^-\s()'"#@.&](?!.*[%&?,';:!\s-]{2}).{10,120}$/, + shortDescription: /^.{10,120}$/, }, offerPage: { - longDescriptionEN: - /^[^ @=<>*\-+#?%&_:;]([a-zA-Z0-9 !?@&#'"()[\]_\-+=<>/*.,;:%\r\n]){9,1999}$/, - longDescriptionDE: - /^[^ @=<>*\-+#?%&_:;]([a-zA-Z0-9 !?@&#'"()[\]_\-+=<>/*.,;:%\r\n]){9,1999}$/, + longDescription: /^.{10,1999}$/, }, appPage: { longDescriptionEN: diff --git a/yarn.lock b/yarn.lock index a58c660bb..cd1b3ac54 100644 --- a/yarn.lock +++ b/yarn.lock @@ -948,29 +948,29 @@ clsx "^2.1.0" prop-types "^15.8.1" -"@mui/core-downloads-tracker@^5.15.15": - version "5.15.15" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.15.tgz#2bc2bda50db66c12f10aefec907c48c8f669ef59" - integrity sha512-aXnw29OWQ6I5A47iuWEI6qSSUfH6G/aCsW9KmW3LiFqr7uXZBK4Ks+z8G+qeIub8k0T5CMqlT2q0L+ZJTMrqpg== +"@mui/core-downloads-tracker@^5.15.21": + version "5.16.7" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz#182a325a520f7ebd75de051fceabfc0314cfd004" + integrity sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ== -"@mui/icons-material@^5.11.16", "@mui/icons-material@^5.15.14": - version "5.15.15" - resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.15.15.tgz#84ce08225a531d9f5dc5132009d91164b456a0ae" - integrity sha512-kkeU/pe+hABcYDH6Uqy8RmIsr2S/y5bP2rp+Gat4CcRjCcVne6KudS1NrZQhUCRysrTDCAhcbcf9gt+/+pGO2g== +"@mui/icons-material@^5.11.16", "@mui/icons-material@^5.15.21": + version "5.15.21" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.15.21.tgz#1e29e1bdb90916be5b66c95c45951f441821f34a" + integrity sha512-yqkq1MbdkmX5ZHyvZTBuAaA6RkvoqkoAgwBSx9Oh0L0jAfj9T/Ih/NhMNjkl8PWVSonjfDUkKroBnjRyo/1M9Q== dependencies: "@babel/runtime" "^7.23.9" -"@mui/material@^5.13.2", "@mui/material@^5.15.14": - version "5.15.15" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.15.15.tgz#e3ba35f50b510aa677cec3261abddc2db7b20b59" - integrity sha512-3zvWayJ+E1kzoIsvwyEvkTUKVKt1AjchFFns+JtluHCuvxgKcLSRJTADw37k0doaRtVAsyh8bz9Afqzv+KYrIA== +"@mui/material@^5.13.2", "@mui/material@^5.15.21": + version "5.15.21" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.15.21.tgz#b2c8d756af570a61cb4975acf0e71dafb110b001" + integrity sha512-nTyCcgduKwHqiuQ/B03EQUa+utSMzn2sQp0QAibsnYe4tvc3zkMbO0amKpl48vhABIY3IvT6w9615BFIgMt0YA== dependencies: "@babel/runtime" "^7.23.9" "@mui/base" "5.0.0-beta.40" - "@mui/core-downloads-tracker" "^5.15.15" - "@mui/system" "^5.15.15" + "@mui/core-downloads-tracker" "^5.15.21" + "@mui/system" "^5.15.20" "@mui/types" "^7.2.14" - "@mui/utils" "^5.15.14" + "@mui/utils" "^5.15.20" "@types/react-transition-group" "^4.4.10" clsx "^2.1.0" csstype "^3.1.3" @@ -978,53 +978,55 @@ react-is "^18.2.0" react-transition-group "^4.4.5" -"@mui/private-theming@^5.15.14": - version "5.15.14" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.15.14.tgz#edd9a82948ed01586a01c842eb89f0e3f68970ee" - integrity sha512-UH0EiZckOWcxiXLX3Jbb0K7rC8mxTr9L9l6QhOZxYc4r8FHUkefltV9VDGLrzCaWh30SQiJvAEd7djX3XXY6Xw== +"@mui/private-theming@^5.16.6": + version "5.16.6" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.16.6.tgz#547671e7ae3f86b68d1289a0b90af04dfcc1c8c9" + integrity sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw== dependencies: "@babel/runtime" "^7.23.9" - "@mui/utils" "^5.15.14" + "@mui/utils" "^5.16.6" prop-types "^15.8.1" -"@mui/styled-engine@^5.15.14": - version "5.15.14" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.15.14.tgz#168b154c4327fa4ccc1933a498331d53f61c0de2" - integrity sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw== +"@mui/styled-engine@^5.16.6": + version "5.16.6" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.16.6.tgz#60110c106dd482dfdb7e2aa94fd6490a0a3f8852" + integrity sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g== dependencies: "@babel/runtime" "^7.23.9" "@emotion/cache" "^11.11.0" csstype "^3.1.3" prop-types "^15.8.1" -"@mui/system@^5.15.14", "@mui/system@^5.15.15": - version "5.15.15" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.15.15.tgz#658771b200ce3c4a0f28e58169f02e5e718d1c53" - integrity sha512-aulox6N1dnu5PABsfxVGOZffDVmlxPOVgj56HrUnJE8MCSh8lOvvkd47cebIVQQYAjpwieXQXiDPj5pwM40jTQ== +"@mui/system@^5.15.14", "@mui/system@^5.15.20": + version "5.16.7" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.16.7.tgz#4583ca5bf3b38942e02c15a1e622ba869ac51393" + integrity sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA== dependencies: "@babel/runtime" "^7.23.9" - "@mui/private-theming" "^5.15.14" - "@mui/styled-engine" "^5.15.14" - "@mui/types" "^7.2.14" - "@mui/utils" "^5.15.14" + "@mui/private-theming" "^5.16.6" + "@mui/styled-engine" "^5.16.6" + "@mui/types" "^7.2.15" + "@mui/utils" "^5.16.6" clsx "^2.1.0" csstype "^3.1.3" prop-types "^15.8.1" -"@mui/types@^7.2.14": - version "7.2.14" - resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.14.tgz#8a02ac129b70f3d82f2f9b76ded2c8d48e3fc8c9" - integrity sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ== +"@mui/types@^7.2.14", "@mui/types@^7.2.15": + version "7.2.15" + resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.15.tgz#dadd232fe9a70be0d526630675dff3b110f30b53" + integrity sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q== -"@mui/utils@^5.14.16", "@mui/utils@^5.15.14": - version "5.15.14" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.15.14.tgz#e414d7efd5db00bfdc875273a40c0a89112ade3a" - integrity sha512-0lF/7Hh/ezDv5X7Pry6enMsbYyGKjADzvHyo3Qrc/SSlTsQ1VkbDMbH0m2t3OR5iIVLwMoxwM7yGd+6FCMtTFA== +"@mui/utils@^5.14.16", "@mui/utils@^5.15.14", "@mui/utils@^5.15.20", "@mui/utils@^5.16.6": + version "5.16.6" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.16.6.tgz#905875bbc58d3dcc24531c3314a6807aba22a711" + integrity sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA== dependencies: "@babel/runtime" "^7.23.9" - "@types/prop-types" "^15.7.11" + "@mui/types" "^7.2.15" + "@types/prop-types" "^15.7.12" + clsx "^2.1.1" prop-types "^15.8.1" - react-is "^18.2.0" + react-is "^18.3.1" "@mui/x-data-grid@^6.19.11", "@mui/x-data-grid@^6.19.8": version "6.19.11" @@ -1088,10 +1090,10 @@ resolved "https://registry.yarnpkg.com/@react-hook/latest/-/latest-1.0.3.tgz#c2d1d0b0af8b69ec6e2b3a2412ba0768ac82db80" integrity sha512-dy6duzl+JnAZcDbNTfmaP3xHiKtbXYOaz3G51MGVljh548Y8MWzTr+PHLOfvpypEVW9zwvl+VyKjbWKEVbV1Rg== -"@reduxjs/toolkit@^2.2.6": - version "2.2.6" - resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-2.2.6.tgz#4a8356dad9d0c1ab255607a555d492168e0e3bc1" - integrity sha512-kH0r495c5z1t0g796eDQAkYbEQ3a1OLYN9o8jQQVZyKyw367pfRGS+qZLkHYvFHiUUdafpoSlQ2QYObIApjPWA== +"@reduxjs/toolkit@^2.2.7": + version "2.2.7" + resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-2.2.7.tgz#199e3d10ccb39267cb5aee92c0262fd9da7fdfb2" + integrity sha512-faI3cZbSdFb8yv9dhDTmGwclW0vk0z5o1cia+kf7gCbaCwHI5e+7tP57mJUv22pNcNbeA62GSrPpfrUfdXcQ6g== dependencies: immer "^10.0.3" redux "^5.0.1" @@ -1308,10 +1310,10 @@ lz-string "^1.5.0" pretty-format "^27.0.2" -"@testing-library/jest-dom@^6.4.6": - version "6.4.6" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.4.6.tgz#ec1df8108651bed5475534955565bed88c6732ce" - integrity sha512-8qpnGVincVDLEcQXWaHOf6zmlbwTKc6Us6PPu4CRnPXCzo2OGBS5cwgMMOWdxDpEz1mkbvXHpEy99M5Yvt682w== +"@testing-library/jest-dom@^6.4.8": + version "6.4.8" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.4.8.tgz#9c435742b20c6183d4e7034f2b329d562c079daa" + integrity sha512-JD0G+Zc38f5MBHA4NgxQMR5XtO5Jx9g86jqturNTt2WUfRmLDIY7iKkWHDCCTiDuFMre6nxAD5wHw9W5kI4rGw== dependencies: "@adobe/css-tools" "^4.4.0" "@babel/runtime" "^7.9.2" @@ -1508,11 +1510,16 @@ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== -"@types/prop-types@*", "@types/prop-types@^15.7.11": +"@types/prop-types@*": version "15.7.11" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== +"@types/prop-types@^15.7.12": + version "15.7.12" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" + integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== + "@types/qs@^6.9.15": version "6.9.15" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.15.tgz#adde8a060ec9c305a82de1babc1056e73bd64dce" @@ -2249,10 +2256,10 @@ cliui@^8.0.1: strip-ansi "^6.0.1" wrap-ansi "^7.0.0" -clsx@^2.0.0, clsx@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb" - integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg== +clsx@^2.0.0, clsx@^2.1.0, clsx@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" + integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== co@^4.6.0: version "4.6.0" @@ -2426,10 +2433,10 @@ date-fns@^3.6.0: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-3.6.0.tgz#f20ca4fe94f8b754951b24240676e8618c0206bf" integrity sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww== -dayjs@^1.11.12: - version "1.11.12" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.12.tgz#5245226cc7f40a15bf52e0b99fd2a04669ccac1d" - integrity sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg== +dayjs@^1.11.13: + version "1.11.13" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c" + integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" @@ -4861,10 +4868,10 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -phone@^3.1.49: - version "3.1.49" - resolved "https://registry.yarnpkg.com/phone/-/phone-3.1.49.tgz#607672cbb2a7e6808b800ce597ab98640c6708f8" - integrity sha512-S+rHWXSQrllK5eQwz0sDbwfxQ2PzennWPgsP/jdpEPH3k7P5IBJZYjvYfU8e/RF5AwKCgOtzbTGTGJcBSLJVVw== +phone@^3.1.50: + version "3.1.50" + resolved "https://registry.yarnpkg.com/phone/-/phone-3.1.50.tgz#2b97ea469ff4669fe9091da8ddc3671fc2b7823e" + integrity sha512-TRmb2bX3sX+rrOrc8FRd8hmy4exoH2Lu3vjBP/dLgwwci1lv7DbjJ2iHMe7X4Hm8Pa0rJcfqTbq/O1vjU4NgxQ== picocolors@^1.0.0: version "1.0.0" @@ -5029,10 +5036,10 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-is@^18.0.0, react-is@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== +react-is@^18.0.0, react-is@^18.2.0, react-is@^18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== react-player@^2.15.1: version "2.15.1"