diff --git a/CHANGELOG.md b/CHANGELOG.md index a825fd911..009942bd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,40 @@ - Fixed incorrect usage of pre-commit hook - Fix consistency issue in constants file. Use camel case for all page paths. Update corresponding usage in other files +## 2.1.0-RC2 + +### Feature + +- **Imprint**: + - updated imprint page with anonymized data [#906](https://github.com/eclipse-tractusx/portal-frontend/pull/906) + +### Bugfixes + +- **Company Data Management**: + - removed unwanted input forms [#887](https://github.com/eclipse-tractusx/portal-frontend/issues/887) + - fixed crash issue in details page + - added error handling component in table [#888](https://github.com/eclipse-tractusx/portal-frontend/issues/888) +- **User Management**: + - fixed disable button state when deselect all checkboxes [#923](https://github.com/eclipse-tractusx/portal-frontend/pull/923) +- **Connector Management**: + - updated GET endpoint for 'Connect Company Connector' to consider technical user status [#938](https://github.com/eclipse-tractusx/portal-frontend/pull/938) +- **UI Language** + - updated translations in locale files [#935](https://github.com/eclipse-tractusx/portal-frontend/pull/935) +- **Application Requests**: + - made UI improvements [#911](https://github.com/eclipse-tractusx/portal-frontend/pull/911) +- **Connector Management**: + - show appropriate error information to the user along with refetch button [#923](https://github.com/eclipse-tractusx/portal-frontend/issues/923) +- **App marketplace**: + - show appropriate error information to the user along with refetch button [#910](https://github.com/eclipse-tractusx/portal-frontend/pull/910) +- **Service Marketplace**: + - show appropriate error information to the user along with refetch button [#910](https://github.com/eclipse-tractusx/portal-frontend/pull/910) + +### Technical Support + +- **Upgraded dependencies** + - bumped braces from 3.0.2 to 3.0.3 [#927](https://github.com/eclipse-tractusx/portal-frontend/pull/927) + - bumped ws from 8.16.0 to 8.18.0 [#928](https://github.com/eclipse-tractusx/portal-frontend/pull/928) + ## 2.1.0-RC1 ### Change @@ -34,7 +68,7 @@ - **Connector Management**: - released connector detail view including change connector url, view SD document, etc. Add details overlay [#848](https://github.com/eclipse-tractusx/portal-frontend/pull/848) -### Technical Maintenance +### Technical Support - **Dependencies**: - bumped GitHub actions [#846](https://github.com/eclipse-tractusx/portal-frontend/pull/846) diff --git a/DEPENDENCIES b/DEPENDENCIES index b11d3dce8..23f1ea071 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -42,7 +42,7 @@ npm/npmjs/-/base64-js/1.5.1, MIT, approved, clearlydefined npm/npmjs/-/binary-extensions/2.3.0, MIT, approved, #13867 npm/npmjs/-/brace-expansion/1.1.11, MIT, approved, clearlydefined npm/npmjs/-/brace-expansion/2.0.1, MIT, approved, clearlydefined -npm/npmjs/-/braces/3.0.2, MIT, approved, #14866 +npm/npmjs/-/braces/3.0.3, MIT, approved, #14866 npm/npmjs/-/browserslist/4.23.0, MIT, approved, clearlydefined npm/npmjs/-/bs-logger/0.2.6, MIT, approved, clearlydefined npm/npmjs/-/bser/2.1.1, Apache-2.0, approved, clearlydefined @@ -168,7 +168,7 @@ npm/npmjs/-/fastq/1.17.1, ISC, approved, clearlydefined npm/npmjs/-/fb-watchman/2.0.2, MIT AND Apache-2.0, approved, #5379 npm/npmjs/-/file-entry-cache/6.0.1, MIT, approved, clearlydefined npm/npmjs/-/file-selector/0.6.0, MIT, approved, #3230 -npm/npmjs/-/fill-range/7.0.1, MIT, approved, clearlydefined +npm/npmjs/-/fill-range/7.1.1, MIT, approved, #14867 npm/npmjs/-/find-root/1.1.0, MIT, approved, clearlydefined npm/npmjs/-/find-up/4.1.0, MIT, approved, clearlydefined npm/npmjs/-/find-up/5.0.0, MIT, approved, clearlydefined @@ -544,7 +544,7 @@ npm/npmjs/-/which/2.0.2, ISC, approved, clearlydefined npm/npmjs/-/wrap-ansi/7.0.0, MIT, approved, clearlydefined npm/npmjs/-/wrappy/1.0.2, ISC, approved, clearlydefined npm/npmjs/-/write-file-atomic/4.0.2, ISC, approved, clearlydefined -npm/npmjs/-/ws/8.16.0, MIT, approved, clearlydefined +npm/npmjs/-/ws/8.18.0, MIT, approved, clearlydefined npm/npmjs/-/xml-name-validator/4.0.0, Apache-2.0, approved, clearlydefined npm/npmjs/-/xmlchars/2.2.0, MIT, approved, clearlydefined npm/npmjs/-/y18n/5.0.8, ISC, approved, clearlydefined diff --git a/package.json b/package.json index df05dc07a..b64f09216 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@catena-x/portal-frontend", - "version": "v2.1.0-RC1", + "version": "v2.1.0-RC2", "description": "Catena-X Portal Frontend", "author": "Catena-X Contributors", "license": "Apache-2.0", diff --git a/src/assets/locales/de/footer.json b/src/assets/locales/de/footer.json index 9dc3cd7a5..5b2151487 100644 --- a/src/assets/locales/de/footer.json +++ b/src/assets/locales/de/footer.json @@ -6,14 +6,19 @@ "imprint": { "title": "Abdruck", "directors": "Verwaltungsrat", - "ceo": "HAUPTGESCHÄFTSFÜHRER", - "deputyCeo": "Stellvertretender Geschäftsführer", - "treasurer": "Schatzmeister", + "ceo": "CEO: [Platzhalter für CEO-Name]", + "deputyCeo": "Stellvertretender CEO: [Platzhalter für Name des stellvertretenden CEO]", + "treasurer": "Schatzmeister: [Platzhalter für Name des Schatzmeisters]", "address": "Adresse", - "contact&support": "Kontakt & Support", - "contact&supportDesc": "Antworten auf viele Fragen finden Sie auf unserer Support-Seite. Sollte Ihre Frage nicht beantwortet werden, nutzen Sie bitte unser Kontaktformular. Alternativ können Sie uns auch per E-Mail unter info@catena-x.net kontaktieren.", + "contact&Support": "Kontakt & Support", + "contact&SupportDesc": "Wenn Sie Hilfe benötigen, besuchen Sie bitte unsere Support-Seite oder nutzen Sie das Kontaktformular auf unserer Website. Für direkte Anfragen kontaktieren Sie uns über die bereitgestellten Kanäle auf der Kontaktseite.", "privacy": "Privatsphäre", - "privacyDesc": "Für Fragen zum Datenschutz und Informationen darüber, welche Daten bei Ihnen erhoben werden, finden Sie alle Details unter folgendem Link:" + "privacyDesc": "Für Fragen zum Datenschutz und Informationen darüber, welche Daten bei Ihnen erhoben werden, finden Sie alle Details unter folgendem Link:", + "privacyPolicy": "Datenschutzrichtlinie", + "nameOfOrganization": "[Name der Organisation]", + "careOf": "c/o [Platzhalter für Dienstleistungsunternehmen]", + "street": "[Platzhalter für Straße]", + "postalCode&City": "[Platzhalter für Postleitzahl und Ort]" }, "privacy": { "title": "Privatsphäre", diff --git a/src/assets/locales/de/main.json b/src/assets/locales/de/main.json index d763ec012..6c271492c 100644 --- a/src/assets/locales/de/main.json +++ b/src/assets/locales/de/main.json @@ -106,7 +106,7 @@ "Lang_en": "Sprache auf Englisch stellen" }, "error": { - "deleteTechUserNotificationErrorDescription": "Please try it later again or contact your administrator.", + "deleteTechUserNotificationErrorDescription": "Bitte versuchen Sie es später noch einmal oder wenden Sie sich an Ihren Administrator.", "tryAgain": "Try Again", "errorBar": "Something went wrong. Try again", "title": "Hoppla! Etwas ist schiefgelaufen.", @@ -165,7 +165,7 @@ "admin": { "registration-requests": { "columns": { - "companyinfo": "Bewerbungsinformationen des Unternehmens", + "companyinfo": "Unternehmen", "contact": "Kontakt", "bpn": "BPN", "age": "Alter", @@ -204,7 +204,8 @@ "appProvider": "App Anbieter", "onboardingProvider": "Onboarding Service Anbieter", "serviceProvider": "Service Anbieter", - "noinfo": "no data available", + "noinfo": "Keine Daten verfügbar", + "noRolesAvailable": "Keine Rollen verfügbar", "commercialRegisterNumber": "Handelsregisternummer", "vatId": "VAT ID", "leiCode": "LEI Code", @@ -233,10 +234,10 @@ "error": "Bitte überprüfen Sie Ihre Eingabe erneut; Die Nachricht sollte nicht mit '=' beginnen." }, "addBpn": { - "successTitle": "Update BPN number successfully completed", - "successDescription": "Update BPN number successfully completed.", + "successTitle": "Aktualisierung der BPN-Nummer erfolgreich abgeschlossen", + "successDescription": "Aktualisierung der BPN-Nummer erfolgreich abgeschlossen", "errorTitle": "Something went wrong", - "errorDescription": "Something went wrong. Please try it later again or contact your administrator." + "errorDescription": "Something went wrong. Bitte versuchen Sie es später noch einmal oder wenden Sie sich an Ihren Administrator." }, "filter": { "all": "Alle", @@ -322,7 +323,9 @@ "modularproduction": "Modular Production" }, "noMatch": "Keine Treffer", - "for": "zu Ihrem Suchausdruck" + "for": "zu Ihrem Suchausdruck", + "dataLoadFailed": "Das Laden der Daten ist aufgrund fehlender Berechtigungsrechte fehlgeschlagen.", + "loadFailed": "Laden fehlgeschlagen" } }, "semantichub": { @@ -937,42 +940,42 @@ }, "deleteUserConfirm": { "header": "Delete user account", - "confirmTitle": "Are you sure you want to delete the user account of {userName}?", - "description": "By deleting the account, the access of this user to Catena-X as well as any rights and data access will get revoked.", - "note": "Note: If you delete the account now, you wont be able to reactivate it later.", + "confirmTitle": "Sind Sie sicher, dass Sie das Benutzerkonto von {userName} löschen möchten?", + "description": "Durch das Löschen des Kontos werden dem Benutzer der Zugriff auf Catena-X sowie sämtliche Rechte und Datenzugriffe entzogen.", + "note": "Hinweis: Wenn Sie das Konto jetzt löschen, können Sie es später nicht erneut aktivieren.", "successTitle": "User successfully deleted", - "successDescription": "The user got successfully deleted. All rights have been disabled. Please note that the user might still be able to use the application for the next 10 minutes. Latest in 10 minutes the user is automatically logged out and a new login attempt will get declined", + "successDescription": "Der Benutzer wurde erfolgreich gelöscht. Alle Rechte wurden deaktiviert. Bitte beachten Sie, dass der Benutzer die Anwendung möglicherweise noch in den nächsten 10 Minuten nutzen kann. Spätestens nach 10 Minuten wird der Benutzer automatisch abgemeldet und ein neuer Anmeldeversuch wird abgelehnt", "errorTitle": "Something went wrong", - "errorDescription": "Your user couldn't get deleted. Please try it later again or contact your administrator." + "errorDescription": "Ihr Benutzer konnte nicht gelöscht werden. Bitte versuchen Sie es später noch einmal oder wenden Sie sich an Ihren Administrator." }, "suspendUserConfirm": { "header": "Suspend user account", - "confirmTitle": "Are you sure you want to suspend the user account of {userName}?", - "description": "By suspending the account, the access of this user to Catena-X as well as any permissions and data accesses will get deactivated temporarily.", - "note": "Note: Suspended accounts can get reactivated anytime.", + "confirmTitle": "Sind Sie sicher, dass Sie das Benutzerkonto von {userName} sperren möchten?", + "description": "Durch die Sperrung des Kontos werden der Zugriff dieses Benutzers auf Catena-X sowie alle Berechtigungen und Datenzugriffe vorübergehend deaktiviert.", + "note": "Hinweis: Gesperrte Konten können jederzeit reaktiviert werden.", "successTitle": "User successfully suspended", - "successDescription": "The user is successfully suspended and all rights are disabled.", + "successDescription": "Der Benutzer wurde erfolgreich gesperrt und alle Rechte wurden deaktiviert.", "errorTitle": "Something went wrong", - "errorDescription": "Your user couldn't get suspended. Please try it later again or contact your administrator." + "errorDescription": "Ihr Benutzer konnte nicht gesperrt werden. Bitte versuchen Sie es später noch einmal oder wenden Sie sich an Ihren Administrator." }, "resetPasswordConfirm": { "header": "Password Reset", "confirmTitle": "Are you sure you want to reset the password?", - "note": "The user {userName} will receive an email to reset the password.", - "successTitle": "Password Reset successfully triggered", - "successDescription": "The password reset request got send to {userName}.", + "note": "Der Benutzer {userName} erhält eine E-Mail zum Zurücksetzen des Passworts.", + "successTitle": "Passwort-Reset erfolgreich ausgelöst", + "successDescription": "Die Anfrage zum Zurücksetzen des Passworts wurde an {userName} gesendet.", "errorTitle": "Something went wrong", - "errorDescription": "The password reset was unsuccessful. Please try it later again or contact the administrator." + "errorDescription": "Das Zurücksetzen des Passworts war nicht erfolgreich. Bitte versuchen Sie es später noch einmal oder wenden Sie sich an den Administrator." }, "deleteOwnUserConfirm": { "header": "Delete my user account", - "confirmTitle": "Are you sure you want to delete this user account?", - "description": "By deleting the account, the access of this user to Catena-X as well as any rights and data access will get revoked.", - "note": "Note: If you delete the account now, you wont be able to reactivate it later.", + "confirmTitle": "Sind Sie sicher, dass Sie dieses Benutzerkonto löschen möchten?", + "description": "Durch das Löschen des Kontos werden dem Benutzer der Zugriff auf Catena-X sowie sämtliche Rechte und Datenzugriffe entzogen.", + "note": "Hinweis: Wenn Sie das Konto jetzt löschen, können Sie es später nicht erneut aktivieren.", "successTitle": "User successfully deleted", - "successDescription": "Your user got successfully deleted, you will get disconnected within the following 5 seconds.", + "successDescription": "Ihr Benutzer wurde erfolgreich gelöscht. Ihre Verbindung wird innerhalb der folgenden 5 Sekunden getrennt.", "errorTitle": "Something went wrong", - "errorDescription": "Your user couldn't get deleted. Please try it later again or contact your administrator." + "errorDescription": "Ihr Benutzer konnte nicht gelöscht werden. Bitte versuchen Sie es später noch einmal oder wenden Sie sich an Ihren Administrator." } }, "idpmanagement": { @@ -1379,6 +1382,8 @@ "noDataMessage": "No data available", "subscriptionHeading": ">> there are already active subscriptions for the service {serviceName}", "subscribeSuccessMsg": "Subscribed Successfully", + "dataLoadFailed": "Das Laden der Daten ist aufgrund fehlender Berechtigungsrechte fehlgeschlagen.", + "loadFailed": "Laden fehlgeschlagen", "newServices": "New Services", "recommendations": "Recommendations", "allServices": "All Services", diff --git a/src/assets/locales/en/footer.json b/src/assets/locales/en/footer.json index 323345259..e5821af9f 100644 --- a/src/assets/locales/en/footer.json +++ b/src/assets/locales/en/footer.json @@ -6,14 +6,19 @@ "imprint": { "title": "Imprint", "directors": "Board of Directors", - "ceo": "CEO", - "deputyCeo": "Deputy CEO", - "treasurer": "Treasurer", + "ceo": "CEO: [Placeholder for CEO Name]", + "deputyCeo": "Deputy CEO: [Placeholder for Deputy CEO Name]", + "treasurer": "Treasurer: [Placeholder for Treasurer Name]", "address": "Address", - "contact&support": "Contact & Support", - "contact&supportDesc": "You can find answers to many questions on our support page. If your question is not answered, please use our contact form. Alternatively, you can also contact us by email at info@catena-x.net.", + "contact&Support": "Contact & Support", + "contact&SupportDesc": "For assistance, please refer to our support page or use the contact form provided on our website. For direct inquiries, contact us via the provided channels on the contact page.", "privacy": "Privacy", - "privacyDesc": "For questions about data protection and information about what data is collected from you, you can find all the details under the following link:" + "privacyDesc": "For questions about data protection and information about what data is collected from you, you can find all the details under the following link:", + "privacyPolicy": "Privacy Policy", + "nameOfOrganization": "[Name of the Organization]", + "careOf": "c/o [Service Company Placeholder]", + "street": "[Placeholder for Street]", + "postalCode&City": "[Placeholder for Postal Code and City]" }, "privacy": { "title": "Privacy", diff --git a/src/assets/locales/en/main.json b/src/assets/locales/en/main.json index 269ff3323..cd9b3a1f9 100644 --- a/src/assets/locales/en/main.json +++ b/src/assets/locales/en/main.json @@ -164,7 +164,7 @@ "admin": { "registration-requests": { "columns": { - "companyinfo": "Company Application Info", + "companyinfo": "Company", "contact": "Contact", "bpn": "BPN", "age": "Age", @@ -203,7 +203,8 @@ "appProvider": "App Provider", "onboardingProvider": "Onboarding Service Provider", "serviceProvider": "Service Provider", - "noinfo": "no data available", + "noinfo": "No data available", + "noRolesAvailable": "No roles available", "commercialRegisterNumber": "Commercial Register Number", "vatId": "VAT ID", "leiCode": "LEI Code", @@ -321,7 +322,9 @@ "modularproduction": "Modular Production" }, "noMatch": "No Match", - "for": "for your search term" + "for": "for your search term", + "dataLoadFailed": "Data Load Failed due to missing permission rights.", + "loadFailed": "Load Failed" } }, "semantichub": { @@ -1346,6 +1349,8 @@ "noDataMessage": "No data available", "subscriptionHeading": ">> there are already active subscriptions for the service {serviceName}", "subscribeSuccessMsg": "Subscribed Successfully", + "dataLoadFailed": "Data Load Failed due to missing permission rights.", + "loadFailed": "Load Failed", "newServices": "New Services", "recommendations": "Recommendations", "allServices": "All Services", diff --git a/src/components/overlays/EditPortalRoles/index.tsx b/src/components/overlays/EditPortalRoles/index.tsx index 788fb7a4e..2f08f5a57 100644 --- a/src/components/overlays/EditPortalRoles/index.tsx +++ b/src/components/overlays/EditPortalRoles/index.tsx @@ -106,10 +106,11 @@ export default function EditPortalRoles({ id }: { id: string }) { } const checkConfirmButton = () => - assignedRoles && - selectedRoles && - assignedRoles.length === selectedRoles.length && - assignedRoles.every((value) => selectedRoles.includes(value)) + selectedRoles.length === 0 || + (assignedRoles && + selectedRoles && + assignedRoles.length === selectedRoles.length && + assignedRoles.every((value) => selectedRoles.includes(value))) return ( <> diff --git a/src/components/pages/Admin/components/RegistrationRequests/CompanyDetailOverlay/index.tsx b/src/components/pages/Admin/components/RegistrationRequests/CompanyDetailOverlay/index.tsx index 801520989..0b1862aa9 100644 --- a/src/components/pages/Admin/components/RegistrationRequests/CompanyDetailOverlay/index.tsx +++ b/src/components/pages/Admin/components/RegistrationRequests/CompanyDetailOverlay/index.tsx @@ -222,12 +222,7 @@ const CompanyDetailOverlay = ({ )} ) : ( - + {t('content.admin.registration-requests.overlay.noinfo')} )} @@ -241,17 +236,25 @@ const CompanyDetailOverlay = ({ key: '', value: ( <> - {selectedCompany?.companyRoles?.map( - (role: { companyRole: string }) => ( - + {selectedCompany?.companyRoles?.length > 0 ? ( + selectedCompany?.companyRoles?.map( + (role: { companyRole: string }) => ( + + ) ) + ) : ( + + {t( + 'content.admin.registration-requests.overlay.noRolesAvailable' + )} + )} ), diff --git a/src/components/pages/Admin/components/RegistrationRequests/components/RequestList/index.tsx b/src/components/pages/Admin/components/RegistrationRequests/components/RequestList/index.tsx index 37d2af012..662270e9f 100644 --- a/src/components/pages/Admin/components/RegistrationRequests/components/RequestList/index.tsx +++ b/src/components/pages/Admin/components/RegistrationRequests/components/RequestList/index.tsx @@ -123,6 +123,11 @@ export const RequestList = ({ return (
+ sx={{ + '.MuiDataGrid-cell': { + alignContent: 'center !important', + }, + }} autoFocus={false} searchExpr={searchExpr} rowHeight={90} diff --git a/src/components/pages/Admin/components/RegistrationRequests/registrationTableColumns.tsx b/src/components/pages/Admin/components/RegistrationRequests/registrationTableColumns.tsx index f02e0e72b..e185305bd 100644 --- a/src/components/pages/Admin/components/RegistrationRequests/registrationTableColumns.tsx +++ b/src/components/pages/Admin/components/RegistrationRequests/registrationTableColumns.tsx @@ -77,7 +77,7 @@ export const StatusProgress = ({ totalItems={row.applicationChecklist.length} /> @@ -103,7 +103,7 @@ export const StatusProgress = ({ )} {type && ( { e.stopPropagation() diff --git a/src/components/pages/AppMarketplace/AppMarketplace.scss b/src/components/pages/AppMarketplace/AppMarketplace.scss index 974b9b9c8..ddfbe9b81 100644 --- a/src/components/pages/AppMarketplace/AppMarketplace.scss +++ b/src/components/pages/AppMarketplace/AppMarketplace.scss @@ -23,7 +23,7 @@ .app-store { width: 100%; padding: 0; - margin-bottom: -230px; + margin-bottom: -50px; input[type='radio'] { margin-left: 12px; diff --git a/src/components/pages/AppMarketplace/components/AppListSection/index.tsx b/src/components/pages/AppMarketplace/components/AppListSection/index.tsx index feed78d21..33f043518 100644 --- a/src/components/pages/AppMarketplace/components/AppListSection/index.tsx +++ b/src/components/pages/AppMarketplace/components/AppListSection/index.tsx @@ -18,7 +18,11 @@ ********************************************************************************/ import { useTranslation } from 'react-i18next' -import { CircleProgress, Typography } from '@catena-x/portal-shared-components' +import { + CircleProgress, + ErrorBar, + Typography, +} from '@catena-x/portal-shared-components' import { useTheme } from '@mui/material' import { AppListGroupView } from '../AppListGroupView' import { useDispatch, useSelector } from 'react-redux' @@ -34,6 +38,7 @@ import { appsControlSelector } from 'features/apps/control' import { type AppMarketplaceApp } from 'features/apps/types' import { useEffect, useState } from 'react' import { cloneDeep } from 'lodash' +import NoItems from 'components/pages/NoItems' export const label = 'AppList' @@ -43,12 +48,16 @@ export default function AppListSection() { const dispatch = useDispatch() const navigate = useNavigate() - const { data } = useFetchActiveAppsQuery() + const { data, error, isError, refetch } = useFetchActiveAppsQuery() const { data: favoriteItems } = useFetchFavoriteAppsQuery() const control = useSelector(appsControlSelector) const [list, setList] = useState([]) const [favList, setFavlist] = useState([]) + // To-Do fix the type issue with status and data from FetchBaseQueryError + // eslint-disable-next-line + const activeAppsError = error as any + const checkIsFavorite = (appId: string) => favList?.includes(appId) const addOrRemoveFavorite = (event: React.MouseEvent, appId: string) => { @@ -133,10 +142,31 @@ export default function AppListSection() { ) const renderList = () => { + if (data && data.length === 0) return if (!data) return renderProgress() if (!data.length) return renderNoMatch() return renderGroups() } - return
{renderList()}
+ return ( +
+ {!isError ? ( + renderList() + ) : ( + = 400 && + activeAppsError?.data?.status < 500 + ? t('content.appstore.appOverviewSection.dataLoadFailed') + : t('content.appstore.appOverviewSection.loadFailed') + } + showButton={ + activeAppsError.code >= 500 && activeAppsError?.data?.status < 600 + } + buttonText={t('error.tryAgain')} + handleButton={refetch} + /> + )} +
+ ) } diff --git a/src/components/pages/CompanyData/components/AddressDetails.tsx b/src/components/pages/CompanyData/components/AddressDetails.tsx index a150f324f..3db7f0eb9 100644 --- a/src/components/pages/CompanyData/components/AddressDetails.tsx +++ b/src/components/pages/CompanyData/components/AddressDetails.tsx @@ -33,23 +33,20 @@ export default function AddressDetails({ const addressData = [ { key: t('content.companyData.address.form.companySite.name'), - value: companyAddressData.site.name ?? '', - }, - { - key: t('content.companyData.address.form.addressTitle.name'), - value: companyAddressData.address.name ?? '', + value: companyAddressData.site?.name ?? '', }, { key: t('content.companyData.address.form.street.name'), - value: companyAddressData.address.physicalPostalAddress.street.name ?? '', + value: + companyAddressData.address?.physicalPostalAddress.street.name ?? '', }, { key: t('content.companyData.address.form.postal.name'), - value: companyAddressData.address.physicalPostalAddress.postalCode ?? '', + value: companyAddressData.address?.physicalPostalAddress.postalCode ?? '', }, { key: t('content.companyData.address.form.city.name'), - value: companyAddressData.address.physicalPostalAddress.city ?? '', + value: companyAddressData.address?.physicalPostalAddress.city ?? '', }, ] return ( diff --git a/src/components/pages/CompanyData/components/CompanyAddressList.tsx b/src/components/pages/CompanyData/components/CompanyAddressList.tsx index 74867c333..2ac52d56d 100644 --- a/src/components/pages/CompanyData/components/CompanyAddressList.tsx +++ b/src/components/pages/CompanyData/components/CompanyAddressList.tsx @@ -54,10 +54,17 @@ export const CompanyAddressList = ({ handleConfirm: () => void }) => { const { t } = useTranslation() - const { data, refetch: refreshSharingData } = useFetchSharingStateQuery() + const { + data, + refetch: refreshSharingData, + isFetching, + error: sharingStateError, + } = useFetchSharingStateQuery() const sharingStates = data?.content - const [outputRequest] = useFetchOutputCompanyBusinessPartnersMutation() - const [inputRequest] = useFetchInputCompanyBusinessPartnersMutation() + const [outputRequest, { isLoading: isOutputLoading, error: outputError }] = + useFetchOutputCompanyBusinessPartnersMutation() + const [inputRequest, { isLoading: isInputLoading, error: inputError }] = + useFetchInputCompanyBusinessPartnersMutation() const [outputs, setOutputs] = useState([]) const [inputs, setInputs] = useState([]) const [details, setDetails] = useState(false) @@ -72,12 +79,15 @@ export const CompanyAddressList = ({ ) .map((state) => state.externalId) - if (params && params?.length > 0) + if (params && params?.length > 0) { await inputRequest(params) .unwrap() .then((payload) => { setOutputs(payload.content) }) + } else { + setOutputs([]) + } } const getOutputItems = async () => { @@ -86,12 +96,15 @@ export const CompanyAddressList = ({ (state) => state.sharingStateType === SharingStateStatusType.Success ) .map((state) => state.externalId) - if (params && params?.length > 0) + if (params && params?.length > 0) { await outputRequest(params) .unwrap() .then((payload) => { setInputs(payload.content) }) + } else { + setInputs([]) + } } useEffect(() => { @@ -141,9 +154,19 @@ export const CompanyAddressList = ({ } } + const errorObj = { + status: 0, + } + + const error = sharingStateError ?? inputError ?? outputError + + if (error && 'status' in error) { + errorObj.status = error.status as number + } + return ( <> - {inputs.length > 0 || outputs.length > 0 ? ( + {!isFetching && !isOutputLoading && !isInputLoading ? ( row.createdAt} rows={inputs.concat(outputs)} onCellClick={onRowClick} + error={errorObj} columns={[ { field: 'site', diff --git a/src/components/pages/CompanyData/components/EditForm.tsx b/src/components/pages/CompanyData/components/EditForm.tsx index 6f9ad05a8..8102a1a51 100644 --- a/src/components/pages/CompanyData/components/EditForm.tsx +++ b/src/components/pages/CompanyData/components/EditForm.tsx @@ -90,11 +90,6 @@ export default function EditForm({ inputParams.address.physicalPostalAddress.city = form.body.city inputParams.address.physicalPostalAddress.country = form.body.countryCode inputParams.address.physicalPostalAddress.street.name = form.body.street - inputParams.identifiers.push({ - type: form.body.countryIdentifier, - value: form.body.identifierNumber, - issuingBody: null, - }) setInput(inputParams) } @@ -115,8 +110,12 @@ export default function EditForm({ setIsValid(form !== undefined) if (form) { inputParams.site.name = form.body.siteName - inputParams.address.name = form.body.addressTitle inputParams.address.addressType = AddressType.AdditionalAddress + inputParams.identifiers.push({ + type: form.body.countryIdentifier, + value: form.body.identifierNumber, + issuingBody: null, + }) getFilledData(form) } } @@ -163,6 +162,7 @@ export default function EditForm({ ? handleAddressValidation(form) : handleSiteValidation(form) }} + isAddress={isAddress} /> diff --git a/src/components/pages/CompanyData/components/FormFields.tsx b/src/components/pages/CompanyData/components/FormFields.tsx index befcd7a01..3b5ede58b 100644 --- a/src/components/pages/CompanyData/components/FormFields.tsx +++ b/src/components/pages/CompanyData/components/FormFields.tsx @@ -50,7 +50,6 @@ const responseToForm = (data: CompanyDataFieldsType) => { form.countryCode = data.countryCode ?? '' form.countryIdentifier = data.countryIdentifier ?? '' form.identifierNumber = data.identifierNumber ?? '' - form.addressTitle = data.addressTitle ?? '' return form } @@ -62,7 +61,6 @@ const formToUpdate = (form: IHashMap) => ({ countryCode: form.countryCode, countryIdentifier: form.countryIdentifier, identifierNumber: form.identifierNumber, - addressTitle: form.addressTitle, }) const UpdateForm = ({ @@ -70,11 +68,13 @@ const UpdateForm = ({ onChange, identifiers, newForm, + isAddress, }: { data: CompanyDataFieldsType onChange: (key: string, value: string | undefined) => boolean identifiers: UniqueIdentifier[] newForm: boolean + isAddress: boolean }) => { const { t } = useTranslation() const [defaultIdentifier, setDefaultIdentifier] = @@ -89,19 +89,6 @@ const UpdateForm = ({ return ( <> -
- -
-
- { - onChange('countryIdentifier', val.label) - }} - keyTitle={'label'} - /> -
-
- - isCommercialRegNumber(expr) || - isVatID(expr) || - isVies(expr) || - isEori(expr) - } - onValid={onChange} - onInvalid={onChange} - errorMessage={t( - 'content.companyData.site.form.identifierNumber.error' - )} - skipInitialValidation={newForm} - /> -
+ {isAddress && ( + <> +
+ { + onChange('countryIdentifier', val.label) + }} + keyTitle={'label'} + /> +
+
+ + isCommercialRegNumber(expr) || + isVatID(expr) || + isVies(expr) || + isEori(expr) + } + onValid={onChange} + onInvalid={onChange} + errorMessage={t( + 'content.companyData.site.form.identifierNumber.error' + )} + skipInitialValidation={newForm} + /> +
+ + )} ) } @@ -215,9 +208,11 @@ const UpdateForm = ({ export const FormFields = ({ onValid, newForm, + isAddress, }: { onValid: (form: { body: CompanyDataFieldsType } | undefined) => void newForm: boolean + isAddress: boolean }) => { const companyData = useSelector(companyDataSelector) @@ -247,7 +242,6 @@ export const FormFields = ({ : companyData.address.physicalPostalAddress.country, countryIdentifier: newForm ? '' : identifier?.[0]?.type ?? '', identifierNumber: newForm ? '' : identifier?.[0]?.value ?? '', - addressTitle: newForm ? '' : companyData.address.name, } const [formData, setFormData] = useState>( responseToForm(data) @@ -264,8 +258,7 @@ export const FormFields = ({ current.postalCode && current.countryCode && current.identifierNumber && - current.countryIdentifier && - current.addressTitle + current.countryIdentifier onValid( formValid ? { @@ -288,6 +281,7 @@ export const FormFields = ({ identifiers={identifiers ?? []} data={data} onChange={checkData} + isAddress={isAddress} /> ) } diff --git a/src/components/pages/CompanyData/components/StatusInformation.tsx b/src/components/pages/CompanyData/components/StatusInformation.tsx index 179346de2..796754090 100644 --- a/src/components/pages/CompanyData/components/StatusInformation.tsx +++ b/src/components/pages/CompanyData/components/StatusInformation.tsx @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -import { Typography } from '@catena-x/portal-shared-components' +import { Chip, Typography } from '@catena-x/portal-shared-components' import { Box } from '@mui/material' import { statusSelector } from 'features/companyData/slice' import { useTranslation } from 'react-i18next' @@ -25,6 +25,7 @@ import { useSelector } from 'react-redux' import HourglassBottomIcon from '@mui/icons-material/HourglassBottom' import WarningAmberIcon from '@mui/icons-material/WarningAmber' import CheckCircleIcon from '@mui/icons-material/CheckCircle' +import { SharingStateStatusType } from 'features/companyData/companyDataApiSlice' export default function StatusInformation() { const { t } = useTranslation() @@ -33,11 +34,24 @@ export default function StatusInformation() { const statusIcon: Record = { Success: , Pending: , - Ready: , - Initial: , + Ready: , + Initial: , Error: , } + const getStatusColor = (status: string | undefined) => { + if (status === SharingStateStatusType.Success) { + return 'success' + } else if ( + status === SharingStateStatusType.Pending || + status === SharingStateStatusType.Initial + ) { + return 'warning' + } else { + return 'error' + } + } + return ( - {statusIcon[status]} - - {status} - + /> ) diff --git a/src/components/pages/EdcConnector/ConfigurationDetailsOverlay.tsx b/src/components/pages/EdcConnector/ConfigurationDetailsOverlay.tsx index 5d089c898..17566dc2d 100644 --- a/src/components/pages/EdcConnector/ConfigurationDetailsOverlay.tsx +++ b/src/components/pages/EdcConnector/ConfigurationDetailsOverlay.tsx @@ -29,6 +29,7 @@ import { type TableType, Typography, CircleProgress, + ErrorBar, } from '@catena-x/portal-shared-components' import { useFetchDecentralIdentityUrlsQuery } from 'features/connector/connectorApiSlice' import './EdcConnector.scss' @@ -45,7 +46,12 @@ const ConfigurationDetailsOverlay = ({ handleOverlayClose, }: ConfigurationDetailsOverlayProps) => { const { t } = useTranslation() - const { data, isFetching } = useFetchDecentralIdentityUrlsQuery() + const { data, isFetching, error, isError, refetch } = + useFetchDecentralIdentityUrlsQuery() + + // To-Do fix the type issue with status and data from FetchBaseQueryError + // eslint-disable-next-line + const decentralIdentityUrlsError = error as any const handleIconDisplay = (value: string | undefined) => { if (value) return true @@ -177,7 +183,26 @@ const ConfigurationDetailsOverlay = ({ ) : ( <> - + {!isError ? ( + + ) : ( + = 400 && + decentralIdentityUrlsError.code < 500 + ? t('error.description') + + ' ' + + t('error.additionalDescription') + : t('error.errorBar') + } + showButton={ + decentralIdentityUrlsError.code >= 500 && + decentralIdentityUrlsError.code < 600 + } + buttonText={t('error.tryAgain')} + handleButton={refetch} + /> + )}
{t('directors')} - Oliver Ganser ({t('ceo')}) - - Prof. Dr.-Ing. Boris Otto ({t('deputyCeo')}) - - - Claus Cremers ({t('treasurer')}) - + {t('ceo')} + {t('deputyCeo')} + {t('treasurer')}
- {t('address')} - - Catena-X Automotive Network e.V. - - c/o IFOK GmbH - Reinhardtstraße 58 - 10117 Berlin + {t('address')} + {t('nameOfOrganization')} + {t('careOf')} + {t('street')} + {t('postalCode&City')}
- {t('contact&support')} - {t('contact&supportDesc')} + {t('contact&Support')} + {t('contact&SupportDesc')}
{t('privacy')} {t('privacyDesc')} - xxx.xxx.xxx + {/* TODO: once privacy page's content is available, then href url can be changed to href="./privacy" */} + {t('privacyPolicy')}
) diff --git a/src/components/pages/ServiceMarketplace/index.tsx b/src/components/pages/ServiceMarketplace/index.tsx index 9b56336c5..2127af51f 100644 --- a/src/components/pages/ServiceMarketplace/index.tsx +++ b/src/components/pages/ServiceMarketplace/index.tsx @@ -41,6 +41,7 @@ import { ViewSelector, SortOption, CircleProgress, + ErrorBar, } from '@catena-x/portal-shared-components' import { type ServiceRequest, @@ -48,6 +49,7 @@ import { } from 'features/serviceMarketplace/serviceApiSlice' import SortImage from 'components/shared/frame/SortImage' import { ServiceTypeIdsEnum } from 'features/serviceManagement/apiSlice' +import NoItems from '../NoItems' dayjs.extend(isToday) dayjs.extend(isYesterday) @@ -77,13 +79,17 @@ export default function ServiceMarketplace() { const indexToSplit = 2 //show only 2 services in recommended - const { data } = useFetchServicesQuery({ + const { data, error, isError, refetch } = useFetchServicesQuery({ page: 0, serviceType: serviceTypeId, sortingType, }) const services = data?.content + // To-Do fix the type issue with status and data from FetchBaseQueryError + // eslint-disable-next-line + const servicesError = error as any + useEffect(() => { services && setCardServices(services) }, [services]) @@ -162,6 +168,26 @@ export default function ServiceMarketplace() { setShowModal(true) }, []) + const renderServices = () => { + if (services && services.length === 0) return + if (!services) + return ( +
+ +
+ ) + return ( + + ) + } + return (
@@ -193,20 +219,21 @@ export default function ServiceMarketplace() { />
- {!services ? ( -
- -
+ {!isError ? ( + renderServices() ) : ( - = 400 && + servicesError?.data?.status < 500 + ? t('content.serviceMarketplace.dataLoadFailed') + : t('content.serviceMarketplace.loadFailed') + } + showButton={ + servicesError.code >= 500 && servicesError?.data?.status < 600 + } + buttonText={t('error.tryAgain')} + handleButton={refetch} /> )} diff --git a/src/features/admin/serviceApiSlice.ts b/src/features/admin/serviceApiSlice.ts index ac0cfd290..d999eb9c8 100644 --- a/src/features/admin/serviceApiSlice.ts +++ b/src/features/admin/serviceApiSlice.ts @@ -180,7 +180,7 @@ export const apiSlice = createApi({ number >({ query: (page) => - `/api/administration/serviceaccount/owncompany/serviceaccounts?page=${page}&size=${PAGE_SIZE}&filterForInactive=false`, + `/api/administration/serviceaccount/owncompany/serviceaccounts?page=${page}&size=${PAGE_SIZE}&filterForInactive=false&userStatus=ACTIVE`, }), }), }) diff --git a/src/features/companyData/companyDataApiSlice.tsx b/src/features/companyData/companyDataApiSlice.tsx index 6df35c4ee..742c9fe07 100644 --- a/src/features/companyData/companyDataApiSlice.tsx +++ b/src/features/companyData/companyDataApiSlice.tsx @@ -41,7 +41,6 @@ export type CompanyDataFieldsType = { countryCode: string | undefined | null countryIdentifier: string | undefined | null identifierNumber: string | undefined | null - addressTitle: string | undefined | null } export interface CompanyDataRequestType { diff --git a/yarn.lock b/yarn.lock index 67f71462a..b8184d7d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2128,11 +2128,11 @@ brace-expansion@^2.0.1: balanced-match "^1.0.0" braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: - fill-range "^7.0.1" + fill-range "^7.1.1" browserslist@^4.22.2: version "4.23.0" @@ -3197,10 +3197,10 @@ file-selector@^0.6.0: dependencies: tslib "^2.4.0" -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" @@ -5974,9 +5974,9 @@ write-file-atomic@^4.0.2: signal-exit "^3.0.7" ws@^8.11.0: - version "8.16.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" - integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== xml-name-validator@^4.0.0: version "4.0.0"