From 8e089ced10388a304585de3bb2ac488f58785d1c Mon Sep 17 00:00:00 2001 From: arausly Date: Thu, 11 Sep 2025 15:13:45 +0100 Subject: [PATCH 001/105] upgrades for redux and related pkgs --- workspace/package.json | 6 +- workspace/src/app/App.tsx | 9 ++- .../src/app/hooks/useSelectFirstResult.ts | 3 +- workspace/src/app/store/configureStore.ts | 16 +++--- .../src/app/store/ducks/common/commonSlice.ts | 57 +++++++++---------- workspace/src/app/store/reducers.ts | 4 +- .../Header/ExampleProjectImportMenu.tsx | 3 +- .../src/app/views/layout/Header/Header.tsx | 3 +- .../Header/useKeyBoardHeaderShortcuts.ts | 3 +- .../views/pages/Activities/ActivityList.tsx | 13 +++-- .../src/app/views/pages/Activities/index.tsx | 3 +- .../Activities/tests/ActivitiesList.test.tsx | 20 ++++--- .../pages/Project/ActivityInfoWidget.tsx | 3 +- .../pages/Project/FileWidget/FileWidget.tsx | 7 ++- .../src/app/views/pages/Project/Project.tsx | 3 +- .../ConfigWidget.tsx | 3 +- .../PrefixesDialog.tsx | 7 ++- .../Project/WarningWidget/WarningWidget.tsx | 9 +-- .../Workspace/AppliedFacets/AppliedFacets.tsx | 3 +- .../pages/Workspace/Filterbar/FacetsList.tsx | 5 +- .../pages/Workspace/Filterbar/Filterbar.tsx | 5 +- .../app/views/pages/Workspace/Workspace.tsx | 3 +- .../views/pages/Workspace/WorkspaceSearch.tsx | 3 +- .../ActionsMenu/ArtefactManagementOptions.tsx | 3 +- .../app/views/shared/Metadata/Metadata.tsx | 9 +-- .../views/shared/PageHeader/PageHeader.tsx | 3 +- .../views/shared/RelatedItems/RelatedItem.tsx | 11 ++-- .../views/shared/SearchList/SearchItem.tsx | 3 +- .../views/shared/SearchList/SearchList.tsx | 3 +- .../CreateArtefactModal.tsx | 20 +++---- .../shared/modals/ProjectImportModal.tsx | 3 +- .../shared/modals/RecentlyViewedModal.tsx | 7 ++- .../projectTaskTabView/ProjectTaskTabView.tsx | 3 +- workspace/test/integration/TestHelper.tsx | 13 ++--- 34 files changed, 143 insertions(+), 126 deletions(-) diff --git a/workspace/package.json b/workspace/package.json index acfe723c52..5d12d2da0e 100644 --- a/workspace/package.json +++ b/workspace/package.json @@ -28,7 +28,7 @@ "@eccenca/gui-elements": "^24.4.0", "@eccenca/superagent": "^1.4.1", "@mavrin/remark-typograf": "^2.2.0", - "@reduxjs/toolkit": "^1.9.7", + "@reduxjs/toolkit": "^2.9.0", "@uppy/core": "1.17.0", "@uppy/react": "1.11.10", "@uppy/xhr-upload": "1.7.5", @@ -53,11 +53,11 @@ "react-helmet": "^6.0.0", "react-hook-form": "^5.1.3", "react-i18next": "^11.18.6", - "react-redux": "^7.2.9", + "react-redux": "^9.2.0", "react-router": "^5.3.4", "react-router-dom": "^5.3.4", "react-sparklines": "^1.7.0", - "redux": "^4.2.1", + "redux": "^5.0.1", "redux-logger": "^3.0.6", "store": "^2.0.12" }, diff --git a/workspace/src/app/App.tsx b/workspace/src/app/App.tsx index a40da83c6d..53654b4e55 100644 --- a/workspace/src/app/App.tsx +++ b/workspace/src/app/App.tsx @@ -1,10 +1,10 @@ import React, { useEffect } from "react"; import { ConnectedRouter } from "connected-react-router"; -import { useDispatch } from "react-redux"; +import { useDispatch, ReactReduxContext } from "react-redux"; import { commonOp } from "@ducks/common"; import RouterOutlet from "./RouterOutlet"; -import { getHistory } from "./store/configureStore"; +import { AppDispatch, getHistory } from "./store/configureStore"; import { IRouteProps } from "./appRoutes"; interface IProps { @@ -13,15 +13,14 @@ interface IProps { } export default function App({ externalRoutes, routes }: IProps) { - const dispatch = useDispatch(); + const dispatch = useDispatch(); useEffect(() => { dispatch(commonOp.fetchCommonSettingsAsync()); dispatch(commonOp.fetchExportTypesAsync()); }, [commonOp]); - return ( - + ); diff --git a/workspace/src/app/hooks/useSelectFirstResult.ts b/workspace/src/app/hooks/useSelectFirstResult.ts index c871c2b835..d2c1b2e2cd 100644 --- a/workspace/src/app/hooks/useSelectFirstResult.ts +++ b/workspace/src/app/hooks/useSelectFirstResult.ts @@ -5,9 +5,10 @@ import { IPageLabels } from "@ducks/router/operations"; import { workspaceOp, workspaceSel } from "@ducks/workspace"; import { DATA_TYPES } from "../constants"; import { batch, useDispatch, useSelector } from "react-redux"; +import { AppDispatch } from "store/configureStore"; export const useSelectFirstResult = () => { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const data = useSelector(workspaceSel.resultsSelector); const dataArrayRef = React.useRef(data); const enabled = React.useRef(true); diff --git a/workspace/src/app/store/configureStore.ts b/workspace/src/app/store/configureStore.ts index 94211a22cf..05b8101e74 100644 --- a/workspace/src/app/store/configureStore.ts +++ b/workspace/src/app/store/configureStore.ts @@ -1,5 +1,5 @@ import rootReducer from "./reducers"; -import { configureStore, getDefaultMiddleware } from "@reduxjs/toolkit"; +import { configureStore } from "@reduxjs/toolkit"; import { createBrowserHistory } from "history"; import { routerMiddleware } from "connected-react-router"; import { createLogger } from "redux-logger"; @@ -16,12 +16,7 @@ export const getHistory = () => history; export default function configStore(options: any = {}) { const enhancers: any[] = []; - const middleware = [ - ...getDefaultMiddleware({ - serializableCheck: false, - }), - routerMiddleware(getHistory()), - ]; + const middleware = [routerMiddleware(getHistory())]; if (isDevelopment) { const { enableStoreDevUtils, monitorPerformance, logReduxActions, logUselessRenders } = options; // Enable redux development actions, e.g. reset store @@ -59,10 +54,13 @@ export default function configStore(options: any = {}) { store = configureStore({ reducer: rootReducer(getHistory()), - middleware, + middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false }).concat(middleware), devTools: isDevelopment, - enhancers, + enhancers: (defaultEnhancers) => defaultEnhancers().concat(enhancers), }); return store; } + +export type AppDispatch = typeof store.dispatch; +export type RootState = ReturnType; diff --git a/workspace/src/app/store/ducks/common/commonSlice.ts b/workspace/src/app/store/ducks/common/commonSlice.ts index ff13c5bbf7..12a984a47f 100644 --- a/workspace/src/app/store/ducks/common/commonSlice.ts +++ b/workspace/src/app/store/ducks/common/commonSlice.ts @@ -1,4 +1,4 @@ -import { createAction, createSlice, PayloadAction } from "@reduxjs/toolkit"; +import { ActionReducerMapBuilder, createAction, createSlice, PayloadAction, WritableDraft } from "@reduxjs/toolkit"; import { initialCommonState } from "./initialState"; import { LOCATION_CHANGE } from "connected-react-router"; import appRoutes from "../../../appRoutes"; @@ -13,6 +13,7 @@ import { IInitFrontend, IProjectTaskUpdatePayload, IArtefactModal, + ICommonState, } from "@ducks/common/typings"; import { setStoredLang } from "../../../../language"; @@ -20,37 +21,33 @@ import { setStoredLang } from "../../../../language"; * @override connect-react-router location change action * set projectId and taskId on location change */ -const getExtraReducers = () => { +const getExtraReducers = (builder: ActionReducerMapBuilder>) => { const routerChange = createAction(LOCATION_CHANGE); - return { - [routerChange.toString()]: (state) => { - const { location } = getHistory(); - const updatedState = { - ...state, - }; - - let match; - for (let route of appRoutes) { - match = matchPath<{ taskId?: string; projectId?: string }>(location.pathname, { - path: getFullRoutePath(route.path), - exact: true, - }); - - if (match) { - updatedState.currentProjectId = match.params.projectId || null; - updatedState.currentTaskId = match.params.taskId || null; - break; - } - } + builder.addCase(routerChange.toString(), (state) => { + const { location } = getHistory(); + const updatedState = { + ...state, + }; + + let match; + for (let route of appRoutes) { + match = matchPath<{ taskId?: string; projectId?: string }>(location.pathname, { + path: getFullRoutePath(route.path), + exact: true, + }); - if (!match) { - updatedState.currentTaskId = null; - updatedState.currentProjectId = null; + if (match) { + updatedState.currentProjectId = match.params.projectId || null; + updatedState.currentTaskId = match.params.taskId || null; + break; } + } - return updatedState; - }, - }; + if (!match) { + updatedState.currentTaskId = undefined; + updatedState.currentProjectId = undefined; + } + }); }; export const commonSlice = createSlice({ @@ -164,7 +161,7 @@ export const commonSlice = createSlice({ createNewTask: ( state, - action: PayloadAction> + action: PayloadAction>, ) => { const { newTaskPreConfiguration, selectedDType } = action.payload; state.artefactModal.newTaskPreConfiguration = newTaskPreConfiguration; @@ -185,5 +182,5 @@ export const commonSlice = createSlice({ state.artefactModal.info = action.payload; }, }, - extraReducers: getExtraReducers(), + extraReducers: (builder) => getExtraReducers(builder), }); diff --git a/workspace/src/app/store/reducers.ts b/workspace/src/app/store/reducers.ts index 682646fe7a..d13f2f1295 100644 --- a/workspace/src/app/store/reducers.ts +++ b/workspace/src/app/store/reducers.ts @@ -3,11 +3,11 @@ import { combineReducers } from "@reduxjs/toolkit"; import workspace from "@ducks/workspace"; import common from "@ducks/common"; import routerReducers from "@ducks/router"; -import { Reducer, Action, CombinedState } from "redux"; +import { Reducer, Action } from "redux"; import { IStore } from "./typings/IStore"; import error from "@ducks/error"; -const reducers = (history): Reducer, Action> => { +const reducers = (history): Reducer => { return combineReducers({ common: common.reducer, workspace, diff --git a/workspace/src/app/views/layout/Header/ExampleProjectImportMenu.tsx b/workspace/src/app/views/layout/Header/ExampleProjectImportMenu.tsx index 55e4b0c0c0..d1c3305ad1 100644 --- a/workspace/src/app/views/layout/Header/ExampleProjectImportMenu.tsx +++ b/workspace/src/app/views/layout/Header/ExampleProjectImportMenu.tsx @@ -6,11 +6,12 @@ import React from "react"; import { useTranslation } from "react-i18next"; import { routerOp } from "@ducks/router"; import { requestProjectMetadata } from "@ducks/shared/requests"; +import { AppDispatch } from "store/configureStore"; /** Component to load the "movies" example project. */ export const ExampleProjectImportMenu = () => { const { registerError } = useErrorHandler(); - const dispatch = useDispatch(); + const dispatch = useDispatch(); const [t] = useTranslation(); const [exampleProjectLoaded, setExampleProjectLoaded] = React.useState(undefined); const [loading, setLoading] = React.useState(false); diff --git a/workspace/src/app/views/layout/Header/Header.tsx b/workspace/src/app/views/layout/Header/Header.tsx index db79da1a84..1dd84f4c74 100644 --- a/workspace/src/app/views/layout/Header/Header.tsx +++ b/workspace/src/app/views/layout/Header/Header.tsx @@ -37,6 +37,7 @@ import { UserMenuFooterProps } from "../../plugins/plugin.types"; import { ExampleProjectImportMenu } from "./ExampleProjectImportMenu"; import { useKeyboardHeaderShortcuts } from "./useKeyBoardHeaderShortcuts"; import { getFullRoutePath } from "../../../utils/routerUtils"; +import { AppDispatch } from "store/configureStore"; interface IProps { onClickApplicationSidebarExpand: any; @@ -44,7 +45,7 @@ interface IProps { } export function Header({ onClickApplicationSidebarExpand, isApplicationSidebarExpanded }: IProps) { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const location = useLocation(); const locationParams = new URLSearchParams(location.search?.substring(1)); const { hotKeys } = useSelector(commonSel.initialSettingsSelector); diff --git a/workspace/src/app/views/layout/Header/useKeyBoardHeaderShortcuts.ts b/workspace/src/app/views/layout/Header/useKeyBoardHeaderShortcuts.ts index 35b11a8796..a0434feb0a 100644 --- a/workspace/src/app/views/layout/Header/useKeyBoardHeaderShortcuts.ts +++ b/workspace/src/app/views/layout/Header/useKeyBoardHeaderShortcuts.ts @@ -10,9 +10,10 @@ import { uppercaseFirstChar } from "../../../utils/transformers"; import { useTranslation } from "react-i18next"; import { useInitFrontend } from "../../pages/MappingEditor/api/silkRestApi.hooks"; import { absoluteProjectPath } from "../../../utils/routerUtils"; +import { AppDispatch } from "store/configureStore"; export const useKeyboardHeaderShortcuts = () => { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const [t] = useTranslation(); const projectId = useSelector(commonSel.currentProjectIdSelector); diff --git a/workspace/src/app/views/pages/Activities/ActivityList.tsx b/workspace/src/app/views/pages/Activities/ActivityList.tsx index 6c6a9f97e8..6559377333 100644 --- a/workspace/src/app/views/pages/Activities/ActivityList.tsx +++ b/workspace/src/app/views/pages/Activities/ActivityList.tsx @@ -36,6 +36,7 @@ import { routerOp } from "@ducks/router"; import { batch } from "react-redux"; import { SERVE_PATH } from "../../../constants/path"; import { DIErrorTypes } from "@ducks/error/typings"; +import { AppDispatch } from "store/configureStore"; interface IActivity extends ISearchResultsServer { isCacheActivity: boolean; @@ -56,7 +57,7 @@ export const nonStartableActivitiesBlacklist = { }; const ActivityList = () => { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const pageSizes = [10, 25, 50, 100]; const { registerError } = useErrorHandler(); @@ -80,7 +81,7 @@ const ActivityList = () => { const translateActions = React.useCallback( (key: SilkActivityControlTranslationKeys) => t("widget.TaskActivityOverview.activityControl." + key), - [t] + [t], ); const emptyListWithoutFilters: boolean = isEmpty && !textQuery && !appliedFacets.length; @@ -106,7 +107,7 @@ const ActivityList = () => { return connectWebSocket( legacyApiEndpoint("/activities/updatesWebSocket"), legacyApiEndpoint("/activities/updates"), - updateActivityStatus + updateActivityStatus, ); }; @@ -132,7 +133,7 @@ const ActivityList = () => { registerError( `ActivityList.${action}`, `Activity action '${action}' against activity '${activityName}' could not be executed.`, - error + error, ); }; @@ -146,7 +147,7 @@ const ActivityList = () => { registerError( `taskActivityOverview-fetchErrorReport`, t("widget.TaskActivityOverview.errorMessages.errorReport.fetchReport"), - ex + ex, ); }); }; @@ -171,7 +172,7 @@ const ActivityList = () => { diff --git a/workspace/src/app/views/pages/Activities/index.tsx b/workspace/src/app/views/pages/Activities/index.tsx index 4c86022e4d..193d8b9f2e 100644 --- a/workspace/src/app/views/pages/Activities/index.tsx +++ b/workspace/src/app/views/pages/Activities/index.tsx @@ -30,9 +30,10 @@ import { useHistory, useParams } from "react-router"; import { SERVE_PATH } from "../../../constants/path"; import { ProjectTaskParams } from "views/shared/typings"; import { previewSlice } from "@ducks/workspace/previewSlice"; +import { AppDispatch } from "store/configureStore"; const Activities = () => { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const { registerError } = useErrorHandler(); const history = useHistory(); const error = useSelector(workspaceSel.errorSelector); diff --git a/workspace/src/app/views/pages/Activities/tests/ActivitiesList.test.tsx b/workspace/src/app/views/pages/Activities/tests/ActivitiesList.test.tsx index 323a200d3e..3626350bb8 100644 --- a/workspace/src/app/views/pages/Activities/tests/ActivitiesList.test.tsx +++ b/workspace/src/app/views/pages/Activities/tests/ActivitiesList.test.tsx @@ -1,7 +1,7 @@ import React from "react"; import "@testing-library/jest-dom/extend-expect"; import { render as rtlRender } from "@testing-library/react"; -import { configureStore } from "@reduxjs/toolkit"; +import { combineReducers, configureStore } from "@reduxjs/toolkit"; import { Provider } from "react-redux"; import workspaceReducer from "../../../../store/ducks/workspace"; import ActivityList, { nonStartableActivitiesBlacklist } from "../ActivityList"; @@ -46,16 +46,20 @@ const dummyState = { }, }; +const rootReducer = combineReducers({ + workspace: workspaceReducer, +}); + const render = ( ui: JSX.Element, { store = configureStore({ - reducer: { workspace: workspaceReducer }, + reducer: rootReducer, preloadedState: { ...(dummyState as any), }, }), - } = {} + } = {}, ) => { function Wrapper({ children }) { return {children}; @@ -72,7 +76,7 @@ describe("ActivityList", () => { test("that ActivityList has right number of activity control items", () => { const wrapper = render(); expect(wrapper.container.querySelectorAll(`.${bluePrintClassPrefix}-card`).length).toBe( - testData.activities.length + testData.activities.length, ); }); @@ -93,8 +97,8 @@ describe("ActivityList", () => { activityProperties[label!].blacklisted ? "activity-stop-activity" : activityProperties[label!].cacheActivity - ? "activity-reload-activity" - : "activity-start-activity" + ? "activity-reload-activity" + : "activity-start-activity", ); } }); @@ -104,11 +108,11 @@ describe("ActivityList", () => { const activities = wrapper.container.querySelectorAll(`.${bluePrintClassPrefix}-card`); activities.forEach((activity, index) => { const [parentTypeTag, projectTag] = Array.from( - activity.querySelectorAll(`.${bluePrintClassPrefix}-tag`) + activity.querySelectorAll(`.${bluePrintClassPrefix}-tag`), ).reverse(); const activityData = testData.activities[index]; expect(parentTypeTag?.textContent).toBe( - activityData.parentType[0].toUpperCase() + activityData.parentType.substr(1) + activityData.parentType[0].toUpperCase() + activityData.parentType.substr(1), ); //no project tag possibly global activity expect(projectTag?.textContent).toBe(!projectTag ? undefined : activityData.project); diff --git a/workspace/src/app/views/pages/Project/ActivityInfoWidget.tsx b/workspace/src/app/views/pages/Project/ActivityInfoWidget.tsx index 623cfda087..d15222f453 100644 --- a/workspace/src/app/views/pages/Project/ActivityInfoWidget.tsx +++ b/workspace/src/app/views/pages/Project/ActivityInfoWidget.tsx @@ -5,10 +5,11 @@ import { useDispatch, useSelector } from "react-redux"; import { commonSel } from "@ducks/common"; import { routerOp } from "@ducks/router"; import { SERVE_PATH } from "../../../constants/path"; +import { AppDispatch } from "store/configureStore"; const ActivityInfoWidget = () => { const projectId = useSelector(commonSel.currentProjectIdSelector); - const dispatch = useDispatch(); + const dispatch = useDispatch(); const [t] = useTranslation(); const projectPath = `projects/${projectId}/activities?page=1&limit=25&sortBy=recentlyUpdated&sortOrder=ASC`; diff --git a/workspace/src/app/views/pages/Project/FileWidget/FileWidget.tsx b/workspace/src/app/views/pages/Project/FileWidget/FileWidget.tsx index 28a031d767..382aee1ac7 100644 --- a/workspace/src/app/views/pages/Project/FileWidget/FileWidget.tsx +++ b/workspace/src/app/views/pages/Project/FileWidget/FileWidget.tsx @@ -30,10 +30,11 @@ import { useTranslation } from "react-i18next"; import { FileRemoveModal } from "../../../shared/modals/FileRemoveModal"; import { CONTEXT_PATH } from "../../../../constants/path"; import { fileValue } from "@ducks/shared/typings"; +import { AppDispatch } from "store/configureStore"; /** Project file management widget. */ export const FileWidget = () => { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const filesList = useSelector(workspaceSel.filesListSelector); const fileWidget = useSelector(workspaceSel.widgetsSelector).files; @@ -130,7 +131,7 @@ export const FileWidget = () => { {filesList .slice( (pagination.current - 1) * pagination.limit, - pagination.current * pagination.limit + pagination.current * pagination.limit, ) .map((file) => ( @@ -168,7 +169,7 @@ export const FileWidget = () => { text={t("common.action.download")} small href={`${CONTEXT_PATH}/workspace/projects/${projectId}/files?path=${encodeURIComponent( - fileValue(file) + fileValue(file), )}`} /> { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const { textQuery } = useSelector(workspaceSel.appliedFiltersSelector); const currentSearchQuery = useRef(""); diff --git a/workspace/src/app/views/pages/Project/ProjectNamespacePrefixManagementWidget/ConfigWidget.tsx b/workspace/src/app/views/pages/Project/ProjectNamespacePrefixManagementWidget/ConfigWidget.tsx index ed2bd61efb..958cd11d35 100644 --- a/workspace/src/app/views/pages/Project/ProjectNamespacePrefixManagementWidget/ConfigWidget.tsx +++ b/workspace/src/app/views/pages/Project/ProjectNamespacePrefixManagementWidget/ConfigWidget.tsx @@ -21,12 +21,13 @@ import { import { useTranslation } from "react-i18next"; import { commonSel } from "@ducks/common"; import useHotKey from "../../../../views/shared/HotKeyHandler/HotKeyHandler"; +import { AppDispatch } from "store/configureStore"; const VISIBLE_COUNT = 5; /** The project namespace prefix management widget that allows adding, updating and removing namespace prefixes. */ export const ProjectNamespacePrefixManagementWidget = () => { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const prefixList = useSelector(workspaceSel.prefixListSelector); const [visiblePrefixes, setVisiblePrefixes] = useState([]); diff --git a/workspace/src/app/views/pages/Project/ProjectNamespacePrefixManagementWidget/PrefixesDialog.tsx b/workspace/src/app/views/pages/Project/ProjectNamespacePrefixManagementWidget/PrefixesDialog.tsx index fd4225d9df..6b474ed47a 100644 --- a/workspace/src/app/views/pages/Project/ProjectNamespacePrefixManagementWidget/PrefixesDialog.tsx +++ b/workspace/src/app/views/pages/Project/ProjectNamespacePrefixManagementWidget/PrefixesDialog.tsx @@ -13,6 +13,7 @@ import { requestChangePrefixes, requestRemoveProjectPrefix } from "@ducks/worksp import { widgetsSlice } from "@ducks/workspace/widgetsSlice"; import { ErrorResponse } from "../../../../services/fetch/responseInterceptor"; import { useModalError } from "../../../../hooks/useModalError"; +import { AppDispatch } from "store/configureStore"; interface IProps { projectId: string; @@ -23,7 +24,7 @@ interface IProps { /** Manages project prefix definitions. */ const PrefixesDialog = ({ onCloseModal, isOpen, existingPrefixes, projectId }: IProps) => { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const prefixList = useSelector(workspaceSel.prefixListSelector); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(); @@ -64,7 +65,7 @@ const PrefixesDialog = ({ onCloseModal, isOpen, existingPrefixes, projectId }: I } catch (err) { checkAndDisplayPrefixError( err, - t("widget.ConfigWidget.modal.errors.prefixDeletionFailure", "Prefix deletion failed") + t("widget.ConfigWidget.modal.errors.prefixDeletionFailure", "Prefix deletion failed"), ); } finally { setLoading(false); @@ -86,7 +87,7 @@ const PrefixesDialog = ({ onCloseModal, isOpen, existingPrefixes, projectId }: I } catch (err) { checkAndDisplayPrefixError( err, - t("widget.ConfigWidget.modal.errors.prefixChangeFailure", "Prefix change failed") + t("widget.ConfigWidget.modal.errors.prefixChangeFailure", "Prefix change failed"), ); } finally { setLoading(false); diff --git a/workspace/src/app/views/pages/Project/WarningWidget/WarningWidget.tsx b/workspace/src/app/views/pages/Project/WarningWidget/WarningWidget.tsx index 0043dcc9c7..a1e563e2fb 100644 --- a/workspace/src/app/views/pages/Project/WarningWidget/WarningWidget.tsx +++ b/workspace/src/app/views/pages/Project/WarningWidget/WarningWidget.tsx @@ -26,6 +26,7 @@ import { failedTaskParameters, fixFailedTask } from "./TaskLoadingError.requests import { AlternativeTaskUpdateFunction } from "@ducks/common/typings"; import { FixTaskDataNotFoundModal } from "./FixTaskDataNotFoundModal"; import { TaskParameterValues } from "./TaskLoadingError.typing"; +import { AppDispatch } from "store/configureStore"; interface Props { refreshProjectPage: () => any; @@ -33,7 +34,7 @@ interface Props { /** Displays the task loading errors for a project, i.e. tasks that could not be loaded/initialized. */ export const ProjectTaskLoadingErrors = ({ refreshProjectPage }: Props) => { const { registerErrorI18N } = useErrorHandler(); - const dispatch = useDispatch(); + const dispatch = useDispatch(); const projectId = useSelector(commonSel.currentProjectIdSelector); const warningList = useSelector(workspaceSel.warningListSelector); const { cachedArtefactProperties } = useSelector(commonSel.artefactModalSelector); @@ -92,14 +93,14 @@ export const ProjectTaskLoadingErrors = ({ refreshProjectPage }: Props) => { taskId, parameterData, variableTemplateData, - dataParameters + dataParameters, ) => { await fixFailedTask( projectId, taskId, parameterData as TaskParameterValues, variableTemplateData as TaskParameterValues, - dataParameters + dataParameters, ); // Update warning list and project page fetchWarningList(); @@ -138,7 +139,7 @@ export const ProjectTaskLoadingErrors = ({ refreshProjectPage }: Props) => { // FIXME: Add label to failedTaskData in order to display task label alternativeTitle: t("widget.WarningWidget.fixTaskModalTitle", { taskLabel: taskLabel }), alternativeUpdateFunction: fixTask, - }) + }), ); } catch (ex) { if (ex.httpStatus === 404 || ex.status === 404) { diff --git a/workspace/src/app/views/pages/Workspace/AppliedFacets/AppliedFacets.tsx b/workspace/src/app/views/pages/Workspace/AppliedFacets/AppliedFacets.tsx index 8c7269eb73..39d885a8b1 100644 --- a/workspace/src/app/views/pages/Workspace/AppliedFacets/AppliedFacets.tsx +++ b/workspace/src/app/views/pages/Workspace/AppliedFacets/AppliedFacets.tsx @@ -3,10 +3,11 @@ import { useDispatch, useSelector } from "react-redux"; import { workspaceOp, workspaceSel } from "@ducks/workspace"; import { IFacetState } from "@ducks/workspace/typings"; import { Spacing, Tag, TagList } from "@eccenca/gui-elements"; +import { AppDispatch } from "store/configureStore"; /** The currently active search filter facets represented as tags. Clicking a tag removes the facet. */ export function AppliedFacets() { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const facets = useSelector(workspaceSel.facetsSelector); const appliedFacets = useSelector(workspaceSel.appliedFacetsSelector); diff --git a/workspace/src/app/views/pages/Workspace/Filterbar/FacetsList.tsx b/workspace/src/app/views/pages/Workspace/Filterbar/FacetsList.tsx index ac926b65da..7dac2ee9e6 100644 --- a/workspace/src/app/views/pages/Workspace/Filterbar/FacetsList.tsx +++ b/workspace/src/app/views/pages/Workspace/Filterbar/FacetsList.tsx @@ -6,10 +6,11 @@ import FacetItem from "./FacetItem"; import { Button, ClassNames, Spacing, TitleSubsection, Label } from "@eccenca/gui-elements"; import { useTranslation } from "react-i18next"; import { useLocation } from "react-router"; +import { AppDispatch } from "store/configureStore"; /** List of filter facets used to re-fine search results. */ export default function FacetsList({ projectId }: { projectId?: string }) { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const [t] = useTranslation(); const facets = useSelector(workspaceSel.facetsSelector); @@ -95,7 +96,7 @@ export default function FacetsList({ projectId }: { projectId?: string }) { {t( `widget.FacetsList.facet.${facet.id}.valueLabels.${val.id}`, - val.label + val.label, )} ({val.count}) diff --git a/workspace/src/app/views/pages/Workspace/Filterbar/Filterbar.tsx b/workspace/src/app/views/pages/Workspace/Filterbar/Filterbar.tsx index a1812497b5..a122629600 100644 --- a/workspace/src/app/views/pages/Workspace/Filterbar/Filterbar.tsx +++ b/workspace/src/app/views/pages/Workspace/Filterbar/Filterbar.tsx @@ -6,6 +6,7 @@ import { RadioButton, Spacing, TitleSubsection, Label } from "@eccenca/gui-eleme import FacetsList from "./FacetsList"; import { useTranslation } from "react-i18next"; import { IAvailableDataTypeOption } from "@ducks/common/typings"; +import { AppDispatch } from "store/configureStore"; interface IFilterBarProps { extraItemTypeModifiers?: IAvailableDataTypeOption[]; @@ -15,7 +16,7 @@ interface IFilterBarProps { /** The filter menu that allows to filter the search results by selecting a specific item type and * filter by type specific facets. */ export function Filterbar({ extraItemTypeModifiers = [], projectId }: IFilterBarProps) { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const [t] = useTranslation(); const appliedFilters = useSelector(workspaceSel.appliedFiltersSelector); @@ -63,7 +64,7 @@ export function Filterbar({ extraItemTypeModifiers = [], projectId }: IFilterBar checked={appliedFilters[typeModifier.field] === opt.id} label={t( `widget.Filterbar.subsections.valueLabels.itemType.${opt.id}`, - opt.label + opt.label, )} onChange={() => handleFilterSelect(typeModifier.field, opt.id)} value={opt.id} diff --git a/workspace/src/app/views/pages/Workspace/Workspace.tsx b/workspace/src/app/views/pages/Workspace/Workspace.tsx index 90e2fcf76b..63c8a978a2 100644 --- a/workspace/src/app/views/pages/Workspace/Workspace.tsx +++ b/workspace/src/app/views/pages/Workspace/Workspace.tsx @@ -9,9 +9,10 @@ import { EmptyWorkspace } from "./EmptyWorkspace/EmptyWorkspace"; import { commonOp, commonSel } from "@ducks/common"; import useErrorHandler from "../../../hooks/useErrorHandler"; import { previewSlice } from "@ducks/workspace/previewSlice"; +import { AppDispatch } from "store/configureStore"; export function Workspace() { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const { registerError } = useErrorHandler(); const error = useSelector(workspaceSel.errorSelector); diff --git a/workspace/src/app/views/pages/Workspace/WorkspaceSearch.tsx b/workspace/src/app/views/pages/Workspace/WorkspaceSearch.tsx index 48b4459070..f3588d54ae 100644 --- a/workspace/src/app/views/pages/Workspace/WorkspaceSearch.tsx +++ b/workspace/src/app/views/pages/Workspace/WorkspaceSearch.tsx @@ -21,9 +21,10 @@ import SearchBar from "../../shared/SearchBar"; import { usePageHeader } from "../../shared/PageHeader/PageHeader"; import Filterbar from "./Filterbar"; import { useSelectFirstResult } from "../../../hooks/useSelectFirstResult"; +import { AppDispatch } from "store/configureStore"; const WorkspaceSearch = () => { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const [t] = useTranslation(); const { textQuery } = useSelector(workspaceSel.appliedFiltersSelector); diff --git a/workspace/src/app/views/shared/ActionsMenu/ArtefactManagementOptions.tsx b/workspace/src/app/views/shared/ActionsMenu/ArtefactManagementOptions.tsx index f98d988a99..0aa7988499 100644 --- a/workspace/src/app/views/shared/ActionsMenu/ArtefactManagementOptions.tsx +++ b/workspace/src/app/views/shared/ActionsMenu/ArtefactManagementOptions.tsx @@ -16,6 +16,7 @@ import CopyToModal from "../modals/CopyToModal/CopyToModal"; import ShowIdentifierModal from "../modals/ShowIdentifierModal"; import { SERVE_PATH } from "../../../constants/path"; import { absoluteProjectPath } from "../../../utils/routerUtils"; +import { AppDispatch } from "store/configureStore"; interface IProps { projectId: string; @@ -34,7 +35,7 @@ export function ArtefactManagementOptions({ updateActionsMenu, notFoundCallback = () => {}, }: IProps) { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const location = useLocation(); const [t] = useTranslation(); const [deleteModalOpen, setDeleteModalOpen] = useState(false); diff --git a/workspace/src/app/views/shared/Metadata/Metadata.tsx b/workspace/src/app/views/shared/Metadata/Metadata.tsx index d9687ddbd9..04ca2108b9 100644 --- a/workspace/src/app/views/shared/Metadata/Metadata.tsx +++ b/workspace/src/app/views/shared/Metadata/Metadata.tsx @@ -40,6 +40,7 @@ import { IMetadataExpanded } from "./Metadatatypings"; import { Keyword, Keywords } from "@ducks/workspace/typings"; import { MultiTagSelect } from "../MultiTagSelect"; import useHotKey from "../HotKeyHandler/HotKeyHandler"; +import { AppDispatch } from "store/configureStore"; export const getDateData = (dateTime: number | string) => { const then = new Date(dateTime); @@ -58,7 +59,7 @@ interface IProps { export function Metadata(props: IProps) { const location = useLocation(); - const dispatch = useDispatch(); + const dispatch = useDispatch(); const { registerError } = useErrorHandler(); const _projectId = useSelector(commonSel.currentProjectIdSelector); @@ -388,7 +389,7 @@ export function Metadata(props: IProps) { ? t( "Metadata.dateFormat", "{{year}}/{{month}}/{{day}}", - getDateData(created) + getDateData(created), ) : "", author: createdByUser?.label ?? t("Metadata.unknownuser", "unknown user"), @@ -427,7 +428,7 @@ export function Metadata(props: IProps) { ? t( "Metadata.dateFormat", "{{year}}/{{month}}/{{day}}", - getDateData(modified) + getDateData(modified), ) : "", author: @@ -439,7 +440,7 @@ export function Metadata(props: IProps) { ), diff --git a/workspace/src/app/views/shared/PageHeader/PageHeader.tsx b/workspace/src/app/views/shared/PageHeader/PageHeader.tsx index 9ee641efde..6acafbb740 100644 --- a/workspace/src/app/views/shared/PageHeader/PageHeader.tsx +++ b/workspace/src/app/views/shared/PageHeader/PageHeader.tsx @@ -19,6 +19,7 @@ import { APPLICATION_CORPORATION_NAME, APPLICATION_SUITE_NAME } from "../../../c import { fetchBreadcrumbs } from "./breadcrumbsHelper"; import ItemDepiction from "../ItemDepiction"; import { convertTaskTypeToItemType, TaskType } from "@ducks/shared/typings"; +import { AppDispatch } from "store/configureStore"; interface IPageHeaderContentBasicProps extends React.HTMLAttributes { /** Optional type of the page item. Can be an ItemType. */ @@ -87,7 +88,7 @@ function PageHeaderContent({ autogeneratePageTitle = false, actionsMenu, }: IPageHeaderContentBasicProps) { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const handleBreadcrumbItemClick = React.useCallback((itemUrl, e) => { e.preventDefault(); diff --git a/workspace/src/app/views/shared/RelatedItems/RelatedItem.tsx b/workspace/src/app/views/shared/RelatedItems/RelatedItem.tsx index 255a08dfeb..4782bc749e 100644 --- a/workspace/src/app/views/shared/RelatedItems/RelatedItem.tsx +++ b/workspace/src/app/views/shared/RelatedItems/RelatedItem.tsx @@ -24,6 +24,7 @@ import { useProjectTaskTabsView } from "../projectTaskTabView/projectTaskTabsVie import { projectTagsRenderer } from "../ProjectTags/ProjectTags"; import { searchTagsRenderer } from "../SearchList/SearchTags"; import { ArtefactTag } from "../ArtefactTag"; +import { AppDispatch } from "store/configureStore"; interface IProps { // The related item to be shown @@ -34,7 +35,7 @@ interface IProps { export function RelatedItem({ relatedItem, textQuery }: IProps) { const [t] = useTranslation(); - const dispatch = useDispatch(); + const dispatch = useDispatch(); const { projectTabView, changeTab, menuItems } = useProjectTaskTabsView({ srcLinks: relatedItem.itemLinks.slice(1), pluginId: relatedItem.pluginId, @@ -51,7 +52,7 @@ export function RelatedItem({ relatedItem, textQuery }: IProps) { routerOp.goToPage(relatedItem.itemLinks[0].path, { taskLabel: relatedItem.label, itemType: relatedItem.type.toLowerCase(), - }) + }), ); } }; @@ -80,20 +81,20 @@ export function RelatedItem({ relatedItem, textQuery }: IProps) { itemTags.push( - + , ); } if (relatedItem.readOnly) { itemTags.push( - + , ); } itemTags.push( - + , ); return ( diff --git a/workspace/src/app/views/shared/SearchList/SearchItem.tsx b/workspace/src/app/views/shared/SearchList/SearchItem.tsx index 9ebf9707b0..264a1dcfee 100644 --- a/workspace/src/app/views/shared/SearchList/SearchItem.tsx +++ b/workspace/src/app/views/shared/SearchList/SearchItem.tsx @@ -37,6 +37,7 @@ import { wrapTooltip } from "../../../utils/uiUtils"; import { projectTagsRenderer } from "../ProjectTags/ProjectTags"; import { searchTagsRenderer } from "./SearchTags"; import { ArtefactTag } from "../ArtefactTag"; +import { AppDispatch } from "store/configureStore"; interface IProps { item: ISearchResultsServer; @@ -68,7 +69,7 @@ export default function SearchItem({ parentProjectId, toggleShowIdentifierModal, }: IProps) { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const exportTypes = useSelector(commonSel.exportTypesSelector); const [t] = useTranslation(); const itemLinks = item.itemLinks ?? [{ path: "", label: "" }]; diff --git a/workspace/src/app/views/shared/SearchList/SearchList.tsx b/workspace/src/app/views/shared/SearchList/SearchList.tsx index 012cd1c9c2..3640b94f14 100644 --- a/workspace/src/app/views/shared/SearchList/SearchList.tsx +++ b/workspace/src/app/views/shared/SearchList/SearchList.tsx @@ -17,9 +17,10 @@ import CopyToModal from "../modals/CopyToModal/CopyToModal"; import { IModalItem } from "@ducks/shared/typings"; import ShowIdentifierModal from "../modals/ShowIdentifierModal"; import { IArtefactModal } from "@ducks/common/typings"; +import { AppDispatch } from "store/configureStore"; export function SearchList() { - const dispatch = useDispatch(); + const dispatch = useDispatch(); const pageSizes = [10, 25, 50, 100]; diff --git a/workspace/src/app/views/shared/modals/CreateArtefactModal/CreateArtefactModal.tsx b/workspace/src/app/views/shared/modals/CreateArtefactModal/CreateArtefactModal.tsx index 9e0099e62a..5cdc5e3513 100644 --- a/workspace/src/app/views/shared/modals/CreateArtefactModal/CreateArtefactModal.tsx +++ b/workspace/src/app/views/shared/modals/CreateArtefactModal/CreateArtefactModal.tsx @@ -60,6 +60,7 @@ import useHotKey from "../../HotKeyHandler/HotKeyHandler"; import { CreateArtefactModalContext } from "./CreateArtefactModalContext"; import { TaskDocumentationModal } from "./TaskDocumentationModal"; import { PARAMETER_DOC_PREFIX } from "./ArtefactForms/TaskForm"; +import { AppDispatch } from "store/configureStore"; const ignorableFields = new Set(["label", "description"]); @@ -84,7 +85,7 @@ export interface ArtefactDocumentation { export function CreateArtefactModal() { const MAX_SINGLEPLUGINBUTTONS = 2; - const dispatch = useDispatch(); + const dispatch = useDispatch(); const form = useForm(); const [searchValue, setSearchValue] = useState(""); @@ -157,14 +158,14 @@ export function CreateArtefactModal() { const [taskActionResult, setTaskActionResult] = React.useState<{ label: string; message: string }>(); const [taskActionLoading, setTaskActionLoading] = React.useState(null); const [taskFormGeneralWarning, setTaskFormGeneralWarning] = React.useState(); - const generalWarningTimeout = React.useRef() + const generalWarningTimeout = React.useRef(); const taskFormWarning = React.useCallback((message: string) => { - if(generalWarningTimeout.current) { - clearTimeout(generalWarningTimeout.current) + if (generalWarningTimeout.current) { + clearTimeout(generalWarningTimeout.current); } - generalWarningTimeout.current = window.setTimeout(() => setTaskFormGeneralWarning(message), 250) - }, []) + generalWarningTimeout.current = window.setTimeout(() => setTaskFormGeneralWarning(message), 250); + }, []); React.useEffect(() => { if (infoMessage?.removeAfterSeconds && infoMessage.removeAfterSeconds > 0) { @@ -946,12 +947,9 @@ export function CreateArtefactModal() { ); } - if(taskFormGeneralWarning) { + if (taskFormGeneralWarning) { notifications.push( - setTaskFormGeneralWarning(undefined)} - />, + setTaskFormGeneralWarning(undefined)} />, ); } diff --git a/workspace/src/app/views/shared/modals/ProjectImportModal.tsx b/workspace/src/app/views/shared/modals/ProjectImportModal.tsx index 9be6b89cee..760e387190 100644 --- a/workspace/src/app/views/shared/modals/ProjectImportModal.tsx +++ b/workspace/src/app/views/shared/modals/ProjectImportModal.tsx @@ -31,6 +31,7 @@ import { useDispatch } from "react-redux"; import { routerOp } from "@ducks/router"; import { absoluteProjectPath } from "../../../utils/routerUtils"; import { UploadNewFile } from "../FileUploader/cases/UploadNewFile/UploadNewFile"; +import { AppDispatch } from "store/configureStore"; interface IProps { // Called when closing the modal @@ -44,7 +45,7 @@ interface IProps { export function ProjectImportModal({ close, back, maxFileUploadSizeBytes }: IProps) { const [t] = useTranslation(); const [uppy] = useState(Uppy()); - const dispatch = useDispatch(); + const dispatch = useDispatch(); const [loading, setLoading] = useState(false); const [projectImportId, setProjectImportId] = useState(null); const [projectImportDetails, setProjectImportDetails] = useState(null); diff --git a/workspace/src/app/views/shared/modals/RecentlyViewedModal.tsx b/workspace/src/app/views/shared/modals/RecentlyViewedModal.tsx index e12cf75c68..d631643d0a 100644 --- a/workspace/src/app/views/shared/modals/RecentlyViewedModal.tsx +++ b/workspace/src/app/views/shared/modals/RecentlyViewedModal.tsx @@ -36,6 +36,7 @@ import { uppercaseFirstChar } from "../../../utils/transformers"; import { projectTagsRenderer } from "../ProjectTags/ProjectTags"; import { searchTagsRenderer } from "../SearchList/SearchTags"; import { ArtefactTag } from "../ArtefactTag"; +import { AppDispatch } from "store/configureStore"; /** Shows the recently viewed items a user has visited. Also allows to trigger a workspace search. */ export function RecentlyViewedModal() { @@ -50,7 +51,7 @@ export function RecentlyViewedModal() { // Current path name const { pathname } = useLocation(); const { t } = useTranslation(); - const dispatch = useDispatch(); + const dispatch = useDispatch(); const { hotKeys } = useSelector(commonSel.initialSettingsSelector); const loadRecentItems = async () => { setError(null); @@ -124,7 +125,7 @@ export function RecentlyViewedModal() { item: IRecentlyViewedItem, query: string, modifiers: SuggestFieldItemRendererModifierProps, - handleSelectClick: () => any + handleSelectClick: () => any, ) => { console.log("quick search item", item); const label = item.taskLabel || item.taskId || item.projectLabel || item.projectId; @@ -218,7 +219,7 @@ export function RecentlyViewedModal() { // Displays the 'search in workspace' option in the list. const createNewItemRenderer = suggestFieldUtils.createNewItemRendererFactory( (query) => t("RecentlyViewedModal.globalSearch", { query }), - "operation-search" + "operation-search", ); // The auto-completion of the recently viewed items diff --git a/workspace/src/app/views/shared/projectTaskTabView/ProjectTaskTabView.tsx b/workspace/src/app/views/shared/projectTaskTabView/ProjectTaskTabView.tsx index d2627578e3..14cd823aad 100644 --- a/workspace/src/app/views/shared/projectTaskTabView/ProjectTaskTabView.tsx +++ b/workspace/src/app/views/shared/projectTaskTabView/ProjectTaskTabView.tsx @@ -30,6 +30,7 @@ import { IProjectTaskView, IViewActions, pluginRegistry } from "../../plugins/Pl import PromptModal from "./PromptModal"; import ErrorBoundary from "../../../ErrorBoundary"; import { ProjectTaskTabViewContext } from "./ProjectTaskTabViewContext"; +import { AppDispatch } from "store/configureStore"; const getBookmark = () => window.location.pathname.split("/").slice(-1)[0]; @@ -99,7 +100,7 @@ export function ProjectTaskTabView({ const globalTaskId = useSelector(commonSel.currentTaskIdSelector); const projectId = taskViewConfig?.projectId ?? globalProjectId; const taskId = taskViewConfig?.taskId ?? globalTaskId; - const dispatch = useDispatch(); + const dispatch = useDispatch(); const history = useHistory(); const [t] = useTranslation(); const [isFetchingLinks, setIsFetchingLinks] = useState(true); diff --git a/workspace/test/integration/TestHelper.tsx b/workspace/test/integration/TestHelper.tsx index 11033a85c2..4f36611dc0 100644 --- a/workspace/test/integration/TestHelper.tsx +++ b/workspace/test/integration/TestHelper.tsx @@ -2,7 +2,7 @@ import React from "react"; import { createBrowserHistory, createMemoryHistory, History, LocationState } from "history"; import { EnzymePropSelector, mount, ReactWrapper, shallow } from "enzyme"; import { Provider } from "react-redux"; -import { configureStore, getDefaultMiddleware } from "@reduxjs/toolkit"; +import { configureStore } from "@reduxjs/toolkit"; import rootReducer from "../../src/app/store/reducers"; import { ConnectedRouter, routerMiddleware } from "connected-react-router"; import { AxiosMockQueueItem, AxiosMockRequestCriteria, AxiosMockType, HttpResponse } from "jest-mock-axios"; @@ -64,18 +64,13 @@ jest.mock("react-router", () => ({ */ export const createStore = (history: History, initialState: RecursivePartial) => { const root = rootReducer(history); - const middleware = [ - ...getDefaultMiddleware({ - serializableCheck: false, - }), - routerMiddleware(history), - ]; + const middleware = [routerMiddleware(history)]; // Get the initial state (defaults) of the store // FIXME: Is there a better way to get the initial state of the store? const tempStore = configureStore({ reducer: root, - middleware, + middleware: (getDefaultMiddleWare) => getDefaultMiddleWare({ serializableCheck: false }).concat(middleware), }); const rootState = tempStore.getState(); @@ -84,7 +79,7 @@ export const createStore = (history: History, initialState: Recur // Create store with merged state return configureStore({ reducer: root, - middleware, + middleware: (getDefaultMiddleWare) => getDefaultMiddleWare({ serializableCheck: false }).concat(middleware), preloadedState: state, }); }; From 087675dab67f703acb143f04c5c8f4b257c6a3b8 Mon Sep 17 00:00:00 2001 From: arausly Date: Tue, 30 Sep 2025 08:38:28 +0100 Subject: [PATCH 002/105] adapted for react 18 --- libs/gui-elements | 2 +- package.json | 10 +- workspace/package.json | 4 +- workspace/src/app/hooks/useCopyButton.tsx | 2 +- workspace/src/app/hooks/useErrorHandler.tsx | 4 +- workspace/src/app/services/errorLogger.ts | 2 +- .../src/app/store/ducks/common/typings.ts | 3 +- workspace/src/app/utils/uiUtils.tsx | 8 +- .../Activities/tests/ActivitiesList.test.tsx | 2 +- .../Linking/config/LinkageRuleConfigModal.tsx | 10 +- .../ExecutionReport/ExecutionReport.tsx | 10 +- .../components/AutoComplete.tsx | 18 +-- .../MappingRule/ObjectRule/ObjectRuleForm.tsx | 34 +++--- .../elements/RuleTypes.tsx | 6 +- .../PrefixNew.tsx | 6 +- .../Project/WarningWidget/WarningWidget.tsx | 8 +- .../src/app/views/plugins/PluginRegistry.tsx | 19 +-- .../plugins/RegisteredCoreTaskPlugins.tsx | 16 +-- .../ActionsMenu/ArtefactManagementOptions.tsx | 2 +- .../app/views/shared/Datalist/Datalist.tsx | 4 +- .../app/views/shared/Metadata/Metadata.tsx | 8 +- .../views/shared/PageHeader/PageHeader.tsx | 4 +- .../views/shared/ProjectTags/ProjectTags.tsx | 2 +- .../views/shared/RelatedItems/RelatedItem.tsx | 10 +- .../views/shared/RuleEditor/RuleEditor.tsx | 7 +- .../RuleEditor/contexts/RuleEditorContext.tsx | 2 +- .../contexts/RuleEditorEvaluationContext.tsx | 6 +- .../RuleEditor/model/RuleEditorModel.tsx | 2 +- .../model/test/RuleEditorModel.test.tsx | 5 +- .../RuleEditor/view/RuleEditorCanvas.tsx | 2 +- .../evaluation/EvaluationActivityControl.tsx | 2 +- .../view/ruleNode/PathInputOperator.tsx | 12 +- .../view/ruleNode/ruleNode.utils.tsx | 12 +- .../views/shared/SearchList/SearchTags.tsx | 2 +- .../TaskActivityOverview.tsx | 42 +++---- .../VariablesWidget/VariablesWidget.tsx | 14 +-- .../app/views/shared/buttons/CreateButton.tsx | 4 +- .../ArtefactForms/ArtefactFormParameter.tsx | 4 +- .../ArtefactForms/ParameterAutoCompletion.tsx | 3 +- .../ArtefactForms/ParameterWidget.tsx | 6 +- .../CreateArtefactModal.tsx | 29 ++--- .../modals/InvisibleCharacterCleanUpModal.tsx | 4 +- .../shared/modals/ProjectImportModal.tsx | 2 +- .../projectTaskTabsViewHooks.tsx | 4 +- .../components/ConnectionAvailable.tsx | 6 +- .../components/ConnectionEnabled.tsx | 22 +--- .../activeLearning/components/PropertyBox.tsx | 6 +- .../evaluation/LinkingRuleEvaluation.tsx | 112 +++++++++--------- .../tabView/LinkingEvaluationRow.tsx | 4 +- .../tabView/LinkingEvaluationTabView.tsx | 3 +- .../shared/evaluations/OperatorLabel.tsx | 3 +- .../taskViews/shared/rules/rule.utils.tsx | 52 ++++---- .../transform/TransformRuleEditor.tsx | 30 ++--- .../evaluation/TransformRuleEvaluation.tsx | 20 ++-- .../tabView/TransformEvaluationTabView.tsx | 2 +- workspace/src/index.tsx | 8 +- workspace/test/integration/TestHelper.tsx | 2 +- 57 files changed, 316 insertions(+), 312 deletions(-) diff --git a/libs/gui-elements b/libs/gui-elements index 0d37beced4..b9fd1c0bde 160000 --- a/libs/gui-elements +++ b/libs/gui-elements @@ -1 +1 @@ -Subproject commit 0d37beced46f090d84063a47728e0813bb05a790 +Subproject commit b9fd1c0bdeb68000d5e30e522461ac3f87007ec0 diff --git a/package.json b/package.json index 763e9dcd4f..8e96a3d061 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ ], "scripts": {}, "dependencies": { - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^19.1.1", + "react-dom": "^19.1.1" }, "devDependencies": {}, "resolutions": { @@ -22,10 +22,10 @@ "**/minimist": "1.2.8", "**/moment": "2.29.4", "**/nanoid": "3.3.4", - "**/react": "^17.0.2", - "**/react-dom": "^17.0.2", + "**/react": "^19.1.1", + "**/react-dom": "^19.1.1", "**/semver-regex": "3.1.4", - "**/@types/react": "^17.0.85", + "**/@types/react": "^19.1.15", "**/url-parse": "1.5.9" } } diff --git a/workspace/package.json b/workspace/package.json index 93da79bace..6aa29875d3 100644 --- a/workspace/package.json +++ b/workspace/package.json @@ -184,8 +184,8 @@ "@testing-library/user-event": "^14.6.1", "@types/jest": "^30.0.0", "@types/ramda": "^0.26.6", - "@types/react": "^17.0.85", - "@types/react-dom": "^17.0.8", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", "@types/react-redux": "^7.1.34", "@types/react-router": "^5.1.20", "@types/react-router-dom": "^5.3.3", diff --git a/workspace/src/app/hooks/useCopyButton.tsx b/workspace/src/app/hooks/useCopyButton.tsx index f796e88fd1..193a8a7a79 100644 --- a/workspace/src/app/hooks/useCopyButton.tsx +++ b/workspace/src/app/hooks/useCopyButton.tsx @@ -19,7 +19,7 @@ interface ICopyData { const COPY_RESET_TIMEOUT = 1000; -const useCopyButton = (data: Array, resetTimeout = COPY_RESET_TIMEOUT): JSX.Element[] => { +const useCopyButton = (data: Array, resetTimeout = COPY_RESET_TIMEOUT): React.JSX.Element[] => { const [activeButton, setActiveButton] = React.useState(); const { registerError } = useErrorHandler(); const [t] = useTranslation(); diff --git a/workspace/src/app/hooks/useErrorHandler.tsx b/workspace/src/app/hooks/useErrorHandler.tsx index 20f3980b67..4a2090ba9d 100644 --- a/workspace/src/app/hooks/useErrorHandler.tsx +++ b/workspace/src/app/hooks/useErrorHandler.tsx @@ -19,7 +19,7 @@ export type ErrorHandlerRegisterFuncType = ( errorMessage: string, cause: DIErrorTypes | null, options?: ErrorHandlerOptions, -) => JSX.Element | null; +) => React.JSX.Element | null; interface ErrorHandlerOptions { /** The notification instance where the error should be displayed. If this is set, the @@ -40,7 +40,7 @@ type ErrorHandlerRegisterShortFuncType = ( /** The error cause. */ cause: DIErrorTypes | null, options?: ErrorHandlerOptions, -) => JSX.Element | null; +) => React.JSX.Element | null; interface ErrorHandlerDict { registerError: ErrorHandlerRegisterFuncType; diff --git a/workspace/src/app/services/errorLogger.ts b/workspace/src/app/services/errorLogger.ts index 2b86866742..6d4b7a3c48 100644 --- a/workspace/src/app/services/errorLogger.ts +++ b/workspace/src/app/services/errorLogger.ts @@ -161,7 +161,7 @@ const logError = (error: FetchError | Error, reactErrorInfo?: ErrorInfo): boolea } else if (error instanceof Error) { const { name, message, stack } = error; const newStack = reactErrorInfo ? reactErrorInfo.componentStack : stack; - err = generateDefaultError(name, message, newStack); + err = generateDefaultError(name, message, newStack || undefined); } else { err = generateDefaultError("Uncaught Error type received ", error); } diff --git a/workspace/src/app/store/ducks/common/typings.ts b/workspace/src/app/store/ducks/common/typings.ts index 6e0c72e6f6..cb85a5734b 100644 --- a/workspace/src/app/store/ducks/common/typings.ts +++ b/workspace/src/app/store/ducks/common/typings.ts @@ -1,3 +1,4 @@ +import React from "react"; import { IAutocompleteDefaultResponse, IMetadata, @@ -37,7 +38,7 @@ interface AutoCompletionFrontendExtensions { query: string, modifiers: SuggestFieldItemRendererModifierProps, handleSelectClick: () => any, - ) => string | JSX.Element; + ) => string | React.JSX.Element; } /** Properties for parameter auto-completion. */ diff --git a/workspace/src/app/utils/uiUtils.tsx b/workspace/src/app/utils/uiUtils.tsx index c5c1b8515e..2164e8906d 100644 --- a/workspace/src/app/utils/uiUtils.tsx +++ b/workspace/src/app/utils/uiUtils.tsx @@ -4,11 +4,11 @@ import React from "react"; /** Wraps an element inside a tooltip when the wrap predicate is true. */ export const wrapTooltip = ( wrapPredicate: boolean, - childTooltip: string | JSX.Element, - child: JSX.Element, + childTooltip: string | React.JSX.Element, + child: React.JSX.Element, position: ContextOverlayProps["placement"] = "bottom-start", - size: "large" | "small" | "medium" = "large" -): JSX.Element => { + size: "large" | "small" | "medium" = "large", +): React.JSX.Element => { if (wrapPredicate) { return ( diff --git a/workspace/src/app/views/pages/Activities/tests/ActivitiesList.test.tsx b/workspace/src/app/views/pages/Activities/tests/ActivitiesList.test.tsx index 336226687a..3ce0ef8c51 100644 --- a/workspace/src/app/views/pages/Activities/tests/ActivitiesList.test.tsx +++ b/workspace/src/app/views/pages/Activities/tests/ActivitiesList.test.tsx @@ -47,7 +47,7 @@ const dummyState = { }; const render = ( - ui: JSX.Element, + ui: React.JSX.Element, { store = configureStore({ reducer: { workspace: workspaceReducer }, diff --git a/workspace/src/app/views/pages/Linking/config/LinkageRuleConfigModal.tsx b/workspace/src/app/views/pages/Linking/config/LinkageRuleConfigModal.tsx index eb01d5c46d..1eb97c2080 100644 --- a/workspace/src/app/views/pages/Linking/config/LinkageRuleConfigModal.tsx +++ b/workspace/src/app/views/pages/Linking/config/LinkageRuleConfigModal.tsx @@ -18,7 +18,7 @@ export const LinkageRuleConfigModal = ({ onClose, parameters, submit }: IProps) const [t] = useTranslation(); const [parameterDiff] = useState>(new Map()); const [changed, setChanged] = useState(false); - const [requestError, setRequestError] = useState(undefined); + const [requestError, setRequestError] = useState(undefined); const [errorCount, setErrorCount] = useState(0); const initialParameters = new Map(parameters.map((p) => [p.id, p])); const [errors] = useState(new Map()); @@ -45,8 +45,8 @@ export const LinkageRuleConfigModal = ({ onClose, parameters, submit }: IProps) forParameter: string, autoCompleteRequest: ( textQuery: string, - limit: number - ) => Promise> + limit: number, + ) => Promise>, ) => async (textQuery: string) => { try { @@ -58,7 +58,7 @@ export const LinkageRuleConfigModal = ({ onClose, parameters, submit }: IProps) warning > Auto-completion request has failed. Cannot suggest values for '${forParameter}' parameter. - + , ); return []; } @@ -113,7 +113,7 @@ export const LinkageRuleConfigModal = ({ onClose, parameters, submit }: IProps) "LinkageRuleConfig-save-config", t("widget.LinkingRuleConfigWidget.saveError"), ex, - { errorNotificationInstanceId: "_none_" } + { errorNotificationInstanceId: "_none_" }, ); setRequestError(errorWidget || undefined); } diff --git a/workspace/src/app/views/pages/MappingEditor/ExecutionReport/ExecutionReport.tsx b/workspace/src/app/views/pages/MappingEditor/ExecutionReport/ExecutionReport.tsx index 8bb23a2b68..9aeaa01914 100644 --- a/workspace/src/app/views/pages/MappingEditor/ExecutionReport/ExecutionReport.tsx +++ b/workspace/src/app/views/pages/MappingEditor/ExecutionReport/ExecutionReport.tsx @@ -69,7 +69,7 @@ export const ExecutionReport = ({ executionReport, executionMetaData, trackRuleI title = t("ExecutionReport.defaultTitle"); } - let executionMetaDataPairs: JSX.Element[] = []; + let executionMetaDataPairs: React.JSX.Element[] = []; if (executionMetaData != null) { executionMetaDataPairs = executionMetaDataPairs.concat([ @@ -110,7 +110,7 @@ export const ExecutionReport = ({ executionReport, executionMetaData, trackRuleI Cancelled at {executionMetaData.cancelledAt} - + , ); } if (executionMetaData.cancelledBy != null) { @@ -118,7 +118,7 @@ export const ExecutionReport = ({ executionReport, executionMetaData, trackRuleI Cancelled by {executionMetaData.cancelledBy} - + , ); } } @@ -200,7 +200,7 @@ export const ExecutionReport = ({ executionReport, executionMetaData, trackRuleI if (rules.typeRules != null) { m.set( rule.id, - rules.typeRules.map((r) => ({ id: r.id, typeRuleId: r.typeUri })) + rules.typeRules.map((r) => ({ id: r.id, typeRuleId: r.typeUri })), ); } if (rules.propertyRules != null) { @@ -329,7 +329,7 @@ export const ExecutionReport = ({ executionReport, executionMetaData, trackRuleI // Check type rules const typeRulesOfRule = typeRulesPerContainerRule.get(ruleId) ?? []; typeRulesWithIssues = typeRulesOfRule.filter( - (typeRuleId) => ruleValidation && ruleValidation[typeRuleId.id] === "warning" + (typeRuleId) => ruleValidation && ruleValidation[typeRuleId.id] === "warning", ); return (
diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/AutoComplete.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/AutoComplete.tsx index a438b15564..449c7203a6 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/AutoComplete.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/AutoComplete.tsx @@ -24,7 +24,7 @@ import { ValidIconName } from "@eccenca/gui-elements/src/components/Icon/canonic const onSearchFactory = ( ruleId?: string, entity?: string, - taskContext?: TaskContext + taskContext?: TaskContext, ): ((searchText: string) => Promise) => { return (searchText: string) => { return new Promise((resolve, reject) => { @@ -37,7 +37,7 @@ const onSearchFactory = ( ({ options }) => { resolve(options); }, - (err) => reject(err) + (err) => reject(err), ); }); }; @@ -117,20 +117,20 @@ interface OptionalRenderFunctions { optionalLabelFn?: (obj: T) => string | undefined; optionalValueFn?: (obj: T) => string; optionalDescriptionFn?: (obj: T) => string | undefined; - optionalIconFn?: (obj: T) => ValidIconName | JSX.Element | undefined; - optionalItemActionsFn?: (obj: T) => JSX.Element | undefined; + optionalIconFn?: (obj: T) => ValidIconName | React.JSX.Element | undefined; + optionalItemActionsFn?: (obj: T) => React.JSX.Element | undefined; } export function autoCompleteItemRendererFactory( showValueWhenLabelExists: boolean, - optionalFunctions: OptionalRenderFunctions = {} + optionalFunctions: OptionalRenderFunctions = {}, ) { return ( autoCompleteItem: IAutoCompleteItem & T, query: string, modifiers: SuggestFieldItemRendererModifierProps, - handleClick: () => any - ): JSX.Element => { + handleClick: () => any, + ): React.JSX.Element => { const { optionalLabelFn, optionalValueFn, optionalDescriptionFn, optionalIconFn, optionalItemActionsFn } = optionalFunctions; let label: string | undefined; @@ -251,12 +251,12 @@ const AutoComplete = ({ const newItemRenderer = ( query: string, modifiers: SuggestFieldItemRendererModifierProps, - handleClick: React.MouseEventHandler + handleClick: React.MouseEventHandler, ) => { if (isValidNewOption({ label: query })) { const newItemRenderer = suggestFieldUtils.createNewItemRendererFactory( (query: string) => (newOptionText ? newOptionText(query) : `Create option '${query}'`), - "item-add-artefact" + "item-add-artefact", ); return newItemRenderer(query, modifiers, handleClick); } diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx index 736ce0b9a7..1921673c6a 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx @@ -84,7 +84,7 @@ export const ObjectRuleForm = (props: IProps) => { } }; const [targetEntityType, setTargetEntityType] = useState<(string | { value: string })[]>( - _modifiedValues.current.targetEntityType + _modifiedValues.current.targetEntityType, ); // Used for setting a new URI pattern from the existing URI pattern selection const [initialUriPattern, setInitialUriPattern] = useState((props.ruleData as any).pattern ?? ""); @@ -106,8 +106,8 @@ export const ObjectRuleForm = (props: IProps) => { const distinctUriPatterns = Array.from( new Map( - uriPatternSuggestions.filter((p) => p.value !== (modifiedValues() as any).pattern).map((p) => [p.value, p]) - ).values() + uriPatternSuggestions.filter((p) => p.value !== (modifiedValues() as any).pattern).map((p) => [p.value, p]), + ).values(), ); const currentUriPatterns = React.useRef([]); currentUriPatterns.current = distinctUriPatterns; @@ -207,7 +207,7 @@ export const ObjectRuleForm = (props: IProps) => { pattern: modifiedValues().uriRule?.type === MAPPING_RULE_TYPE_URI && !uriPattern ? null : uriPattern, entityConnection: modifiedValues().entityConnection === "to", }, - true + true, ).subscribe( () => { if (props.onAddNewRule) { @@ -221,7 +221,7 @@ export const ObjectRuleForm = (props: IProps) => { (err) => { setSaveObjectError(err.response.body); setLoading(false); - } + }, ); }; @@ -317,7 +317,7 @@ export const ObjectRuleForm = (props: IProps) => { parentId ? parentId : MAPPING_ROOT_RULE_ID, input, cursorPosition, - modifiedValues().sourceProperty + modifiedValues().sourceProperty, ) } onFocusChange={setUriPatternInputHasFocus} @@ -326,7 +326,7 @@ export const ObjectRuleForm = (props: IProps) => { reInitOnInitialValueChange={true} /> ), - [initialUriPattern, uriPatternSelector] + [initialUriPattern, uriPatternSelector], ); if (loading) { @@ -345,10 +345,10 @@ export const ObjectRuleForm = (props: IProps) => { ); - let targetPropertyInput: JSX.Element | undefined = undefined; - let targetCardinality: JSX.Element | undefined = undefined; - let entityRelationInput: JSX.Element | undefined = undefined; - let sourcePropertyInput: JSX.Element | undefined = undefined; + let targetPropertyInput: React.JSX.Element | undefined = undefined; + let targetCardinality: React.JSX.Element | undefined = undefined; + let entityRelationInput: React.JSX.Element | undefined = undefined; + let sourcePropertyInput: React.JSX.Element | undefined = undefined; targetCardinality = ( { initialValues.sourceProperty == null ? "" : typeof initialValues.sourceProperty === "string" - ? initialValues.sourceProperty - : initialValues.sourceProperty.value; + ? initialValues.sourceProperty + : initialValues.sourceProperty.value; sourcePropertyInput = ( { ); } - let patternInput: JSX.Element | undefined; + let patternInput: React.JSX.Element | undefined; // URI pattern if (!id || modifiedValues().uriRuleType === "uri") { @@ -453,7 +453,7 @@ export const ObjectRuleForm = (props: IProps) => { ); } - let previewExamples: null | JSX.Element = null; + let previewExamples: null | React.JSX.Element = null; const noUriRule = !modifiedValues().uriRule || modifiedValues().uriRule.type === MAPPING_RULE_TYPE_URI; const noUriPattern = !modifiedValues().pattern; @@ -479,8 +479,8 @@ export const ObjectRuleForm = (props: IProps) => { const ruleType = modifiedValues().pattern ? MAPPING_RULE_TYPE_URI : modifiedValues().uriRule - ? modifiedValues().uriRule.type - : MAPPING_RULE_TYPE_URI; + ? modifiedValues().uriRule.type + : MAPPING_RULE_TYPE_URI; previewExamples = ( { // add language tag if available appendText = ` (${appendText})`; } - let dataTypeLabel: string | JSX.Element = _.get(rule, "mappingTarget.valueType.nodeType", ); + let dataTypeLabel: string | React.JSX.Element = _.get( + rule, + "mappingTarget.valueType.nodeType", + , + ); if (typeof dataTypeLabel === "string") { const label = mappingEditorContext.valueTypeLabels.get(dataTypeLabel); if (label) { diff --git a/workspace/src/app/views/pages/Project/ProjectNamespacePrefixManagementWidget/PrefixNew.tsx b/workspace/src/app/views/pages/Project/ProjectNamespacePrefixManagementWidget/PrefixNew.tsx index 6ad8feeed4..bfd12d351d 100644 --- a/workspace/src/app/views/pages/Project/ProjectNamespacePrefixManagementWidget/PrefixNew.tsx +++ b/workspace/src/app/views/pages/Project/ProjectNamespacePrefixManagementWidget/PrefixNew.tsx @@ -81,8 +81,8 @@ const PrefixNew = ({ onAdd, existingPrefixes }: IProps) => { } }; - let prefixNameErrorIcon: JSX.Element | undefined = undefined; - let prefixValueErrorIcon: JSX.Element | undefined = undefined; + let prefixNameErrorIcon: React.JSX.Element | undefined = undefined; + let prefixValueErrorIcon: React.JSX.Element | undefined = undefined; if (!isValidPrefixName && prefixDefinition.prefixName) { prefixNameErrorIcon = ; @@ -114,7 +114,7 @@ const PrefixNew = ({ onAdd, existingPrefixes }: IProps) => { handleSubmit(); } }, - [submitButtonDisabled, prefixDefinition] + [submitButtonDisabled, prefixDefinition], ); const closeOverwriteDialog = React.useCallback(() => setOverwriteDialogOpen(false), []); diff --git a/workspace/src/app/views/pages/Project/WarningWidget/WarningWidget.tsx b/workspace/src/app/views/pages/Project/WarningWidget/WarningWidget.tsx index 0043dcc9c7..2ca7bff652 100644 --- a/workspace/src/app/views/pages/Project/WarningWidget/WarningWidget.tsx +++ b/workspace/src/app/views/pages/Project/WarningWidget/WarningWidget.tsx @@ -92,14 +92,14 @@ export const ProjectTaskLoadingErrors = ({ refreshProjectPage }: Props) => { taskId, parameterData, variableTemplateData, - dataParameters + dataParameters, ) => { await fixFailedTask( projectId, taskId, parameterData as TaskParameterValues, variableTemplateData as TaskParameterValues, - dataParameters + dataParameters, ); // Update warning list and project page fetchWarningList(); @@ -138,7 +138,7 @@ export const ProjectTaskLoadingErrors = ({ refreshProjectPage }: Props) => { // FIXME: Add label to failedTaskData in order to display task label alternativeTitle: t("widget.WarningWidget.fixTaskModalTitle", { taskLabel: taskLabel }), alternativeUpdateFunction: fixTask, - }) + }), ); } catch (ex) { if (ex.httpStatus === 404 || ex.status === 404) { @@ -174,7 +174,7 @@ export const ProjectTaskLoadingErrors = ({ refreshProjectPage }: Props) => {
    {warningList.map((warn, id) => { - const actions: JSX.Element[] = projectId + const actions: React.JSX.Element[] = projectId ? [ JSX.Element | undefined; + taskViewSuffix?: (taskContext: TaskContext) => React.JSX.Element | undefined; /** A notification shown in the tab view regarding the task context, e.g. a warning. */ taskContextNotification?: ( - taskContext: TaskContext + taskContext: TaskContext, ) => Promise | TaskContextNotification[] | undefined; } @@ -48,7 +48,12 @@ export interface IProjectTaskView { // The label that should be shown to the user label: string; // Function that renders the view - render: (projectId: string, taskId: string, viewActions?: IViewActions, startInFullScreen?: boolean) => JSX.Element; + render: ( + projectId: string, + taskId: string, + viewActions?: IViewActions, + startInFullScreen?: boolean, + ) => React.JSX.Element; /** The query parameters to get from other tabs or propagate to other tabs. */ queryParametersToKeep?: string[]; /** Specifies the task context support for this view, e.g. that it uses the information given with the task context. */ @@ -71,7 +76,7 @@ export interface IPluginComponent { // The label that should be shown to the user label: string; // Function that renders the view - Component: (params: I) => JSX.Element; + Component: (params: I) => React.JSX.Element; } class PluginRegistry { @@ -91,7 +96,7 @@ class PluginRegistry { views.push(view); } else { console.warn( - `Trying to register project task plugin view '${view.id}' that already exists in the registry for plugin '${pluginId}'!` + `Trying to register project task plugin view '${view.id}' that already exists in the registry for plugin '${pluginId}'!`, ); } } @@ -100,7 +105,7 @@ class PluginRegistry { public registerReactPluginComponent(pluginComponent: IPluginComponent) { if (this.pluginReactComponents.has(pluginComponent.id)) { console.warn( - `Trying to register a React plugin component with ID '${pluginComponent.id}' that already exists in the React plugin component registry!` + `Trying to register a React plugin component with ID '${pluginComponent.id}' that already exists in the React plugin component registry!`, ); } else { this.pluginReactComponents.set(pluginComponent.id, pluginComponent); @@ -111,7 +116,7 @@ class PluginRegistry { public registerPluginComponent(pluginId: string, plugin: I) { if (this.pluginComponents.has(pluginId)) { console.warn( - `Trying to register a plugin component with ID '${pluginId}' that already exists in the plugin component registry!` + `Trying to register a plugin component with ID '${pluginId}' that already exists in the plugin component registry!`, ); } else { this.pluginComponents.set(pluginId, plugin); diff --git a/workspace/src/app/views/plugins/RegisteredCoreTaskPlugins.tsx b/workspace/src/app/views/plugins/RegisteredCoreTaskPlugins.tsx index b6900fc487..b24ca4d9e2 100644 --- a/workspace/src/app/views/plugins/RegisteredCoreTaskPlugins.tsx +++ b/workspace/src/app/views/plugins/RegisteredCoreTaskPlugins.tsx @@ -17,7 +17,7 @@ export const registerCorePlugins = () => { pluginRegistry.registerTaskView("linking", { id: "linkingEditor", label: "Linking editor", - render(projectId: string, taskId: string, viewActions: IViewActions | undefined): JSX.Element { + render(projectId: string, taskId: string, viewActions: IViewActions | undefined): React.JSX.Element { return ( { pluginRegistry.registerTaskView("linking", { id: "linkingEvaluation", label: "Linking evaluation", - render(projectId: string, taskId: string, _: IViewActions, startFullScreen: boolean): JSX.Element { + render(projectId: string, taskId: string, _: IViewActions, startFullScreen: boolean): React.JSX.Element { return ; }, }); @@ -46,7 +46,7 @@ export const registerCorePlugins = () => { pluginRegistry.registerTaskView("linking", { id: "LinkingExecution", label: "Linking execution", - render(projectId: string, taskId: string, viewActions: IViewActions | undefined): JSX.Element { + render(projectId: string, taskId: string, viewActions: IViewActions | undefined): React.JSX.Element { return ; }, }); @@ -61,8 +61,8 @@ export const registerCorePlugins = () => { projectId: string, taskId: string, viewActions: IViewActions, - startFullScreen: boolean - ): JSX.Element { + startFullScreen: boolean, + ): React.JSX.Element { return ( { id: "TransformExecution", label: "Transform execution", queryParametersToKeep: ["ruleId"], - render(projectId: string, taskId: string, viewActions: IViewActions | undefined): JSX.Element { + render(projectId: string, taskId: string, viewActions: IViewActions | undefined): React.JSX.Element { return ; }, }); @@ -91,8 +91,8 @@ export const registerCorePlugins = () => { projectId: string, taskId: string, viewActions: IViewActions | undefined, - startFullScreen: boolean - ): JSX.Element { + startFullScreen: boolean, + ): React.JSX.Element { setApiDetails({ project: projectId, transformTask: taskId }); return ( any; + updateActionsMenu: (actionMenu: React.JSX.Element) => any; // Called with true when the item links endpoint returns a 404 notFoundCallback?: (boolean) => any; } diff --git a/workspace/src/app/views/shared/Datalist/Datalist.tsx b/workspace/src/app/views/shared/Datalist/Datalist.tsx index 202d9e7a1e..d777d1725c 100644 --- a/workspace/src/app/views/shared/Datalist/Datalist.tsx +++ b/workspace/src/app/views/shared/Datalist/Datalist.tsx @@ -4,10 +4,10 @@ import { OverviewItemList, Notification } from "@eccenca/gui-elements"; import { useTranslation } from "react-i18next"; interface IProps { - children: JSX.Element | JSX.Element[]; + children: React.JSX.Element | React.JSX.Element[]; isLoading: boolean; isEmpty: boolean; - emptyContainer?: JSX.Element; + emptyContainer?: React.JSX.Element; emptyListMessage?: string; [key: string]: any; } diff --git a/workspace/src/app/views/shared/Metadata/Metadata.tsx b/workspace/src/app/views/shared/Metadata/Metadata.tsx index d9687ddbd9..446d6e42bd 100644 --- a/workspace/src/app/views/shared/Metadata/Metadata.tsx +++ b/workspace/src/app/views/shared/Metadata/Metadata.tsx @@ -70,7 +70,7 @@ export function Metadata(props: IProps) { const [loading, setLoading] = useState(false); const [data, setData] = useState({ label: "", description: "", tags: [] }); const [formEditData, setFormEditData] = useState(undefined); - const formRef = React.useRef(); + const formRef = React.useRef(undefined); const [isEditing, setIsEditing] = useState(false); const [unsavedChanges, setUnsavedChanges] = useState(false); const [createdTags, setCreatedTags] = React.useState[]>([]); @@ -388,7 +388,7 @@ export function Metadata(props: IProps) { ? t( "Metadata.dateFormat", "{{year}}/{{month}}/{{day}}", - getDateData(created) + getDateData(created), ) : "", author: createdByUser?.label ?? t("Metadata.unknownuser", "unknown user"), @@ -427,7 +427,7 @@ export function Metadata(props: IProps) { ? t( "Metadata.dateFormat", "{{year}}/{{month}}/{{day}}", - getDateData(modified) + getDateData(modified), ) : "", author: @@ -439,7 +439,7 @@ export function Metadata(props: IProps) { ), diff --git a/workspace/src/app/views/shared/PageHeader/PageHeader.tsx b/workspace/src/app/views/shared/PageHeader/PageHeader.tsx index 9ee641efde..c852ceeb56 100644 --- a/workspace/src/app/views/shared/PageHeader/PageHeader.tsx +++ b/workspace/src/app/views/shared/PageHeader/PageHeader.tsx @@ -31,7 +31,7 @@ interface IPageHeaderContentBasicProps extends React.HTMLAttributes { updatePageHeader({ breadcrumbsExtensions: update, autogenerateBreadcrumbs: true }); }, - updateActionsMenu: (update: JSX.Element) => { + updateActionsMenu: (update: React.JSX.Element) => { updatePageHeader({ actionsMenu: update }); }, updatePageHeader, diff --git a/workspace/src/app/views/shared/ProjectTags/ProjectTags.tsx b/workspace/src/app/views/shared/ProjectTags/ProjectTags.tsx index 20d7a8a0ac..1bd3998657 100644 --- a/workspace/src/app/views/shared/ProjectTags/ProjectTags.tsx +++ b/workspace/src/app/views/shared/ProjectTags/ProjectTags.tsx @@ -9,7 +9,7 @@ interface IProps { query?: string; } -export const projectTagsRenderer = (props: IProps): JSX.Element[] => { +export const projectTagsRenderer = (props: IProps): React.JSX.Element[] => { const { tags = [], query = "" } = props; return metadataUtils.sortTags(tags.slice()).map((t, i) => ( diff --git a/workspace/src/app/views/shared/RelatedItems/RelatedItem.tsx b/workspace/src/app/views/shared/RelatedItems/RelatedItem.tsx index 255a08dfeb..01b06b1735 100644 --- a/workspace/src/app/views/shared/RelatedItems/RelatedItem.tsx +++ b/workspace/src/app/views/shared/RelatedItems/RelatedItem.tsx @@ -51,7 +51,7 @@ export function RelatedItem({ relatedItem, textQuery }: IProps) { routerOp.goToPage(relatedItem.itemLinks[0].path, { taskLabel: relatedItem.label, itemType: relatedItem.type.toLowerCase(), - }) + }), ); } }; @@ -75,25 +75,25 @@ export function RelatedItem({ relatedItem, textQuery }: IProps) { )); const contextMenuItems = [otherMenuItems[0], ...menuItems, ...otherMenuItems.slice(1)]; - const itemTags = [] as JSX.Element[]; + const itemTags = [] as React.JSX.Element[]; if (relatedItem.type === "Dataset") { itemTags.push( - + , ); } if (relatedItem.readOnly) { itemTags.push( - + , ); } itemTags.push( - + , ); return ( diff --git a/workspace/src/app/views/shared/RuleEditor/RuleEditor.tsx b/workspace/src/app/views/shared/RuleEditor/RuleEditor.tsx index 32bfd22ed8..1427190514 100644 --- a/workspace/src/app/views/shared/RuleEditor/RuleEditor.tsx +++ b/workspace/src/app/views/shared/RuleEditor/RuleEditor.tsx @@ -72,7 +72,7 @@ export interface RuleEditorProps { /** Tabs that allow to show different rule operators or only a subset. */ tabs?: (IRuleSideBarFilterTabConfig | IRuleSidebarPreConfiguredOperatorsTabConfig)[]; /** Additional components that will be placed in the tool bar left to the save button. */ - additionalToolBarComponents?: () => JSX.Element | JSX.Element[]; + additionalToolBarComponents?: () => React.JSX.Element | React.JSX.Element[]; /** parent configuration to extract stickyNote from taskData*/ getStickyNotes?: (taskData: RULE_TYPE | undefined) => StickyNote[]; /** When enabled only the rule is shown without side- and toolbar and any other means to edit the rule. */ @@ -309,13 +309,14 @@ const RuleEditor = ({ ); }; +const Provider: React.FC<{ children: React.JSX.Element }> = ReactFlowProvider; const WrappedRuleEditor = ( props: RuleEditorProps, ) => ( - + {...props} /> - + ); diff --git a/workspace/src/app/views/shared/RuleEditor/contexts/RuleEditorContext.tsx b/workspace/src/app/views/shared/RuleEditor/contexts/RuleEditorContext.tsx index de9290b979..614b64a12a 100644 --- a/workspace/src/app/views/shared/RuleEditor/contexts/RuleEditorContext.tsx +++ b/workspace/src/app/views/shared/RuleEditor/contexts/RuleEditorContext.tsx @@ -60,7 +60,7 @@ export interface RuleEditorContextProps { /** If set to true the editor will be in read-only mode and cannot be set into edit mode. */ readOnlyMode?: boolean; /** Additional components that will be placed in the tool bar left to the save button. */ - additionalToolBarComponents?: () => JSX.Element | JSX.Element[]; + additionalToolBarComponents?: () => React.JSX.Element | React.JSX.Element[]; /** The last save result. */ lastSaveResult?: RuleSaveResult; /** UI annotation sticky notes */ diff --git a/workspace/src/app/views/shared/RuleEditor/contexts/RuleEditorEvaluationContext.tsx b/workspace/src/app/views/shared/RuleEditor/contexts/RuleEditorEvaluationContext.tsx index b4255ca33c..d73fd3d16f 100644 --- a/workspace/src/app/views/shared/RuleEditor/contexts/RuleEditorEvaluationContext.tsx +++ b/workspace/src/app/views/shared/RuleEditor/contexts/RuleEditorEvaluationContext.tsx @@ -20,7 +20,7 @@ export interface RuleEditorEvaluationContextProps { startEvaluation: (ruleOperatorNodes: IRuleOperatorNode[], originalTask: any, quickEvaluationOnly: boolean) => void; /** Creates the evaluation component for a single operator node. */ - createRuleEditorEvaluationComponent: (ruleOperatorId: string) => JSX.Element; + createRuleEditorEvaluationComponent: (ruleOperatorId: string) => React.JSX.Element; /** If the evaluation is currently running. */ evaluationRunning: boolean; @@ -94,5 +94,5 @@ export interface RuleEditorEvaluationCallbackContextProps { } export const RuleEditorEvaluationCallbackContext = React.createContext({ - enableErrorModal: NOP -}) + enableErrorModal: NOP, +}); diff --git a/workspace/src/app/views/shared/RuleEditor/model/RuleEditorModel.tsx b/workspace/src/app/views/shared/RuleEditor/model/RuleEditorModel.tsx index a1cb973ae4..b083ff8b3a 100644 --- a/workspace/src/app/views/shared/RuleEditor/model/RuleEditorModel.tsx +++ b/workspace/src/app/views/shared/RuleEditor/model/RuleEditorModel.tsx @@ -63,7 +63,7 @@ import { copyToClipboard } from "../../../../utils/copyToClipboard"; export interface RuleEditorModelProps { /** The children that work on this rule model. */ - children: JSX.Element | JSX.Element[]; + children: React.JSX.Element | React.JSX.Element[]; } // Object to denote transaction boundaries between change operations diff --git a/workspace/src/app/views/shared/RuleEditor/model/test/RuleEditorModel.test.tsx b/workspace/src/app/views/shared/RuleEditor/model/test/RuleEditorModel.test.tsx index 3c37ab51f0..0ac9196d32 100644 --- a/workspace/src/app/views/shared/RuleEditor/model/test/RuleEditorModel.test.tsx +++ b/workspace/src/app/views/shared/RuleEditor/model/test/RuleEditorModel.test.tsx @@ -76,6 +76,7 @@ describe("Rule editor model", () => { stickyNotes: StickyNote[] = [], ) => { modelContext = undefined; + const Provider: React.FC<{ children: React.JSX.Element }> = ReactFlowProvider; const ruleModel = renderWrapper( { partialAutoCompletion: () => async () => undefined, }} > - + - + , ); await waitFor(() => { diff --git a/workspace/src/app/views/shared/RuleEditor/view/RuleEditorCanvas.tsx b/workspace/src/app/views/shared/RuleEditor/view/RuleEditorCanvas.tsx index 1772413bc8..d0a4d4f33b 100644 --- a/workspace/src/app/views/shared/RuleEditor/view/RuleEditorCanvas.tsx +++ b/workspace/src/app/views/shared/RuleEditor/view/RuleEditorCanvas.tsx @@ -57,7 +57,7 @@ export const RuleEditorCanvas = () => { transactionStarted: false, }); // Context menu that is shown on specific user actions - const [contextMenu, setContextMenu] = React.useState(null); + const [contextMenu, setContextMenu] = React.useState(null); // At the moment react-flow's selection logic is buggy in some places, e.g. https://github.com/wbkd/react-flow/issues/1314 // Until fixed, we will track selections ourselves and use them where bugs exist. const [selectionState] = React.useState<{ elements: Elements | null }>({ elements: null }); diff --git a/workspace/src/app/views/shared/RuleEditor/view/evaluation/EvaluationActivityControl.tsx b/workspace/src/app/views/shared/RuleEditor/view/evaluation/EvaluationActivityControl.tsx index 4cd6a0b6ab..5aded06dfb 100644 --- a/workspace/src/app/views/shared/RuleEditor/view/evaluation/EvaluationActivityControl.tsx +++ b/workspace/src/app/views/shared/RuleEditor/view/evaluation/EvaluationActivityControl.tsx @@ -55,7 +55,7 @@ export const EvaluationActivityControl = ({ label: {t("RuleEditor.evaluation.scoreWidget.title")}, statusMessage: t("RuleEditor.evaluation.scoreWidget.notStarted"), } as ActivityControlWidgetProps; - let EvaluationTooltip = ({ children }: { children: JSX.Element }): JSX.Element => children; + let EvaluationTooltip = ({ children }: { children: React.JSX.Element }): React.JSX.Element => children; if (score) { const allEvaluatedTrue = score.truePositives + score.falsePositives; diff --git a/workspace/src/app/views/shared/RuleEditor/view/ruleNode/PathInputOperator.tsx b/workspace/src/app/views/shared/RuleEditor/view/ruleNode/PathInputOperator.tsx index 988dd0e234..27fe89a122 100644 --- a/workspace/src/app/views/shared/RuleEditor/view/ruleNode/PathInputOperator.tsx +++ b/workspace/src/app/views/shared/RuleEditor/view/ruleNode/PathInputOperator.tsx @@ -274,14 +274,14 @@ const LanguageSwitcherContext = React.createContext { +const LanguageSwitcher = ({ onLanguageChange, initialLanguage }: LanguageSwitcherProps) => { const [t] = useTranslation(); const [languageFilter, setLanguageFilter] = React.useState(initialLanguage); - const currentLanguageFilter = React.useRef(); + const currentLanguageFilter = React.useRef(undefined); currentLanguageFilter.current = languageFilter; const context = React.useContext(LanguageSwitcherContext); - return context.showLanguageFilterButton ? + return context.showLanguageFilterButton ? ( inputProps={{ id: "language-filter-input", @@ -310,7 +310,7 @@ const LanguageSwitcher = ({onLanguageChange, initialLanguage}: LanguageSwitcherP ); } }} - itemRenderer={(lang, {handleClick, modifiers}) => { + itemRenderer={(lang, { handleClick, modifiers }) => { return lang === NO_LANG ? ( currentLanguageFilter.current ? ( )} - : - null + + ) : null; }; /** Extract the last property of the path that is not in a filter. */ diff --git a/workspace/src/app/views/shared/RuleEditor/view/ruleNode/ruleNode.utils.tsx b/workspace/src/app/views/shared/RuleEditor/view/ruleNode/ruleNode.utils.tsx index 2b2cd5992a..a5b01a535c 100644 --- a/workspace/src/app/views/shared/RuleEditor/view/ruleNode/ruleNode.utils.tsx +++ b/workspace/src/app/views/shared/RuleEditor/view/ruleNode/ruleNode.utils.tsx @@ -5,7 +5,7 @@ import { ruleEditorNodeParameterValue, RuleEditorNodeParameterValue } from "../. import Color from "color"; /** Adds highlighting to the text if query is non-empty. */ -export const addHighlighting = (text: string, query?: string): string | JSX.Element => { +export const addHighlighting = (text: string, query?: string): string | React.JSX.Element => { return query ? : text; }; @@ -13,9 +13,9 @@ export const addHighlighting = (text: string, query?: string): string | JSX.Elem const createOperatorTags = ( tags: string[], query?: string, - color?: (tag: string) => Color | string | undefined -): JSX.Element[] => { - const returnArray: JSX.Element[] = []; + color?: (tag: string) => Color | string | undefined, +): React.JSX.Element[] => { + const returnArray: React.JSX.Element[] = []; tags.forEach((tag, idx) => { returnArray.push( {addHighlighting(tag, query)} - + , ); idx < tags.length + 1 && returnArray.push(); @@ -43,7 +43,7 @@ export const invalidValueResult = (message: string): IParameterValidationResult const validateValue = ( parameterValue: RuleEditorNodeParameterValue, parameterSpec: IParameterSpecification, - translate: (key: string, additionalParameters?: object) => string + translate: (key: string, additionalParameters?: object) => string, ): IParameterValidationResult => { const value = ruleEditorNodeParameterValue(parameterValue); if (value == null) { diff --git a/workspace/src/app/views/shared/SearchList/SearchTags.tsx b/workspace/src/app/views/shared/SearchList/SearchTags.tsx index 945dfb13c3..ffd9d25416 100644 --- a/workspace/src/app/views/shared/SearchList/SearchTags.tsx +++ b/workspace/src/app/views/shared/SearchList/SearchTags.tsx @@ -7,7 +7,7 @@ interface SearchTagsProps { searchText?: string; } -export const searchTagsRenderer = (props: SearchTagsProps): JSX.Element[] => { +export const searchTagsRenderer = (props: SearchTagsProps): React.JSX.Element[] => { const { searchTags = [], searchText = "" } = props; return searchTags.map((searchTag) => { const tagContent = ; diff --git a/workspace/src/app/views/shared/TaskActivityOverview/TaskActivityOverview.tsx b/workspace/src/app/views/shared/TaskActivityOverview/TaskActivityOverview.tsx index dd4fbcfe92..7e5c09fcf2 100644 --- a/workspace/src/app/views/shared/TaskActivityOverview/TaskActivityOverview.tsx +++ b/workspace/src/app/views/shared/TaskActivityOverview/TaskActivityOverview.tsx @@ -100,13 +100,13 @@ export function TaskActivityOverview({ projectId, taskId }: IProps) { updateActivityStatus: (activityStatus: SilkActivityStatusProps) => any, project: StringOrUndefined, task: StringOrUndefined, - activityName: StringOrUndefined + activityName: StringOrUndefined, ) => { const query = activityQueryString(project, task, activityName); return connectWebSocket( legacyApiEndpoint(`/activities/updatesWebSocket${query}`), legacyApiEndpoint(`/activities/updates${query}`), - updateActivityStatus + updateActivityStatus, ); }; @@ -127,7 +127,7 @@ export function TaskActivityOverview({ projectId, taskId }: IProps) { //check if any caches activity is running const currentlyRunningCacheActivity = !!Array.from(activityStatusMap.entries()).find( ([activityKey, a]) => - cacheActivityIds.has(activityKey) && !["Waiting", "Finished", "Idle"].includes(a.statusName) + cacheActivityIds.has(activityKey) && !["Waiting", "Finished", "Idle"].includes(a.statusName), ); if (!currentlyRunningCacheActivity && nonExecutedCacheActivities.current.length) { executeAllNonExecutedCacheActivities(); @@ -180,7 +180,7 @@ export function TaskActivityOverview({ projectId, taskId }: IProps) { registerError( `taskActivityOverview-fetchTaskActivityInfos`, t("widget.TaskActivityOverview.errorMessages.fetchActivityInfo"), - ex + ex, ); setLoading(false); } @@ -218,7 +218,7 @@ export function TaskActivityOverview({ projectId, taskId }: IProps) { registerError( `taskActivityOverview-fetchTaskActivityInfos`, t("widget.TaskActivityOverview.errorMessages.fetchActivityInfo"), - ex + ex, ); } finally { setLoading(false); @@ -233,7 +233,7 @@ export function TaskActivityOverview({ projectId, taskId }: IProps) { registerError( `taskActivityOverview-fetchErrorReport`, t("widget.TaskActivityOverview.errorMessages.errorReport.fetchReport"), - ex + ex, ); }); }; @@ -243,16 +243,16 @@ export function TaskActivityOverview({ projectId, taskId }: IProps) { const handleActivityActionError = ( activityName: string, action: SilkActivityControlAction, - error: DIErrorTypes + error: DIErrorTypes, ) => { const errorIsStillRunningError = !!/running/.test( - (error as FetchError)?.errorDetails?.response?.data?.detail ?? "" + (error as FetchError)?.errorDetails?.response?.data?.detail ?? "", ); if (ignoreStillRunningError.current && errorIsStillRunningError) return; registerError( `taskActivityOverview-${activityName}-${action}`, t("widget.TaskActivityOverview.errorMessages.actions." + action, { activityName: activityName }), - error + error, ); }; @@ -282,7 +282,7 @@ export function TaskActivityOverview({ projectId, taskId }: IProps) { activity.name, metaData.projectId, metaData.taskId, - handleActivityActionError + handleActivityActionError, ), registerForUpdates: createRegisterForUpdatesFn(key), unregisterFromUpdates: createUnregisterFromUpdateFn(key), @@ -319,10 +319,10 @@ export function TaskActivityOverview({ projectId, taskId }: IProps) { const cacheActivities = nonMainActivities.filter((a) => a.activityCharacteristics.isCacheActivity); const cacheActivityIds = new Set(cacheActivities.map((c) => activityKeyOfEntry(c))); const runningNonMainActivities = nonMainActivities.filter( - (a) => activityStatusMap.get(activityKeyOfEntry(a))?.isRunning && !a.activityCharacteristics.isCacheActivity + (a) => activityStatusMap.get(activityKeyOfEntry(a))?.isRunning && !a.activityCharacteristics.isCacheActivity, ); const failedNonMainActivities = nonMainActivities.filter( - (a) => activityStatusMap.get(activityKeyOfEntry(a))?.failed && !a.activityCharacteristics.isCacheActivity + (a) => activityStatusMap.get(activityKeyOfEntry(a))?.failed && !a.activityCharacteristics.isCacheActivity, ); // to decide if the widget should be shown at all const nrActivitiesToShow = @@ -347,7 +347,7 @@ export function TaskActivityOverview({ projectId, taskId }: IProps) { registerError( `TaskActivityOverview.startPrioritized`, `Activity action 'Run prioritized' against activity '${activityName}' has failed, see details.`, - error + error, ); }; await activityStartPrioritized(activityName, project, task, registerActivityError); @@ -356,8 +356,8 @@ export function TaskActivityOverview({ projectId, taskId }: IProps) { // A single activity control const activityControl = ( activity: IActivityListEntry, - layoutConfig: SilkActivityControlLayoutProps - ): JSX.Element => { + layoutConfig: SilkActivityControlLayoutProps, + ): React.JSX.Element => { const activityFunctions = activityFunctionsCreator(activity); const activityLabel = t(`widget.TaskActivityOverview.activities.${activity.name}.title`, activity.label); const elapsedTime = activity.activityCharacteristics.isCacheActivity @@ -425,7 +425,7 @@ export function TaskActivityOverview({ projectId, taskId }: IProps) { // check that all cache activities are in waiting or idle state const currentlyRunningActivity = !!Array.from(activityStatusMap.entries()).find( ([activityKey, a]) => - cacheActivityIds.has(activityKey) && !["Waiting", "Finished", "Idle"].includes(a.statusName) + cacheActivityIds.has(activityKey) && !["Waiting", "Finished", "Idle"].includes(a.statusName), ); if (!currentlyRunningActivity) { @@ -439,7 +439,7 @@ export function TaskActivityOverview({ projectId, taskId }: IProps) { if (!wasExecuted) { notExecutedActivities.push(activity); } - }) + }), ); if (notExecutedActivities.length) { nonExecutedCacheActivities.current = notExecutedActivities; @@ -497,18 +497,18 @@ export function TaskActivityOverview({ projectId, taskId }: IProps) { // Returns the sorted list of activity controls function activityWidgets( activities: IActivityListEntry[], - layoutConfig: SilkActivityControlLayoutProps - ): JSX.Element[] { + layoutConfig: SilkActivityControlLayoutProps, + ): React.JSX.Element[] { const activitiesWithLabels = activities .map((activity) => { const activityLabel = t( `widget.TaskActivityOverview.activities.${activity.name}.title`, - activity.label + activity.label, ); return [activityLabel, activityControl(activity, layoutConfig)]; }) .sort(([aLabel], [bLabel]) => (aLabel < bLabel ? -1 : 1)); - return activitiesWithLabels.map(([label, activityControl]) => activityControl) as JSX.Element[]; + return activitiesWithLabels.map(([label, activityControl]) => activityControl) as React.JSX.Element[]; } return nrActivitiesToShow > 0 ? ( diff --git a/workspace/src/app/views/shared/VariablesWidget/VariablesWidget.tsx b/workspace/src/app/views/shared/VariablesWidget/VariablesWidget.tsx index 61b32dd284..aba6018648 100644 --- a/workspace/src/app/views/shared/VariablesWidget/VariablesWidget.tsx +++ b/workspace/src/app/views/shared/VariablesWidget/VariablesWidget.tsx @@ -48,7 +48,7 @@ const VariablesWidget: React.FC = ({ projectId, taskId }) = const checkAndDisplayDeletionError = useModalError({ setError: setDeleteError }); const [dropChangeLoading, setDropChangeLoading] = React.useState(false); const [dependencies, setVariableDependencies] = React.useState(); - const [errorNotification, setErrorNotification] = React.useState(null); + const [errorNotification, setErrorNotification] = React.useState(null); const [t] = useTranslation(); const variableHasDependencies = dependencies?.dependentTasks.length || dependencies?.dependentVariables.length; @@ -68,7 +68,7 @@ const VariablesWidget: React.FC = ({ projectId, taskId }) = })(); }, [refetch, projectId]); - const handleModalOpen = React.useCallback((variable = undefined) => { + const handleModalOpen = React.useCallback((variable: Variable | undefined = undefined) => { setSelectedVariable(variable); setErrorNotification(null); setModalOpen(true); @@ -84,7 +84,7 @@ const VariablesWidget: React.FC = ({ projectId, taskId }) = } catch (err) { checkAndDisplayDeletionError( err, - t("widget.VariableWidget.errorMessages.dependencyRetrievalFailure", "Failed to retrieve variable") + t("widget.VariableWidget.errorMessages.dependencyRetrievalFailure", "Failed to retrieve variable"), ); } }, []); @@ -103,7 +103,7 @@ const VariablesWidget: React.FC = ({ projectId, taskId }) = } catch (err) { checkAndDisplayDeletionError( err, - t("widget.VariableWidget.errorMessages.variableDeletionFailure", "Failed to delete variable") + t("widget.VariableWidget.errorMessages.variableDeletionFailure", "Failed to delete variable"), ); } finally { setIsDeleting(false); @@ -133,7 +133,7 @@ const VariablesWidget: React.FC = ({ projectId, taskId }) = setDropChangeLoading(true); const res = await reorderVariablesRequest( projectId, - reorderedVariables.map((v) => v.name) + reorderedVariables.map((v) => v.name), ); if (res.axiosResponse.status === 200) { setVariables(reorderedVariables); @@ -150,7 +150,7 @@ const VariablesWidget: React.FC = ({ projectId, taskId }) = setDropChangeLoading(false); } }, - [variables] + [variables], ); const renderDeleteVariable = React.useCallback(() => { @@ -310,7 +310,7 @@ const VariablesWidget: React.FC = ({ projectId, taskId }) = data-test-id="template-variable-delimiter" tooltipText={ t( - "widget.TaskConfigWidget.templateValueInfo" + "widget.TaskConfigWidget.templateValueInfo", ) + `\n\n\`\`\`${variable.template}\`\`\`` } diff --git a/workspace/src/app/views/shared/buttons/CreateButton.tsx b/workspace/src/app/views/shared/buttons/CreateButton.tsx index 0d6a8ef67c..097f595bc9 100644 --- a/workspace/src/app/views/shared/buttons/CreateButton.tsx +++ b/workspace/src/app/views/shared/buttons/CreateButton.tsx @@ -1,8 +1,8 @@ import React, { memo } from "react"; -import { Button } from "@eccenca/gui-elements"; +import { Button, ButtonProps } from "@eccenca/gui-elements"; import { useTranslation } from "react-i18next"; -const CreateButton = memo((props) => { +const CreateButton = memo((props) => { const [t] = useTranslation(); return ( diff --git a/workspace/src/app/views/shared/modals/CreateArtefactModal/ArtefactForms/ArtefactFormParameter.tsx b/workspace/src/app/views/shared/modals/CreateArtefactModal/ArtefactForms/ArtefactFormParameter.tsx index 7753e0c3da..6ba2d25005 100644 --- a/workspace/src/app/views/shared/modals/CreateArtefactModal/ArtefactForms/ArtefactFormParameter.tsx +++ b/workspace/src/app/views/shared/modals/CreateArtefactModal/ArtefactForms/ArtefactFormParameter.tsx @@ -42,11 +42,11 @@ interface Props { initialValueReplace?: string, onChange?: (value: string) => any, showRareActions?: (show: boolean) => any, - ) => JSX.Element; + ) => React.JSX.Element; // If the parameter is disabled disabled?: boolean; // Is displayed between label and input element. - helperText?: string | JSX.Element; + helperText?: string | React.JSX.Element; // Tooltip to display tooltip?: string; /* If defined, the parameter supports variable templates that gets their values set in the backend with variable substitution. diff --git a/workspace/src/app/views/shared/modals/CreateArtefactModal/ArtefactForms/ParameterAutoCompletion.tsx b/workspace/src/app/views/shared/modals/CreateArtefactModal/ArtefactForms/ParameterAutoCompletion.tsx index 9249f72218..81ce131503 100644 --- a/workspace/src/app/views/shared/modals/CreateArtefactModal/ArtefactForms/ParameterAutoCompletion.tsx +++ b/workspace/src/app/views/shared/modals/CreateArtefactModal/ArtefactForms/ParameterAutoCompletion.tsx @@ -74,7 +74,6 @@ type StringOrReifiedValue = IAutocompleteDefaultResponse | string; const AUTOCOMPLETION_LIMIT = 100; - /** Component for parameter auto-completion. */ export const ParameterAutoCompletion = ({ paramId, @@ -278,7 +277,7 @@ export const labelAndOrValueItemRenderer = ( query: string, modifiers: SuggestFieldItemRendererModifierProps, handleSelectClick: () => any, -): JSX.Element | string => { +): React.JSX.Element | string => { const labelValueKindOfSame = (autoCompleteResponse.label ?? "").toLowerCase() === autoCompleteResponse.value.toLowerCase(); const showLabel = autoCompleteResponse.label && !labelValueKindOfSame; diff --git a/workspace/src/app/views/shared/modals/CreateArtefactModal/ArtefactForms/ParameterWidget.tsx b/workspace/src/app/views/shared/modals/CreateArtefactModal/ArtefactForms/ParameterWidget.tsx index 6ad31cc167..5295a9e057 100644 --- a/workspace/src/app/views/shared/modals/CreateArtefactModal/ArtefactForms/ParameterWidget.tsx +++ b/workspace/src/app/views/shared/modals/CreateArtefactModal/ArtefactForms/ParameterWidget.tsx @@ -144,10 +144,10 @@ export const ParameterWidget = (props: IProps) => { : undefined; const detailedDocumentationAvailable = parameterCallbacks.namedAnchors.includes(formParamId); - let propertyHelperText: JSX.Element | undefined = undefined; + let propertyHelperText: React.JSX.Element | undefined = undefined; if ((description && description.length > MAXLENGTH_TOOLTIP) || detailedDocumentationAvailable) { - let parameterDescription: JSX.Element = {description}; - let detailedLink: JSX.Element | undefined = undefined; + let parameterDescription: React.JSX.Element = {description}; + let detailedLink: React.JSX.Element | undefined = undefined; if (detailedDocumentationAvailable) { detailedLink = ( (); const [taskActionLoading, setTaskActionLoading] = React.useState(null); const [taskFormGeneralWarning, setTaskFormGeneralWarning] = React.useState(); - const generalWarningTimeout = React.useRef() + const generalWarningTimeout = React.useRef(undefined); const taskFormWarning = React.useCallback((message: string) => { - if(generalWarningTimeout.current) { - clearTimeout(generalWarningTimeout.current) + if (generalWarningTimeout.current) { + clearTimeout(generalWarningTimeout.current); } - generalWarningTimeout.current = window.setTimeout(() => setTaskFormGeneralWarning(message), 250) - }, []) + generalWarningTimeout.current = window.setTimeout(() => setTaskFormGeneralWarning(message), 250); + }, []); React.useEffect(() => { if (infoMessage?.removeAfterSeconds && infoMessage.removeAfterSeconds > 0) { @@ -507,7 +507,7 @@ export function CreateArtefactModal() { * @param artefactForm * @returns */ - const addChangeProjectHandler = (artefactForm: JSX.Element): JSX.Element => { + const addChangeProjectHandler = (artefactForm: React.JSX.Element): React.JSX.Element => { if ( currentProject && (newTaskPreConfiguration?.showProjectChangeWidget == null || @@ -551,7 +551,7 @@ export function CreateArtefactModal() { const projectArtefactSelected = selectedArtefactKey === DATA_TYPES.PROJECT; - let artefactForm: JSX.Element | null = null; + let artefactForm: React.JSX.Element | null = null; /** if no current Project context, redirect to project selection first */ if (selectedArtefactKey && !currentProject) { @@ -749,7 +749,7 @@ export function CreateArtefactModal() { }; const isCreationUpdateDialog = selectedArtefactKey || updateExistingTask; - const additionalButtons: JSX.Element[] = []; + const additionalButtons: React.JSX.Element[] = []; if ( (projectId || currentProject) && ((updateExistingTask && updateExistingTask.taskPluginDetails.autoConfigurable) || @@ -774,7 +774,7 @@ export function CreateArtefactModal() { ); } - const pluginActions: JSX.Element[] = []; + const pluginActions: React.JSX.Element[] = []; if (selectedArtefact?.actions) { const describedActions = Object.entries(selectedArtefact.actions); pluginActions.push( @@ -876,7 +876,7 @@ export function CreateArtefactModal() { ] : pluginActions; - const headerOptions: JSX.Element[] = []; + const headerOptions: React.JSX.Element[] = []; if (selectedArtefactTitle && (selectedArtefact?.markdownDocumentation || selectedArtefact?.description)) { headerOptions.push( updateData.metaData.label ?? updateData.taskId; - const notifications: JSX.Element[] = []; + const notifications: React.JSX.Element[] = []; if (!!error.detail || !!error.errorMessage || !!error.body?.taskLoadingError?.errorMessage || error.isFetchError) { // Special case for fix task loading error @@ -946,12 +946,9 @@ export function CreateArtefactModal() { ); } - if(taskFormGeneralWarning) { + if (taskFormGeneralWarning) { notifications.push( - setTaskFormGeneralWarning(undefined)} - />, + setTaskFormGeneralWarning(undefined)} />, ); } diff --git a/workspace/src/app/views/shared/modals/InvisibleCharacterCleanUpModal.tsx b/workspace/src/app/views/shared/modals/InvisibleCharacterCleanUpModal.tsx index 5c7d774146..49e65d1756 100644 --- a/workspace/src/app/views/shared/modals/InvisibleCharacterCleanUpModal.tsx +++ b/workspace/src/app/views/shared/modals/InvisibleCharacterCleanUpModal.tsx @@ -130,9 +130,9 @@ export const useInvisibleCharacterCleanUpModal = ({ interface HookResult { /** Standard IconButton element that can be clicked to open the modal. */ - iconButton?: JSX.Element; + iconButton?: React.JSX.Element; /** The modal that should be displayed. */ - modalElement: JSX.Element | null; + modalElement: React.JSX.Element | null; /** The object that should be forwarded to the input element. */ invisibleCharacterWarning?: InvisibleCharacterWarningProps; /** Allows to reset this component, i.e. resetting the detected characters. */ diff --git a/workspace/src/app/views/shared/modals/ProjectImportModal.tsx b/workspace/src/app/views/shared/modals/ProjectImportModal.tsx index 9be6b89cee..89d0b16bb8 100644 --- a/workspace/src/app/views/shared/modals/ProjectImportModal.tsx +++ b/workspace/src/app/views/shared/modals/ProjectImportModal.tsx @@ -218,7 +218,7 @@ export function ProjectImportModal({ close, back, maxFileUploadSizeBytes }: IPro attachFileNameToEndpoint={false} /> ); - const actions: JSX.Element[] = []; + const actions: React.JSX.Element[] = []; if (projectImportDetails) { if (!projectImportDetails.errorMessage && !projectImportDetails.projectAlreadyExists) { actions.push( diff --git a/workspace/src/app/views/shared/projectTaskTabView/projectTaskTabsViewHooks.tsx b/workspace/src/app/views/shared/projectTaskTabView/projectTaskTabsViewHooks.tsx index 7a5e4b1743..9de19a02e1 100644 --- a/workspace/src/app/views/shared/projectTaskTabView/projectTaskTabsViewHooks.tsx +++ b/workspace/src/app/views/shared/projectTaskTabView/projectTaskTabsViewHooks.tsx @@ -32,7 +32,7 @@ export const useProjectTaskTabsView = ({ const [activeTab, setActiveTab] = useState(startLink); const initialSettings = useSelector(commonSel.initialSettingsSelector); const taskViews = (pluginId ? pluginRegistry.taskViews(pluginId) : []).filter( - (plugin) => !plugin.available || plugin.available(initialSettings) + (plugin) => !plugin.available || plugin.available(initialSettings), ); const menuItems = taskViews.map(({ id, label }) => ( { return { diff --git a/workspace/src/app/views/taskViews/linking/activeLearning/components/ConnectionAvailable.tsx b/workspace/src/app/views/taskViews/linking/activeLearning/components/ConnectionAvailable.tsx index ea272543ca..9d23273f04 100644 --- a/workspace/src/app/views/taskViews/linking/activeLearning/components/ConnectionAvailable.tsx +++ b/workspace/src/app/views/taskViews/linking/activeLearning/components/ConnectionAvailable.tsx @@ -8,12 +8,10 @@ export interface ConnectionAvailableProps { /** * Action buttons (or other content) displayed when the connection element is hovered. */ - actions: JSX.Element; + actions: React.JSX.Element; } -const ConnectionAvailable = ({ - actions, -}: ConnectionAvailableProps) => { +const ConnectionAvailable = ({ actions }: ConnectionAvailableProps) => { return ( diff --git a/workspace/src/app/views/taskViews/linking/activeLearning/components/ConnectionEnabled.tsx b/workspace/src/app/views/taskViews/linking/activeLearning/components/ConnectionEnabled.tsx index 63fe79136a..c16f740d51 100644 --- a/workspace/src/app/views/taskViews/linking/activeLearning/components/ConnectionEnabled.tsx +++ b/workspace/src/app/views/taskViews/linking/activeLearning/components/ConnectionEnabled.tsx @@ -7,29 +7,19 @@ interface ArrowProps { /** Arrow giond to the left. */ export const ArrowLeft = ({ color = "#000" }: ArrowProps) => { - return ( -
    - ); -} + return
    ; +}; /** Arrow going to the right. */ export const ArrowRight = ({ color = "#000" }: ArrowProps) => { - return ( -
    - ); -} + return
    ; +}; export interface ConnectionEnabledProps { /** * Action buttons (or other content) displayed when the connection element is hovered. */ - actions?: JSX.Element; + actions?: React.JSX.Element; /** * Color used to display the connection. */ @@ -47,7 +37,7 @@ const ConnectionEnabled = ({ label, actions, color }: ConnectionEnabledProps) => - { label } + {label} diff --git a/workspace/src/app/views/taskViews/linking/activeLearning/components/PropertyBox.tsx b/workspace/src/app/views/taskViews/linking/activeLearning/components/PropertyBox.tsx index d34139b453..57ff703bdd 100644 --- a/workspace/src/app/views/taskViews/linking/activeLearning/components/PropertyBox.tsx +++ b/workspace/src/app/views/taskViews/linking/activeLearning/components/PropertyBox.tsx @@ -11,7 +11,7 @@ import { useTranslation } from "react-i18next"; export interface PropertyBoxProps extends Omit, "children"> { propertyName: string; propertyTooltip?: string; - exampleValues?: JSX.Element; + exampleValues?: React.JSX.Element; exampleTooltip?: string; /** handler to forward a filter function */ onFilter?: () => any; @@ -24,7 +24,7 @@ export const PropertyBox = ({ exampleValues, exampleTooltip, onFilter, - filtered + filtered, }: PropertyBoxProps) => { const [t] = useTranslation(); return ( @@ -48,4 +48,4 @@ export const PropertyBox = ({
    ); -} +}; diff --git a/workspace/src/app/views/taskViews/linking/evaluation/LinkingRuleEvaluation.tsx b/workspace/src/app/views/taskViews/linking/evaluation/LinkingRuleEvaluation.tsx index 2cef7c8fb9..19648cff9b 100644 --- a/workspace/src/app/views/taskViews/linking/evaluation/LinkingRuleEvaluation.tsx +++ b/workspace/src/app/views/taskViews/linking/evaluation/LinkingRuleEvaluation.tsx @@ -1,7 +1,7 @@ /** Component that handles the linking rule (inline) evaluation. */ import { RuleEditorEvaluationCallbackContext, - RuleEditorEvaluationContext + RuleEditorEvaluationContext, } from "../../../shared/RuleEditor/contexts/RuleEditorEvaluationContext"; import React, { ReactElement } from "react"; import { @@ -31,7 +31,7 @@ import { ruleEditorNodeParameterValue } from "../../../shared/RuleEditor/model/R import { PathNotInCacheModal } from "../../shared/evaluations/PathNotInCacheModal"; import evaluationUtils from "../../shared/evaluations/evaluationOperations"; import { SampleError } from "../../../shared/SampleError/SampleError"; -import {DIErrorTypes} from "@ducks/error/typings"; +import { DIErrorTypes } from "@ducks/error/typings"; type EvaluationChildType = ReactElement, IPluginDetails>>; @@ -66,17 +66,17 @@ export const LinkingRuleEvaluation = ({ const [evaluationScore, setEvaluationScore] = React.useState(undefined); const [evaluatesQuickly, setEvaluatesQuickly] = React.useState(false); const [nodeUpdateCallbacks] = React.useState( - new Map any>() + new Map any>(), ); const [referenceLinksUrl, setReferenceLinksUrl] = React.useState(undefined); const [evaluationResultsShown, setEvaluationResultsShown] = React.useState(false); const [ruleValidationError, setRuleValidationError] = React.useState(undefined); const [evaluatedRuleOperatorIds, setEvaluatedRuleOperatorIds] = React.useState([]); const [errorModalEnabled, setErrorModalEnabled] = React.useState(true); - const popupErrorsEnabled = React.useRef(true) - popupErrorsEnabled.current = errorModalEnabled + const popupErrorsEnabled = React.useRef(true); + popupErrorsEnabled.current = errorModalEnabled; // The root node of the sub-tree that will be evaluated - const evaluatedSubTreeNode = React.useRef(); + const evaluatedSubTreeNode = React.useRef(undefined); const [pathNotInCacheValidationError, setPathNotInCacheValidationError] = React.useState< { path: string; toTarget: boolean } | undefined @@ -89,9 +89,9 @@ export const LinkingRuleEvaluation = ({ const registerError = (errorKey: string, error: DIErrorTypes) => { _registerError(errorKey, t(errorKey), error, { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE, - notAutoOpen: !popupErrorsEnabled.current - }) - } + notAutoOpen: !popupErrorsEnabled.current, + }); + }; const clearRuleValidationErrors = () => { setRuleValidationError(undefined); @@ -99,8 +99,8 @@ export const LinkingRuleEvaluation = ({ }; const enableErrorModal = React.useCallback((enable: boolean) => { - setErrorModalEnabled(enable) - }, []) + setErrorModalEnabled(enable); + }, []); React.useEffect(() => { setEvaluationResult([]); @@ -135,7 +135,7 @@ export const LinkingRuleEvaluation = ({ updateCallback( !evaluatedRuleOperatorIds.includes(ruleOperatorId) ? undefined - : evaluationResultMap.get(ruleOperatorId) + : evaluationResultMap.get(ruleOperatorId), ); }); } else { @@ -149,14 +149,14 @@ export const LinkingRuleEvaluation = ({ const clearEntities = () => evaluationResultEntities.splice(0, evaluationResultEntities.length); const fetchReferenceLinksEvaluation: ( - linkageRule: ILinkingRule + linkageRule: ILinkingRule, ) => Promise = async (linkageRule: ILinkingRule) => { try { const result = await evaluateLinkingRuleAgainstReferenceEntities( projectId, linkingTaskId, linkageRule, - numberOfLinkToShow + numberOfLinkToShow, ); return result.data; } catch (ex) { @@ -184,7 +184,7 @@ export const LinkingRuleEvaluation = ({ const startEvaluation = async ( _ruleOperatorNodes: IRuleOperatorNode[], originalTask: any, - quickEvaluationOnly: boolean = false + quickEvaluationOnly: boolean = false, ) => { setEvaluationRunning(true); let ruleOperatorNodes = _ruleOperatorNodes; @@ -228,7 +228,7 @@ export const LinkingRuleEvaluation = ({ const pathNode = ruleOperatorNodes.find( (op) => op.pluginType === "PathInputOperator" && - ruleEditorNodeParameterValue(op.parameters.path) === path + ruleEditorNodeParameterValue(op.parameters.path) === path, ); if (pathNode) { setPathNotInCacheValidationError({ path, toTarget: pathNode.pluginId === "targetPathInput" }); @@ -249,14 +249,14 @@ export const LinkingRuleEvaluation = ({ /** Called by a rule operator node to register for evaluation updates. */ const registerForEvaluationResults = ( ruleOperatorId: string, - evaluationUpdate: (evaluationValues: EvaluationResultType | undefined) => void + evaluationUpdate: (evaluationValues: EvaluationResultType | undefined) => void, ) => { nodeUpdateCallbacks.set(ruleOperatorId, evaluationUpdate); evaluationUpdate(evaluationResultMap.get(ruleOperatorId)); }; /** Factory method used by the rule editor to create an evaluation element. */ - const createRuleEditorEvaluationComponent = (ruleOperatorId: string): JSX.Element => { + const createRuleEditorEvaluationComponent = (ruleOperatorId: string): React.JSX.Element => { return ( - - {errorModalEnabled && pathNotInCacheValidationError && triggerEvaluation.current && ( - { - clearRuleValidationErrors(); - triggerEvaluation.current?.(); - }} - onClose={() => clearRuleValidationErrors()} - /> - )} - {children} - - + + {errorModalEnabled && pathNotInCacheValidationError && triggerEvaluation.current && ( + { + clearRuleValidationErrors(); + triggerEvaluation.current?.(); + }} + onClose={() => clearRuleValidationErrors()} + /> + )} + {children} + + + ); }; diff --git a/workspace/src/app/views/taskViews/linking/evaluation/tabView/LinkingEvaluationRow.tsx b/workspace/src/app/views/taskViews/linking/evaluation/tabView/LinkingEvaluationRow.tsx index a946e8f550..41aa0ec7be 100644 --- a/workspace/src/app/views/taskViews/linking/evaluation/tabView/LinkingEvaluationRow.tsx +++ b/workspace/src/app/views/taskViews/linking/evaluation/tabView/LinkingEvaluationRow.tsx @@ -151,7 +151,7 @@ export const LinkingEvaluationRow = React.memo( ); // Returns an icon element that warns the user that the entity has no values at all - const emptyEntityWarning = (values?: Record): JSX.Element | null => { + const emptyEntityWarning = (values?: Record): React.JSX.Element | null => { if (!values) { return null; } @@ -360,7 +360,7 @@ export const LinkingEvaluationRow = React.memo( +{(evaluationMap.get(id)?.value || []).length - cutAfter} ) : null; - let exampleValues: JSX.Element[] = []; + let exampleValues: React.JSX.Element[] = []; if (!evaluationMap.get(id)?.value.length) { exampleValues = [ diff --git a/workspace/src/app/views/taskViews/linking/evaluation/tabView/LinkingEvaluationTabView.tsx b/workspace/src/app/views/taskViews/linking/evaluation/tabView/LinkingEvaluationTabView.tsx index e9066036d4..fee41381d7 100644 --- a/workspace/src/app/views/taskViews/linking/evaluation/tabView/LinkingEvaluationTabView.tsx +++ b/workspace/src/app/views/taskViews/linking/evaluation/tabView/LinkingEvaluationTabView.tsx @@ -85,7 +85,7 @@ const LinkingEvaluationTabView: React.FC = ({ pro const [t] = useTranslation(); const errorHandler = useErrorHandler(); const commonSel = useSelector(workspaceSel.commonSelector); - const evaluationResults = React.useRef(); + const evaluationResults = React.useRef(undefined); const [pagination, paginationElement, onTotalChange] = usePagination({ pageSizes, initialPageSize: 20, @@ -108,7 +108,6 @@ const LinkingEvaluationTabView: React.FC = ({ pro const hasRenderedBefore = useFirstRender(); const [showReferenceLinks, setShowReferenceLinks] = React.useState(() => { const show = new URLSearchParams(window.location.search).get("showReferenceLinks"); - console.log({ show }); return Boolean(show); }); const [showImportLinkModal, setShowImportLinkModal] = React.useState(false); diff --git a/workspace/src/app/views/taskViews/shared/evaluations/OperatorLabel.tsx b/workspace/src/app/views/taskViews/shared/evaluations/OperatorLabel.tsx index 4aff803170..67343ed129 100644 --- a/workspace/src/app/views/taskViews/shared/evaluations/OperatorLabel.tsx +++ b/workspace/src/app/views/taskViews/shared/evaluations/OperatorLabel.tsx @@ -9,6 +9,7 @@ interface OperatorLabelProps { tagPluginType: "Input" | "Transform" | "Comparison" | "Aggregation" | "Source path" | "Target path"; operator: any; operatorPlugins: Array; + children: React.ReactNode; } export const OperatorLabel: React.FC = React.memo( @@ -23,5 +24,5 @@ export const OperatorLabel: React.FC = React.memo( {children} ); - } + }, ); diff --git a/workspace/src/app/views/taskViews/shared/rules/rule.utils.tsx b/workspace/src/app/views/taskViews/shared/rules/rule.utils.tsx index 781e66c893..a0a4cd7473 100644 --- a/workspace/src/app/views/taskViews/shared/rules/rule.utils.tsx +++ b/workspace/src/app/views/taskViews/shared/rules/rule.utils.tsx @@ -36,7 +36,7 @@ import { optionallyLabelledParameterToValue } from "../../linking/linking.types" const extractOperatorNodeFromPathInput = ( pathInput: IPathInput, result: IRuleOperatorNode[], - isTarget: boolean | undefined + isTarget: boolean | undefined, ): string => { result.push({ nodeId: pathInput.id, @@ -62,10 +62,10 @@ const extractOperatorNodeFromTransformInput = ( transformInput: ITransformOperator, result: IRuleOperatorNode[], isTarget: boolean | undefined, - ruleOperator: RuleOperatorFetchFnType + ruleOperator: RuleOperatorFetchFnType, ): string => { const inputs = transformInput.inputs.map((input) => - extractOperatorNodeFromValueInput(input, result, isTarget, ruleOperator) + extractOperatorNodeFromValueInput(input, result, isTarget, ruleOperator), ); const op = ruleOperator(transformInput.function, "TransformOperator"); const parameters = transformInput.parameters; @@ -105,7 +105,7 @@ const extractOperatorNodeFromValueInput = ( operator: IValueInput | undefined, result: IRuleOperatorNode[], isTarget: boolean | undefined, - ruleOperator: (pluginId: string, pluginType?: string) => IRuleOperator | undefined + ruleOperator: (pluginId: string, pluginType?: string) => IRuleOperator | undefined, ): string | undefined => { if (operator) { const nodeId = @@ -120,8 +120,8 @@ const customInputPathRenderer = ( autoCompleteResponse: IAutocompleteDefaultResponse, query: string, modifiers: SuggestFieldItemRendererModifierProps, - handleSelectClick: () => any -): JSX.Element | string => { + handleSelectClick: () => any, +): React.JSX.Element | string => { return autoCompleteResponse.label ? ( IAutocompleteDefaultResponse[] | Promise, - customValidation?: (value: RuleEditorNodeParameterValue) => IParameterValidationResult + customValidation?: (value: RuleEditorNodeParameterValue) => IParameterValidationResult, ): IRuleOperator => { return { pluginType: "PathInputOperator", @@ -234,7 +234,9 @@ const REVERSE_PARAMETER_ID = "reverse"; */ const convertRuleOperator = ( pluginDetails: IPluginDetails, - addAdditionParameterSpecifications: (pluginDetails: IPluginDetails) => [id: string, spec: IParameterSpecification][] + addAdditionParameterSpecifications: ( + pluginDetails: IPluginDetails, + ) => [id: string, spec: IParameterSpecification][], ): IRuleOperator => { const required = (parameterId: string) => pluginDetails.required.includes(parameterId); // If this is true then source and target inputs can be connected in any order. @@ -343,7 +345,7 @@ const portSpecification = (op: IPluginDetails): IPortSpecification => { /** Converts a rule operator node to a value input. */ const convertRuleOperatorNodeToValueInput = ( ruleOperatorNode: IRuleOperatorNode, - ruleOperatorNodes: Map + ruleOperatorNodes: Map, ): IValueInput => { if (ruleOperatorNode.pluginType === "TransformOperator") { const transformOperator: ITransformOperator = { @@ -354,14 +356,14 @@ const convertRuleOperatorNodeToValueInput = ( .map((i) => convertRuleOperatorNodeToValueInput( fetchRuleOperatorNode(i!!, ruleOperatorNodes, ruleOperatorNode), - ruleOperatorNodes - ) + ruleOperatorNodes, + ), ), parameters: Object.fromEntries( Object.entries(ruleOperatorNode.parameters).map(([parameterKey, parameterValue]) => [ parameterKey, parameterValue ?? "", - ]) + ]), ), type: "transformInput", }; @@ -375,7 +377,7 @@ const convertRuleOperatorNodeToValueInput = ( return pathInput; } else { throw Error( - `Tried to convert ${ruleOperatorNode.pluginType} node '${ruleOperatorNode.label}' to incompatible value input!` + `Tried to convert ${ruleOperatorNode.pluginType} node '${ruleOperatorNode.label}' to incompatible value input!`, ); } }; @@ -384,7 +386,7 @@ const convertRuleOperatorNodeToValueInput = ( const fetchRuleOperatorNode = ( nodeId: string, ruleOperators: Map, - parentNode?: IRuleOperatorNode + parentNode?: IRuleOperatorNode, ): IRuleOperatorNode => { const ruleOperatorNode = ruleOperators.get(nodeId); if (ruleOperatorNode) { @@ -393,7 +395,7 @@ const fetchRuleOperatorNode = ( throw new Error( `Rule operator node with ID '${nodeId}' does not exist${ parentNode ? `, but is defined as input for node '${parentNode.label}'!` : "!" - }` + }`, ); } }; @@ -401,14 +403,14 @@ const fetchRuleOperatorNode = ( /** Converts the editor rule operator nodes to a map from ID to node and also returns all root nodes, i.e. nodes without parent. */ const convertToRuleOperatorNodeMap = ( ruleOperatorNodes: IRuleOperatorNode[], - validate: boolean + validate: boolean, ): [Map, IRuleOperatorNode[]] => { const hasParent = new Set(); const nodeMap = new Map( ruleOperatorNodes.map((node) => { node.inputs.filter((i) => i != null).forEach((i) => hasParent.add(i!!)); return [node.nodeId, node]; - }) + }), ); const rootNodes = ruleOperatorNodes.filter((node) => !hasParent.has(node.nodeId)); if (validate && rootNodes.length > 1) { @@ -419,7 +421,7 @@ const convertToRuleOperatorNodeMap = ( rootNodes.map((node) => ({ nodeId: node.nodeId, message: `Rule operator '${node.label}' is not the only root node.`, - })) + })), ); } else if (validate && rootNodes.length === 0 && nodeMap.size > 0) { throw Error(`Rule tree cannot be saved, because it contains cycles!`); @@ -429,7 +431,7 @@ const convertToRuleOperatorNodeMap = ( throw new RuleValidationError( "Illegal cycle found in rule. Path from root node to cycled node: " + cycle.map((n) => n.label).join(", "), - cycle + cycle, ); } } @@ -439,7 +441,7 @@ const convertToRuleOperatorNodeMap = ( /** Returns the first cycle found if any exist. */ const findCycles = ( rootNode: IRuleOperatorNode, - nodeMap: Map + nodeMap: Map, ): IRuleOperatorNode[] | undefined => { const visitedNodes = new Set(); const iterate = (operatorNode: IRuleOperatorNode): IRuleOperatorNode[] | undefined => { @@ -462,7 +464,7 @@ const findCycles = ( if (visitedNodes.size !== nodeMap.size) { throw new RuleValidationError( `Root node '${rootNode.label}' is not connected to all nodes! There are overall ${nodeMap.size} nodes, but only ${visitedNodes.size} are part of the rule tree spanned by '${rootNode.label}'.`, - [rootNode] + [rootNode], ); } return result ? result.reverse() : undefined; @@ -491,7 +493,7 @@ const ruleLayout = (nodes: IRuleOperatorNode[]): RuleLayout => { const validateConnection = ( fromRuleOperatorNode: RuleEditorValidationNode, toRuleOperatorNode: RuleEditorValidationNode, - targetPortIdx: number + targetPortIdx: number, ): boolean => { const sourcePluginType = fromRuleOperatorNode.node.pluginType; const sourcePluginId = fromRuleOperatorNode.node.pluginId; @@ -592,7 +594,7 @@ const toType = (node: RuleEditorValidationNode, targetPortIdx: number): PathVali default: // If this happens then it's a bug throw new RuleValidationError( - `Bug: Invalid connection to comparison operator ${node.node.label} on input port ${targetPortIdx} detected.` + `Bug: Invalid connection to comparison operator ${node.node.label} on input port ${targetPortIdx} detected.`, ); } } @@ -628,7 +630,7 @@ const invalidCombination = (s: PathValidationType, t: PathValidationType) => { const inputPathValidation = ( fromRuleOperatorNode: RuleEditorValidationNode, toRuleOperatorNode: RuleEditorValidationNode, - targetPortIdx: number + targetPortIdx: number, ): boolean => { const sourceNodeFromType = fromType(fromRuleOperatorNode); const targetNodeToType = toType(toRuleOperatorNode, targetPortIdx); diff --git a/workspace/src/app/views/taskViews/transform/TransformRuleEditor.tsx b/workspace/src/app/views/taskViews/transform/TransformRuleEditor.tsx index 25ed6d0142..5a07268840 100644 --- a/workspace/src/app/views/taskViews/transform/TransformRuleEditor.tsx +++ b/workspace/src/app/views/taskViews/transform/TransformRuleEditor.tsx @@ -47,7 +47,7 @@ export interface TransformRuleEditorProps { /** The instance of the transform rule editor. This needs to be unique if multiple instances of the linking editor are displayed on the same page. */ instanceId: string; /** Additional components that will be placed in the tool bar left to the save button. */ - additionalToolBarComponents?: () => JSX.Element | JSX.Element[]; + additionalToolBarComponents?: () => React.JSX.Element | React.JSX.Element[]; } /** Editor for creating and changing transform rule operator trees. */ @@ -78,7 +78,7 @@ export const TransformRuleEditor = ({ "transformRuleEditor_fetchTransformRule", t("taskViews.transformRulesEditor.errors.fetchTransformRule.msg"), err, - { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE } + { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE }, ); } }; @@ -92,7 +92,7 @@ export const TransformRuleEditor = ({ "TransformRuleEditor_fetchTransformRuleOperatorDetails", t("taskViews.transformRulesEditor.errors.fetchTransformRuleOperatorDetails.msg"), err, - { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE } + { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE }, ); } }; @@ -101,7 +101,7 @@ export const TransformRuleEditor = ({ const saveTransformRule = async ( ruleOperatorNodes: IRuleOperatorNode[], stickyNotes: StickyNote[], - originalRule: IComplexMappingRule + originalRule: IComplexMappingRule, ): Promise => { try { const [operatorNodeMap, rootNodes] = ruleUtils.convertToRuleOperatorNodeMap(ruleOperatorNodes, true); @@ -141,7 +141,7 @@ export const TransformRuleEditor = ({ })); return new RuleValidationError( t("taskViews.transformRulesEditor.errors.saveTransformRule.msg"), - nodeErrors + nodeErrors, ); } else { return { @@ -158,7 +158,7 @@ export const TransformRuleEditor = ({ /** Converts the linking task rule to the internal representation. */ const convertToRuleOperatorNodes = ( mappingRule: IComplexMappingRule, - ruleOperator: RuleOperatorFetchFnType + ruleOperator: RuleOperatorFetchFnType, ): IRuleOperatorNode[] => { const operatorNodes: IRuleOperatorNode[] = []; ruleUtils.extractOperatorNodeFromValueInput(mappingRule.operator, operatorNodes, false, ruleOperator); @@ -191,7 +191,7 @@ export const TransformRuleEditor = ({ ruleId, term, mappingEditorContext.taskContext, - limit + limit, ); let results = response.data.map((data) => ({ ...data, valueType: "" })); if (term.trim() === "") { @@ -205,7 +205,7 @@ export const TransformRuleEditor = ({ "LinkingRuleEditor_inputPathAutoCompletion", t("taskViews.linkRulesEditor.errors.inputPathAutoCompletion.msg"), err, - { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE } + { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE }, ); return []; } @@ -221,18 +221,18 @@ export const TransformRuleEditor = ({ containerRuleId, inputString, cursorPosition, - 200 + 200, ); return result.data; } catch (err) { registerError( "TransformRuleEditor_partialAutoCompletion", t("taskViews.transformRulesEditor.errors.partialPathAutoCompletion.msg"), - err + err, ); } }, - [] + [], ); const sourcePathInput = () => @@ -241,7 +241,7 @@ export const TransformRuleEditor = ({ "Source path", ["Source path"], "The value path of the input source of the transformation task.", - inputPathAutoCompletion + inputPathAutoCompletion, ); const fetchDatasetCharacteristics = async () => { @@ -258,7 +258,7 @@ export const TransformRuleEditor = ({ "TransformRuleEditor-fetchDatasetCharacteristics", "Dataset characteristics could not be fetched. UI-support for language filters will not be available.", ex, - { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE } + { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE }, ); } } @@ -278,9 +278,9 @@ export const TransformRuleEditor = ({ "linking-rule-editor-fetch-source-paths", t("taskViews.linkRulesEditor.errors.fetchLinkingPaths.msg"), ex, - { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE } + { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE }, ), - mappingEditorContext.taskContext + mappingEditorContext.taskContext, ), ruleUtils.sidebarTabs.transform, ]; diff --git a/workspace/src/app/views/taskViews/transform/evaluation/TransformRuleEvaluation.tsx b/workspace/src/app/views/taskViews/transform/evaluation/TransformRuleEvaluation.tsx index 49147f7da8..2aedbb83b3 100644 --- a/workspace/src/app/views/taskViews/transform/evaluation/TransformRuleEvaluation.tsx +++ b/workspace/src/app/views/taskViews/transform/evaluation/TransformRuleEvaluation.tsx @@ -48,18 +48,18 @@ export const TransformRuleEvaluation: React.FC = ( const [evaluationResultMap] = React.useState>(new Map()); const [evaluationResultsShown, setEvaluationResultsShown] = React.useState(false); const [nodeUpdateCallbacks] = React.useState( - new Map any>() + new Map any>(), ); const [ruleValidationError, setRuleValidationError] = React.useState(undefined); const [validationNotifications, setValidationNotifications] = React.useState( - [] + [], ); const { registerError, registerErrorI18N } = useErrorHandler(); const [t] = useTranslation(); const taskContextWarningShown = React.useRef(false); const mappingEditorContext = React.useContext(GlobalMappingEditorContext); // The root node of the sub-tree that will be evaluated - const evaluatedSubTreeNode = React.useRef(); + const evaluatedSubTreeNode = React.useRef(undefined); const [evaluationError, setEvaluationError] = React.useState(); const addValidationNotification = React.useCallback((n: RuleEditorEvaluationNotification) => { @@ -105,7 +105,7 @@ export const TransformRuleEvaluation: React.FC = ( }; const fetchTransformRuleEvaluation: ( - rule: IComplexMappingRule + rule: IComplexMappingRule, ) => Promise = async (rule: IComplexMappingRule) => { try { const result = await evaluateTransformRule( @@ -113,7 +113,7 @@ export const TransformRuleEvaluation: React.FC = ( transformTaskId, containerRuleId, rule, - numberOfLinkToShow + numberOfLinkToShow, ); return result.data; } catch (ex) { @@ -143,7 +143,7 @@ export const TransformRuleEvaluation: React.FC = ( const startEvaluation = async ( _ruleOperatorNodes: IRuleOperatorNode[], originalRule: any, - quickEvaluationOnly: boolean = false + quickEvaluationOnly: boolean = false, ) => { setEvaluationRunning(true); setRuleValidationError(undefined); @@ -178,7 +178,7 @@ export const TransformRuleEvaluation: React.FC = ( "TransformRuleEvaluation.startEvaluation", t("taskViews.linkRulesEditor.errors.startEvaluation.msg"), ex, - { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE } + { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE }, ); } else if (ex.isRuleValidationError) { setRuleValidationError(ex); @@ -187,7 +187,7 @@ export const TransformRuleEvaluation: React.FC = ( "LinkingRuleEvaluation.beforeStartEvaluation", t("taskViews.linkRulesEditor.errors.beforeStartEvaluation.msg"), ex, - { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE } + { errorNotificationInstanceId: RULE_EDITOR_NOTIFICATION_INSTANCE }, ); } } finally { @@ -216,14 +216,14 @@ export const TransformRuleEvaluation: React.FC = ( /** Called by a rule operator node to register for evaluation updates. */ const registerForEvaluationResults = ( ruleOperatorId: string, - evaluationUpdate: (evaluationValues: EvaluationResultType | undefined) => void + evaluationUpdate: (evaluationValues: EvaluationResultType | undefined) => void, ) => { nodeUpdateCallbacks.set(ruleOperatorId, evaluationUpdate); evaluationUpdate(evaluationResultMap.get(ruleOperatorId)); }; /** Factory method used by the rule editor to create an evaluation element. */ - const createRuleEditorEvaluationComponent = (ruleOperatorId: string): JSX.Element => { + const createRuleEditorEvaluationComponent = (ruleOperatorId: string): React.JSX.Element => { return ( = ({ startFullScreen, viewActions, }) => { - const evaluatedEntityResults = React.useRef(); + const evaluatedEntityResults = React.useRef(undefined); const [allRowsExpanded, setAllRowsExpanded] = React.useState(false); const [loading, setLoading] = React.useState(false); const [currentRuleId, setCurrentRuleId] = React.useState(() => { diff --git a/workspace/src/index.tsx b/workspace/src/index.tsx index 95b33cac49..8e3f1c0506 100644 --- a/workspace/src/index.tsx +++ b/workspace/src/index.tsx @@ -2,7 +2,7 @@ import "react-app-polyfill/ie11"; import "react-app-polyfill/stable"; import React from "react"; -import ReactDOM from "react-dom"; +import { createRoot } from "react-dom/client"; import { Provider } from "react-redux"; import ErrorBoundary from "./app/ErrorBoundary"; import registerGlobalListeners from "./global"; @@ -26,13 +26,15 @@ const bootstrapPlugins = (plugins) => plugins.map((plugin) => createPlugin(plugi const bootstrapApp = (routes: IRouteProps[], externalRoutes) => { const store = configureStore(configs.dev); - ReactDOM.render( + const rootDIv = document.getElementById("root"); + if (!rootDIv) return null; + const root = createRoot(rootDIv); + root.render( , - document.getElementById("root") ); }; diff --git a/workspace/test/integration/TestHelper.tsx b/workspace/test/integration/TestHelper.tsx index 8f48346ff0..13f7c8f8e5 100644 --- a/workspace/test/integration/TestHelper.tsx +++ b/workspace/test/integration/TestHelper.tsx @@ -102,7 +102,7 @@ export type RecursivePartial = { export const withRender = (component) => render(component); export const renderWrapper = ( - ui: JSX.Element, + ui: React.JSX.Element, history: History = createBrowserHistory(), initialState: RecursivePartial = {}, options = {}, From c60b5ec1c078233a1ce09b11a81c7b6a83d1e5df Mon Sep 17 00:00:00 2001 From: arausly Date: Tue, 30 Sep 2025 22:27:46 +0100 Subject: [PATCH 003/105] added react-redux resolution --- package.json | 13 +++++++------ workspace/package.json | 3 ++- workspace/src/app/App.tsx | 2 +- workspace/src/app/store/ducks/common/commonSlice.ts | 2 ++ 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 8e96a3d061..c8ece31b40 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ ], "scripts": {}, "dependencies": { - "react": "^19.1.1", - "react-dom": "^19.1.1" + "react": "^18.2.0", + "react-dom": "^18.2.0" }, "devDependencies": {}, "resolutions": { @@ -22,10 +22,11 @@ "**/minimist": "1.2.8", "**/moment": "2.29.4", "**/nanoid": "3.3.4", - "**/react": "^19.1.1", - "**/react-dom": "^19.1.1", + "**/react": "^18.2.0", + "**/react-dom": "^18.2.0", "**/semver-regex": "3.1.4", - "**/@types/react": "^19.1.15", - "**/url-parse": "1.5.9" + "**/@types/react": "^18.2.0", + "**/url-parse": "1.5.9", + "**/react-redux": "^9.1.2" } } diff --git a/workspace/package.json b/workspace/package.json index 9f922fb503..9a01d15420 100644 --- a/workspace/package.json +++ b/workspace/package.json @@ -264,6 +264,7 @@ "resolutions": { "**/minimist": "^1.2.8", "sanitize.css": "12.0.1", - "**/url-parse": "1.5.9" + "**/url-parse": "1.5.9", + "react-redux": "^9.1.2" } } diff --git a/workspace/src/app/App.tsx b/workspace/src/app/App.tsx index 53654b4e55..a7425be134 100644 --- a/workspace/src/app/App.tsx +++ b/workspace/src/app/App.tsx @@ -20,7 +20,7 @@ export default function App({ externalRoutes, routes }: IProps) { dispatch(commonOp.fetchExportTypesAsync()); }, [commonOp]); return ( - + ); diff --git a/workspace/src/app/store/ducks/common/commonSlice.ts b/workspace/src/app/store/ducks/common/commonSlice.ts index 12a984a47f..f334cbceda 100644 --- a/workspace/src/app/store/ducks/common/commonSlice.ts +++ b/workspace/src/app/store/ducks/common/commonSlice.ts @@ -47,6 +47,8 @@ const getExtraReducers = (builder: ActionReducerMapBuilder Date: Tue, 30 Sep 2025 23:01:15 +0100 Subject: [PATCH 004/105] fixed compilation issue in gui-elements --- libs/gui-elements | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/gui-elements b/libs/gui-elements index ad360d9a5c..f8a22ebeae 160000 --- a/libs/gui-elements +++ b/libs/gui-elements @@ -1 +1 @@ -Subproject commit ad360d9a5ccf3d6bb315c23401734377005e00b0 +Subproject commit f8a22ebeae584b7eab2ff40771e3aebb938a4ea4 From 75cfe272e0c53711ed79816ee4bd04c05b30125e Mon Sep 17 00:00:00 2001 From: arausly Date: Mon, 8 Dec 2025 09:56:52 +0100 Subject: [PATCH 005/105] corrected interface to fix compilation errors --- libs/gui-elements | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/gui-elements b/libs/gui-elements index 919bca3dd7..ef6fede0c1 160000 --- a/libs/gui-elements +++ b/libs/gui-elements @@ -1 +1 @@ -Subproject commit 919bca3dd7e42ebc22af33b9e086430657a84b75 +Subproject commit ef6fede0c1cea9e21966be3daa4f2991b7c0eea4 From 44048eef3475c670d8fd39471a9517127785bb88 Mon Sep 17 00:00:00 2001 From: arausly Date: Mon, 15 Dec 2025 09:57:50 +0100 Subject: [PATCH 006/105] fixed failing tests --- libs/gui-elements | 2 +- workspace/package.json | 9 +++++---- workspace/src/setupTests.ts | 4 ++++ .../test/integration/views/pages/Task/Task.test.tsx | 1 - 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/libs/gui-elements b/libs/gui-elements index ef6fede0c1..f8edf61ede 160000 --- a/libs/gui-elements +++ b/libs/gui-elements @@ -1 +1 @@ -Subproject commit ef6fede0c1cea9e21966be3daa4f2991b7c0eea4 +Subproject commit f8edf61edeb26aa19c802a443953a42004686468 diff --git a/workspace/package.json b/workspace/package.json index a5a97a279b..8821aabe4f 100644 --- a/workspace/package.json +++ b/workspace/package.json @@ -16,7 +16,7 @@ "watch": "node --openssl-legacy-provider --max_old_space_size=2048 scripts/build-di.dev.js --watch", "build-di-dev": "node --openssl-legacy-provider scripts/build-di.dev.js", "build-di-prod": "node --openssl-legacy-provider --max_old_space_size=2048 scripts/build-di.prod.js", - "test": "node scripts/test.js", + "test": "DEBUG=true node scripts/test.js", "test-ci": "export CI=true && node scripts/test.js --coverage --reporters=\"default\" --reporters=\"jest-junit\" --no-colors -ci --silent", "sync-trans": "sync-i18n --files 'src/locales/manual/*.json' --primary en --languages de --space 4 -- --check", "i18n-parser": "node scripts/i18next-scanner.js", @@ -28,7 +28,7 @@ "@eccenca/gui-elements": "^25.0.0", "@eccenca/superagent": "^1.4.1", "@mavrin/remark-typograf": "^2.2.0", - "@reduxjs/toolkit": "^2.9.0", + "@reduxjs/toolkit": "^2.11.1", "@uppy/core": "1.17.0", "@uppy/react": "1.11.10", "@uppy/xhr-upload": "1.7.5", @@ -129,12 +129,12 @@ "/test/**/*(*.)@(spec|test).{js,jsx,ts,tsx}" ], "transform": { - "^.+\\.(js|jsx|ts|tsx)$": "babel-jest", + "^.+\\.(js|jsx|ts|tsx|mjs|cjs)$": "babel-jest", "^.+\\.css$": "/config/jest/cssTransform.js", "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "/config/jest/fileTransform.js" }, "transformIgnorePatterns": [ - "[/\\\\]node_modules[/\\\\](?!react-markdown|vfile|unist-util-stringify-position|).+\\.(js|jsx|ts|tsx)$", + "[/\\\\]node_modules[/\\\\](?!react-markdown|vfile|unist-util-stringify-position|@reduxjs/toolkit|).+\\.(js|jsx|ts|tsx|mjs|cjs)$", "^.+\\.module\\.(css|sass|scss)$" ], "moduleNameMapper": { @@ -142,6 +142,7 @@ "^react-markdown$": "/../../node_modules/react-markdown", "^@eccenca/gui-elements$": "/../../node_modules/@eccenca/gui-elements", "^@eccenca/gui-elements/(.*)$": "/../../node_modules/@eccenca/gui-elements/$1", + "^@reduxjs/toolkit$": "/../../node_modules/@reduxjs/toolkit/dist/cjs/redux-toolkit.development.cjs", "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy", "@ducks(.*)$": "/src/app/store/ducks/$1" }, diff --git a/workspace/src/setupTests.ts b/workspace/src/setupTests.ts index 77a0165800..440fdcafca 100644 --- a/workspace/src/setupTests.ts +++ b/workspace/src/setupTests.ts @@ -1,5 +1,9 @@ import "regenerator-runtime/runtime"; import "@testing-library/jest-dom"; +import { TextEncoder, TextDecoder } from "util"; + +(global as any).TextEncoder = TextEncoder; +(global as any).TextDecoder = TextDecoder; jest.setTimeout(30000); diff --git a/workspace/test/integration/views/pages/Task/Task.test.tsx b/workspace/test/integration/views/pages/Task/Task.test.tsx index a7049d87e7..c02e814070 100644 --- a/workspace/test/integration/views/pages/Task/Task.test.tsx +++ b/workspace/test/integration/views/pages/Task/Task.test.tsx @@ -22,7 +22,6 @@ import { requestTaskDataTestResponse, } from "../../../requests/sharedResponseStubs"; import { RenderResult, waitFor } from "@testing-library/react"; -import { ReactWrapper } from "enzyme"; import { IArtefactItemProperty } from "../../../../../src/app/store/ducks/common/typings"; import { IMetadata } from "@ducks/shared/typings"; From af62d92e528d238acb69cb8dab90650071e2ec98 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Mon, 19 Jan 2026 11:42:04 +0100 Subject: [PATCH 007/105] Fix rule editor model tests --- workspace/package.json | 2 +- workspace/scripts/test.js | 2 +- .../elements/DiscardChangesDialog.jsx | 44 ----------- .../model/RuleEditorModel.utils.tsx | 1 - .../model/test/RuleEditorModel.test.tsx | 77 ++++++++++--------- .../elements/DiscardChangesDialog.test.jsx | 42 ---------- 6 files changed, 44 insertions(+), 124 deletions(-) delete mode 100644 workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/DiscardChangesDialog.jsx delete mode 100644 workspace/test/HierarchicalMapping/elements/DiscardChangesDialog.test.jsx diff --git a/workspace/package.json b/workspace/package.json index 8821aabe4f..64775a3ae2 100644 --- a/workspace/package.json +++ b/workspace/package.json @@ -181,7 +181,7 @@ "@cyclonedx/webpack-plugin": "^2.0.2", "@svgr/webpack": "^8.1.0", "@testing-library/jest-dom": "^6.6.4", - "@testing-library/react": "^12.1.5", + "@testing-library/react": "^14.3.1", "@testing-library/user-event": "^14.6.1", "@types/jest": "^30.0.0", "@types/ramda": "^0.26.6", diff --git a/workspace/scripts/test.js b/workspace/scripts/test.js index 9ccd3dba61..484a63f440 100644 --- a/workspace/scripts/test.js +++ b/workspace/scripts/test.js @@ -54,5 +54,5 @@ if ( if (argv.indexOf("--no-watch") !== -1) { argv = argv.filter((arg) => arg !== "--no-watch"); } - +argv.push("--detectOpenHandles", "--logHeapUsage") jest.run(argv); diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/DiscardChangesDialog.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/DiscardChangesDialog.jsx deleted file mode 100644 index 1f12d1323b..0000000000 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/DiscardChangesDialog.jsx +++ /dev/null @@ -1,44 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { ConfirmationDialog } from "gui-elements-deprecated"; -import { Button } from "@eccenca/gui-elements"; - -const DiscardChangesDialog = (props) => { - const { numberEditingElements, handleDiscardCancel, handleDiscardConfirm } = props; - return ( - - Discard - - } - cancelButton={ - - } - > -

    - {`You currently have unsaved changes${ - numberEditingElements === 1 ? "" : ` in ${numberEditingElements} mapping rules` - }.`} -

    -
    - ); -}; - -DiscardChangesDialog.propTypes = { - numberEditingElements: PropTypes.number, - handleDiscardCancel: PropTypes.func.isRequired, - handleDiscardConfirm: PropTypes.func.isRequired, -}; - -DiscardChangesDialog.defaultProps = { - numberEditingElements: 0, -}; - -export default DiscardChangesDialog; diff --git a/workspace/src/app/views/shared/RuleEditor/model/RuleEditorModel.utils.tsx b/workspace/src/app/views/shared/RuleEditor/model/RuleEditorModel.utils.tsx index 202c364c21..b09fa31aec 100644 --- a/workspace/src/app/views/shared/RuleEditor/model/RuleEditorModel.utils.tsx +++ b/workspace/src/app/views/shared/RuleEditor/model/RuleEditorModel.utils.tsx @@ -118,7 +118,6 @@ function createOperatorNode( /> ); const type = nodeType(node.pluginType, node.pluginId); - console.log("NODE ==>", node); let data: NodeContentPropsWithBusinessData = { size: "medium", diff --git a/workspace/src/app/views/shared/RuleEditor/model/test/RuleEditorModel.test.tsx b/workspace/src/app/views/shared/RuleEditor/model/test/RuleEditorModel.test.tsx index d1dfd5404f..de5de3ccf2 100644 --- a/workspace/src/app/views/shared/RuleEditor/model/test/RuleEditorModel.test.tsx +++ b/workspace/src/app/views/shared/RuleEditor/model/test/RuleEditorModel.test.tsx @@ -3,7 +3,7 @@ import { RuleEditorModel } from "../RuleEditorModel"; import { RenderResultApi, renderWrapper } from "../../../../../../../test/integration/TestHelper"; import { RuleEditorModelContext, RuleEditorModelContextProps } from "../../contexts/RuleEditorModelContext"; import { Elements, FitViewParams, FlowExportObject, FlowTransform, ReactFlowProvider } from "react-flow-renderer"; -import { act, waitFor } from "@testing-library/react"; +import { act, waitFor, cleanup } from "@testing-library/react"; import { RuleEditorContext } from "../../contexts/RuleEditorContext"; import { IParameterSpecification, @@ -75,38 +75,42 @@ describe("Rule editor model", () => { ) => boolean = () => true, stickyNotes: StickyNote[] = [], ) => { + // Remove previously mounted components (needed if called multiple times in the same test) + cleanup() modelContext = undefined; const Provider: React.FC<{ children: React.JSX.Element }> = ReactFlowProvider; - const ruleModel = renderWrapper( - { - savedRuleOperatorNodes = ruleOperatorNodes; - return { success: true }; - }, - convertRuleOperatorToRuleNode: utils.defaults.convertRuleOperatorToRuleNode, - operatorSpec, - validateConnection, - instanceId: "id", - datasetCharacteristics: new Map(), - partialAutoCompletion: () => async () => undefined, - saveInitiallyEnabled: false, - }} - > - - - - - - , - ); + const ruleModel = await act(() => { + return renderWrapper( + { + savedRuleOperatorNodes = ruleOperatorNodes; + return {success: true}; + }, + convertRuleOperatorToRuleNode: utils.defaults.convertRuleOperatorToRuleNode, + operatorSpec, + validateConnection, + instanceId: "id", + datasetCharacteristics: new Map(), + partialAutoCompletion: () => async () => undefined, + saveInitiallyEnabled: false, + }} + > + + + + + + + ); + }) await waitFor(() => { expect(modelContext).toBeTruthy(); modelContext!!.setReactFlowInstance({ @@ -321,11 +325,14 @@ describe("Rule editor model", () => { borderColor: "#000000", color: "#000", }; - const node = allStickyNodes()[0]; const checkBeforeChange = () => { + const node = allStickyNodes()[0]; expect(node.data.style).toEqual(defaultStyle); + return node }; - checkBeforeChange(); + const node = await waitFor(() => { + return checkBeforeChange(); + }) const checkAfterChange = () => { expect(modelUtils.nodeById(currentContext().elements, node.id)!!.data.style).not.toStrictEqual( @@ -719,9 +726,9 @@ describe("Rule editor model", () => { changeAction: () => any, additionalCheck: () => any | Promise = () => {}, ) => { - await act(() => { + await act(async () => { currentContext().executeModelEditOperation.startChangeTransaction(); - changeAction(); + await changeAction(); }); // Check that something has changed await waitFor(() => { diff --git a/workspace/test/HierarchicalMapping/elements/DiscardChangesDialog.test.jsx b/workspace/test/HierarchicalMapping/elements/DiscardChangesDialog.test.jsx deleted file mode 100644 index 88191f2181..0000000000 --- a/workspace/test/HierarchicalMapping/elements/DiscardChangesDialog.test.jsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from "react"; -import DiscardChangesDialog from "../../../src/app/views/pages/MappingEditor/HierarchicalMapping/elements/DiscardChangesDialog"; -import { render } from "@testing-library/react"; -import { clickFoundElement } from "../../integration/TestHelper"; - -const handleDiscardCancelMock = jest.fn(); -const handleDiscardConfirmMock = jest.fn(); -const props = { - numberEditingElements: 2, - handleDiscardCancel: handleDiscardCancelMock, - handleDiscardConfirm: handleDiscardConfirmMock, -}; - -const getWrapper = () => render(); - -const selectors = { - DISCARD_BUTTON: "button.ecc-hm-accept-discard", - CANCEL_BUTTON: "button.ecc-hm-cancel-discard", -}; - -describe("DiscardChangesDialog Component", () => { - describe("on user interaction, ", () => { - let wrapper; - beforeEach(() => { - wrapper = getWrapper(); - }); - - it("should handleDiscardConfirm called, when click on Discard button", () => { - clickFoundElement(wrapper, selectors.DISCARD_BUTTON); - expect(handleDiscardConfirmMock).toHaveBeenCalled(); - }); - - it("should handleDiscardCancel called, when click on Cancel button", () => { - clickFoundElement(wrapper, selectors.CANCEL_BUTTON); - expect(handleDiscardCancelMock).toHaveBeenCalled(); - }); - - afterEach(() => { - wrapper.unmount(); - }); - }); -}); From 76086c7783946788a493fddfc68000732f0c60d2 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Mon, 19 Jan 2026 11:42:34 +0100 Subject: [PATCH 008/105] Add missing scrollTo function to window object --- workspace/src/setupTests.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/workspace/src/setupTests.ts b/workspace/src/setupTests.ts index 440fdcafca..9d1445ecb9 100644 --- a/workspace/src/setupTests.ts +++ b/workspace/src/setupTests.ts @@ -39,3 +39,9 @@ Object.defineProperty(window, "matchMedia", { dispatchEvent: jest.fn(), })), }); + +// Mock window.scrollTo and related scroll methods +Object.defineProperty(window, "scrollTo", { + writable: true, + value: jest.fn(), +}); From 5cf73b55d08d53a7ab55cb25f14d3bfda080fe63 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Mon, 19 Jan 2026 11:43:35 +0100 Subject: [PATCH 009/105] Fix warning in ActivitiesList.test --- .../app/views/pages/Activities/tests/ActivitiesList.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workspace/src/app/views/pages/Activities/tests/ActivitiesList.test.tsx b/workspace/src/app/views/pages/Activities/tests/ActivitiesList.test.tsx index 29460743cc..5bd77441fa 100644 --- a/workspace/src/app/views/pages/Activities/tests/ActivitiesList.test.tsx +++ b/workspace/src/app/views/pages/Activities/tests/ActivitiesList.test.tsx @@ -59,8 +59,8 @@ const render = ( { store = configureStore({ reducer: rootReducer, + middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(routerMiddleware(history)), preloadedState: { - middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(routerMiddleware(history)), ...(dummyState as any), }, }), From 1f32d7c4d0902a15e4ce794035120cd7398a1170 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Mon, 19 Jan 2026 11:44:48 +0100 Subject: [PATCH 010/105] Fix deprecation warning in old mapping editor code --- .../MappingRule/ObjectRule/ObjectRule.jsx | 8 ------- .../elements/RemoveMappingRuleDialog.jsx | 7 +------ .../app/views/pages/MappingEditor/index.jsx | 21 ++++++++++++------- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.jsx index 7709053148..5df75469a8 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.jsx @@ -81,14 +81,6 @@ class ObjectRule extends React.Component { } } - componentWillReceiveProps(nextProps) { - if (_.has(nextProps, "ruleData.rules.uriRule.id")) { - this.setState({ - href: getEditorHref(_.get(nextProps, "ruleData.rules.uriRule.id", "")), - }); - } - } - openEditor = () => { let uriRuleId = _.get(this.props.ruleData, "rules.uriRule")?.id; if (!uriRuleId) { diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RemoveMappingRuleDialog.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RemoveMappingRuleDialog.jsx index f1fdd06bd4..d160e5fd29 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RemoveMappingRuleDialog.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RemoveMappingRuleDialog.jsx @@ -4,8 +4,7 @@ import { ConfirmationDialog } from "gui-elements-deprecated"; import { MAPPING_RULE_TYPE_OBJECT } from "../utils/constants"; import { Button } from "@eccenca/gui-elements"; -const RemoveMappingRuleDialog = (props) => { - const { mappingType, handleConfirmRemove, handleCancelRemove, label } = props; +const RemoveMappingRuleDialog = ({ mappingType = "", handleConfirmRemove, handleCancelRemove, label }) => { return ( { + const root = createRoot(document.getElementById(elementId)); + root.render(reactNode); +} + const silkReactComponents = { hierarchicalMapping: (containerId, apiSettings) => { - ReactDom.render(, document.getElementById(containerId)); + render(containerId, ); }, executionReport: (containerId, apiSettings) => { - ReactDom.render(, document.getElementById(containerId)); + render(containerId, ); }, transformExecutionReport: (containerId, apiSettings) => { - ReactDom.render(, document.getElementById(containerId)); + render(containerId, ); }, linkingExecutionReport: (containerId, apiSettings) => { - ReactDom.render(, document.getElementById(containerId)); + render(containerId, ); }, workflowExecutionReport: (containerId, apiSettings) => { - ReactDom.render(, document.getElementById(containerId)); + render(containerId, ); }, workflowNodeExecutionReport: (containerId, apiSettings) => { - ReactDom.render(, document.getElementById(containerId)); + render(containerId, ); }, workflowReportManager: (containerId, apiSettings) => { - ReactDom.render(, document.getElementById(containerId)); + render(containerId, ); }, }; From 587b0058319a43d9101355d6c11efb834673ede6 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Mon, 19 Jan 2026 11:45:20 +0100 Subject: [PATCH 011/105] Fix tests because of missing act usage --- libs/gui-elements | 2 +- .../containers/MappingRule/ObjectRule/ObjectRule.test.jsx | 1 + workspace/test/integration/Project/Project.test.tsx | 4 ++-- .../integration/components/RelatedItems/RelatedItems.test.tsx | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/libs/gui-elements b/libs/gui-elements index e7ab6a0217..47395f9c30 160000 --- a/libs/gui-elements +++ b/libs/gui-elements @@ -1 +1 @@ -Subproject commit e7ab6a021759e32575d954fa729f6c2f2a38c98a +Subproject commit 47395f9c304e4013166b5e12dfd1098fb40f5dfb diff --git a/workspace/test/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.test.jsx b/workspace/test/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.test.jsx index faefac3033..dbe8092b58 100644 --- a/workspace/test/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.test.jsx +++ b/workspace/test/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.test.jsx @@ -38,6 +38,7 @@ const props = { }, mappingTarget: { uri: "uri", + isAttribute: false }, type: "root", }, diff --git a/workspace/test/integration/Project/Project.test.tsx b/workspace/test/integration/Project/Project.test.tsx index ebc1dc470e..e08d932a82 100644 --- a/workspace/test/integration/Project/Project.test.tsx +++ b/workspace/test/integration/Project/Project.test.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { RenderResult, waitFor } from "@testing-library/react"; +import {act, RenderResult, waitFor} from "@testing-library/react"; import mockAxios from "../../__mocks__/axios"; import { apiUrl, @@ -87,7 +87,7 @@ describe("Project page", () => { it("should search items when switching from one project to another", async () => { const otherProject = "otherProject"; checkRequestMade(apiUrl("/workspace/searchItems"), "POST", { project: testProjectId }, true); - history.push(workspacePath("/projects/" + otherProject)); + act(() => history.push(workspacePath("/projects/" + otherProject))); await waitFor(() => { checkRequestMade(apiUrl("/workspace/searchItems"), "POST", { project: otherProject }, true); }); diff --git a/workspace/test/integration/components/RelatedItems/RelatedItems.test.tsx b/workspace/test/integration/components/RelatedItems/RelatedItems.test.tsx index 6eb32dc41b..bbb9650c96 100644 --- a/workspace/test/integration/components/RelatedItems/RelatedItems.test.tsx +++ b/workspace/test/integration/components/RelatedItems/RelatedItems.test.tsx @@ -14,7 +14,7 @@ import { RelatedItems } from "../../../../src/app/views/shared/RelatedItems/Rela import { RelatedItemsTestHelper } from "./RelatedItemsTestHelper"; import { CONTEXT_PATH, SERVE_PATH } from "../../../../src/app/constants/path"; import { ReactWrapper } from "enzyme"; -import { RenderResult, waitFor } from "@testing-library/react"; +import {act, RenderResult, waitFor} from "@testing-library/react"; describe("Related items", () => { let hostPath = process.env.HOST; @@ -41,7 +41,7 @@ describe("Related items", () => { it("should reload the related items when changing the project or task", async () => { const otherTask = "otherTask"; - history.push(workspacePath(`/projects/${PROJECT_ID}/task/${otherTask}`)); + act(() => history.push(workspacePath(`/projects/${PROJECT_ID}/task/${otherTask}`))); await waitFor(() => { checkRequestMade(relatedItemsUrl(otherTask)); }); From 3ddc1d0914e97eecd662927cab1b2b35dc736e79 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Mon, 19 Jan 2026 15:03:03 +0100 Subject: [PATCH 012/105] Fix more deprecation warnings and test issues --- .../components/InfoBox.jsx | 15 +++++++------ .../elements/buttons/CloneButton.jsx | 1 - workspace/src/setupTests.ts | 22 +++++++++++++++++++ .../MappingRule/MappingRule.test.jsx | 3 ++- .../MappingRule/ValueRule/ValueRule.test.jsx | 7 ++++-- .../views/shared/AutoComplete.test.tsx | 6 +++-- 6 files changed, 41 insertions(+), 13 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/InfoBox.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/InfoBox.jsx index 4507943572..39cdbddea3 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/InfoBox.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/InfoBox.jsx @@ -1,18 +1,18 @@ import React from 'react'; -import { Button } from 'gui-elements-deprecated'; +import { IconButton } from "@eccenca/gui-elements" export class InfoBox extends React.Component { state = { expanded: false, }; - + toggleExpander = event => { event.stopPropagation(); this.setState({ expanded: !this.state.expanded, }); }; - + render() { return (
    -
    {this.props.expanded ? ( -
    {expandedView}
    +
    {expandedView}
    ) : ( false )} diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRuleRow.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRuleRow.jsx index ff9c8085d4..59b42e9b65 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRuleRow.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRuleRow.jsx @@ -8,25 +8,24 @@ import { getRuleLabel } from '../../utils/getRuleLabel'; class MappingRuleRow extends React.Component { render() { const {mappingTarget, metadata, rules, sourcePath, type} = this.props; - + const label = _.get(metadata, 'label', ''); const ruleLabelData = getRuleLabel({label, uri: mappingTarget.uri}); const statusType = _.get(this.props, 'status[0].type', false); const statusMsg = _.get(this.props, 'status[0].message', false); return (
    -
    -
    +
    {ruleLabelData.displayLabel}
    {ruleLabelData.uri &&
    {ruleLabelData.uri}
    } + className="ecc-silk-mapping__ruleitem-extraline ecc-silk-mapping__ruleitem-url nodrag">{ruleLabelData.uri}
    }
    DataType:{' '} @@ -36,6 +35,7 @@ class MappingRuleRow extends React.Component { mappingTarget, rules, }} + className={"nodrag"} />
    diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx index 81283990fb..c3ca962e3e 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx @@ -1,16 +1,18 @@ -import React, { useEffect, useState } from "react"; -import { Card, CardTitle } from "gui-elements-deprecated"; -import { DragDropContext, Droppable } from "react-beautiful-dnd"; -import { getApiDetails } from "../../store"; +import React, {useEffect, useState} from "react"; +import {Card, CardTitle} from "gui-elements-deprecated"; +import {DndContext, KeyboardSensor, useSensor, useSensors} from "@dnd-kit/core"; +import {arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy} from "@dnd-kit/sortable"; +import {getApiDetails} from "../../store"; import DraggableItem from "../MappingRule/DraggableItem"; import rulesToList from "../../utils/rulesToList"; import ListActions from "./ListActions"; import EmptyList from "./EmptyList"; -import reorderArray from "../../utils/reorderArray"; -import { Spinner } from "@eccenca/gui-elements"; +import {Spinner} from "@eccenca/gui-elements"; import silkRestApi from "../../../api/silkRestApi"; import useErrorHandler from "../../../../../../hooks/useErrorHandler"; -import { IViewActions } from "../../../../../../views/plugins/PluginRegistry"; +import {IViewActions} from "../../../../../../views/plugins/PluginRegistry"; +import dndkitUtils from "../../../../../../utils/dndkitUtils"; +import {restrictToVerticalAxis} from "@dnd-kit/modifiers"; interface MappingsListProps { rules: any[]; @@ -56,22 +58,27 @@ const MappingsList = ({ const [items, setItems] = useState(rulesToList(rules, parentRuleId || currentRuleId)); const [reorderingRequestPending, setReorderingRequestPending] = useState(false); const { registerError } = useErrorHandler(); + + const sensors = useSensors( + useSensor(dndkitUtils.DefaultMouseSensor), + useSensor(KeyboardSensor, { + coordinateGetter: sortableKeyboardCoordinates, + }) + ); + useEffect(() => { setItems(rulesToList(rules, parentRuleId || currentRuleId)); }, [rules, parentRuleId, currentRuleId]); const handleOrderRules = async ({ fromPos, toPos }: { fromPos: number; toPos: number }) => { - const childrenRules = reorderArray( - items.map((a) => a.key), - fromPos, - toPos - ); + const reorderedItems = arrayMove(items, fromPos, toPos); + const childrenRules = reorderedItems.map((a) => a.key); const { project, transformTask } = getApiDetails(); if (project != null && transformTask != null && parentRuleId != null) { setReorderingRequestPending(true); try { - setItems(reorderArray(items, fromPos, toPos)); + setItems(reorderedItems); await silkRestApi.reorderRules(project, transformTask, parentRuleId, childrenRules); } catch (ex) { registerError("MappingsList.handleOrderRules", "Reordering of the mappings rules has failed.", ex); @@ -83,25 +90,27 @@ const MappingsList = ({ } }; - const onDragStart = () => {}; + const onDragEnd = (event) => { + const { active, over } = event; - // template rendering - const onDragEnd = (result) => { // dropped outside the list - if (!result.destination) { + if (!over) { return; } - const fromPos = result.source.index; - const toPos = result.destination.index; // no actual movement - if (fromPos === toPos) { + if (active.id === over.id) { return; } - handleOrderRules({ - fromPos, - toPos, - }); + const fromPos = items.findIndex(item => `draggable-${item.key}` === active.id); + const toPos = items.findIndex(item => `draggable-${item.key}` === over.id); + + if (fromPos !== -1 && toPos !== -1) { + handleOrderRules({ + fromPos, + toPos, + }); + } }; return ( @@ -114,32 +123,30 @@ const MappingsList = ({ {!rules.length ? ( ) : ( - - - {(provided) => ( -
      - {items.map((item, index) => ( - - ))} - {provided.placeholder} -
    - )} -
    -
    + + `draggable-${item.key}`)} strategy={verticalListSortingStrategy}> +
      + {items.map((item, index) => ( + + ))} +
    +
    +
    )} { return ( diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/buttons/NavigateButton.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/buttons/NavigateButton.jsx index 359434a530..365e0e5817 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/buttons/NavigateButton.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/buttons/NavigateButton.jsx @@ -3,7 +3,7 @@ import React from "react"; const NavigateButton = ({ onClick, id }) => { return ( - + ); }; diff --git a/workspace/src/app/views/shared/VariablesWidget/VariablesWidget.tsx b/workspace/src/app/views/shared/VariablesWidget/VariablesWidget.tsx index b909fbde71..7112228a86 100644 --- a/workspace/src/app/views/shared/VariablesWidget/VariablesWidget.tsx +++ b/workspace/src/app/views/shared/VariablesWidget/VariablesWidget.tsx @@ -1,11 +1,17 @@ import React from "react"; -import { DndContext, PointerSensor, KeyboardSensor, useSensor, useSensors } from "@dnd-kit/core"; -import { SortableContext, useSortable, verticalListSortingStrategy, sortableKeyboardCoordinates, arrayMove } from "@dnd-kit/sortable"; -import { CSS } from "@dnd-kit/utilities"; -import { restrictToVerticalAxis } from "@dnd-kit/modifiers"; +import {DndContext, KeyboardSensor, useSensor, useSensors} from "@dnd-kit/core"; +import { + arrayMove, + SortableContext, + sortableKeyboardCoordinates, + useSortable, + verticalListSortingStrategy +} from "@dnd-kit/sortable"; +import {CSS} from "@dnd-kit/utilities"; +import {restrictToVerticalAxis} from "@dnd-kit/modifiers"; //typing -import { Variable, VariableDependencies, VariableWidgetProps } from "./typing"; +import {Variable, VariableDependencies, VariableWidgetProps} from "./typing"; import { Card, CardContent, @@ -15,10 +21,8 @@ import { Divider, Icon, IconButton, - Label, Link, Notification, - OverflowText, OverviewItemList, PropertyName, PropertyValue, @@ -28,14 +32,14 @@ import { ToolbarSection, Tooltip, } from "@eccenca/gui-elements"; -import { useTranslation } from "react-i18next"; -import { deleteVariableRequest, getVariableDependencies, getVariables, reorderVariablesRequest } from "./requests"; +import {useTranslation} from "react-i18next"; +import {deleteVariableRequest, getVariableDependencies, getVariables, reorderVariablesRequest} from "./requests"; import useErrorHandler from "../../../hooks/useErrorHandler"; import Loading from "../Loading"; import NewVariableModal from "./modals/NewVariableModal"; import DeleteModal from "../modals/DeleteModal"; -import { ErrorResponse, FetchError } from "../../../services/fetch/responseInterceptor"; -import { useModalError } from "../../../hooks/useModalError"; +import {ErrorResponse, FetchError} from "../../../services/fetch/responseInterceptor"; +import {useModalError} from "../../../hooks/useModalError"; import dndkitUtils from "../../../utils/dndkitUtils"; const VariablesWidget: React.FC = ({ projectId, taskId }) => { From 1f3177ea8937e177ddc1bb2a624101414b65788b Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Fri, 23 Jan 2026 12:00:25 +0100 Subject: [PATCH 021/105] Improve drag and drop behavior in mapping editor and variables widget --- workspace/src/app/utils/dndkitUtils.ts | 16 +++++++++++++--- .../containers/MappingRule/MappingRule.jsx | 6 +----- .../containers/MappingsList/MappingsList.tsx | 2 +- .../elements/buttons/ExpandButton.jsx | 2 +- .../elements/buttons/NavigateButton.jsx | 2 +- .../shared/VariablesWidget/VariablesWidget.tsx | 4 +--- .../containers/MappingList/MappingsList.test.tsx | 2 +- 7 files changed, 19 insertions(+), 15 deletions(-) diff --git a/workspace/src/app/utils/dndkitUtils.ts b/workspace/src/app/utils/dndkitUtils.ts index ca2e9dcb8e..69b04356cb 100644 --- a/workspace/src/app/utils/dndkitUtils.ts +++ b/workspace/src/app/utils/dndkitUtils.ts @@ -1,9 +1,12 @@ /** Contains utility functions for the dnd-kit drag and drop library.*/ -import {MouseSensor} from "@dnd-kit/core"; +import {MouseSensor, MouseSensorOptions, SensorDescriptor} from "@dnd-kit/core"; import {MouseEvent} from "react"; -/** Blocks DnD event propagation if element has "nodrag" class */ +/** Blocks DnD event propagation if element has "nodrag" class. Do not use this for allowing clicks. Clicks should be + * fixed by adding the distance activationConstraint to the useSensor function. + * Use this for cases like allowing copying text or input elements. + * */ const preventDraggingInNoDragElements = (targetElement: HTMLElement ): boolean => { let cur = targetElement while (cur) { @@ -24,9 +27,16 @@ class DefaultMouseSensor extends MouseSensor { }] satisfies typeof MouseSensor['activators']; } +const defaultMouseSensorOptions: MouseSensorOptions = { + activationConstraint: { + distance: 5, + } +} + const exportObject = { preventDraggingInNoDragElements, - DefaultMouseSensor + DefaultMouseSensor, + defaultMouseSensorOptions } export default exportObject diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRule.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRule.jsx index 59fbf2251d..0f411d0f36 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRule.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRule.jsx @@ -176,7 +176,7 @@ export class MappingRule extends React.Component { ); const reorderHandleButton = !this.props.expanded ? (
    - +
    diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx index c3ca962e3e..e1ffb15930 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx @@ -60,7 +60,7 @@ const MappingsList = ({ const { registerError } = useErrorHandler(); const sensors = useSensors( - useSensor(dndkitUtils.DefaultMouseSensor), + useSensor(dndkitUtils.DefaultMouseSensor, dndkitUtils.defaultMouseSensorOptions), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates, }) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/buttons/ExpandButton.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/buttons/ExpandButton.jsx index 6326a36afe..855cc50d05 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/buttons/ExpandButton.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/buttons/ExpandButton.jsx @@ -5,7 +5,7 @@ const ExpandButton = ({ onToggle, id, expanded }) => { return ( diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/buttons/NavigateButton.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/buttons/NavigateButton.jsx index 365e0e5817..359434a530 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/buttons/NavigateButton.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/buttons/NavigateButton.jsx @@ -3,7 +3,7 @@ import React from "react"; const NavigateButton = ({ onClick, id }) => { return ( - + ); }; diff --git a/workspace/src/app/views/shared/VariablesWidget/VariablesWidget.tsx b/workspace/src/app/views/shared/VariablesWidget/VariablesWidget.tsx index 7112228a86..0708718e5b 100644 --- a/workspace/src/app/views/shared/VariablesWidget/VariablesWidget.tsx +++ b/workspace/src/app/views/shared/VariablesWidget/VariablesWidget.tsx @@ -59,7 +59,7 @@ const VariablesWidget: React.FC = ({ projectId, taskId }) = const [t] = useTranslation(); const sensors = useSensors( - useSensor(dndkitUtils.DefaultMouseSensor), + useSensor(dndkitUtils.DefaultMouseSensor, dndkitUtils.defaultMouseSensorOptions), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates, }) @@ -370,7 +370,6 @@ const SortableVariableItem: React.FC = ({ variable, i data-test-id="variable-edit-btn" onClick={() => onEdit(variable)} size={"small"} - className={"nodrag"} /> = ({ variable, i onClick={() => onDelete(variable)} disruptive size={"small"} - className={"nodrag"} /> diff --git a/workspace/test/HierarchicalMapping/containers/MappingList/MappingsList.test.tsx b/workspace/test/HierarchicalMapping/containers/MappingList/MappingsList.test.tsx index 706116ec28..0c14a09492 100644 --- a/workspace/test/HierarchicalMapping/containers/MappingList/MappingsList.test.tsx +++ b/workspace/test/HierarchicalMapping/containers/MappingList/MappingsList.test.tsx @@ -1,4 +1,4 @@ -import React from "react"; + import React from "react"; import "@testing-library/jest-dom"; import MappingsList from "../../../../src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList"; From 4bc9eef2f614b2641ba5bc2bb9ad1e855fc9db2f Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Fri, 23 Jan 2026 12:10:27 +0100 Subject: [PATCH 022/105] Only allow dragging via left mouse key by default --- workspace/src/app/utils/dndkitUtils.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/workspace/src/app/utils/dndkitUtils.ts b/workspace/src/app/utils/dndkitUtils.ts index 69b04356cb..b3b75385aa 100644 --- a/workspace/src/app/utils/dndkitUtils.ts +++ b/workspace/src/app/utils/dndkitUtils.ts @@ -23,7 +23,14 @@ const preventDraggingInNoDragElements = (targetElement: HTMLElement ): boolean = class DefaultMouseSensor extends MouseSensor { static activators = [{ eventName: 'onMouseDown', - handler: ({ nativeEvent: event }: MouseEvent) => preventDraggingInNoDragElements(event.target as HTMLElement) + handler: ({ nativeEvent: event }: MouseEvent): boolean => { + if(event.button !== 0) { + // Only allow dragging with left mouse button + return false + } else { + return preventDraggingInNoDragElements(event.target as HTMLElement) + } + } }] satisfies typeof MouseSensor['activators']; } From a9df632d468b4fe42ef600c86a47690b1eccd047 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Fri, 23 Jan 2026 12:21:25 +0100 Subject: [PATCH 023/105] Adapt mapping list UI test --- .../MappingList/MappingsList.test.tsx | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/workspace/test/HierarchicalMapping/containers/MappingList/MappingsList.test.tsx b/workspace/test/HierarchicalMapping/containers/MappingList/MappingsList.test.tsx index 0c14a09492..5caeaebc32 100644 --- a/workspace/test/HierarchicalMapping/containers/MappingList/MappingsList.test.tsx +++ b/workspace/test/HierarchicalMapping/containers/MappingList/MappingsList.test.tsx @@ -1,9 +1,10 @@ - import React from "react"; +import React from "react"; import "@testing-library/jest-dom"; -import MappingsList from "../../../../src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList"; -import { findAllDOMElements, findElement, renderWrapper } from "../../../integration/TestHelper"; -import { RenderResult } from "@testing-library/react"; +import MappingsList + from "../../../../src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList"; +import {findAllDOMElements, renderWrapper} from "../../../integration/TestHelper"; +import {RenderResult} from "@testing-library/react"; const props = { rules: [ @@ -110,7 +111,7 @@ const getWrapper = (args: any = props): RenderResult => { return renderWrapper(); }; -const droppableSelector = `[data-rbd-droppable-id="droppable"]`; +const ruleItemSelector = ".ecc-silk-mapping__ruleitem" describe("MappingsList Component", () => { describe("on component mounted, ", () => { @@ -124,15 +125,11 @@ describe("MappingsList Component", () => { ...props, rules: [], }); - expect(wrapper.container.querySelector(droppableSelector)).not.toBeInTheDocument(); + expect(wrapper.container.querySelector(ruleItemSelector)).not.toBeInTheDocument(); }); - it("should render DragDropContext component, when rules is NOT empty", () => { - expect(findElement(wrapper, droppableSelector)).toBeInTheDocument(); - }); - - it("should render DraggableItem component, the right count", () => { - expect(findAllDOMElements(wrapper, `${droppableSelector} li`)).toHaveLength(2); + it("should render the right number of mapping rule items", () => { + expect(findAllDOMElements(wrapper, ruleItemSelector)).toHaveLength(2); }); it("should render ListActions component", () => { From 09370bb48ac5fa72ad066c0fecc99c57340dab70 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Wed, 28 Jan 2026 14:56:16 +0100 Subject: [PATCH 024/105] remove usage of deprecated Card components --- .../containers/MappingsList/EmptyList.tsx | 10 ++--- .../containers/MappingsList/MappingsList.tsx | 43 +++++++++++-------- .../style/legacyimports/_index.scss | 19 -------- 3 files changed, 30 insertions(+), 42 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/EmptyList.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/EmptyList.tsx index 5827d88c07..f647f482dd 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/EmptyList.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/EmptyList.tsx @@ -1,14 +1,12 @@ -import React from 'react'; -import { CardContent, Info } from 'gui-elements-deprecated'; +import React from "react"; +import { CardContent, Notification } from "@eccenca/gui-elements"; const EmptyList = () => { return ( - - No existing mapping rules. - + No existing mapping rules. - ) + ); }; export default EmptyList; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx index e1ffb15930..2bb489c414 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx @@ -1,18 +1,23 @@ -import React, {useEffect, useState} from "react"; -import {Card, CardTitle} from "gui-elements-deprecated"; -import {DndContext, KeyboardSensor, useSensor, useSensors} from "@dnd-kit/core"; -import {arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy} from "@dnd-kit/sortable"; -import {getApiDetails} from "../../store"; +import React, { useEffect, useState } from "react"; +import { Card, CardHeader, CardTitle, Divider } from "@eccenca/gui-elements"; +import { DndContext, KeyboardSensor, useSensor, useSensors } from "@dnd-kit/core"; +import { + arrayMove, + SortableContext, + sortableKeyboardCoordinates, + verticalListSortingStrategy, +} from "@dnd-kit/sortable"; +import { getApiDetails } from "../../store"; import DraggableItem from "../MappingRule/DraggableItem"; import rulesToList from "../../utils/rulesToList"; import ListActions from "./ListActions"; import EmptyList from "./EmptyList"; -import {Spinner} from "@eccenca/gui-elements"; +import { Spinner } from "@eccenca/gui-elements"; import silkRestApi from "../../../api/silkRestApi"; import useErrorHandler from "../../../../../../hooks/useErrorHandler"; -import {IViewActions} from "../../../../../../views/plugins/PluginRegistry"; +import { IViewActions } from "../../../../../../views/plugins/PluginRegistry"; import dndkitUtils from "../../../../../../utils/dndkitUtils"; -import {restrictToVerticalAxis} from "@dnd-kit/modifiers"; +import { restrictToVerticalAxis } from "@dnd-kit/modifiers"; interface MappingsListProps { rules: any[]; @@ -25,7 +30,7 @@ interface MappingsListProps { handleClone?: (id, type, parent) => any; onClickedRemove?: () => any; onShowSuggestions?: () => any; - onRuleIdChange?: (param: any) => any; + onRuleIdChange?: (param: any) => any; onAskDiscardChanges?: (param: any) => any; openMappingEditor: () => void; startFullScreen: boolean; @@ -63,7 +68,7 @@ const MappingsList = ({ useSensor(dndkitUtils.DefaultMouseSensor, dndkitUtils.defaultMouseSensorOptions), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates, - }) + }), ); useEffect(() => { @@ -102,8 +107,8 @@ const MappingsList = ({ return; } - const fromPos = items.findIndex(item => `draggable-${item.key}` === active.id); - const toPos = items.findIndex(item => `draggable-${item.key}` === over.id); + const fromPos = items.findIndex((item) => `draggable-${item.key}` === active.id); + const toPos = items.findIndex((item) => `draggable-${item.key}` === over.id); if (fromPos !== -1 && toPos !== -1) { handleOrderRules({ @@ -116,15 +121,19 @@ const MappingsList = ({ return (
    {reorderingRequestPending && } - - -
    Mapping rules {`(${rules.length})`}
    -
    + + + Mapping rules {`(${rules.length})`} + + {!rules.length ? ( ) : ( - `draggable-${item.key}`)} strategy={verticalListSortingStrategy}> + `draggable-${item.key}`)} + strategy={verticalListSortingStrategy} + >
      {items.map((item, index) => ( Date: Wed, 28 Jan 2026 16:09:33 +0100 Subject: [PATCH 025/105] replace deprecated alerts by Notification component --- .../HierarchicalMapping.scss | 7 +- .../components/ErrorView.tsx | 115 ++++++++++-------- .../components/MessageHandler.jsx | 83 ++++++------- .../style/legacyimports/_index.scss | 1 - 4 files changed, 101 insertions(+), 105 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss index 6b1e30b2be..74d7d3e748 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss @@ -1,6 +1,7 @@ @import "~@eccenca/gui-elements/src/includes/blueprintjs/variables"; @import "~@eccenca/gui-elements/src/includes/blueprintjs/requisits"; +// TODO: we need to check if this is still necessary .ecc-component-messagehandler { .ecc-temp__appmessages & { position: fixed; @@ -41,12 +42,6 @@ } } -ul.ecc-hierarchical-mapping-error-list { - margin-left: 0; - padding-left: 0; - list-style-type: none; -} - .ecc-silk-mapping__header { margin: $ecc-size-block-whitespace * 0.5 $ecc-size-block-whitespace; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ErrorView.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ErrorView.tsx index bd835b0544..07cae26a77 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ErrorView.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ErrorView.tsx @@ -1,13 +1,12 @@ -import React, {useState} from 'react'; +import React, { useState } from "react"; -import { Error } from 'gui-elements-deprecated'; -import _ from 'lodash'; -import {Spacing} from "@eccenca/gui-elements"; +import _ from "lodash"; +import { Spacing, Notification, IconButton, HtmlContentBlock } from "@eccenca/gui-elements"; export const ErrorCause = ({ errorCause }) => ( -
        +
          {_.map(errorCause, ({ title, detail, cause }) => { - let renderedCause: React.ReactElement | undefined = undefined + let renderedCause: React.ReactElement | undefined = undefined; if (_.isArray(cause)) { renderedCause = ; @@ -15,8 +14,12 @@ export const ErrorCause = ({ errorCause }) => ( return (
        • -

          {title}

          -

          {detail}

          + +

          + {title} +

          +

          {detail}

          +
          {renderedCause}
        • ); @@ -25,10 +28,12 @@ export const ErrorCause = ({ errorCause }) => ( ); export const ErrorIssue = ({ errorCause }) => ( -
            +
              {_.map(errorCause, ({ message }) => (
            • -

              {message}

              + +

              {message}

              +
            • ))}
            @@ -36,73 +41,75 @@ export const ErrorIssue = ({ errorCause }) => ( interface IProps { // Error title - title: string + title: string; // Error detail - detail: string + detail: string; // it may contain a list for errors with title and detail itself - cause?: any[] + cause?: any[]; // it may contain a list for errors with title and detail itself, too - issues?: any[] + issues?: any[]; // True if the problem is a HTTP request related problem - isHTTPProblem?: boolean + isHTTPProblem?: boolean; // The status code of the HTTP request if this is a HTTP error - status?: number + status?: number; // An title prefix - titlePrefix?: string + titlePrefix?: string; } /** A component to show error with expandable details. */ -export function ErrorView({title, detail, cause, issues, isHTTPProblem, status, titlePrefix = ""}: IProps) { - const [errorExpanded, setErrorExpanded] = useState(false) +export function ErrorView({ title, detail, cause, issues, isHTTPProblem, status, titlePrefix = "" }: IProps) { + const [errorExpanded, setErrorExpanded] = useState(false); const toggleExpansion = () => { - setErrorExpanded(prev => !prev) - } + setErrorExpanded((prev) => !prev); + }; - let shownTitle = titlePrefix + title + let shownTitle = titlePrefix + title; if (isHTTPProblem && !status) { - shownTitle = "There has been a connection problem." + shownTitle = "There has been a connection problem."; } - const errorClassName = errorExpanded - ? '' - : 'mdl-alert--narrowed'; - let causesHtml: React.ReactElement | undefined = undefined - let issuesHtml: React.ReactElement | undefined = undefined + let causesHtml: React.ReactElement | undefined = undefined; + let issuesHtml: React.ReactElement | undefined = undefined; if (errorExpanded && cause) { - if(_.isArray(cause)) { - causesHtml = ; - } else if(_.isObject(cause)) { - causesHtml = + if (_.isArray(cause)) { + causesHtml = ; + } else if (_.isObject(cause)) { + causesHtml = ; } } if (errorExpanded && _.isArray(issues)) { - issuesHtml = ; + issuesHtml = ; } - const detailHtml = title !== detail ? - <>

            {detail}

            - : undefined - - return - {shownTitle} - {detailHtml} - {causesHtml} - {issuesHtml} - - + const detailHtml = + title !== detail ? ( + <> + +

            {detail}

            + + ) : undefined; + + return ( + + } + > + {shownTitle} +
            + {detailHtml} + {causesHtml} + {issuesHtml} +
            + ); } export default ErrorView; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/MessageHandler.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/MessageHandler.jsx index 06e969a772..06ea93f67b 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/MessageHandler.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/MessageHandler.jsx @@ -1,61 +1,61 @@ // react -import React from 'react'; -import _ from 'lodash'; -import rxmq from 'ecc-messagebus'; - -import { Alert, Error, Info, Success, Warning } from 'gui-elements-deprecated'; - -const RENDER_CLASSES = { - alert: Alert, - error: Error, - info: Info, - success: Success, - warning: Warning, +import React from "react"; +import _ from "lodash"; +import rxmq from "ecc-messagebus"; + +import { Notification } from "@eccenca/gui-elements"; + +const RENDER_INTENT = { + alert: "neutral", + error: "danger", + info: "info", + success: "success", + warning: "warning", }; -const errorChannel = rxmq.channel('errors'); +const errorChannel = rxmq.channel("errors"); +// TODO: we need to check if we can re-write this to our new message queue class MessageHandler extends React.Component { state = { errorMessages: [], }; componentDidMount() { - // listen for graphs loading - errorChannel.subject('message').subscribe(data => this.onError('alert', data)); - errorChannel.subject('message.alert').subscribe(data => this.onError('alert', data)); - errorChannel.subject('message.error').subscribe(data => this.onError('error', data)); - errorChannel.subject('message.info').subscribe(data => this.onError('info', data)); - errorChannel.subject('message.success').subscribe(data => this.onError('success', data)); - errorChannel.subject('message.warning').subscribe(data => this.onError('warning', data)); + // listen for graphs loading + errorChannel.subject("message").subscribe((data) => this.onError("alert", data)); + errorChannel.subject("message.alert").subscribe((data) => this.onError("alert", data)); + errorChannel.subject("message.error").subscribe((data) => this.onError("error", data)); + errorChannel.subject("message.info").subscribe((data) => this.onError("info", data)); + errorChannel.subject("message.success").subscribe((data) => this.onError("success", data)); + errorChannel.subject("message.warning").subscribe((data) => this.onError("warning", data)); } - // handle graphs loaded + // handle graphs loaded onError = (errorType, data) => { - // get current messages + // get current messages const { errorMessages } = this.state; - const messageKey = _.uniqueId('messageHandler--message-'); + const messageKey = _.uniqueId("messageHandler--message-"); const result = { message: _.isString(data) ? data : data.message }; - if (data.response && data.response.type === 'application/json') { + if (data.response && data.response.type === "application/json") { try { const body = JSON.parse(data.response.text); result.message = body.message || result.message; - } catch (syntax) { - } + } catch (syntax) {} } - // assign errorType + // assign errorType result.errorType = errorType; result.key = messageKey; - // prevent doublettes (same type/same message) + // prevent doublettes (same type/same message) if (!_.some(errorMessages, { message: result.message, errorType })) { errorMessages.unshift(result); this.removeAfterDelay(errorType, messageKey); - // apply to state + // apply to state this.setState({ errorMessages, }); @@ -68,33 +68,28 @@ class MessageHandler extends React.Component { }, 3000); } - removeMessage = key => { - const errorMessages = _.reject(this.state.errorMessages, ['key', key]); - // apply to state + removeMessage = (key) => { + const errorMessages = _.reject(this.state.errorMessages, ["key", key]); + // apply to state this.setState({ errorMessages }); }; render() { const messages = this.state.errorMessages.map(({ message, errorType, key }, index) => { - const Class = RENDER_CLASSES[errorType]; - return ( - {message} - + ); }); - return (messages.length > 0) ? ( -
            - {messages} -
            - ) : false; + return messages.length > 0 ?
            {messages}
            : false; } } diff --git a/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss b/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss index 50a96bbc82..14582722fe 100644 --- a/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss +++ b/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss @@ -32,7 +32,6 @@ $font_root: "~gui-elements-deprecated/dist/fonts"; // -- Own MDL & GUI extensions ------------------------------------------------- -@import "~gui-elements-deprecated/src/elements/Alert/alert"; @import "~gui-elements-deprecated/src/elements/Button/button"; @import "~gui-elements-deprecated/src/elements/Breadcrumbs/breadcrumbs"; @import "~gui-elements-deprecated/src/elements/Checkbox/checkbox"; From f67ef82cf6dc36f1a094efaa4234de65968f9d61 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Wed, 28 Jan 2026 16:33:49 +0100 Subject: [PATCH 026/105] replace deprecated Icon component --- .../components/ThingIcon.jsx | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ThingIcon.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ThingIcon.jsx index fb725f7813..6e6f4673f3 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ThingIcon.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ThingIcon.jsx @@ -1,29 +1,32 @@ -import { MAPPING_RULE_TYPE_COMPLEX, MAPPING_RULE_TYPE_DIRECT, MAPPING_RULE_TYPE_OBJECT } from '../utils/constants'; -import { Icon } from 'gui-elements-deprecated'; -import React from 'react'; +import { MAPPING_RULE_TYPE_COMPLEX, MAPPING_RULE_TYPE_DIRECT, MAPPING_RULE_TYPE_OBJECT } from "../utils/constants"; +import { Icon, Spacing } from "@eccenca/gui-elements"; +import React from "react"; -export const ThingIcon = ({type, status, message}) => { - let iconName = 'help_outline'; - let tooltip = ''; +export const ThingIcon = ({ type, status, message }) => { + let iconName = "item-question"; + let tooltip = ""; switch (type) { case MAPPING_RULE_TYPE_DIRECT: case MAPPING_RULE_TYPE_COMPLEX: - tooltip = 'Value mapping'; - iconName = 'insert_drive_file'; + tooltip = "Value mapping"; + iconName = "artefact-file"; break; case MAPPING_RULE_TYPE_OBJECT: - tooltip = 'Object mapping'; - iconName = 'folder'; + tooltip = "Object mapping"; + iconName = "artefact-project"; break; default: - iconName = 'help_outline'; + iconName = "item-question"; } - + return ( - + <> + + + ); }; From fc8efccadfc61bc223ece308684840b17080603b Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Wed, 28 Jan 2026 17:40:31 +0100 Subject: [PATCH 027/105] replace FAB by button in sticky card header --- .../HierarchicalMapping.scss | 4 - .../containers/MappingsList/ListActions.tsx | 113 ++++++++---------- .../containers/MappingsList/MappingsList.tsx | 34 ++++-- 3 files changed, 75 insertions(+), 76 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss index 74d7d3e748..f018dce643 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss @@ -221,10 +221,6 @@ } .ecc-silk-mapping__ruleslist { - .ecc-floatingactionlist__wrapper--fixed { - z-index: 2; // TODO: need to be moved to gui elements - } - &:not(.ecc-silk-mapping__suggestionlist) { & .mdl-card__actions { background-color: transparent; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/ListActions.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/ListActions.tsx index 77d7ea2ac5..9331ad4e01 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/ListActions.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/ListActions.tsx @@ -1,75 +1,66 @@ -import React from 'react'; -import { FloatingActionList } from 'gui-elements-deprecated'; -import _ from 'lodash'; -import { MAPPING_RULE_TYPE_DIRECT, MAPPING_RULE_TYPE_OBJECT } from '../../utils/constants'; - -const openToBottomFn = () => { - // Calculates if the floating menu list should be opened to the top or bottom depending on the space to the top. - let toBottom = false; - try { - const floatButtonRect = document.querySelectorAll('.ecc-floatingactionlist button.mdl-button')[0].getBoundingClientRect(); - const navHeaderRect = document.querySelectorAll('.ecc-silk-mapping__navheader div.eccgui-card')[0].getBoundingClientRect(); - const availableSpace = floatButtonRect.top - navHeaderRect.bottom; - const spaceNeededForMenuList = 200; // This is not known before the menu list is rendered, so we assume at most 4 elements - toBottom = availableSpace < spaceNeededForMenuList; - } catch (error) {} - return toBottom; -}; +import React from "react"; +import { ContextMenu, MenuItem, Button } from "@eccenca/gui-elements"; +import _ from "lodash"; +import { MAPPING_RULE_TYPE_DIRECT, MAPPING_RULE_TYPE_OBJECT } from "../../utils/constants"; interface ListActionsProps { // Executes when one of the create mapping options are clicked. The type specifies the type of mapping. - onMappingCreate: (mappingSkeleton: { type: "direct" | "object" }) => any + onMappingCreate: (mappingSkeleton: { type: "direct" | "object" }) => any; // Executes when the 'Paste' option is clicked - onPaste: () => any + onPaste: () => any; // Executes when the 'Mapping suggestion' option is clicked - onShowSuggestions: () => any + onShowSuggestions: () => any; // true if the mapping rules list is still loading - listLoading: boolean + listLoading: boolean; } const ListActions = ({ onMappingCreate, onPaste, onShowSuggestions, listLoading }: ListActionsProps) => { return listLoading ? null : ( - { - onMappingCreate({ - type: MAPPING_RULE_TYPE_DIRECT, - }); - }, - }, - { - icon: 'folder', - label: 'Add object mapping', - handler: () => { - onMappingCreate({ - type: MAPPING_RULE_TYPE_OBJECT, - }); - }, - }, - (sessionStorage.getItem('copyingData') !== null) ? { - icon: 'folder', - label: 'Paste mapping', - handler: () => onPaste(), - } : [], - { - icon: 'lightbulb_outline', - label: 'Suggest mappings', - handler: e => { - e.stopPropagation(); - onShowSuggestions() - }, - }, + + } + > + { + onMappingCreate({ + type: MAPPING_RULE_TYPE_DIRECT, + }); + }} + /> + { + onMappingCreate({ + type: MAPPING_RULE_TYPE_OBJECT, + }); + }} + /> + {sessionStorage.getItem("copyingData") !== null ? ( + onPaste()} /> + ) : ( + <> )} - /> - ) + { + e.stopPropagation(); + onShowSuggestions(); + }} + /> + + ); }; export default ListActions; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx index 2bb489c414..fd29fc83a4 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx @@ -1,5 +1,13 @@ import React, { useEffect, useState } from "react"; -import { Card, CardHeader, CardTitle, Divider } from "@eccenca/gui-elements"; +import { + Card, + CardHeader, + CardOptions, + CardTitle, + Divider, + StickyTarget, + StickyTargetProps, +} from "@eccenca/gui-elements"; import { DndContext, KeyboardSensor, useSensor, useSensors } from "@dnd-kit/core"; import { arrayMove, @@ -122,10 +130,20 @@ const MappingsList = ({
            {reorderingRequestPending && } - - Mapping rules {`(${rules.length})`} - - + + + Mapping rules {`(${rules.length})`} + + + + + + {!rules.length ? ( ) : ( @@ -157,12 +175,6 @@ const MappingsList = ({ )} -
            ); From 101fe0f6c714a24924a93f4473af8b38dad0b07e Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Thu, 29 Jan 2026 17:34:17 +0100 Subject: [PATCH 028/105] forward gui elements, include new NotAvailable component --- libs/gui-elements | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/gui-elements b/libs/gui-elements index 47395f9c30..52bd09a1e2 160000 --- a/libs/gui-elements +++ b/libs/gui-elements @@ -1 +1 @@ -Subproject commit 47395f9c304e4013166b5e12dfd1098fb40f5dfb +Subproject commit 52bd09a1e2e52396511692bc6fb8e0b972742980 From 051779fa6e4ae9595050b51ba2d8ca1b89b2ab14 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Thu, 29 Jan 2026 17:34:56 +0100 Subject: [PATCH 029/105] replace deprecated NotAvailable component by new one --- .../ObjectMapping/ObjectUriPattern.tsx | 14 +++--- .../components/SourcePath.jsx | 12 ++--- .../components/ThingDescription.jsx | 17 +++---- .../components/URIInfo.jsx | 2 +- .../containers/RootMappingRule.jsx | 7 ++- .../elements/RuleTitle.jsx | 47 +++++++------------ .../elements/RuleTypes.tsx | 2 +- .../style/legacyimports/_index.scss | 1 - 8 files changed, 41 insertions(+), 61 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectUriPattern.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectUriPattern.tsx index 292e9fd44a..8fff5548f5 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectUriPattern.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectUriPattern.tsx @@ -1,24 +1,23 @@ import React from "react"; -import { NotAvailable } from "gui-elements-deprecated"; import { MAPPING_RULE_TYPE_COMPLEX_URI, MAPPING_RULE_TYPE_URI } from "../../utils/constants"; import getPathsRecursive from "../../utils/getUriPaths"; import getUriOperatorsRecursive from "../../utils/getUriOperators"; import ComplexDeleteButton from "../../elements/buttons/ComplexeDeleteButton"; -import { IconButton } from "@eccenca/gui-elements"; +import { IconButton, NotAvailable } from "@eccenca/gui-elements"; import { useGetRuleOperatorPlugins } from "../../../../../../hooks/useGetOperatorPlugins"; interface ObjectUriPatternProps { uriRule: any; onRemoveUriRule: () => void; openMappingEditor: () => void; - showLabel?: boolean + showLabel?: boolean; } const ObjectUriPattern = ({ uriRule, onRemoveUriRule, openMappingEditor, showLabel = true }: ObjectUriPatternProps) => { const { getPluginDetailLabel } = useGetRuleOperatorPlugins(); const { type, pattern } = uriRule; - let uriPattern = ; + let uriPattern = ; let uriPatternLabel = "URI pattern"; let tooltipText = "Create URI formula"; @@ -51,10 +50,9 @@ const ObjectUriPattern = ({ uriRule, onRemoveUriRule, openMappingEditor, showLab
            - {showLabel ? -
            {uriPatternLabel}
            : - null - } + {showLabel ? ( +
            {uriPatternLabel}
            + ) : null}
            {uriPattern} { - const path = _.get(rule, 'sourcePath', ); - return {_.isArray(path) ? path.join(', ') : path}; +export const SourcePath = ({ rule }) => { + const path = _.get(rule, "sourcePath", ); + return {_.isArray(path) ? path.join(", ") : path}; }; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ThingDescription.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ThingDescription.jsx index 1f93776561..94c607fe0d 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ThingDescription.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ThingDescription.jsx @@ -1,13 +1,8 @@ -import { NotAvailable } from 'gui-elements-deprecated'; -import { URIInfo } from './URIInfo'; -import React from 'react'; +import { NotAvailable } from "@eccenca/gui-elements"; +import { URIInfo } from "./URIInfo"; +import React from "react"; -export const ThingDescription = ({id}) => { - const fallbackInfo = ( - - ); - return ; +export const ThingDescription = ({ id }) => { + const fallbackInfo = ; + return ; }; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/URIInfo.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/URIInfo.jsx index a8ef55d72d..31232280a3 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/URIInfo.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/URIInfo.jsx @@ -1,7 +1,7 @@ import React from "react"; import _ from "lodash"; import { getApiDetails, getVocabInfoAsync } from "../store"; -import { NotAvailable } from "gui-elements-deprecated"; +import { NotAvailable } from "@eccenca/gui-elements"; export class URIInfo extends React.Component { state = { diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/RootMappingRule.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/RootMappingRule.jsx index fb2899d7de..a2d13fa7a1 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/RootMappingRule.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/RootMappingRule.jsx @@ -1,8 +1,7 @@ import React from "react"; import _ from "lodash"; import className from "classnames"; -import { NotAvailable } from "gui-elements-deprecated"; -import { Card, CardHeader, CardTitle, CardOptions, Divider } from "@eccenca/gui-elements"; +import { Card, CardHeader, CardTitle, CardOptions, Divider, NotAvailable } from "@eccenca/gui-elements"; import { ThingIcon } from "../components/ThingIcon"; import RuleTitle from "../elements/RuleTitle"; import RuleTypes from "../elements/RuleTypes"; @@ -101,7 +100,7 @@ class RootMappingRule extends React.Component { { expanded: !this.state.expanded, }, - this.updateQueryOnExpansion + this.updateQueryOnExpansion, ); } } @@ -119,7 +118,7 @@ class RootMappingRule extends React.Component { const breadcrumbs = _.get(this.props, "rule.breadcrumbs", []); const parent = _.last(breadcrumbs); - let uriPattern = ; + let uriPattern = ; const uriRuleType = _.get(this.props.rule.rules, "uriRule.type", false); if (uriRuleType === MAPPING_RULE_TYPE_URI) { diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RuleTitle.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RuleTitle.jsx index 6d1dfb58d6..87679f648c 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RuleTitle.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RuleTitle.jsx @@ -1,17 +1,14 @@ -import React from 'react'; -import _ from 'lodash'; -import { NotAvailable } from 'gui-elements-deprecated'; -import { ThingName } from '../components/ThingName'; +import React from "react"; +import _ from "lodash"; +import { NotAvailable } from "@eccenca/gui-elements"; +import { ThingName } from "../components/ThingName"; -import { - MAPPING_RULE_TYPE_COMPLEX_URI, - MAPPING_RULE_TYPE_ROOT, MAPPING_RULE_TYPE_URI, -} from '../utils/constants'; -import { MAPPING_RULE_TYPE_COMPLEX, MAPPING_RULE_TYPE_DIRECT, MAPPING_RULE_TYPE_OBJECT } from '../utils/constants'; +import { MAPPING_RULE_TYPE_COMPLEX_URI, MAPPING_RULE_TYPE_ROOT, MAPPING_RULE_TYPE_URI } from "../utils/constants"; +import { MAPPING_RULE_TYPE_COMPLEX, MAPPING_RULE_TYPE_DIRECT, MAPPING_RULE_TYPE_OBJECT } from "../utils/constants"; const RuleTitle = ({ rule, ...otherProps }) => { let uri; - const label = _.get(rule, 'metadata.label', ''); + const label = _.get(rule, "metadata.label", ""); if (label) { return {label}; } @@ -20,25 +17,17 @@ const RuleTitle = ({ rule, ...otherProps }) => { } switch (rule.type) { - case MAPPING_RULE_TYPE_ROOT: - uri = _.get(rule, 'rules.typeRules[0].typeUri', false); - return uri ? ( - - ) : ( - Mapping - ); - case MAPPING_RULE_TYPE_DIRECT: - case MAPPING_RULE_TYPE_OBJECT: - case MAPPING_RULE_TYPE_COMPLEX: - uri = _.get(rule, 'mappingTarget.uri', false); - return uri ? ( - - ) : ( - - ); - case MAPPING_RULE_TYPE_URI: - case MAPPING_RULE_TYPE_COMPLEX_URI: - return uri + case MAPPING_RULE_TYPE_ROOT: + uri = _.get(rule, "rules.typeRules[0].typeUri", false); + return uri ? : Mapping; + case MAPPING_RULE_TYPE_DIRECT: + case MAPPING_RULE_TYPE_OBJECT: + case MAPPING_RULE_TYPE_COMPLEX: + uri = _.get(rule, "mappingTarget.uri", false); + return uri ? : ; + case MAPPING_RULE_TYPE_URI: + case MAPPING_RULE_TYPE_COMPLEX_URI: + return uri; default: } diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RuleTypes.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RuleTypes.tsx index f54a4e010a..1db7802cbe 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RuleTypes.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RuleTypes.tsx @@ -1,6 +1,6 @@ import React from "react"; import _ from "lodash"; -import { NotAvailable } from "gui-elements-deprecated"; +import { NotAvailable } from "@eccenca/gui-elements"; import { ThingName } from "../components/ThingName"; import { MAPPING_RULE_TYPE_ROOT } from "../utils/constants"; diff --git a/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss b/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss index 14582722fe..56a774b70d 100644 --- a/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss +++ b/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss @@ -38,7 +38,6 @@ $font_root: "~gui-elements-deprecated/dist/fonts"; @import "replace-chip"; @import "~gui-elements-deprecated/src/elements/ContextMenu/contextmenu"; @import "~gui-elements-deprecated/src/elements/Dialog/dialog"; -@import "~gui-elements-deprecated/src/elements/NotAvailable/notavailable"; @import "~gui-elements-deprecated/src/elements/Radio/radio"; @import "~gui-elements-deprecated/src/elements/Progressbar/progressbar"; @import "~gui-elements-deprecated/src/elements/SelectBox/selectbox"; From da69c830cb42cc7afe2d5eafe63e4fa3db8c5c08 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Mon, 2 Feb 2026 10:59:49 +0100 Subject: [PATCH 030/105] forward gui elements --- libs/gui-elements | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/gui-elements b/libs/gui-elements index 52bd09a1e2..b921c68529 160000 --- a/libs/gui-elements +++ b/libs/gui-elements @@ -1 +1 @@ -Subproject commit 52bd09a1e2e52396511692bc6fb8e0b972742980 +Subproject commit b921c68529c4dbd4242b1bc51b278eec7cf94ffa From 29c2fc5d7e12e829488a7eaf5ad2870d67b40f87 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Mon, 2 Feb 2026 11:00:38 +0100 Subject: [PATCH 031/105] replace usage of deprecated ConfirmationDialog component --- .../elements/RemoveMappingRuleDialog.jsx | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RemoveMappingRuleDialog.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RemoveMappingRuleDialog.jsx index d160e5fd29..f2051438ac 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RemoveMappingRuleDialog.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/elements/RemoveMappingRuleDialog.jsx @@ -1,33 +1,33 @@ import React from "react"; import PropTypes from "prop-types"; -import { ConfirmationDialog } from "gui-elements-deprecated"; import { MAPPING_RULE_TYPE_OBJECT } from "../utils/constants"; -import { Button } from "@eccenca/gui-elements"; +import { Button, SimpleDialog, HtmlContentBlock } from "@eccenca/gui-elements"; const RemoveMappingRuleDialog = ({ mappingType = "", handleConfirmRemove, handleCancelRemove, label }) => { return ( - Remove - - } - cancelButton={ + , - } + , + ]} > -

            - When you click REMOVE the mapping rule{label ? ` '${label}'` : ""} - {mappingType === MAPPING_RULE_TYPE_OBJECT ? " including all child rules " : " "} - will be deleted permanently. -

            -
            + +

            + Remove the mapping rule{label ? ` "${label}"` : ""} + {mappingType === MAPPING_RULE_TYPE_OBJECT ? " including all child rules " : " "} + permanently? +

            +
            + ); }; From f4da4dc31e46d44591ac8aa9f609c92684a43bf1 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Mon, 2 Feb 2026 13:46:17 +0100 Subject: [PATCH 032/105] replace ScrollingHOC from deprecated GUI elements by minimal replication --- .../containers/MappingRule/DraggableItem.jsx | 55 +++++++++---------- .../MappingRule/ObjectRule/ObjectRuleForm.tsx | 2 +- .../MappingRule/ValueRule/ValueRuleForm.tsx | 4 +- .../HierarchicalMapping/utils/ScrollingHOC.js | 50 +++++++++++++++++ 4 files changed, 80 insertions(+), 31 deletions(-) create mode 100644 workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/utils/ScrollingHOC.js diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/DraggableItem.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/DraggableItem.jsx index 9349a3ba29..82aa95c1b5 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/DraggableItem.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/DraggableItem.jsx @@ -2,7 +2,7 @@ import React, { useState, useEffect, useRef, useCallback } from "react"; import { useSortable } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; import { MappingRule } from "./MappingRule"; -import { ScrollingHOC } from "gui-elements-deprecated"; +import { ScrollingHOC } from "../../utils/ScrollingHOC"; import { URI } from "ecc-utils"; import { MAPPING_RULE_TYPE_OBJECT } from "../../utils/constants"; @@ -25,14 +25,7 @@ const DraggableItem = (props) => { const [isPastedState, setIsPastedState] = useState(isPasted(props.id)); const [expanded, setExpanded] = useState(isExpanded(props.id) || isPasted(props.id)); - const { - attributes, - listeners, - setNodeRef, - transform, - transition, - isDragging, - } = useSortable({ + const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: `draggable-${props.id}`, disabled: expanded, }); @@ -55,14 +48,17 @@ const DraggableItem = (props) => { } }, []); // Only run on mount - const updateHistory = useCallback((ruleId) => { - if (!props.startFullScreen) { - const history = getHistory(); - history.replace({ - search: `?${new URLSearchParams({ ruleId })}`, - }); - } - }, [props.startFullScreen]); + const updateHistory = useCallback( + (ruleId) => { + if (!props.startFullScreen) { + const history = getHistory(); + history.replace({ + search: `?${new URLSearchParams({ ruleId })}`, + }); + } + }, + [props.startFullScreen], + ); const updateQueryOnExpansion = useCallback(() => { if (expanded) { @@ -73,16 +69,19 @@ const DraggableItem = (props) => { } }, [expanded, props.id, props.parentRuleId, props.scrollIntoView, updateHistory]); - const handleExpand = useCallback((newExpanded = !expanded, id = true) => { - // only trigger state / render change if necessary - if ( - newExpanded !== expanded && - props.type !== MAPPING_RULE_TYPE_OBJECT && - (id === true || id === props.id) - ) { - setExpanded(newExpanded); - } - }, [expanded, props.type, props.id]); + const handleExpand = useCallback( + (newExpanded = !expanded, id = true) => { + // only trigger state / render change if necessary + if ( + newExpanded !== expanded && + props.type !== MAPPING_RULE_TYPE_OBJECT && + (id === true || id === props.id) + ) { + setExpanded(newExpanded); + } + }, + [expanded, props.type, props.id], + ); // Call updateQueryOnExpansion when expanded changes useEffect(() => { @@ -118,6 +117,6 @@ const DraggableItem = (props) => { {...props} /> ); -} +}; export default ScrollingHOC(DraggableItem); diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx index 2d38400bc1..e4f8ddf3b7 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from "react"; -import { ScrollingHOC } from "gui-elements-deprecated"; +import { ScrollingHOC } from "../../../utils/ScrollingHOC"; import { Button, CodeAutocompleteField, diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ValueRule/ValueRuleForm.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ValueRule/ValueRuleForm.tsx index a2d57f974b..11c6fe638c 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ValueRule/ValueRuleForm.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ValueRule/ValueRuleForm.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from "react"; -import { ScrollingHOC } from "gui-elements-deprecated"; +import { ScrollingHOC } from "../../../utils/ScrollingHOC"; import { debounce } from "lodash"; import { Card, @@ -458,7 +458,7 @@ export function ValueRuleForm(props: IProps) { checkInput={checkValuePathValidity} onInputChecked={setValuePathValid} onFocusChange={changeValuePathInputHasFocus} - rightElement={} + rightElement={} /> ); } else if (type === MAPPING_RULE_TYPE_COMPLEX) { diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/utils/ScrollingHOC.js b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/utils/ScrollingHOC.js new file mode 100644 index 0000000000..32a9be1e84 --- /dev/null +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/utils/ScrollingHOC.js @@ -0,0 +1,50 @@ +import React from "react"; +import ReactDOM from "react-dom"; +import _ from "lodash"; + +// minimal replication of the original `ScrollingHOC` component from the deprecated GUI elements +export function ScrollingHOC(WrappedComponent) { + return class extends React.Component { + constructor(props) { + super(props); + this.scrollIntoView = this.scrollIntoView.bind(this); + } + + scrollIntoView(options = {}) { + this.scrollElementIntoView(ReactDOM.findDOMNode(this), options); + + /* + options { + topOffset: 0, // (optional) integer, pixels to offset top alignment + } + */ + } + + scrollElementIntoView(element, options = {}) { + let domElement = false; + if (_.isElement(element)) { + // is already a DOM element + domElement = element; + } else if (_.get(element, "props", false) !== false) { + // await a mounted react element or component + domElement = ReactDOM.findDOMNode(element); + } + + if (!domElement) { + return false; + } + + return domElement.scrollIntoView({ + behavior: "smooth", + block: "nearest", + container: "all", + }); + } + + render() { + return ; + } + }; +} + +export default ScrollingHOC; From f8cf60bca4d236b9c37178065353b9a21e676346 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Mon, 2 Feb 2026 15:16:38 +0100 Subject: [PATCH 033/105] replace deprecated Radio/Groups --- .../ObjectMapping/ObjectEntityRelation.jsx | 31 +++++++------------ .../components/TargetCardinality.jsx | 25 ++++++++------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectEntityRelation.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectEntityRelation.jsx index 95f84c693d..4d9d70b2a0 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectEntityRelation.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectEntityRelation.jsx @@ -1,41 +1,34 @@ -import React from 'react'; -import { - Radio, - RadioGroup, -} from 'gui-elements-deprecated'; -import { ParentElement } from '../ParentElement'; +import React from "react"; +import { RadioButton, FieldItem } from "@eccenca/gui-elements"; +import { ParentElement } from "../ParentElement"; const ObjectEntityRelation = ({ isBackwardProperty, parent }) => { return ( - - + - Connect from{' '} - + Connect from
            } /> - - Connect to{' '} - + Connect to
            } /> - - ) + + ); }; export default ObjectEntityRelation; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetCardinality.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetCardinality.jsx index 2774dda1f0..c29c096480 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetCardinality.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetCardinality.jsx @@ -1,5 +1,4 @@ import React from "react"; -import { RadioGroup } from "gui-elements-deprecated"; import * as PropTypes from "prop-types"; import { FieldItem, RadioButton, Tooltip } from "@eccenca/gui-elements"; @@ -30,16 +29,20 @@ class TargetCardinality extends React.Component { renderRadioBox() { return ( - { - this.onChange(value === "single"); - }} - > - - - + this.onChange(true)} + checked={this.state.isAttribute} + /> + this.onChange(false)} + checked={!this.state.isAttribute} + /> ); } From 32ab0a7570272e4f8f63aeb3f23e50e8368f2c54 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Mon, 2 Feb 2026 15:54:46 +0100 Subject: [PATCH 034/105] remove all deprecated style imports that are not necessary anymore --- .../style/legacyimports/_index.scss | 31 +----------- .../style/legacyimports/_replace-chip.scss | 49 ------------------- 2 files changed, 1 insertion(+), 79 deletions(-) delete mode 100644 workspace/src/app/views/pages/MappingEditor/style/legacyimports/_replace-chip.scss diff --git a/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss b/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss index 56a774b70d..0ac5c393e6 100644 --- a/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss +++ b/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss @@ -10,49 +10,20 @@ $font_root: "~gui-elements-deprecated/dist/fonts"; // -- Eccenca Material Design Lite ----------------------------------------------------- -// Resets and dependencies -@import "~@eccenca/material-design-lite/src/resets/resets"; - // Components -@import "~@eccenca/material-design-lite/src/badge/badge"; @import "~@eccenca/material-design-lite/src/button/button"; -@import "~@eccenca/material-design-lite/src/checkbox/checkbox"; -@import "~@eccenca/material-design-lite/src/chip/chip"; -@import "~@eccenca/material-design-lite/src/list/list"; -@import "~@eccenca/material-design-lite/src/menu/menu"; -@import "~@eccenca/material-design-lite/src/progress/progress"; -@import "~@eccenca/material-design-lite/src/layout/layout"; // only necessary for legacy includes via iframe -@import "~@eccenca/material-design-lite/src/radio/radio"; -@import "~@eccenca/material-design-lite/src/spinner/spinner"; -@import "~@eccenca/material-design-lite/src/switch/switch"; @import "~@eccenca/material-design-lite/src/textfield/textfield"; @import "~@eccenca/material-design-lite/src/tooltip/tooltip"; -@import "~@eccenca/material-design-lite/src/shadow/shadow"; -@import "~@eccenca/material-design-lite/src/grid/grid"; // only necessary for legacy includes via iframe // -- Own MDL & GUI extensions ------------------------------------------------- @import "~gui-elements-deprecated/src/elements/Button/button"; -@import "~gui-elements-deprecated/src/elements/Breadcrumbs/breadcrumbs"; -@import "~gui-elements-deprecated/src/elements/Checkbox/checkbox"; -@import "replace-chip"; -@import "~gui-elements-deprecated/src/elements/ContextMenu/contextmenu"; -@import "~gui-elements-deprecated/src/elements/Dialog/dialog"; -@import "~gui-elements-deprecated/src/elements/Radio/radio"; -@import "~gui-elements-deprecated/src/elements/Progressbar/progressbar"; +@import "~gui-elements-deprecated/src/elements/TextField/textfield"; @import "~gui-elements-deprecated/src/elements/SelectBox/selectbox"; @import "~gui-elements-deprecated/src/elements/AutoCompleteBox/autocomplete"; -@import "~gui-elements-deprecated/src/elements/Spinner/spinner"; -@import "~gui-elements-deprecated/src/elements/Table/table"; -@import "~gui-elements-deprecated/src/elements/TextField/textfield"; -@import "~gui-elements-deprecated/src/elements/Tooltip/tooltip"; // -- Changes ------------------------------------------------------------------ -@import "~gui-elements-deprecated/src/scss/adjustments"; -@import "~gui-elements-deprecated/src/scss/patches"; - // -- Fonts -------------------------------------------------------------------- -@import "~gui-elements-deprecated/src/scss/roboto"; @import "~gui-elements-deprecated/src/scss/iconfont"; diff --git a/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_replace-chip.scss b/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_replace-chip.scss deleted file mode 100644 index a309fcfa5f..0000000000 --- a/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_replace-chip.scss +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright 2017 eccenca GmbH. All Rights Reserved. - * - * @author Michael Haschke - */ - -.mdl-chip { - margin-right: $chips-margin-vertical; - font-weight: inherit; - max-width: calc(100% - #{$chips-margin-vertical}); -} - -.mdl-chip__text { - max-width: 100%; - text-overflow: ellipsis; - overflow: hidden; - - .mdl-chip__contact + & { - max-width: calc(101% - #{$chip-height} - #{$chips-margin-vertical}); - } -} - -.mdl-chip__contact { - background-color: $chip-bg-color; - margin-right: $chips-margin-vertical; - - .material-icons { - line-height: $chip-height; - width: $chip-height; - height: $chip-height; - } - - img { - height: auto; - width: auto; - max-height: 100%; - max-width: 100%; - vertical-align: middle; - } -} - -a.mdl-chip, -button.mdl-chip { - cursor: pointer; - - &:hover { - @extend .mdl-chip, :focus; - } -} From 3a7c25b6d5604a75a6eaa899716cc0b865c4b4bd Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Mon, 2 Feb 2026 17:45:51 +0100 Subject: [PATCH 035/105] remove almost all mdl styles and replace elements that were based on them --- .../HierarchicalMapping.scss | 194 +----------------- .../components/ThingIcon.jsx | 1 + .../containers/MappingRule/MappingRule.jsx | 14 +- .../containers/MappingRule/MappingRuleRow.jsx | 101 ++++----- .../containers/MappingsList/MappingsList.tsx | 2 +- .../containers/RootMappingRule.jsx | 45 ++-- .../MappingEditor/style/_workbench-rules.scss | 20 -- .../pages/MappingEditor/style/style.scss | 1 - 8 files changed, 101 insertions(+), 277 deletions(-) delete mode 100644 workspace/src/app/views/pages/MappingEditor/style/_workbench-rules.scss diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss index f018dce643..9e1f676111 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss @@ -22,26 +22,6 @@ // box-sizing: inherit; } -.ecc-silk-mapping { - .mdl-alert--narrowed { - .mdl-alert__content > *:not(:first-child) { - display: none; - } - - .mdl-alert__content, - .mdl-alert__content > * { - max-height: 5em; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - } - - .mdl-textfield__label { - pointer-events: none; - } -} - .ecc-silk-mapping__header { margin: $ecc-size-block-whitespace * 0.5 $ecc-size-block-whitespace; @@ -175,20 +155,6 @@ margin: $ecc-size-block-whitespace * 0.5; box-sizing: border-box; - .mdl-card__title { - z-index: auto; // TODO: only if sticky, need to be moved to gui elements - background-color: $card-background-color; // TODO: 90% like action row, need to be moved to gui elements - } - - .mdl-card__title-back { - align-self: flex-start; - } - - .mdl-card__title-text { - align-self: center; - display: flex; - } - .ecc-breadcrumbs__button { padding-top: 0; padding-bottom: 0; @@ -209,45 +175,6 @@ .ecc-silk-mapping__rulesobject { position: relative; margin-bottom: $ecc-size-block-whitespace; - - .mdl-card__title { - display: block; - padding: 0; - } - - .mdl-card__actions { - border-bottom: 1px solid to_color($card-border-color); - } -} - -.ecc-silk-mapping__ruleslist { - &:not(.ecc-silk-mapping__suggestionlist) { - & .mdl-card__actions { - background-color: transparent; - } - } - - .mdl-list { - margin: 0; - padding: 0; - - & > li:nth-child(odd):not(.ecc-silk-mapping__ruleitem--defect) { - background-color: rgba(to_color($data-table-hover-color), 0.12); - } - - .mdl-card, - .mdl-data-table { - background-color: transparent; - } - } - - &.ecc-silk-mapping__suggestionlist { - .mdl-list { - & > li:first-child { - background-color: transparent; - } - } - } } .ecc-silk-mapping__suggestionlist__target-dropdown { @@ -272,30 +199,12 @@ &:last-child { border-bottom: none; } - - .mdl-list__item { - color: inherit; - } - - .mdl-list__item-primary-content { - display: block; - min-width: 0; - } } .ecc-silk-mapping__ruleitem--dnd { outline: none; } -.mdl-list__item-secondary-content { - .ecc-silk-mapping__ruleitem--literal &, - .ecc-silk-mapping__ruleitem--object & { - align-self: stretch; - justify-content: center; - align-items: center; - } -} - .ecc-silk-mapping__ruleitem--defect { color: to_color($ecc-color-warning-text); background-color: to_color($ecc-color-warning-background); @@ -303,20 +212,9 @@ } .ecc-silk-mapping__ruleitem-headline { - @include typo-body-1(); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; font-weight: 500; } -.ecc-silk-mapping__ruleitem-subline { - @include typo-caption(); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - .ecc-silk-mapping__ruleitem-extraline { display: block; margin-right: $ecc-size-blockelement-margin-horizontal; @@ -352,38 +250,18 @@ } .ecc-silk-mapping__ruleitem-summary { - @include material-animation-default(0.28s); - transition-property: background-color; - &:hover { background-color: $data-table-hover-color; } &.ecc-silk-mapping__ruleitem-summary--expanded { background-color: transparent; - - .mdl-list__item-primary-content { - opacity: 0.39; - } - } - - .mdl-list__item { - padding: $ecc-size-block-whitespace * 0.5; - overflow: visible; } - /* - // probably not necessary anymore, just comment it out for the moment - .Select-input, - .Select-control { - height: calc(48px - #{2 * $ecc-size-block-whitespace}); + .#{eccgui}-overviewitem__item.#{eccgui}-overviewitem__item--hasspacing { + padding-left: $ecc-size-block-whitespace; } - .Select-placeholder, .Select--single > .Select-control .Select-value { - line-height: calc(48px - #{2 * $ecc-size-block-whitespace}); - } - */ - .Select.is-disabled .Select-value { opacity: 0.61; } @@ -398,57 +276,10 @@ &:hover { background-color: transparent; } - - .ecc-silk-mapping__ruleitem-headline, - .ecc-silk-mapping__ruleitem-subline, - .ecc-silk-mapping__suggestitem-typeselect { - @include typo-body-1(); - font-size: $data-table-header-font-size; - color: $data-table-header-color; - } } - @media (min-width: $grid-desktop-breakpoint) { - .mdl-list__item-primary-content { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - align-items: baseline; - } - - .ecc-silk-mapping__ruleitem-headline, - .ecc-silk-mapping__ruleitem-subline, - .ecc-silk-mapping__suggestitem-typeselect { - font-size: $data-table-font-size; - flex-grow: 1; - flex-shrink: 0; - box-sizing: border-box; - padding: $ecc-size-inline-whitespace * 0.5; - max-width: 33%; - margin-right: 0.333%; - } - .hide-in-table { - display: none; - } - - .ecc-silk-mapping__suggestitem-headline { - width: 40%; - max-width: 40%; - } - - .ecc-silk-mapping__suggestitem-subline { - width: 40%; - max-width: 40%; - } - .ecc-silk-mapping__suggestitem-checkbox { - align-self: center; - } - .ecc-silk-mapping__suggestitem-typeselect { - margin-top: -4px; - width: 20%; - max-width: 20%; - margin-right: 0; - } + .hide-in-table { + display: none; } } @@ -461,7 +292,7 @@ border: $data-table-dividers; background-color: to_color($color-white); - & + .mdl-list__item { + & + .#{eccgui}-overviewitem__item.#{eccgui}-overviewitem__item--hasspacing { padding-left: 2 * $eccgui-size-block-whitespace; } @@ -505,19 +336,6 @@ } } -.ecc-silk-mapping__rulesviewer, -.ecc-silk-mapping__ruleseditor { - .mdl-card__content { - padding-top: 0; - } -} - -.ecc-silk-mapping__rulesviewer__title { - .mdl-card__title-text { - @include typo-subhead(); - } -} - .ecc-silk-mapping__rulesviewer__attribute { margin: $ecc-size-block-whitespace * 0.5 0 $ecc-size-block-whitespace * 0.5 0; @@ -691,7 +509,7 @@ margin: 0 $ecc-size-block-whitespace * 0.5; } -.mdl-layout_item--background-flash { +.ecc-silk-mapping__ruleitem--new { animation-name: anim-new-element; animation-duration: 1s; animation-timing-function: cubic-bezier(0, 0, 0.2, 1); diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ThingIcon.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ThingIcon.jsx index 6e6f4673f3..38fe9b3611 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ThingIcon.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ThingIcon.jsx @@ -25,6 +25,7 @@ export const ThingIcon = ({ type, status, message }) => { className="ecc-silk-mapping__ruleitem-icon" name={status === "error" ? "warning" : iconName} tooltip={status === "error" ? `${tooltip} (${message})` : tooltip} + small /> diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRule.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRule.jsx index 0f411d0f36..45f1275a49 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRule.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRule.jsx @@ -14,7 +14,7 @@ import PropTypes from "prop-types"; import MappingRuleRow from "./MappingRuleRow"; import NavigateButton from "../../elements/buttons/NavigateButton"; import ExpandButton from "../../elements/buttons/ExpandButton"; -import { ContextMenu, MenuItem, Spinner } from "@eccenca/gui-elements"; +import { ContextMenu, MenuItem, Spinner, OverviewItem, OverviewItemActions } from "@eccenca/gui-elements"; import { getRuleLabel } from "../../utils/getRuleLabel"; export class MappingRule extends React.Component { @@ -237,7 +237,7 @@ export class MappingRule extends React.Component { "ecc-silk-mapping__ruleitem--object": type === "object", "ecc-silk-mapping__ruleitem--literal": type !== "object", "ecc-silk-mapping__ruleitem--defect": errorInfo, - "mdl-layout_item--background-flash": this.props.isPasted, + "ecc-silk-mapping__ruleitem--new": this.props.isPasted, })} >
            {reorderHandleButton} -
            isObjectRule(type) ? this.handleNavigate(this.props.id, this.props.parentId, ev) @@ -271,7 +271,7 @@ export class MappingRule extends React.Component { sourcePath={srcPath} type={type} /> -
            + {!isObjectRule(type) && ( )} -
            -
            + +
            {this.props.expanded ? (
            {expandedView}
            diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRuleRow.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRuleRow.jsx index 59b42e9b65..c92418ce11 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRuleRow.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRuleRow.jsx @@ -1,54 +1,63 @@ -import { ThingIcon } from '../../components/ThingIcon'; -import _ from 'lodash'; -import { SourcePath } from '../../components/SourcePath'; -import React from 'react'; -import RuleTypes from '../../elements/RuleTypes'; -import { getRuleLabel } from '../../utils/getRuleLabel'; +import { ThingIcon } from "../../components/ThingIcon"; +import _ from "lodash"; +import { SourcePath } from "../../components/SourcePath"; +import React from "react"; +import RuleTypes from "../../elements/RuleTypes"; +import { getRuleLabel } from "../../utils/getRuleLabel"; +import { OverviewItemDescription, OverviewItemLine, OverflowText } from "@eccenca/gui-elements"; class MappingRuleRow extends React.Component { render() { - const {mappingTarget, metadata, rules, sourcePath, type} = this.props; + const { mappingTarget, metadata, rules, sourcePath, type } = this.props; - const label = _.get(metadata, 'label', ''); - const ruleLabelData = getRuleLabel({label, uri: mappingTarget.uri}); - const statusType = _.get(this.props, 'status[0].type', false); - const statusMsg = _.get(this.props, 'status[0].message', false); + const label = _.get(metadata, "label", ""); + const ruleLabelData = getRuleLabel({ label, uri: mappingTarget.uri }); + const statusType = _.get(this.props, "status[0].type", false); + const statusMsg = _.get(this.props, "status[0].message", false); return ( -
            -
            - -
            - {ruleLabelData.displayLabel} -
            - {ruleLabelData.uri &&
            {ruleLabelData.uri}
            } -
            -
            - DataType:{' '} - -
            -
            - from{' '} - -
            -
            - ) + <> + + + + + {ruleLabelData.displayLabel} + + + {ruleLabelData.uri && ( + + {ruleLabelData.uri} + + )} + + + + + DataType:{" "} + + + + + + + + from{" "} + + + + + + ); } } diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx index fd29fc83a4..a6800439b9 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx @@ -152,7 +152,7 @@ const MappingsList = ({ items={items.map((item) => `draggable-${item.key}`)} strategy={verticalListSortingStrategy} > -
              +
                {items.map((item, index) => ( -
                -
                -
                + + + -
                - -
                + + + + + + + + + {uriPattern} -
                -
                -
                -
                + + +
    diff --git a/workspace/src/app/views/pages/MappingEditor/style/_workbench-rules.scss b/workspace/src/app/views/pages/MappingEditor/style/_workbench-rules.scss deleted file mode 100644 index 8986d565de..0000000000 --- a/workspace/src/app/views/pages/MappingEditor/style/_workbench-rules.scss +++ /dev/null @@ -1,20 +0,0 @@ -// Fixing problems with the rules learner pagination - -ul.navigation { - display: flex; - float: left; - margin: 0; - padding: 0; - list-style-type: none; - - .mdl-button { - &.mdl-button--pagination { - min-width: unset; - list-style-type: none; - } - - &.mdl-button--active { - background-color: $button-hover-color; - } - } -} diff --git a/workspace/src/app/views/pages/MappingEditor/style/style.scss b/workspace/src/app/views/pages/MappingEditor/style/style.scss index f65b0580fc..4d24a2a385 100644 --- a/workspace/src/app/views/pages/MappingEditor/style/style.scss +++ b/workspace/src/app/views/pages/MappingEditor/style/style.scss @@ -3,4 +3,3 @@ // include enhancements for silk mapping editor // moved some imports out to submodules because styles infer between different libraries @import "../HierarchicalMapping/HierarchicalMapping"; -@import "workbench-rules"; From d32c413fdfd4bc85dc6a911b2015ab5315aed2b2 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Tue, 3 Feb 2026 11:21:13 +0100 Subject: [PATCH 036/105] use Grid components instead of custom grid --- .../HierarchicalMapping.jsx | 17 ++++-- .../HierarchicalMapping.scss | 25 -------- .../containers/MappingsList/MappingsList.tsx | 2 +- .../containers/MappingsTreeLegacy.jsx | 57 ++++++++++++------ .../containers/MappingsWorkview.tsx | 59 +++++++++++-------- 5 files changed, 88 insertions(+), 72 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.jsx index 870a57f0dd..d5d4c4dcfc 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.jsx @@ -1,6 +1,6 @@ import React from "react"; import _ from "lodash"; -import { Spinner } from "@eccenca/gui-elements"; +import { Spinner, Grid, GridRow } from "@eccenca/gui-elements"; import PropTypes from "prop-types"; import { ruleRemoveAsync, setApiDetails } from "./store"; @@ -262,7 +262,14 @@ class HierarchicalMapping extends React.Component { transformTaskId: this.props.transformTask, }} > -
    + {showMappingEditor && this.state.mappingEditorRuleDefinition ? (
    -
    + -
    -
+ + ); } diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss index 9e1f676111..3539bddb85 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss @@ -30,25 +30,7 @@ } } -.ecc-silk-mapping__content { - display: flex; - flex-wrap: wrap; - align-items: stretch; -} - .ecc-silk-mapping__treenav { - flex-basis: calc(25% - #{$ecc-size-block-whitespace}); - min-width: 15em; - max-width: 100%; - height: 100%; - flex-shrink: 1; - flex-grow: 1; - position: sticky; - left: 0; - top: 0; - margin: $ecc-size-block-whitespace * 0.5; - box-sizing: border-box; - ul, li { list-style-type: none; @@ -148,13 +130,6 @@ } .ecc-silk-mapping__rules { - flex-basis: calc(75% - #{$ecc-size-block-whitespace}); - flex-grow: 4; - flex-shrink: 1; - min-width: 50%; - margin: $ecc-size-block-whitespace * 0.5; - box-sizing: border-box; - .ecc-breadcrumbs__button { padding-top: 0; padding-bottom: 0; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx index a6800439b9..a1b6b74759 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx @@ -130,7 +130,7 @@ const MappingsList = ({
{reorderingRequestPending && } - + Mapping rules {`(${rules.length})`} diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsTreeLegacy.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsTreeLegacy.jsx index 8884bb9d76..595611bf25 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsTreeLegacy.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsTreeLegacy.jsx @@ -1,7 +1,14 @@ import React from "react"; import PropTypes from "prop-types"; import _ from "lodash"; -import { InteractionGate, Notification, Icon, IconButton } from "@eccenca/gui-elements"; +import { + InteractionGate, + Notification, + Icon, + IconButton, + GridColumn, + WhiteSpaceContainer, +} from "@eccenca/gui-elements"; import RuleTypes from "../elements/RuleTypes"; import RuleTitle from "../elements/RuleTitle"; @@ -320,25 +327,39 @@ class MappingsTree extends React.Component { const NavigationList = this.navigationList(tree); return ( -
+ - {navigationLoading && _.isUndefined(data) && ( - - Loading rules - - )} - {!navigationLoading && _.isEmpty(data) && ( - - No rules found - - )} - {!_.isEmpty(data) && ( -
    -
  • {NavigationList}
  • -
- )} + + {navigationLoading && _.isUndefined(data) && ( + + Loading rules + + )} + {!navigationLoading && _.isEmpty(data) && ( + + No rules found + + )} + {!_.isEmpty(data) && ( +
    +
  • {NavigationList}
  • +
+ )} +
-
+ ); } } diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsWorkview.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsWorkview.tsx index 9abd9520cf..0885d4443d 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsWorkview.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsWorkview.tsx @@ -5,7 +5,7 @@ import React from "react"; import _ from "lodash"; import { copyRuleAsync, errorChannel, getApiDetails, getRuleAsync } from "../store"; -import { Spinner, Spacing, Notification, ClassNames } from "@eccenca/gui-elements"; +import { Spinner, Spacing, Notification, ClassNames, GridColumn, WhiteSpaceContainer } from "@eccenca/gui-elements"; import RootMappingRule from "./RootMappingRule"; import ObjectMappingRuleForm from "./MappingRule/ObjectRule/ObjectRuleForm"; import ValueMappingRuleForm from "./MappingRule/ValueRule/ValueRuleForm"; @@ -349,28 +349,41 @@ const MappingsWorkview = ({ ) : null; return ( -
- {loadingWidget} - - {listSuggestions ||
{listMappings}
} - {createRuleForm} - {error ? ( - <> - - - - ) : null} -
+ + + {loadingWidget} + + {listSuggestions ||
{listMappings}
} + {createRuleForm} + {error ? ( + <> + + + + ) : null} +
+
); }; From 10d6a5788c5389102ca1cd69f2ff021e9d758a5a Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Tue, 3 Feb 2026 11:31:47 +0100 Subject: [PATCH 037/105] remove unused css rules --- .../HierarchicalMapping.scss | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss index 3539bddb85..19c95768c2 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss @@ -22,14 +22,6 @@ // box-sizing: inherit; } -.ecc-silk-mapping__header { - margin: $ecc-size-block-whitespace * 0.5 $ecc-size-block-whitespace; - - &-action-row { - justify-content: flex-end; - } -} - .ecc-silk-mapping__treenav { ul, li { @@ -129,24 +121,6 @@ } } -.ecc-silk-mapping__rules { - .ecc-breadcrumbs__button { - padding-top: 0; - padding-bottom: 0; - } -} - -.ecc-silk-mapping__navheader { - position: sticky; - top: 0; - z-index: 10; - margin-bottom: $ecc-size-block-whitespace; -} - -.ecc-silk-mapping__navheader-row { - //overflow: visible; -} - .ecc-silk-mapping__rulesobject { position: relative; margin-bottom: $ecc-size-block-whitespace; @@ -496,10 +470,3 @@ color: $ecc-color-info-text; } } - -.ecc-silk-mapping__tree-label-wrapper { - cursor: pointer; - flex-grow: 1; - flex-shrink: 1; - padding: $ecc-size-block-whitespace * 0.25 $ecc-size-block-whitespace * 0.5; -} From aa94f9ea874f138420bed3382a543d387ad4af99 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Wed, 4 Feb 2026 15:02:07 +0100 Subject: [PATCH 038/105] replace custom elements by base components from gui elements --- libs/gui-elements | 2 +- .../HierarchicalMapping.scss | 115 ------------------ .../components/ExampleTarget.jsx | 26 ++-- .../components/InfoBox.jsx | 37 +++--- .../components/Metadata/MetadataDesc.jsx | 24 ++-- .../components/Metadata/MetadataLabel.jsx | 23 ++-- .../ObjectMapping/ObjectSourcePath.jsx | 20 +-- .../components/TargetProperty.jsx | 57 +++++---- .../components/TextToggler.tsx | 27 ++++ .../components/URIInfo.jsx | 5 +- .../components/ValueMapping/ValueNodeType.jsx | 25 ++-- .../ValueMapping/ValueSourcePaths.jsx | 27 ++-- .../containers/MappingRule/ExampleView.tsx | 9 +- .../MappingRule/ValueRule/ValueRule.jsx | 108 ++++++++++------ 14 files changed, 240 insertions(+), 265 deletions(-) create mode 100644 workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TextToggler.tsx diff --git a/libs/gui-elements b/libs/gui-elements index b921c68529..8764a22c29 160000 --- a/libs/gui-elements +++ b/libs/gui-elements @@ -1 +1 @@ -Subproject commit b921c68529c4dbd4242b1bc51b278eec7cf94ffa +Subproject commit 8764a22c290a5a9711e4c20ca7946c03d92798da diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss index 19c95768c2..6e1e5b00fb 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss @@ -285,127 +285,12 @@ } } -.ecc-silk-mapping__rulesviewer__attribute { - margin: $ecc-size-block-whitespace * 0.5 0 $ecc-size-block-whitespace * 0.5 0; - - dt, - dd { - margin: 0 0 $ecc-size-block-whitespace * 0.25 0; - padding: 0; - } - - code { - @include typo-caption(); - } - - .ecc-silk-mapping__rulesviewer__attribute-label { - @include typo-caption(); - font-weight: 700; - list-style-type: square; - list-style-position: inside; - } - - .ecc-silk-mapping__rulesviewer__attribute-info { - max-width: 100%; - overflow: visible; - font-weight: 300; - - p { - font-weight: 300; - margin-bottom: 0; - } - } -} - .ecc-silk-mapping__rulesviewer__sourcePath { code { word-wrap: break-word; } } -.ecc-silk-mapping__rulesviewer__infobox { - display: flex; - - &.is-narrowed { - .ecc-silk-mapping__rulesviewer__infobox-main, - .ecc-silk-mapping__rulesviewer__infobox-sub { - max-height: $typo-body-1-line-height * 1em; - overflow: hidden; - - * { - display: inline; - } - - & > * { - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - - &:not(:first-child) { - display: none; - } - } - } - - @media (min-width: $grid-desktop-breakpoint) { - .ecc-silk-mapping__rulesviewer__infobox-content { - display: flex; - flex-wrap: nowrap; - - .ecc-silk-mapping__rulesviewer__examples & { - display: block; - width: auto; - } - - & > div + div { - padding-left: 1rem; - box-sizing: border-box; - position: relative; - - &:before { - content: "•"; - width: $ecc-size-block-whitespace; - height: $typo-body-1-line-height * 1em; - position: absolute; - top: 0; - left: 0; - text-align: center; - vertical-align: middle; - } - } - } - - .ecc-silk-mapping__rulesviewer__infobox-main { - flex-grow: 0; - flex-shrink: 0; - max-width: 61%; - } - - .ecc-silk-mapping__rulesviewer__infobox-sub { - flex-grow: 1; - flex-shrink: 1; - } - } - } -} - -.ecc-silk-mapping__rulesviewer__infobox-toggler { - flex-grow: 0; - flex-shrink: 0; - margin: -0.5 * $ecc-size-block-whitespace 0 0 -1 * $ecc-size-block-whitespace; -} - -.ecc-silk-mapping__rulesviewer__infobox-content { - flex-grow: 1; - flex-shrink: 1; - width: 50vw; // this is a spooky hack but it prevents that the layout explodes - overflow: auto; - - .ecc-silk-mapping__rulesviewer__infobox-sub { - @include typo-caption(); - } -} - .ecc-silk-mapping__rulesviewer__examples-table { background-color: transparent !important; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ExampleTarget.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ExampleTarget.jsx index 2ee5624d6e..d8929f24be 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ExampleTarget.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ExampleTarget.jsx @@ -1,19 +1,21 @@ -import React from 'react'; -import ExampleView from '../containers/MappingRule/ExampleView'; +import React from "react"; +import { PropertyValuePair, PropertyValue, PropertyName, Label, Spacing } from "@eccenca/gui-elements"; +import ExampleView from "../containers/MappingRule/ExampleView"; -const ExampleTarget = ({uriRuleId}) => { +const ExampleTarget = ({ uriRuleId }) => { return (
-
-
- Examples of target data -
-
- -
-
+ + + + + + + +
- ) + ); }; export default ExampleTarget; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/InfoBox.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/InfoBox.jsx index 39cdbddea3..9006dd75a5 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/InfoBox.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/InfoBox.jsx @@ -1,12 +1,12 @@ -import React from 'react'; -import { IconButton } from "@eccenca/gui-elements" +import React from "react"; +import { IconButton, FlexibleLayoutContainer, FlexibleLayoutItem } from "@eccenca/gui-elements"; export class InfoBox extends React.Component { state = { expanded: false, }; - toggleExpander = event => { + toggleExpander = (event) => { event.stopPropagation(); this.setState({ expanded: !this.state.expanded, @@ -15,24 +15,23 @@ export class InfoBox extends React.Component { render() { return ( -
- -
+ + + + {this.props.children} -
-
+ + ); } } diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/Metadata/MetadataDesc.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/Metadata/MetadataDesc.jsx index 4b766e201b..281d6d0557 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/Metadata/MetadataDesc.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/Metadata/MetadataDesc.jsx @@ -1,13 +1,23 @@ import React from "react"; +import { PropertyValue, PropertyName, Label } from "@eccenca/gui-elements"; +import { TextToggler } from "../TextToggler"; -const MetadataDesc = ({ description }) => { +const MetadataDesc = ({ description, hasLabel }) => { return ( -
-
-
Mapping description
-
{description}
-
-
+ <> + {hasLabel ? ( + {description} + ) : ( + <> + + + + + + + )} + ); }; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/Metadata/MetadataLabel.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/Metadata/MetadataLabel.jsx index 770a73f573..e000eebcad 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/Metadata/MetadataLabel.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/Metadata/MetadataLabel.jsx @@ -1,13 +1,22 @@ import React from "react"; +import { PropertyValue, PropertyName, Label } from "@eccenca/gui-elements"; -const MetadataLabel = ({ label }) => { +const MetadataLabel = ({ label, hasDescription }) => { return ( -
-
-
Mapping label
-
{label}
-
-
+ <> + {hasDescription ? ( + + + ) : ( + <> + + + {label} + + )} + ); }; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectSourcePath.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectSourcePath.jsx index 2980945740..ed00504814 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectSourcePath.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectSourcePath.jsx @@ -1,18 +1,18 @@ -import React from 'react'; +import React from "react"; +import { PropertyValuePair, PropertyValue, PropertyName, Label, Spacing } from "@eccenca/gui-elements"; const ObjectSourcePath = ({ children }) => { return (
-
-
- Value path -
-
- {children} -
-
+ + + + {children} + +
- ) + ); }; export default ObjectSourcePath; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetProperty.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetProperty.jsx index 7b16959ed8..bde5bb3d72 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetProperty.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetProperty.jsx @@ -1,35 +1,40 @@ -import React from 'react'; -import { ThingName } from './ThingName'; -import { ThingDescription } from './ThingDescription'; -import { InfoBox } from './InfoBox'; +import React from "react"; +import { PropertyValuePair, PropertyValue, PropertyName, Label, Spacing } from "@eccenca/gui-elements"; +import { ThingName } from "./ThingName"; +import { ThingDescription } from "./ThingDescription"; import TargetCardinality from "./TargetCardinality"; +import { TextToggler } from "../components/TextToggler"; const TargetProperty = ({ mappingTargetUri, isObjectMapping, isAttribute = false }) => { return (
-
-
- Target property -
-
- -
- -
-
- - {mappingTargetUri} - -
-
- -
-
- -
-
+ + + + + {" "} + + {"<"} + {mappingTargetUri} + {">"} + {" "} + } /> + + +
- ) + ); }; export default TargetProperty; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TextToggler.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TextToggler.tsx new file mode 100644 index 0000000000..a2c966b721 --- /dev/null +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TextToggler.tsx @@ -0,0 +1,27 @@ +import React from "react"; +import { StringPreviewContentBlobToggler, InlineText, utils } from "@eccenca/gui-elements"; + +interface TextTogglerProps { + text: string | React.ReactNode; + toggleLength?: number; +} +export const TextToggler = ({ text, toggleLength = 64 }: TextTogglerProps) => { + console.log(text); + let previewText = typeof text === "string" ? text : utils.reduceToText(text); + React.useEffect(() => { + previewText = typeof text === "string" ? text : utils.reduceToText(text); + }, [text]); + + return ( + {text}} + previewMaxLength={toggleLength} + toggleExtendText={"more"} + toggleReduceText={"less"} + forceInline + /> + ); +}; + +export default TextToggler; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/URIInfo.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/URIInfo.jsx index 31232280a3..d2a7772587 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/URIInfo.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/URIInfo.jsx @@ -2,10 +2,11 @@ import React from "react"; import _ from "lodash"; import { getApiDetails, getVocabInfoAsync } from "../store"; import { NotAvailable } from "@eccenca/gui-elements"; +import { TextToggler } from "../components/TextToggler"; export class URIInfo extends React.Component { state = { - info: false, + info: "", }; componentDidMount() { @@ -36,7 +37,7 @@ export class URIInfo extends React.Component { const { info } = this.state; if (info) { - return {info}; + return ; } const { uri, fallback, field, ...otherProps } = this.props; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ValueMapping/ValueNodeType.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ValueMapping/ValueNodeType.jsx index 9554bef67d..e1d986b7f7 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ValueMapping/ValueNodeType.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ValueMapping/ValueNodeType.jsx @@ -1,5 +1,5 @@ import React from "react"; -import { InfoBox } from "../InfoBox"; +import { PropertyValuePair, PropertyValue, PropertyName, Label, Spacing } from "@eccenca/gui-elements"; import { PropertyTypeLabel } from "../Property/PropertyTypeLabel"; import { PropertyTypeDescription } from "../Property/PropertyTypeDescription"; @@ -17,19 +17,16 @@ const propertyTypeLabel = (valueType) => { const ValueNodeType = ({ valueType, nodeType }) => { return (
-
-
Data type
-
- -
- -
-
- -
-
-
-
+ + + + + + + + +
); }; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ValueMapping/ValueSourcePaths.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ValueMapping/ValueSourcePaths.jsx index 2716d2efec..15da9ad0c0 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ValueMapping/ValueSourcePaths.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ValueMapping/ValueSourcePaths.jsx @@ -1,4 +1,5 @@ import React from "react"; +import { PropertyValuePair, PropertyValue, PropertyName, Label, Spacing } from "@eccenca/gui-elements"; import getUriOperatorsRecursive from "../../utils/getUriOperators"; import { useGetRuleOperatorPlugins } from "../../../../../../hooks/useGetOperatorPlugins"; @@ -7,15 +8,23 @@ const ValueSourcePaths = ({ paths, operator, children }) => { const { getPluginDetailLabel } = useGetRuleOperatorPlugins(); return (
-
-
Value formula
-
- Formula uses {paths.length} value path{paths.length > 1 ? "s" : ""}:  - {paths.join(", ")} -  and {operators.length} operator function{operators.length > 1 ? "s" : ""}:  - {operators.map(getPluginDetailLabel).join(", ")}.{children} -
-
+ + + + + Formula uses {paths.length} value path{paths.length > 1 ? "s" : ""}:{" "} + + {"<"} + {paths.join(">, <")} + {">"} + +
+ and {operators.length} operator function{operators.length > 1 ? "s" : ""}:{" "} + {operators.map(getPluginDetailLabel).join(", ")}. +
+
+
); }; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ExampleView.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ExampleView.tsx index 8d7c4d0912..856f07f22e 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ExampleView.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ExampleView.tsx @@ -95,14 +95,7 @@ export const ExampleView = ({ id, rawRule, ruleType, objectSourcePathContext, up }, [id, objectSourcePathContext, ruleType, rawRule]); if (loading) { - return ( - - - - - - - ); + return ; } if (error) { diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ValueRule/ValueRule.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ValueRule/ValueRule.jsx index 8d2f31d6c0..b74f3d5434 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ValueRule/ValueRule.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ValueRule/ValueRule.jsx @@ -1,5 +1,16 @@ import React from "react"; -import { Card, CardActions, CardContent, Divider } from "@eccenca/gui-elements"; +import { + Card, + CardActions, + CardContent, + Divider, + PropertyValueList, + PropertyValuePair, + PropertyValue, + PropertyName, + Label, + Spacing, +} from "@eccenca/gui-elements"; import _ from "lodash"; import PropTypes from "prop-types"; import { getEditorHref } from "../../../store"; @@ -115,45 +126,72 @@ class ValueRule extends React.Component { if (mapRuleLoading) { return ; } + const metaLabel = _.get(metadata, "label"); + const metaDesc = _.get(metadata, "description"); return (
- {mappingTarget.uri ? ( - - ) : null} - {nodeType ? : null} - {this.props.type === MAPPING_RULE_TYPE_DIRECT && !sourcePaths ? ( - - {sourcePath ? sourcePath : ""} - + {(metaLabel || metaDesc) && ( + <> + + {metaLabel && metaDesc ? ( + <> + {_.get(metadata, "label") && ( + + )} + {_.get(metadata, "description") && ( + + )} + + ) : ( + <> + {_.get(metadata, "label") && } + {_.get(metadata, "description") && ( + + )} + + )} + + + + )} + {mappingTarget.uri ? ( + - - ) : null} - {this.props.type !== MAPPING_RULE_TYPE_DIRECT && sourcePaths ? ( - - - - ) : null} - {id ? : null} - {_.get(metadata, "label") ? : null} - {_.get(metadata, "description") ? ( - - ) : null} + ) : null} + {nodeType ? ( + + ) : null} + {this.props.type === MAPPING_RULE_TYPE_DIRECT && !sourcePaths ? ( + + {sourcePath ? sourcePath : ""} + + + ) : null} + {this.props.type !== MAPPING_RULE_TYPE_DIRECT && sourcePaths ? ( + + + + ) : null} + {id ? : null} + Date: Thu, 5 Feb 2026 09:54:52 +0100 Subject: [PATCH 039/105] use base components for object rule details --- .../components/Metadata/MetadataLabel.jsx | 2 +- .../ObjectMapping/ObjectEntityRelation.jsx | 39 ++++------- .../ObjectMapping/ObjectTypeRules.jsx | 59 +++++++--------- .../ObjectMapping/ObjectUriPattern.tsx | 43 ++++++++---- .../components/TargetProperty.jsx | 14 +--- .../ValueMapping/ValueSourcePaths.jsx | 7 +- .../MappingRule/ObjectRule/ObjectRule.jsx | 68 ++++++++++++------- .../elements/buttons/ComplexeDeleteButton.jsx | 2 + 8 files changed, 123 insertions(+), 111 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/Metadata/MetadataLabel.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/Metadata/MetadataLabel.jsx index e000eebcad..76126ae096 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/Metadata/MetadataLabel.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/Metadata/MetadataLabel.jsx @@ -13,7 +13,7 @@ const MetadataLabel = ({ label, hasDescription }) => { - {label} + {label} )} diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectEntityRelation.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectEntityRelation.jsx index 4d9d70b2a0..05b2427522 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectEntityRelation.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectEntityRelation.jsx @@ -1,33 +1,22 @@ import React from "react"; -import { RadioButton, FieldItem } from "@eccenca/gui-elements"; +import { Icon } from "@eccenca/gui-elements"; import { ParentElement } from "../ParentElement"; const ObjectEntityRelation = ({ isBackwardProperty, parent }) => { return ( - - - Connect from -
- } - /> - - Connect to -
- } - /> - +
+ {isBackwardProperty ? ( + <> + +   Connect to + + ) : ( + <> + +   Connect from + + )} +
); }; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectTypeRules.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectTypeRules.jsx index 95ba68654a..7f6d184de1 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectTypeRules.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectTypeRules.jsx @@ -1,45 +1,34 @@ -import React from 'react'; -import { ThingName } from '../ThingName'; -import { ThingDescription } from '../ThingDescription'; -import { InfoBox } from '../InfoBox'; +import React from "react"; +import { PropertyValuePair, PropertyValue, PropertyName, Label, Spacing } from "@eccenca/gui-elements"; +import { ThingName } from "../ThingName"; +import { ThingDescription } from "../ThingDescription"; +import { TextToggler } from "../TextToggler"; const ObjectTypeRules = ({ typeRules }) => { return (
-
-
- {typeRules.length > 1 - ? 'Target entity types' - : 'Target entity type'} -
+ + + {typeRules.map((typeRule, idx) => ( -
- -
- -
-
- - {typeRule.typeUri} - -
-
- -
-
-
+ + {" "} + + {"<"} + {typeRule.typeUri} + {">"} + {" "} + } /> + ))} -
+ +
- ) + ); }; export default ObjectTypeRules; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectUriPattern.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectUriPattern.tsx index 8fff5548f5..cba6866f22 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectUriPattern.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ObjectMapping/ObjectUriPattern.tsx @@ -1,4 +1,5 @@ import React from "react"; +import { PropertyValuePair, PropertyValue, PropertyName, Label, Spacing } from "@eccenca/gui-elements"; import { MAPPING_RULE_TYPE_COMPLEX_URI, MAPPING_RULE_TYPE_URI } from "../../utils/constants"; import getPathsRecursive from "../../utils/getUriPaths"; import getUriOperatorsRecursive from "../../utils/getUriOperators"; @@ -36,9 +37,9 @@ const ObjectUriPattern = ({ uriRule, onRemoveUriRule, openMappingEditor, showLab uriPattern = ( - URI uses {paths.length} value {paths.length > 1 ? "paths" : "path"}:  - {paths.join(", ")} and {operators.length}  operator{" "} - {operators.length > 1 ? "functions" : "function"}:  + URI uses {paths.length} value {paths.length > 1 ? "paths" : "path"}: {paths.join(", ")} +
+ and {operators.length}  operator {operators.length > 1 ? "functions" : "function"}:{" "} {operators.map(getPluginDetailLabel).join(", ")}.
); @@ -49,22 +50,34 @@ const ObjectUriPattern = ({ uriRule, onRemoveUriRule, openMappingEditor, showLab return (
-
+ {showLabel ? ( -
{uriPatternLabel}
+ + ) : null} -
+ {uriPattern} - - {removeButton} -
-
+ +
+
); }; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetProperty.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetProperty.jsx index bde5bb3d72..6c48ed6c9f 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetProperty.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetProperty.jsx @@ -8,19 +8,11 @@ import { TextToggler } from "../components/TextToggler"; const TargetProperty = ({ mappingTargetUri, isObjectMapping, isAttribute = false }) => { return (
+ + - {" "} diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ValueMapping/ValueSourcePaths.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ValueMapping/ValueSourcePaths.jsx index 15da9ad0c0..c25dd51744 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ValueMapping/ValueSourcePaths.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/ValueMapping/ValueSourcePaths.jsx @@ -10,7 +10,12 @@ const ValueSourcePaths = ({ paths, operator, children }) => {
- Formula uses {paths.length} value path{paths.length > 1 ? "s" : ""}:{" "} diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.jsx index 5df75469a8..53b622a1a3 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.jsx @@ -1,6 +1,6 @@ import React from "react"; import PropTypes from "prop-types"; -import { CardActions, CardContent, Divider } from "@eccenca/gui-elements"; +import { CardActions, CardContent, Divider, PropertyValuePair, Spacing } from "@eccenca/gui-elements"; import _ from "lodash"; import { getEditorHref, updateObjectMappingAsync } from "../../../store"; import ObjectMappingRuleForm from "./ObjectRuleForm"; @@ -173,36 +173,64 @@ class ObjectRule extends React.Component { ); } + const metaLabel = _.get(ruleData, "metadata.label"); + const metaDesc = _.get(ruleData, "metadata.description"); + // @FIXME type vs ruleType is it not same? return (
+ {(metaLabel || metaDesc) && ( + <> + + {metaLabel && metaDesc ? ( + <> + {_.get(metadata, "label") && ( + + )} + {_.get(metadata, "description") && ( + + )} + + ) : ( + <> + {_.get(metadata, "label") && } + {_.get(metadata, "description") && } + + )} + + + + )} {!isRootRule(type) ? ( [ + , , - , ] ) : ( - + <> + + )} - {_.get(ruleData, "rules.typeRules[0].typeUri") ? ( + + {_.get(ruleData, "rules.typeRules[0].typeUri") && ( - ) : null} - {isObjectRule(type) && ruleData.sourcePath ? ( + )} + {isObjectRule(type) && ruleData.sourcePath && ( - ) : null} + )} { } - {_.get(ruleData, "rules.uriRule.id") ? ( + {_.get(ruleData, "rules.uriRule.id") && ( - ) : null} - {_.get(ruleData, "metadata.label") ? ( - - ) : null} - {_.get(ruleData, "metadata.description") ? ( - - ) : null} + )} { className="ecc-silk-mapping__ruleseditor__actionrow-complex-delete" onClick={onDelete} text="Reset to default pattern" + small + disruptive /> ); }; From 3ad15d0cb9e217a4a3c440518b003a6118997b20 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Fri, 6 Feb 2026 15:31:39 +0100 Subject: [PATCH 040/105] Replace deprecated MultiAutoComplete component with MultiSuggestField --- libs/gui-elements | 2 +- .../components/MultiAutoComplete.tsx | 40 ---------------- .../TargetTypeMultiAutoComplete.tsx | 48 +++++++++++++++++++ .../MappingRule/ObjectRule/ObjectRuleForm.tsx | 14 +++--- 4 files changed, 55 insertions(+), 49 deletions(-) delete mode 100644 workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/MultiAutoComplete.tsx create mode 100644 workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetTypeMultiAutoComplete.tsx diff --git a/libs/gui-elements b/libs/gui-elements index 8764a22c29..60624bdd7b 160000 --- a/libs/gui-elements +++ b/libs/gui-elements @@ -1 +1 @@ -Subproject commit 8764a22c290a5a9711e4c20ca7946c03d92798da +Subproject commit 60624bdd7b00851e9946a2d13ea25cb9cf4ea462 diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/MultiAutoComplete.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/MultiAutoComplete.tsx deleted file mode 100644 index ad6aa50bdd..0000000000 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/MultiAutoComplete.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react'; -import { AutoCompleteBox } from 'gui-elements-deprecated'; -import { autocompleteAsync } from '../store'; - -const loadOptionsRaw = ({ - input, callback, ruleId, entity, taskContext - }) => { - autocompleteAsync({ - entity, - input, - ruleId, - taskContext - }).subscribe(({ options }) => { - callback(null, { - options, - complete: false, - }, ); - }); -}; - -/** Multi-selection auto-complete component */ -const MultiAutoComplete = ({ entity, ruleId, taskContext, ...otherProps }) => { - return ( - true} - async - multi - loadOptions={(input, callback) => loadOptionsRaw({ - input, - callback, - entity, - ruleId, - taskContext - })} - /> - ); -}; - -export default MultiAutoComplete; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetTypeMultiAutoComplete.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetTypeMultiAutoComplete.tsx new file mode 100644 index 0000000000..f625597ba3 --- /dev/null +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetTypeMultiAutoComplete.tsx @@ -0,0 +1,48 @@ +import React from 'react'; +import {MultiSuggestField, MultiSuggestFieldSelectionProps} from '@eccenca/gui-elements'; +import silkRestApi from "../../api/silkRestApi"; +import {GlobalMappingEditorContext} from "../../contexts/GlobalMappingEditorContext"; +import {TargetPropertyAutoCompletion} from "../../api/types"; +import {removeExtraSpaces} from '@eccenca/gui-elements/src/common/utils/stringUtils'; + +interface Props { + onChange: (changes: MultiSuggestFieldSelectionProps) => void + placeholder: string + className: string + isValidNewOption: (text: string) => boolean + value: (string | Omit)[] +} + +/** Multi-selection auto-complete component */ +const TargetTypeMultiAutoComplete = ({ placeholder, className, isValidNewOption, value, onChange }: Props) => { + const mappingEditorContext = React.useContext(GlobalMappingEditorContext); + const runOnQueryChange = React.useCallback((query: string) => { + return silkRestApi.targetClassAutoCompletions(mappingEditorContext.projectId, mappingEditorContext.transformTaskId, query, 50) + .the + }, [mappingEditorContext.projectId, mappingEditorContext.transformTaskId]) + return | string> + className={className} + prePopulateWithItems={!!value?.length} + openOnKeyDown + itemId={t => typeof t === "string" ? t : t.value} + itemLabel={t => typeof t === "string" ? t : (t.label ?? t.value)} + items={value} + onSelection={onChange} + runOnQueryChange={runOnQueryChange} + newItemCreationText={"Create option"} + inputProps={{ + placeholder: placeholder, + }} + tagInputProps={{ + placeholder: placeholder, + }} + isValidNewOption={isValidNewOption} + createNewItemFromQuery={query => ({ + value: removeExtraSpaces(query) + })} + requestDelay={200} + clearQueryOnSelection={true} // workaround that another Tab does not uncheck matches + /> +}; + +export default TargetTypeMultiAutoComplete; diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx index e4f8ddf3b7..459578a450 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx @@ -15,6 +15,7 @@ import { CardTitle, CardHeader, Divider, + MultiSuggestField } from "@eccenca/gui-elements"; import _ from "lodash"; import ExampleView from "../ExampleView"; @@ -36,7 +37,7 @@ import { trimValue } from "../../../utils/trimValue"; import { wasTouched } from "../../../utils/wasTouched"; import { newValueIsIRI } from "../../../utils/newValueIsIRI"; import TargetCardinality from "../../../components/TargetCardinality"; -import MultiAutoComplete from "../../../components/MultiAutoComplete"; +import TargetTypeMultiAutoComplete from "../../../components/TargetTypeMultiAutoComplete"; import silkApi from "../../../../api/silkRestApi"; import { IUriPattern } from "../../../../api/types"; import { UriPatternSelectionModal } from "./UriPatternSelectionModal"; @@ -45,6 +46,7 @@ import { defaultUriPattern } from "./ObjectRule.utils"; import { GlobalMappingEditorContext } from "../../../../contexts/GlobalMappingEditorContext"; import { EntityRelationshipSelection } from "../../../components/EntityRelationshipSelection"; import { MAPPING_ROOT_RULE_ID } from "../../../HierarchicalMapping"; +import {Keyword} from "@ducks/workspace/typings"; interface IProps { id?: string; @@ -510,18 +512,14 @@ export const ObjectRuleForm = (props: IProps) => { {errorMessage} {targetPropertyInput} {entityRelationInput} - newValueIsIRI({label: text})} value={modifiedValues().targetEntityType} - creatable onChange={(value) => { - handleChangeValue("targetEntityType", value); + handleChangeValue("targetEntityType", value.selectedItems); }} - taskContext={mappingEditorContext.taskContext} /> {targetCardinality} {sourcePropertyInput} From a510f93a7a3f845d5c2fa19b21841e4fac6199ae Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Mon, 9 Feb 2026 15:04:14 +0100 Subject: [PATCH 041/105] Remove old deprecated gui elements from dependencies --- workspace/package.json | 1 - .../MappingRule/ObjectRule/ObjectRuleForm.tsx | 44 +++++++++---------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/workspace/package.json b/workspace/package.json index 0c3ef8652f..380071336a 100644 --- a/workspace/package.json +++ b/workspace/package.json @@ -43,7 +43,6 @@ "dexie": "^3.2.3", "ecc-messagebus": "^3.6.0", "ecc-utils": "^1.4.0", - "gui-elements-deprecated": "npm:@eccenca/gui-elements@^5.1.1", "history": "^4.7.2", "i18next": "^25.1.3", "i18next-browser-languagedetector": "^8.1.0", diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx index 459578a450..84f9f45510 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRuleForm.tsx @@ -1,21 +1,20 @@ -import React, { useEffect, useState } from "react"; -import { ScrollingHOC } from "../../../utils/ScrollingHOC"; +import React, {useEffect, useState} from "react"; +import {ScrollingHOC} from "../../../utils/ScrollingHOC"; import { Button, + Card, + CardActions, + CardContent, + CardHeader, + CardTitle, CodeAutocompleteField, + Divider, FieldItem, Notification, Spacing, Spinner, TextArea, - TextField, - Card, - CardActions, - CardContent, - CardTitle, - CardHeader, - Divider, - MultiSuggestField + TextField } from "@eccenca/gui-elements"; import _ from "lodash"; import ExampleView from "../ExampleView"; @@ -28,25 +27,24 @@ import { updateVocabularyCacheEntry, useApiDetails, } from "../../../store"; -import { convertToUri } from "../../../utils/convertToUri"; +import {convertToUri} from "../../../utils/convertToUri"; import ErrorView from "../../../components/ErrorView"; import AutoComplete from "../../../components/AutoComplete"; -import { MAPPING_RULE_TYPE_ROOT, MAPPING_RULE_TYPE_URI, MESSAGES } from "../../../utils/constants"; +import {MAPPING_RULE_TYPE_ROOT, MAPPING_RULE_TYPE_URI, MESSAGES} from "../../../utils/constants"; import EventEmitter from "../../../utils/EventEmitter"; -import { trimValue } from "../../../utils/trimValue"; -import { wasTouched } from "../../../utils/wasTouched"; -import { newValueIsIRI } from "../../../utils/newValueIsIRI"; +import {trimValue} from "../../../utils/trimValue"; +import {wasTouched} from "../../../utils/wasTouched"; +import {newValueIsIRI} from "../../../utils/newValueIsIRI"; import TargetCardinality from "../../../components/TargetCardinality"; import TargetTypeMultiAutoComplete from "../../../components/TargetTypeMultiAutoComplete"; import silkApi from "../../../../api/silkRestApi"; -import { IUriPattern } from "../../../../api/types"; -import { UriPatternSelectionModal } from "./UriPatternSelectionModal"; -import { IViewActions } from "../../../../../../../views/plugins/PluginRegistry"; -import { defaultUriPattern } from "./ObjectRule.utils"; -import { GlobalMappingEditorContext } from "../../../../contexts/GlobalMappingEditorContext"; -import { EntityRelationshipSelection } from "../../../components/EntityRelationshipSelection"; -import { MAPPING_ROOT_RULE_ID } from "../../../HierarchicalMapping"; -import {Keyword} from "@ducks/workspace/typings"; +import {IUriPattern} from "../../../../api/types"; +import {UriPatternSelectionModal} from "./UriPatternSelectionModal"; +import {IViewActions} from "../../../../../../../views/plugins/PluginRegistry"; +import {defaultUriPattern} from "./ObjectRule.utils"; +import {GlobalMappingEditorContext} from "../../../../contexts/GlobalMappingEditorContext"; +import {EntityRelationshipSelection} from "../../../components/EntityRelationshipSelection"; +import {MAPPING_ROOT_RULE_ID} from "../../../HierarchicalMapping"; interface IProps { id?: string; From c579ac66258db228279954835d2c198d39f2c5e4 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Mon, 9 Feb 2026 13:33:25 +0100 Subject: [PATCH 042/105] move down label/description again --- .../MappingRule/ObjectRule/ObjectRule.jsx | 44 ++++++++--------- .../MappingRule/ValueRule/ValueRule.jsx | 48 +++++++++---------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.jsx index 53b622a1a3..bad87a3931 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/ObjectRule/ObjectRule.jsx @@ -181,28 +181,6 @@ class ObjectRule extends React.Component {
- {(metaLabel || metaDesc) && ( - <> - - {metaLabel && metaDesc ? ( - <> - {_.get(metadata, "label") && ( - - )} - {_.get(metadata, "description") && ( - - )} - - ) : ( - <> - {_.get(metadata, "label") && } - {_.get(metadata, "description") && } - - )} - - - - )} {!isRootRule(type) ? ( [ )} + {(metaLabel || metaDesc) && ( + <> + + {metaLabel && metaDesc ? ( + <> + {_.get(metadata, "label") && ( + + )} + {_.get(metadata, "description") && ( + + )} + + ) : ( + <> + {_.get(metadata, "label") && } + {_.get(metadata, "description") && } + + )} + + + + )} - {(metaLabel || metaDesc) && ( - <> - - {metaLabel && metaDesc ? ( - <> - {_.get(metadata, "label") && ( - - )} - {_.get(metadata, "description") && ( - - )} - - ) : ( - <> - {_.get(metadata, "label") && } - {_.get(metadata, "description") && ( - - )} - - )} - - - - )} {mappingTarget.uri ? ( ) : null} {id ? : null} + {(metaLabel || metaDesc) && ( + <> + + {metaLabel && metaDesc ? ( + <> + {_.get(metadata, "label") && ( + + )} + {_.get(metadata, "description") && ( + + )} + + ) : ( + <> + {_.get(metadata, "label") && } + {_.get(metadata, "description") && ( + + )} + + )} + + + + )} From 180f2c64807a981126c5c24d37a46187ad969adf Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Mon, 9 Feb 2026 13:34:00 +0100 Subject: [PATCH 043/105] add Fieldset around autocomplete box --- .../TargetTypeMultiAutoComplete.tsx | 85 +++++++++++-------- 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetTypeMultiAutoComplete.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetTypeMultiAutoComplete.tsx index f625597ba3..ad74562a86 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetTypeMultiAutoComplete.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/components/TargetTypeMultiAutoComplete.tsx @@ -1,48 +1,59 @@ -import React from 'react'; -import {MultiSuggestField, MultiSuggestFieldSelectionProps} from '@eccenca/gui-elements'; +import React from "react"; +import { MultiSuggestField, MultiSuggestFieldSelectionProps, FieldItem } from "@eccenca/gui-elements"; import silkRestApi from "../../api/silkRestApi"; -import {GlobalMappingEditorContext} from "../../contexts/GlobalMappingEditorContext"; -import {TargetPropertyAutoCompletion} from "../../api/types"; -import {removeExtraSpaces} from '@eccenca/gui-elements/src/common/utils/stringUtils'; +import { GlobalMappingEditorContext } from "../../contexts/GlobalMappingEditorContext"; +import { TargetPropertyAutoCompletion } from "../../api/types"; +import { removeExtraSpaces } from "@eccenca/gui-elements/src/common/utils/stringUtils"; interface Props { - onChange: (changes: MultiSuggestFieldSelectionProps) => void - placeholder: string - className: string - isValidNewOption: (text: string) => boolean - value: (string | Omit)[] + onChange: (changes: MultiSuggestFieldSelectionProps) => void; + placeholder: string; + className: string; + isValidNewOption: (text: string) => boolean; + value: (string | Omit)[]; } /** Multi-selection auto-complete component */ const TargetTypeMultiAutoComplete = ({ placeholder, className, isValidNewOption, value, onChange }: Props) => { const mappingEditorContext = React.useContext(GlobalMappingEditorContext); - const runOnQueryChange = React.useCallback((query: string) => { - return silkRestApi.targetClassAutoCompletions(mappingEditorContext.projectId, mappingEditorContext.transformTaskId, query, 50) - .the - }, [mappingEditorContext.projectId, mappingEditorContext.transformTaskId]) - return | string> - className={className} - prePopulateWithItems={!!value?.length} - openOnKeyDown - itemId={t => typeof t === "string" ? t : t.value} - itemLabel={t => typeof t === "string" ? t : (t.label ?? t.value)} - items={value} - onSelection={onChange} - runOnQueryChange={runOnQueryChange} - newItemCreationText={"Create option"} - inputProps={{ - placeholder: placeholder, - }} - tagInputProps={{ - placeholder: placeholder, - }} - isValidNewOption={isValidNewOption} - createNewItemFromQuery={query => ({ - value: removeExtraSpaces(query) - })} - requestDelay={200} - clearQueryOnSelection={true} // workaround that another Tab does not uncheck matches - /> + const runOnQueryChange = React.useCallback( + (query: string) => { + return silkRestApi.targetClassAutoCompletions( + mappingEditorContext.projectId, + mappingEditorContext.transformTaskId, + query, + 50, + ).the; + }, + [mappingEditorContext.projectId, mappingEditorContext.transformTaskId], + ); + return ( + + | string> + className={className} + prePopulateWithItems={!!value?.length} + openOnKeyDown + itemId={(t) => (typeof t === "string" ? t : t.value)} + itemLabel={(t) => (typeof t === "string" ? t : (t.label ?? t.value))} + items={value} + onSelection={onChange} + runOnQueryChange={runOnQueryChange} + newItemCreationText={"Create option"} + inputProps={{ + placeholder: placeholder, + }} + tagInputProps={{ + placeholder: placeholder, + }} + isValidNewOption={isValidNewOption} + createNewItemFromQuery={(query) => ({ + value: removeExtraSpaces(query), + })} + requestDelay={200} + clearQueryOnSelection={true} // workaround that another Tab does not uncheck matches + /> + + ); }; export default TargetTypeMultiAutoComplete; From bb2dfe64b66c0e54dc68ce63f53ba1db51c90bef Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Mon, 9 Feb 2026 17:12:03 +0100 Subject: [PATCH 044/105] forward gui elements, include fix for tag borders --- libs/gui-elements | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/gui-elements b/libs/gui-elements index 60624bdd7b..24d10e0787 160000 --- a/libs/gui-elements +++ b/libs/gui-elements @@ -1 +1 @@ -Subproject commit 60624bdd7b00851e9946a2d13ea25cb9cf4ea462 +Subproject commit 24d10e0787e0b7d61bf5daca1a235f8e0fd1edb2 From c3a8f01e81a98fdfb6a4868b68f2ac30d8936940 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Tue, 10 Feb 2026 09:31:59 +0100 Subject: [PATCH 045/105] forward gui elements --- libs/gui-elements | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/gui-elements b/libs/gui-elements index 24d10e0787..23720eb086 160000 --- a/libs/gui-elements +++ b/libs/gui-elements @@ -1 +1 @@ -Subproject commit 24d10e0787e0b7d61bf5daca1a235f8e0fd1edb2 +Subproject commit 23720eb086e9c58801c3f2dbae5c38c3b0812952 From 8d64f79ef558e8585cb91337176ae5cad06ba7f1 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Tue, 10 Feb 2026 10:30:14 +0100 Subject: [PATCH 046/105] forward gui elements --- libs/gui-elements | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/gui-elements b/libs/gui-elements index 23720eb086..dcdbc36de7 160000 --- a/libs/gui-elements +++ b/libs/gui-elements @@ -1 +1 @@ -Subproject commit 23720eb086e9c58801c3f2dbae5c38c3b0812952 +Subproject commit dcdbc36de7d773892d710c15960e2026abd179e2 From b8239d8d7db9cf24a3e106036b4576b33b3a9b01 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Tue, 10 Feb 2026 12:27:57 +0100 Subject: [PATCH 047/105] use base components instead of custom styles --- .../containers/MappingsTreeLegacy.jsx | 85 ++++++++++--------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsTreeLegacy.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsTreeLegacy.jsx index 595611bf25..4574b076bb 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsTreeLegacy.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsTreeLegacy.jsx @@ -2,12 +2,17 @@ import React from "react"; import PropTypes from "prop-types"; import _ from "lodash"; import { + Button, + FlexibleLayoutContainer, + FlexibleLayoutItem, + OverflowText, InteractionGate, Notification, Icon, IconButton, GridColumn, WhiteSpaceContainer, + ClassNames, } from "@eccenca/gui-elements"; import RuleTypes from "../elements/RuleTypes"; @@ -244,9 +249,13 @@ class MappingsTree extends React.Component { .filter(({ type }) => showValueMappings || type === MAPPING_RULE_TYPE_OBJECT) .value(); const element = () => ( - + ); return ( -
-
+ - {!_.isEmpty(childs) ? ( - { - this.handleToggleExpandNavigationTree(id); - }} - /> - ) : ( - - )} - {element()} -
+ + {!_.isEmpty(childs) ? ( + { + this.handleToggleExpandNavigationTree(id); + }} + /> + ) : ( + + )} + + {element()} + {expanded && (
    {_.map(childs, (child) => ( @@ -307,7 +316,7 @@ class MappingsTree extends React.Component { ))}
)} -
+ ); }; From 578271277b13264284911022b9f552b0024a6a69 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Tue, 10 Feb 2026 12:31:29 +0100 Subject: [PATCH 048/105] remove usage of styles from the deprecated gui elements --- .../HierarchicalMapping.scss | 156 ++---------------- .../containers/MappingRule/MappingRule.jsx | 4 +- .../containers/MappingsList/MappingsList.tsx | 5 +- .../style/legacyimports/_index.scss | 29 ---- .../_replace-configuration.default.scss | 146 ---------------- .../style/legacyimports/_replace-helpers.scss | 21 --- .../pages/MappingEditor/style/style.scss | 4 - workspace/src/index.tsx | 1 - workspace/src/theme/index.scss | 1 + 9 files changed, 21 insertions(+), 346 deletions(-) delete mode 100644 workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss delete mode 100644 workspace/src/app/views/pages/MappingEditor/style/legacyimports/_replace-configuration.default.scss delete mode 100644 workspace/src/app/views/pages/MappingEditor/style/legacyimports/_replace-helpers.scss diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss index 6e1e5b00fb..89b7bfd204 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/HierarchicalMapping.scss @@ -1,6 +1,3 @@ -@import "~@eccenca/gui-elements/src/includes/blueprintjs/variables"; -@import "~@eccenca/gui-elements/src/includes/blueprintjs/requisits"; - // TODO: we need to check if this is still necessary .ecc-component-messagehandler { .ecc-temp__appmessages & { @@ -17,32 +14,10 @@ } } -// TODO (left here as marker): switch back from gui elements reset to prevent display problems with other parts of the app -*:not([class*="#{$eccgui}"]) { - // box-sizing: inherit; -} - .ecc-silk-mapping__treenav { - ul, - li { - list-style-type: none; - } - ul { - margin: 0; - padding: 0; - &.ecc-silk-mapping__treenav--subtree { - padding-left: $button-icon-size; - } - } - - & > .#{$eccgui}-card { - .#{$eccgui}__content { - max-height: calc( - 100vh - #{$layout-header-desktop-row-height} - #{$tab-height} - #{2 * $ecc-size-block-whitespace} - ); - overflow: auto; + padding-left: $button-height; } } @@ -58,72 +33,18 @@ background-color: transparent; } .#{$ns}-tree-node-content { - margin-bottom: $ecc-size-block-whitespace; + margin-bottom: $eccgui-size-block-whitespace; } .#{$ns}-tree-node-caret-none { min-width: 0; } } - - .ecc-silk-mapping__treenav--item { - display: flex; - justify-content: flex-start; - align-items: center; - color: $button-secondary-color; - } - - .ecc-silk-mapping__treenav--item-active:not(.ecc-silk-mapping__treenav--item--ignorestyles) { - font-weight: 500; - background-color: $chip-bg-active-color; - } - - .ecc-silk-mapping__treenav--item-toggler { - flex-grow: 0; - flex-shrink: 0; - min-width: $button-height !important; - } - - .ecc-silk-mapping__treenav--item-handler:not(.#{$eccgui}-button) { - flex-grow: 1; - flex-shrink: 1; - padding: $ecc-size-block-whitespace * 0.25 0; - @include typo-body-1(); - cursor: pointer; - border: none; - text-align: left; - background-color: transparent; - outline: none; - max-width: calc(100% - $button-height); - - &:hover, - &:focus { - background-color: $button-hover-color; - } - - & .material-icons { - margin-right: $ecc-size-block-whitespace * 0.25; - vertical-align: text-bottom; - } - } - - span.ecc-silk-mapping__treenav--item-maintitle, - span.ecc-silk-mapping__treenav--item-subtitle { - display: block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - - span.ecc-silk-mapping__treenav--item-subtitle, - span.ecc-silk-mapping__treenav--item-rule-subtitle { - @include typo-caption(); - } } .ecc-silk-mapping__rulesobject { position: relative; - margin-bottom: $ecc-size-block-whitespace; + margin-bottom: $eccgui-size-block-whitespace; } .ecc-silk-mapping__suggestionlist__target-dropdown { @@ -140,14 +61,8 @@ } .ecc-silk-mapping__ruleitem { - @include typo-body-1(); max-width: 100%; position: relative; - border-bottom: $data-table-dividers; - - &:last-child { - border-bottom: none; - } } .ecc-silk-mapping__ruleitem--dnd { @@ -155,52 +70,23 @@ } .ecc-silk-mapping__ruleitem--defect { - color: to_color($ecc-color-warning-text); - background-color: to_color($ecc-color-warning-background); - border-color: darken(to_color($ecc-color-warning-background), 5%); + color: $eccgui-color-warning-text; + background-color: $eccgui-color-warning-background; } .ecc-silk-mapping__ruleitem-headline { font-weight: 500; } -.ecc-silk-mapping__ruleitem-extraline { - display: block; - margin-right: $ecc-size-blockelement-margin-horizontal; - font-size: $ecc-size-typo-caption; - font-weight: normal; - opacity: 0.61; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.ecc-silk-mapping__ruleitem-label { - display: inline; -} - -.ecc-silk-mapping__ruleitem-url { - direction: rtl; - text-align: left; -} - .ecc-silk-mapping__suggestitem-checkbox { align-self: flex-start; flex-grow: 0; flex-shrink: 0; } -.ecc-silk-mapping__suggestitem-typeselect { - @include typo-caption(); - - & > .mdl-textfield { - display: block; - } -} - .ecc-silk-mapping__ruleitem-summary { &:hover { - background-color: $data-table-hover-color; + background-color: $button-background-color-hover; } &.ecc-silk-mapping__ruleitem-summary--expanded { @@ -208,17 +94,13 @@ } .#{eccgui}-overviewitem__item.#{eccgui}-overviewitem__item--hasspacing { - padding-left: $ecc-size-block-whitespace; + padding-left: $eccgui-size-block-whitespace; } .Select.is-disabled .Select-value { opacity: 0.61; } - .ecc-silk-mapping__suggestitem-typeselect { - margin-top: 0.5 * $ecc-size-block-whitespace; - } - .ecc-silk-mapping__ruleheader { background-color: transparent; @@ -235,11 +117,11 @@ .ecc-silk-mapping__ruleitem-reorderhandler { width: $eccgui-size-block-whitespace; position: absolute; - top: $ecc-size-block-whitespace * 0.5; - left: $ecc-size-block-whitespace * 0.5; - bottom: $ecc-size-block-whitespace * 0.5; - border: $data-table-dividers; - background-color: to_color($color-white); + top: $eccgui-size-block-whitespace * 0.5; + left: $eccgui-size-block-whitespace * 0.5; + bottom: $eccgui-size-block-whitespace * 0.5; + box-shadow: $button-box-shadow; + background-color: eccgui-color-var("identity", "background", "100"); & + .#{eccgui}-overviewitem__item.#{eccgui}-overviewitem__item--hasspacing { padding-left: 2 * $eccgui-size-block-whitespace; @@ -279,10 +161,6 @@ opacity: $eccgui-opacity-regular; } } - - .material-icons { - transform: translate(-1px, calc(50% - #{$button-fab-font-size * 0.5})); - } } .ecc-silk-mapping__rulesviewer__sourcePath { @@ -335,12 +213,8 @@ } } -.clickable { - cursor: pointer; -} - .ecc-silk-mapping__ruleseditor__actionrow-complex-edit { - margin: 0 $ecc-size-block-whitespace * 0.5; + margin: 0 $eccgui-size-block-whitespace * 0.5; } .ecc-silk-mapping__ruleitem--new { @@ -351,7 +225,7 @@ @keyframes anim-new-element { 25% { - background-color: darken($ecc-color-info-background, 30%); - color: $ecc-color-info-text; + background-color: $eccgui-color-info-background; + color: $eccgui-color-info-text; } } diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRule.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRule.jsx index 45f1275a49..67bde515cb 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRule.jsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingRule/MappingRule.jsx @@ -231,7 +231,7 @@ export class MappingRule extends React.Component { false ); return ( -
  • {this.props.provided.placeholder} -
  • +
    ); } } diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx index a1b6b74759..c02434dbeb 100644 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx +++ b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/containers/MappingsList/MappingsList.tsx @@ -7,6 +7,7 @@ import { Divider, StickyTarget, StickyTargetProps, + OverviewItemList, } from "@eccenca/gui-elements"; import { DndContext, KeyboardSensor, useSensor, useSensors } from "@dnd-kit/core"; import { @@ -152,7 +153,7 @@ const MappingsList = ({ items={items.map((item) => `draggable-${item.key}`)} strategy={verticalListSortingStrategy} > -
      + {items.map((item, index) => ( ))} -
    + )} diff --git a/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss b/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss deleted file mode 100644 index 0ac5c393e6..0000000000 --- a/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_index.scss +++ /dev/null @@ -1,29 +0,0 @@ -// include legacy environment -$font_root: "~gui-elements-deprecated/dist/fonts"; - -// we import them not at once so that we can fix the parts that are not compatible with npm (dart) sass -// we only keep the parts that are really necessary for the mapping editor - -// -- Configuration ------------------------------------------------------------ - -@import "replace-configuration.default"; // gui elements configuration - -// -- Eccenca Material Design Lite ----------------------------------------------------- - -// Components -@import "~@eccenca/material-design-lite/src/button/button"; -@import "~@eccenca/material-design-lite/src/textfield/textfield"; -@import "~@eccenca/material-design-lite/src/tooltip/tooltip"; - -// -- Own MDL & GUI extensions ------------------------------------------------- - -@import "~gui-elements-deprecated/src/elements/Button/button"; -@import "~gui-elements-deprecated/src/elements/TextField/textfield"; -@import "~gui-elements-deprecated/src/elements/SelectBox/selectbox"; -@import "~gui-elements-deprecated/src/elements/AutoCompleteBox/autocomplete"; - -// -- Changes ------------------------------------------------------------------ - -// -- Fonts -------------------------------------------------------------------- - -@import "~gui-elements-deprecated/src/scss/iconfont"; diff --git a/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_replace-configuration.default.scss b/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_replace-configuration.default.scss deleted file mode 100644 index 82c2ab252f..0000000000 --- a/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_replace-configuration.default.scss +++ /dev/null @@ -1,146 +0,0 @@ -@use "sass:math"; -@use "sass:color"; -@use "sass:meta"; -@use "sass:string"; - -// -- our color config - -@import "~@eccenca/gui-elements/src/configuration/libprefix"; -@import "~@eccenca/gui-elements/src/common/scss/color-functions"; -@import "~@eccenca/gui-elements/src/configuration/variables"; -$debug-rgba-values: "no"; - -// replace older scss functions because we cannot change the usage itself - -@function darken($color, $amount) { - @if meta.type-of($color) == "color" { - // value is SASS color value, we use SASS color functionality - $darkercolor: color.adjust($color, $lightness: -1 * $amount); - // @debug "Color $color is not CSS custom property: darken(#{$color}, #{$amount}) -> #{$darkercolor}"; - @return $darkercolor; - } @else { - // value is not a SASS color value, we use our CSS color method - @return eccgui-color-mix(black $amount, $color); - } -} - -@function _from-rgb($color) { - $fixedcolor: "undefined"; - @if string.slice($color, 1, 8) == "rgb(var(" { - $fixedcolor: string.slice($color, 5, string.length($color) - 1); - } @else { - $fixedcolor: $color; - } - @return $fixedcolor; -} - -// -- Load helper functions ---------------------------------------------------------- - -@import "replace-helpers"; - -// -- Load MDL color definitions ----------------------------------------------------- - -@import "~@eccenca/material-design-lite/src/color-definitions"; - -// -- Configuration stack of colors -------------------------------------------------- - -/* - We use ecc- prefix here to have an distinction to native MDL color - variables. Variables are only defined if they are not set before. Use those - variables to overwrite the default look of the application. -*/ - -$ecc-color-primary: $eccgui-color-accent !default; -$ecc-color-primary-contrast: $eccgui-color-accent-contrast !default; -$ecc-color-accent: $eccgui-color-accent !default; -$ecc-color-accent-contrast: $eccgui-color-accent-contrast !default; - -$ecc-color-application-background: $eccgui-color-workspace-background !default; -$ecc-color-application-text: $eccgui-color-workspace-text !default; - -$ecc-color-success-background: $eccgui-color-success-background !default; -$ecc-color-success-text: $eccgui-color-success-text !default; -$ecc-color-info-background: $eccgui-color-info-background !default; -$ecc-color-info-text: $eccgui-color-info-text !default; -$ecc-color-warning-background: $eccgui-color-warning-background !default; -$ecc-color-warning-text: $eccgui-color-warning-text !default; -$ecc-color-danger-background: $eccgui-color-danger-background !default; -$ecc-color-danger-text: $eccgui-color-danger-text !default; - -// -- Configuration stack of sizes --------------------------------------------------- - -/* - We use ecc- prefix here to have an distinction to native MDL variables. All - variables are only defined if they are not set before. Use those - variables to overwrite the default look of the application. -*/ - -$ecc-size-typo-base: 14px !default; // size including absolute unit, preferable px -$ecc-size-typo-base-lineheight: 1.39 !default; // only ratio to font size, no unit! -$ecc-size-type-levelratio: math.div( - 7, - 6 -) !default; // ratio without unit! used to calculate different text sizes, etc ... - -// -- Calculation of more config vars ------------------------------------------------ - -/* - You can overwrite them by setting them before loading this configuration but it is - not recommended to do so. -*/ - -$ecc-size-typo-caption: math.div(1, $ecc-size-type-levelratio) * 1rem !default; -$ecc-size-typo-caption-lineheight: max($ecc-size-type-levelratio * $ecc-size-typo-base-lineheight, 1) !default; -$ecc-size-typo-text: 1rem !default; -$ecc-size-typo-text-lineheight: max($ecc-size-typo-base-lineheight, 1) !default; -$ecc-size-typo-subtitle: $ecc-size-type-levelratio * $ecc-size-typo-text !default; -$ecc-size-typo-subtitle-lineheight: max( - math.div(1, $ecc-size-type-levelratio) * $ecc-size-typo-text-lineheight, - 1 -) !default; -$ecc-size-typo-title: $ecc-size-type-levelratio * $ecc-size-typo-subtitle !default; -$ecc-size-typo-title-lineheight: max( - math.div(1, $ecc-size-type-levelratio) * $ecc-size-typo-subtitle-lineheight, - 1 -) !default; -$ecc-size-typo-headline: $ecc-size-type-levelratio * $ecc-size-typo-title !default; -$ecc-size-typo-headline-lineheight: max( - math.div(1, $ecc-size-type-levelratio) * $ecc-size-typo-title-lineheight, - 1 -) !default; -$ecc-size-typo-display-1: $ecc-size-type-levelratio * $ecc-size-typo-headline !default; -$ecc-size-typo-display-1-lineheight: max( - math.div(1, $ecc-size-type-levelratio) * $ecc-size-typo-headline-lineheight, - 1 -) !default; -$ecc-size-typo-display-2: $ecc-size-type-levelratio * $ecc-size-typo-display-1 !default; -$ecc-size-typo-display-2-lineheight: max( - math.div(1, $ecc-size-type-levelratio) * $ecc-size-typo-display-1-lineheight, - 1 -) !default; -$ecc-size-typo-display-3: $ecc-size-type-levelratio * $ecc-size-typo-display-2 !default; -$ecc-size-typo-display-3-lineheight: max( - math.div(1, $ecc-size-type-levelratio) * $ecc-size-typo-display-2-lineheight, - 1 -) !default; - -$ecc-size-blockelement-margin-vertical: 1rem !default; // deprecated -$ecc-size-blockelement-margin-horizontal: 1rem !default; // deprecated -$ecc-size-blockelement-padding-vertical: 1rem !default; // deprecated -$ecc-size-blockelement-padding-horizontal: 1rem !default; // deprecated - -$ecc-size-inlineelement-margin-vertical: 0.5rem !default; // deprecated -$ecc-size-inlineelement-margin-horizontal: 0.5rem !default; // deprecated -$ecc-size-inlineelement-padding-vertical: 0.25rem !default; // deprecated -$ecc-size-inlineelement-padding-horizontal: 0.25rem !default; // deprecated - -$ecc-size-block-whitespace: $ecc-size-typo-base !default; -$ecc-size-inline-whitespace: $ecc-size-typo-base * 0.5 !default; - -$ecc-size-maxwidth-workview: 100 * $ecc-size-typo-text; - -// -- Load MDL variables and mixins -------------------------------------------------- - -@import "~gui-elements-deprecated/src/configuration.mdl"; // calculation MDL config with our changes -@import "~@eccenca/material-design-lite/src/variables"; // original MDL configuration as fallback -@import "~@eccenca/material-design-lite/src/mixins"; // original MDL mixins diff --git a/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_replace-helpers.scss b/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_replace-helpers.scss deleted file mode 100644 index ab1203be1e..0000000000 --- a/workspace/src/app/views/pages/MappingEditor/style/legacyimports/_replace-helpers.scss +++ /dev/null @@ -1,21 +0,0 @@ -// -- Color helpers ------------------------------------------------------------ - -@import "~sassyjson/stylesheets/decode/helpers/color/color"; - -@function to_color($var) { - @if type-of($var) == "color" { - @return $var; - } - - @if ( - type-of($var) == 'string' and - str-slice($var, 1, 3) != 'rgb' and - str-slice($var, 1, 3) != 'hsl' and - str-slice($var, 1, 1) != '#' - ) { - @return _color(unquote('rgb(#{$var})')); - } - @else { - @return _color($var); - } -} diff --git a/workspace/src/app/views/pages/MappingEditor/style/style.scss b/workspace/src/app/views/pages/MappingEditor/style/style.scss index 4d24a2a385..f6346bddb9 100644 --- a/workspace/src/app/views/pages/MappingEditor/style/style.scss +++ b/workspace/src/app/views/pages/MappingEditor/style/style.scss @@ -1,5 +1 @@ -// include legacy environment -@import "legacyimports"; -// include enhancements for silk mapping editor -// moved some imports out to submodules because styles infer between different libraries @import "../HierarchicalMapping/HierarchicalMapping"; diff --git a/workspace/src/index.tsx b/workspace/src/index.tsx index 8eb28f9fdd..8e3f1c0506 100644 --- a/workspace/src/index.tsx +++ b/workspace/src/index.tsx @@ -12,7 +12,6 @@ import appRoutes, { IRouteProps } from "./app/appRoutes"; import { createPlugin } from "./app/services/pluginApi"; import configureStore from "./app/store/configureStore"; -import "./app/views/pages/MappingEditor/style/style.scss"; // FIXME: remove legacy styles import when not necessary anymore import "./theme/index.scss"; import mappingEditor from "./app/views/pages/MappingEditor/index"; import "./language"; diff --git a/workspace/src/theme/index.scss b/workspace/src/theme/index.scss index 423e6a0001..bf78e2083d 100644 --- a/workspace/src/theme/index.scss +++ b/workspace/src/theme/index.scss @@ -33,3 +33,4 @@ $eccgui-selector-text-spot-highlight: "[id^=parameter_doc_]"; @import "./../app/views/taskViews/linking/evaluation/tabView/LinkingEvaluationTabview.scss"; @import "./../app/views/taskViews/transform/evaluation/tabView/TransformEvaluationTabView.scss"; @import "./../app/views/shared/FileUploader/cases/UploadNewFile/UploadNewFile.scss"; +@import "./../app/views/pages/MappingEditor/style/style.scss"; From a0a1fc0d9f8c588646440cb18e6de071120a6347 Mon Sep 17 00:00:00 2001 From: Michael Haschke Date: Tue, 10 Feb 2026 12:40:56 +0100 Subject: [PATCH 049/105] remove unused code --- .../HierarchicalMapping/EvaluateMapping.jsx | 66 ------------------- 1 file changed, 66 deletions(-) delete mode 100644 workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/EvaluateMapping.jsx diff --git a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/EvaluateMapping.jsx b/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/EvaluateMapping.jsx deleted file mode 100644 index 136f11894b..0000000000 --- a/workspace/src/app/views/pages/MappingEditor/HierarchicalMapping/EvaluateMapping.jsx +++ /dev/null @@ -1,66 +0,0 @@ -import React from "react"; -import _ from "lodash"; - -import PropTypes from "prop-types"; -import { setApiDetails } from "./store"; -import MappingsTree from "./containers/MappingsTreeLegacy"; - -/** - * Legacy mappings evaluation view. - * Uses an inline iFrame to display the old evaluation tree. - * Should be replaced in the future. - */ -class EvaluateMapping extends React.Component { - // define property types - static propTypes = { - project: PropTypes.string.isRequired, // Current DI Project - transformTask: PropTypes.string.isRequired, // Current Transformation - initialRule: PropTypes.string.isRequired, // Initially selected mapping rule - offset: PropTypes.number.isRequired, // Entity offset - limit: PropTypes.number.isRequired, // Entity limit - }; - - constructor(props) { - super(props); - const { initialRule, project, transformTask } = this.props; - setApiDetails({ - project, - transformTask, - }); - - this.state = { - // currently selected rule id - currentRuleId: _.isEmpty(initialRule) ? undefined : initialRule, - }; - } - - // react to rule id changes - onRuleNavigation = ({ newRuleId }) => { - this.setState({ - currentRuleId: newRuleId, - }); - }; - - render() { - return ( -
    -
    - -
    -