diff --git a/docs/source/user/api/apollon-editor.d.ts b/docs/source/user/api/apollon-editor.d.ts index dd394554c..9ba183c46 100644 --- a/docs/source/user/api/apollon-editor.d.ts +++ b/docs/source/user/api/apollon-editor.d.ts @@ -1,10 +1,9 @@ import 'pepjs'; -import { DeepPartial } from 'redux'; import { Styles } from './components/theme/styles'; import { Patch } from './services/patcher'; import { Locale } from './services/editor/editor-types'; import * as Apollon from './typings'; -import { UMLDiagramType, UMLModel } from './typings'; +import { DeepPartial, UMLDiagramType, UMLModel } from './typings'; import { UMLModelCompat } from './compat'; export declare class ApollonEditor { private container; diff --git a/docs/source/user/api/typings.d.ts b/docs/source/user/api/typings.d.ts index 6c90174dc..7763ab5dd 100644 --- a/docs/source/user/api/typings.d.ts +++ b/docs/source/user/api/typings.d.ts @@ -1,4 +1,3 @@ -import { DeepPartial } from 'redux'; import { Styles } from './components/theme/styles'; import { UMLDiagramType } from './packages/diagram-type'; import { UMLElementType } from './packages/uml-element-type'; @@ -169,3 +168,6 @@ export type SVG = { height: number; }; }; +export type DeepPartial = T extends object ? { + [P in keyof T]?: DeepPartial; +} : T; diff --git a/package-lock.json b/package-lock.json index f7091bdad..60ff1adcd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,17 +10,18 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { + "@reduxjs/toolkit": "2.2.5", "fast-json-patch": "3.1.1", "is-mobile": "4.0.0", "pepjs": "0.5.3", "react": "18.2.0", "react-color": "2.19.3", "react-dom": "18.2.0", - "react-redux": "8.1.3", + "react-redux": "9.1.2", "react-tooltip": "4.5.1", - "redux": "4.2.1", + "redux": "5.0.1", "redux-saga": "1.3.0", - "redux-thunk": "2.4.2", + "redux-thunk": "3.1.0", "rxjs": "7.8.1", "styled-components": "5.3.11", "tslib": "2.6.2", @@ -1789,6 +1790,29 @@ "resolved": "https://registry.npmjs.org/@redux-saga/types/-/types-1.2.1.tgz", "integrity": "sha512-1dgmkh+3so0+LlBWRhGA33ua4MYr7tUOj+a9Si28vUi0IUFNbff1T3sgpeDJI/LaC75bBYnQ0A3wXjn0OrRNBA==" }, + "node_modules/@reduxjs/toolkit": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.5.tgz", + "integrity": "sha512-aeFA/s5NCG7NoJe/MhmwREJxRkDs0ZaSqt0MxhWUrwCf1UQXpwR87RROJEql0uAkLI6U7snBOYOcKw83ew3FPg==", + "dependencies": { + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", @@ -2239,6 +2263,7 @@ "version": "3.3.5", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dev": true, "dependencies": { "@types/react": "*", "hoist-non-react-statics": "^3.3.0" @@ -2369,7 +2394,8 @@ "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "devOptional": true }, "node_modules/@types/qs": { "version": "6.9.14", @@ -2387,6 +2413,7 @@ "version": "18.2.79", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz", "integrity": "sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==", + "devOptional": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -2406,7 +2433,7 @@ "version": "18.2.25", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.25.tgz", "integrity": "sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==", - "devOptional": true, + "dev": true, "dependencies": { "@types/react": "*" } @@ -2423,6 +2450,15 @@ "redux": "^4.0.0" } }, + "node_modules/@types/react-redux/node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, "node_modules/@types/reactcss": { "version": "1.2.12", "resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.12.tgz", @@ -2441,6 +2477,15 @@ "redux": "^4.0.5" } }, + "node_modules/@types/redux-mock-store/node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, "node_modules/@types/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", @@ -4964,7 +5009,8 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "devOptional": true }, "node_modules/data-urls": { "version": "3.0.2", @@ -7432,6 +7478,15 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz", + "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -12119,38 +12174,22 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/react-redux": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz", - "integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz", + "integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==", "dependencies": { - "@babel/runtime": "^7.12.1", - "@types/hoist-non-react-statics": "^3.3.1", "@types/use-sync-external-store": "^0.0.3", - "hoist-non-react-statics": "^3.3.2", - "react-is": "^18.0.0", "use-sync-external-store": "^1.0.0" }, "peerDependencies": { - "@types/react": "^16.8 || ^17.0 || ^18.0", - "@types/react-dom": "^16.8 || ^17.0 || ^18.0", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0", - "react-native": ">=0.59", - "redux": "^4 || ^5.0.0-beta.0" + "@types/react": "^18.2.25", + "react": "^18.0", + "redux": "^5.0.0" }, "peerDependenciesMeta": { "@types/react": { "optional": true }, - "@types/react-dom": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - }, "redux": { "optional": true } @@ -12257,12 +12296,9 @@ } }, "node_modules/redux": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", - "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", - "dependencies": { - "@babel/runtime": "^7.9.2" - } + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==" }, "node_modules/redux-mock-store": { "version": "1.5.4", @@ -12282,11 +12318,11 @@ } }, "node_modules/redux-thunk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", - "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", "peerDependencies": { - "redux": "^4" + "redux": "^5.0.0" } }, "node_modules/reflect.getprototypeof": { @@ -12407,6 +12443,11 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "dev": true }, + "node_modules/reselect": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.0.tgz", + "integrity": "sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg==" + }, "node_modules/resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", diff --git a/package.json b/package.json index 55669db98..9ed0ab817 100644 --- a/package.json +++ b/package.json @@ -53,17 +53,18 @@ "*.{ts,tsx,js,css,md}": "prettier --write" }, "dependencies": { + "@reduxjs/toolkit": "2.2.5", "fast-json-patch": "3.1.1", "is-mobile": "4.0.0", "pepjs": "0.5.3", "react": "18.2.0", "react-color": "2.19.3", "react-dom": "18.2.0", - "react-redux": "8.1.3", + "react-redux": "9.1.2", "react-tooltip": "4.5.1", - "redux": "4.2.1", + "redux": "5.0.1", "redux-saga": "1.3.0", - "redux-thunk": "2.4.2", + "redux-thunk": "3.1.0", "rxjs": "7.8.1", "styled-components": "5.3.11", "tslib": "2.6.2", diff --git a/src/main/apollon-editor.ts b/src/main/apollon-editor.ts index c64c05cdf..ffdd214c5 100644 --- a/src/main/apollon-editor.ts +++ b/src/main/apollon-editor.ts @@ -1,7 +1,7 @@ import 'pepjs'; import { createElement } from 'react'; import { createRoot, Root } from 'react-dom/client'; -import { DeepPartial, Store } from 'redux'; +import { Store } from 'redux'; import { ModelState, PartialModelState } from './components/store/model-state'; import { Styles } from './components/theme/styles'; import { UMLElementType } from './packages/uml-element-type'; @@ -14,7 +14,7 @@ import { ApollonMode, ApollonView, Locale } from './services/editor/editor-types import { UMLDiagram } from './services/uml-diagram/uml-diagram'; import { UMLElementRepository } from './services/uml-element/uml-element-repository'; import * as Apollon from './typings'; -import { UMLDiagramType, UMLModel } from './typings'; +import { DeepPartial, UMLDiagramType, UMLModel } from './typings'; import { Dispatch } from './utils/actions/actions'; import { debounce } from './utils/debounce'; import { delay } from './utils/delay'; diff --git a/src/main/components/canvas/mouse-eventlistener.tsx b/src/main/components/canvas/mouse-eventlistener.tsx index 0fddc1f5d..a8f65c617 100644 --- a/src/main/components/canvas/mouse-eventlistener.tsx +++ b/src/main/components/canvas/mouse-eventlistener.tsx @@ -11,7 +11,6 @@ import { UMLElementState } from '../../services/uml-element/uml-element-types'; import { IUMLElement } from '../../services/uml-element/uml-element'; import { EditorRepository } from '../../services/editor/editor-repository'; import { areBoundsIntersecting, IBoundary } from '../../utils/geometry/boundary'; -import { IPoint } from '../../utils/geometry/point'; import { defaults as getTheme } from '../../components/theme/styles'; type OwnProps = {}; diff --git a/src/main/components/store/model-state.ts b/src/main/components/store/model-state.ts index 94f48bc76..3566ed783 100644 --- a/src/main/components/store/model-state.ts +++ b/src/main/components/store/model-state.ts @@ -22,7 +22,6 @@ import { UMLRelationshipRepository } from '../../services/uml-relationship/uml-r import * as Apollon from '../../typings'; import { UMLDiagramType } from '../../typings'; import { backwardsCompatibleModel, UMLModelCompat } from '../../compat'; -import { computeBoundingBoxForElements } from '../../utils/geometry/boundary'; import { UMLDiagram } from '../../services/uml-diagram/uml-diagram'; import { CopyState } from '../../services/copypaste/copy-types'; import { LastActionState } from '../../services/last-action/last-action-types'; diff --git a/src/main/components/store/model-store.tsx b/src/main/components/store/model-store.tsx index f56de96f4..2581d40af 100644 --- a/src/main/components/store/model-store.tsx +++ b/src/main/components/store/model-store.tsx @@ -1,24 +1,13 @@ import React, { Component, PropsWithChildren } from 'react'; import { Provider } from 'react-redux'; -import { - applyMiddleware, - combineReducers, - compose, - createStore, - PreloadedState, - Reducer, - Store, - StoreEnhancer, -} from 'redux'; +import { combineReducers, Reducer, Store } from 'redux'; import createSagaMiddleware, { SagaMiddleware } from 'redux-saga'; -import thunk, { ThunkMiddleware } from 'redux-thunk'; import { Actions } from '../../services/actions'; import { ILayer } from '../../services/layouter/layer'; import { LayouterRepository } from '../../services/layouter/layouter-repository'; import { reducers } from '../../services/reducer'; import { saga, SagaContext } from '../../services/saga'; import { undoable } from '../../services/undo/undo-reducer'; -import { Dispatch } from '../../utils/actions/actions'; import { CanvasContext } from '../canvas/canvas-context'; import { withCanvas } from '../canvas/with-canvas'; import { ModelState, PartialModelState } from './model-state'; @@ -32,23 +21,26 @@ import { } from '../../services/patcher'; import { UMLModel } from '../../typings'; import { merge } from './merge'; +import { configureStore } from '@reduxjs/toolkit'; type OwnProps = PropsWithChildren<{ - initialState?: PreloadedState; + initialState?: PartialModelState; patcher?: Patcher; }>; type Props = OwnProps & CanvasContext; export const createReduxStore = ( - initialState: PreloadedState = {}, + initialState: PartialModelState = {}, layer: ILayer | null = null, patcher?: Patcher, ): Store => { - const baseReducer: Reducer = undoable(combineReducers(reducers)); + const baseReducer: Reducer = undoable( + combineReducers(reducers) as unknown as Reducer, + ); const patchReducer = patcher && - createPatcherReducer(patcher, { + createPatcherReducer(patcher, { transform: (model) => ModelState.fromModel(model) as ModelState, transformInverse: (state) => ModelState.toModel(state), merge, @@ -65,25 +57,27 @@ export const createReduxStore = ( const sagaMiddleware: SagaMiddleware = createSagaMiddleware({ context: { layer } }); - const middleware: StoreEnhancer<{ dispatch: Dispatch }, {}> = applyMiddleware( - ...[ - thunk as ThunkMiddleware, - sagaMiddleware, - ...(patcher - ? [ - createPatcherMiddleware(patcher, { - selectDiscrete: (action) => isDiscreteAction(action) || isSelectionAction(action), - selectContinuous: (action) => isContinuousAction(action), - transform: (state) => ModelState.toModel(state), - }), - ] - : []), - ], - ); - const composeEnhancers: typeof compose = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; - const enhancer = composeEnhancers(middleware); + const store: Store = configureStore({ + reducer: reducer, + preloadedState: initialState as ModelState, + middleware: (getDefaultMiddleware) => { + const middleware = getDefaultMiddleware({ + serializableCheck: false, + }).concat(sagaMiddleware); + + if (patcher) { + const patcherMiddleware = createPatcherMiddleware(patcher, { + selectDiscrete: (action) => isDiscreteAction(action) || isSelectionAction(action), + selectContinuous: (action) => isContinuousAction(action), + transform: (state) => ModelState.toModel(state), + }); + + return middleware.concat(patcherMiddleware); + } - const store: Store = createStore(reducer, initialState as ModelState, enhancer); + return middleware; + }, + }); if (layer) { sagaMiddleware.run(saga); @@ -93,7 +87,7 @@ export const createReduxStore = ( }; const getInitialState = ( - initialState: PreloadedState = {}, + initialState: PartialModelState = {}, layer: ILayer | null = null, patcher?: Patcher, ): { store: Store } => { diff --git a/src/main/components/theme/theme.tsx b/src/main/components/theme/theme.tsx index d84bd0f3e..0e456aa4a 100644 --- a/src/main/components/theme/theme.tsx +++ b/src/main/components/theme/theme.tsx @@ -1,8 +1,9 @@ import React, { Component } from 'react'; -import { DeepPartial } from 'redux'; + import { ThemeProvider } from 'styled-components'; import { update } from '../../utils/update'; import { defaults, Styles } from './styles'; +import { DeepPartial } from '../../typings'; const defaultProps = { styles: {} as DeepPartial, diff --git a/src/main/packages/bpmn/bpmn-end-event/bpmn-end-event.ts b/src/main/packages/bpmn/bpmn-end-event/bpmn-end-event.ts index 84df7e1b8..64c193981 100644 --- a/src/main/packages/bpmn/bpmn-end-event/bpmn-end-event.ts +++ b/src/main/packages/bpmn/bpmn-end-event/bpmn-end-event.ts @@ -1,4 +1,3 @@ -import { DeepPartial } from 'redux'; import { BPMNElementType, BPMNRelationshipType } from '..'; import { ILayer } from '../../../services/layouter/layer'; import { ILayoutable } from '../../../services/layouter/layoutable'; @@ -8,6 +7,7 @@ import { IBoundary } from '../../../utils/geometry/boundary'; import { UMLElementType } from '../../uml-element-type'; import { UMLContainer } from '../../../services/uml-container/uml-container'; import * as Apollon from '../../../typings'; +import { DeepPartial } from '../../../typings'; export type BPMNEndEventType = 'default' | 'message' | 'escalation' | 'error' | 'compensation' | 'signal' | 'terminate'; diff --git a/src/main/packages/bpmn/bpmn-flow/bpmn-flow.ts b/src/main/packages/bpmn/bpmn-flow/bpmn-flow.ts index da1e1ecbb..25539ec13 100644 --- a/src/main/packages/bpmn/bpmn-flow/bpmn-flow.ts +++ b/src/main/packages/bpmn/bpmn-flow/bpmn-flow.ts @@ -1,9 +1,10 @@ import { BPMNRelationshipType } from '..'; import { UMLRelationship } from '../../../services/uml-relationship/uml-relationship'; -import { DeepPartial } from 'redux'; + import { UMLRelationshipCenteredDescription } from '../../../services/uml-relationship/uml-relationship-centered-description'; import { UMLElement } from '../../../services/uml-element/uml-element'; import * as Apollon from '../../../typings'; +import { DeepPartial } from '../../../typings'; export type BPMNFlowType = 'sequence' | 'message' | 'association' | 'data association'; diff --git a/src/main/packages/bpmn/bpmn-gateway/bpmn-gateway.ts b/src/main/packages/bpmn/bpmn-gateway/bpmn-gateway.ts index e81b4ea44..d0ca534ee 100644 --- a/src/main/packages/bpmn/bpmn-gateway/bpmn-gateway.ts +++ b/src/main/packages/bpmn/bpmn-gateway/bpmn-gateway.ts @@ -4,9 +4,10 @@ import { ILayoutable } from '../../../services/layouter/layoutable'; import { UMLElementType } from '../../uml-element-type'; import { UMLElementFeatures } from '../../../services/uml-element/uml-element-features'; import { IBoundary } from '../../../utils/geometry/boundary'; -import { DeepPartial } from 'redux'; + import { assign } from '../../../utils/fx/assign'; import * as Apollon from '../../../typings'; +import { DeepPartial } from '../../../typings'; import { UMLContainer } from '../../../services/uml-container/uml-container'; export type BPMNGatewayType = 'complex' | 'event-based' | 'exclusive' | 'inclusive' | 'parallel'; diff --git a/src/main/packages/bpmn/bpmn-intermediate-event/bpmn-intermediate-event.ts b/src/main/packages/bpmn/bpmn-intermediate-event/bpmn-intermediate-event.ts index fb118d86c..d7c94bbc2 100644 --- a/src/main/packages/bpmn/bpmn-intermediate-event/bpmn-intermediate-event.ts +++ b/src/main/packages/bpmn/bpmn-intermediate-event/bpmn-intermediate-event.ts @@ -1,4 +1,3 @@ -import { DeepPartial } from 'redux'; import { BPMNElementType, BPMNRelationshipType } from '..'; import { ILayer } from '../../../services/layouter/layer'; import { ILayoutable } from '../../../services/layouter/layoutable'; @@ -8,6 +7,7 @@ import { IBoundary } from '../../../utils/geometry/boundary'; import { UMLElementType } from '../../uml-element-type'; import { UMLContainer } from '../../../services/uml-container/uml-container'; import * as Apollon from '../../../typings'; +import { DeepPartial } from '../../../typings'; export type BPMNIntermediateEventType = | 'default' diff --git a/src/main/packages/bpmn/bpmn-pool/bpmn-pool-update.tsx b/src/main/packages/bpmn/bpmn-pool/bpmn-pool-update.tsx index 38e8ec147..b3ec4a97f 100644 --- a/src/main/packages/bpmn/bpmn-pool/bpmn-pool-update.tsx +++ b/src/main/packages/bpmn/bpmn-pool/bpmn-pool-update.tsx @@ -188,6 +188,7 @@ class BPMNPoolUpdateComponent extends Component { name: name ?? this.props.translate('packages.BPMN.BPMNSwimlane'), bounds: { x: BPMNPool.HEADER_WIDTH, + y: 0, width: this.props.element.bounds.width - BPMNPool.HEADER_WIDTH, height: convertToSwimlaneBased ? this.props.element.bounds.height : BPMNSwimlane.DEFAULT_HEIGHT, }, diff --git a/src/main/packages/bpmn/bpmn-start-event/bpmn-start-event.ts b/src/main/packages/bpmn/bpmn-start-event/bpmn-start-event.ts index 0b836bb85..ce53a6b02 100644 --- a/src/main/packages/bpmn/bpmn-start-event/bpmn-start-event.ts +++ b/src/main/packages/bpmn/bpmn-start-event/bpmn-start-event.ts @@ -1,4 +1,3 @@ -import { DeepPartial } from 'redux'; import { BPMNElementType, BPMNRelationshipType } from '..'; import { ILayer } from '../../../services/layouter/layer'; import { ILayoutable } from '../../../services/layouter/layoutable'; @@ -8,6 +7,7 @@ import { IBoundary } from '../../../utils/geometry/boundary'; import { UMLElementType } from '../../uml-element-type'; import { UMLContainer } from '../../../services/uml-container/uml-container'; import * as Apollon from '../../../typings'; +import { DeepPartial } from '../../../typings'; export type BPMNStartEventType = 'default' | 'message' | 'timer' | 'conditional' | 'signal'; diff --git a/src/main/packages/bpmn/bpmn-task/bpmn-task.ts b/src/main/packages/bpmn/bpmn-task/bpmn-task.ts index b0abc0b82..de0f97db1 100644 --- a/src/main/packages/bpmn/bpmn-task/bpmn-task.ts +++ b/src/main/packages/bpmn/bpmn-task/bpmn-task.ts @@ -3,9 +3,10 @@ import { ILayer } from '../../../services/layouter/layer'; import { ILayoutable } from '../../../services/layouter/layoutable'; import { UMLElementType } from '../../uml-element-type'; import { UMLContainer } from '../../../services/uml-container/uml-container'; -import { DeepPartial } from 'redux'; + import { assign } from '../../../utils/fx/assign'; import * as Apollon from '../../../typings'; +import { DeepPartial } from '../../../typings'; import { BPMNMarkerType } from '../common/types'; export type BPMNTaskType = 'default' | 'user' | 'send' | 'receive' | 'manual' | 'business-rule' | 'script'; diff --git a/src/main/packages/common/color-legend/color-legend.ts b/src/main/packages/common/color-legend/color-legend.ts index dffec3370..69879a000 100644 --- a/src/main/packages/common/color-legend/color-legend.ts +++ b/src/main/packages/common/color-legend/color-legend.ts @@ -1,9 +1,9 @@ -import { DeepPartial } from 'redux'; import { ColorLegendElementType } from '.'; import { ILayer } from '../../../services/layouter/layer'; import { ILayoutable } from '../../../services/layouter/layoutable'; import { IUMLElement, UMLElement } from '../../../services/uml-element/uml-element'; import { UMLElementType } from '../../uml-element-type'; +import { DeepPartial } from '../../../typings'; export class ColorLegend extends UMLElement { type: UMLElementType = ColorLegendElementType.ColorLegend; diff --git a/src/main/packages/common/uml-association/uml-association.ts b/src/main/packages/common/uml-association/uml-association.ts index 0712fef26..d521512bd 100644 --- a/src/main/packages/common/uml-association/uml-association.ts +++ b/src/main/packages/common/uml-association/uml-association.ts @@ -1,4 +1,3 @@ -import { DeepPartial } from 'redux'; import { ILayer } from '../../../services/layouter/layer'; import { ILayoutable } from '../../../services/layouter/layoutable'; import { UMLElement } from '../../../services/uml-element/uml-element'; @@ -13,6 +12,7 @@ import { } from './uml-association-component'; import { Text } from '../../../utils/svg/text'; import { Point } from '../../../utils/geometry/point'; +import { DeepPartial } from '../../../typings'; export interface IUMLAssociation extends IUMLRelationship { source: IUMLElementPort & { diff --git a/src/main/packages/common/uml-classifier/uml-classifier-member.ts b/src/main/packages/common/uml-classifier/uml-classifier-member.ts index 436bbdf4d..482508136 100644 --- a/src/main/packages/common/uml-classifier/uml-classifier-member.ts +++ b/src/main/packages/common/uml-classifier/uml-classifier-member.ts @@ -1,4 +1,3 @@ -import { DeepPartial } from 'redux'; import { ILayer } from '../../../services/layouter/layer'; import { ILayoutable } from '../../../services/layouter/layoutable'; import { IUMLElement, UMLElement } from '../../../services/uml-element/uml-element'; @@ -6,6 +5,7 @@ import { UMLElementFeatures } from '../../../services/uml-element/uml-element-fe import { assign } from '../../../utils/fx/assign'; import { IBoundary, computeDimension } from '../../../utils/geometry/boundary'; import { Text } from '../../../utils/svg/text'; +import { DeepPartial } from '../../../typings'; export abstract class UMLClassifierMember extends UMLElement { static features: UMLElementFeatures = { diff --git a/src/main/packages/common/uml-classifier/uml-classifier.ts b/src/main/packages/common/uml-classifier/uml-classifier.ts index e52199b82..648bbc3bc 100644 --- a/src/main/packages/common/uml-classifier/uml-classifier.ts +++ b/src/main/packages/common/uml-classifier/uml-classifier.ts @@ -1,10 +1,10 @@ -import { DeepPartial } from 'redux'; import { ILayer } from '../../../services/layouter/layer'; import { ILayoutable } from '../../../services/layouter/layoutable'; import { IUMLContainer, UMLContainer } from '../../../services/uml-container/uml-container'; import { IUMLElement, UMLElement } from '../../../services/uml-element/uml-element'; import { UMLElementFeatures } from '../../../services/uml-element/uml-element-features'; import * as Apollon from '../../../typings'; +import { DeepPartial } from '../../../typings'; import { assign } from '../../../utils/fx/assign'; import { Text } from '../../../utils/svg/text'; import { UMLElementType } from '../../uml-element-type'; diff --git a/src/main/packages/common/uml-interface/uml-interface.ts b/src/main/packages/common/uml-interface/uml-interface.ts index 8d03916cc..8fadb1528 100644 --- a/src/main/packages/common/uml-interface/uml-interface.ts +++ b/src/main/packages/common/uml-interface/uml-interface.ts @@ -1,9 +1,9 @@ -import { DeepPartial } from 'redux'; import { ILayer } from '../../../services/layouter/layer'; import { ILayoutable } from '../../../services/layouter/layoutable'; import { UMLElement } from '../../../services/uml-element/uml-element'; import { assign } from '../../../utils/fx/assign'; import { IBoundary } from '../../../utils/geometry/boundary'; +import { DeepPartial } from '../../../typings'; export abstract class UMLInterface extends UMLElement { static features = { ...UMLElement.features, resizable: false, alternativePortVisualization: true }; diff --git a/src/main/packages/uml-activity-diagram/uml-activity-final-node/uml-activity-final-node.ts b/src/main/packages/uml-activity-diagram/uml-activity-final-node/uml-activity-final-node.ts index d0588e4a9..8bb31c3ff 100644 --- a/src/main/packages/uml-activity-diagram/uml-activity-final-node/uml-activity-final-node.ts +++ b/src/main/packages/uml-activity-diagram/uml-activity-final-node/uml-activity-final-node.ts @@ -1,4 +1,3 @@ -import { DeepPartial } from 'redux'; import { ActivityElementType, ActivityRelationshipType } from '..'; import { ILayer } from '../../../services/layouter/layer'; import { ILayoutable } from '../../../services/layouter/layoutable'; @@ -7,6 +6,7 @@ import { UMLElementFeatures } from '../../../services/uml-element/uml-element-fe import { assign } from '../../../utils/fx/assign'; import { IBoundary } from '../../../utils/geometry/boundary'; import { UMLElementType } from '../../uml-element-type'; +import { DeepPartial } from '../../../typings'; export class UMLActivityFinalNode extends UMLElement { static supportedRelationships = [ActivityRelationshipType.ActivityControlFlow]; diff --git a/src/main/packages/uml-activity-diagram/uml-activity-fork-node-horizontal/uml-activity-fork-node-horizontal.ts b/src/main/packages/uml-activity-diagram/uml-activity-fork-node-horizontal/uml-activity-fork-node-horizontal.ts index b1cd6943e..9baff6081 100644 --- a/src/main/packages/uml-activity-diagram/uml-activity-fork-node-horizontal/uml-activity-fork-node-horizontal.ts +++ b/src/main/packages/uml-activity-diagram/uml-activity-fork-node-horizontal/uml-activity-fork-node-horizontal.ts @@ -5,7 +5,7 @@ import { IUMLElement, UMLElement } from '../../../services/uml-element/uml-eleme import { UMLElementFeatures } from '../../../services/uml-element/uml-element-features'; import { IBoundary } from '../../../utils/geometry/boundary'; import { UMLElementType } from '../../uml-element-type'; -import { DeepPartial } from 'redux'; +import { DeepPartial } from '../../../typings'; export class UMLActivityForkNodeHorizontal extends UMLElement { static supportedRelationships = [ActivityRelationshipType.ActivityControlFlow]; diff --git a/src/main/packages/uml-activity-diagram/uml-activity-fork-node/uml-activity-fork-node.ts b/src/main/packages/uml-activity-diagram/uml-activity-fork-node/uml-activity-fork-node.ts index 82bdf2374..3ad0ddca4 100644 --- a/src/main/packages/uml-activity-diagram/uml-activity-fork-node/uml-activity-fork-node.ts +++ b/src/main/packages/uml-activity-diagram/uml-activity-fork-node/uml-activity-fork-node.ts @@ -5,7 +5,7 @@ import { IUMLElement, UMLElement } from '../../../services/uml-element/uml-eleme import { UMLElementFeatures } from '../../../services/uml-element/uml-element-features'; import { IBoundary } from '../../../utils/geometry/boundary'; import { UMLElementType } from '../../uml-element-type'; -import { DeepPartial } from 'redux'; +import { DeepPartial } from '../../../typings'; export class UMLActivityForkNode extends UMLElement { static supportedRelationships = [ActivityRelationshipType.ActivityControlFlow]; diff --git a/src/main/packages/uml-activity-diagram/uml-activity-initial-node/uml-activity-initial-node.ts b/src/main/packages/uml-activity-diagram/uml-activity-initial-node/uml-activity-initial-node.ts index 9431c40ee..db26617b7 100644 --- a/src/main/packages/uml-activity-diagram/uml-activity-initial-node/uml-activity-initial-node.ts +++ b/src/main/packages/uml-activity-diagram/uml-activity-initial-node/uml-activity-initial-node.ts @@ -1,4 +1,3 @@ -import { DeepPartial } from 'redux'; import { ActivityElementType, ActivityRelationshipType } from '..'; import { ILayer } from '../../../services/layouter/layer'; import { ILayoutable } from '../../../services/layouter/layoutable'; @@ -7,6 +6,7 @@ import { UMLElementFeatures } from '../../../services/uml-element/uml-element-fe import { assign } from '../../../utils/fx/assign'; import { IBoundary } from '../../../utils/geometry/boundary'; import { UMLElementType } from '../../uml-element-type'; +import { DeepPartial } from '../../../typings'; export class UMLActivityInitialNode extends UMLElement { static supportedRelationships = [ActivityRelationshipType.ActivityControlFlow]; diff --git a/src/main/packages/uml-class-diagram/class-preview.ts b/src/main/packages/uml-class-diagram/class-preview.ts index 052ee6d76..345728392 100644 --- a/src/main/packages/uml-class-diagram/class-preview.ts +++ b/src/main/packages/uml-class-diagram/class-preview.ts @@ -13,6 +13,7 @@ import { UMLInterface } from './uml-interface/uml-interface'; export const composeClassPreview: ComposePreview = (layer: ILayer, translate: (id: string) => string): UMLElement[] => { const elements: UMLElement[] = []; + UMLClassifier.stereotypeHeaderHeight = computeDimension(1.0, 50); UMLClassifier.nonStereotypeHeaderHeight = computeDimension(1.0, 40); @@ -90,7 +91,6 @@ export const composeClassPreview: ComposePreview = (layer: ILayer, translate: (i // UML Interface const umlInterface = new UMLInterface({ name: translate('packages.ClassDiagram.Interface'), - bounds: { height: 110 }, }); umlInterface.bounds = { ...umlInterface.bounds, @@ -123,7 +123,6 @@ export const composeClassPreview: ComposePreview = (layer: ILayer, translate: (i // UML Enumeration const umlEnumeration = new UMLEnumeration({ name: translate('packages.ClassDiagram.Enumeration'), - bounds: { height: 140 }, }); umlEnumeration.bounds = { ...umlEnumeration.bounds, diff --git a/src/main/packages/uml-communication-diagram/uml-communication-link/uml-communication-link-update.tsx b/src/main/packages/uml-communication-diagram/uml-communication-link/uml-communication-link-update.tsx index e0b16ba10..8da7037df 100644 --- a/src/main/packages/uml-communication-diagram/uml-communication-link/uml-communication-link-update.tsx +++ b/src/main/packages/uml-communication-diagram/uml-communication-link/uml-communication-link-update.tsx @@ -154,7 +154,7 @@ class CommunicationLinkUpdate extends Component { private rename = (value: ICommunicationLinkMessage) => (name: string) => { const { element, update } = this.props; - const messages: ICommunicationLinkMessage[] = [...element.messages]; + const messages: ICommunicationLinkMessage[] = element.messages.map((message) => ({ ...message })); const index = messages.findIndex((message) => message.name === value.name); messages[index].name = name; update(element.id, { messages }); @@ -162,7 +162,7 @@ class CommunicationLinkUpdate extends Component { private flip = (value: ICommunicationLinkMessage) => () => { const { element, update } = this.props; - const messages: ICommunicationLinkMessage[] = [...element.messages]; + const messages: ICommunicationLinkMessage[] = element.messages.map((message) => ({ ...message })); const index = messages.findIndex((message) => message.name === value.name); messages[index].direction = messages[index].direction === 'source' ? 'target' : 'source'; update(element.id, { messages }); diff --git a/src/main/packages/uml-communication-diagram/uml-communication-link/uml-communication-link.ts b/src/main/packages/uml-communication-diagram/uml-communication-link/uml-communication-link.ts index eefe9bd64..3659c1ec1 100644 --- a/src/main/packages/uml-communication-diagram/uml-communication-link/uml-communication-link.ts +++ b/src/main/packages/uml-communication-diagram/uml-communication-link/uml-communication-link.ts @@ -1,7 +1,7 @@ -import { DeepPartial } from 'redux'; import { CommunicationRelationshipType } from '..'; import { IUMLRelationship, UMLRelationship } from '../../../services/uml-relationship/uml-relationship'; import * as Apollon from '../../../typings'; +import { DeepPartial } from '../../../typings'; import { assign } from '../../../utils/fx/assign'; import { CommunicationLinkMessage, ICommunicationLinkMessage } from './uml-communiction-link-message'; import { computeBoundingBoxForElements, IBoundary } from '../../../utils/geometry/boundary'; diff --git a/src/main/packages/uml-communication-diagram/uml-communication-link/uml-communiction-link-message.ts b/src/main/packages/uml-communication-diagram/uml-communication-link/uml-communiction-link-message.ts index 6b9f6f733..81160ddc2 100644 --- a/src/main/packages/uml-communication-diagram/uml-communication-link/uml-communiction-link-message.ts +++ b/src/main/packages/uml-communication-diagram/uml-communication-link/uml-communiction-link-message.ts @@ -1,8 +1,9 @@ import { IUMLElement, UMLElement } from '../../../services/uml-element/uml-element'; import { ILayer } from '../../../services/layouter/layer'; import { ILayoutable } from '../../../services/layouter/layoutable'; -import { DeepPartial } from 'redux'; + import { CommunicationElementType } from '../index'; +import { DeepPartial } from '../../../typings'; export interface ICommunicationLinkMessage extends IUMLElement { direction: 'source' | 'target'; diff --git a/src/main/packages/uml-component-diagram/uml-component-subsystem/uml-component-subsystem.ts b/src/main/packages/uml-component-diagram/uml-component-subsystem/uml-component-subsystem.ts index 963132267..973e5ff53 100644 --- a/src/main/packages/uml-component-diagram/uml-component-subsystem/uml-component-subsystem.ts +++ b/src/main/packages/uml-component-diagram/uml-component-subsystem/uml-component-subsystem.ts @@ -1,9 +1,9 @@ -import { DeepPartial } from 'redux'; import { UMLPackage } from '../../common/uml-package/uml-package'; import { ComponentElementType, ComponentRelationshipType } from '..'; import { IUMLContainer } from '../../../services/uml-container/uml-container'; import * as Apollon from '../../../typings'; import { assign } from '../../../utils/fx/assign'; +import { DeepPartial } from '../../../typings'; export interface IUMLSubsystem extends IUMLContainer { stereotype: string; diff --git a/src/main/packages/uml-component-diagram/uml-component/uml-component-component.ts b/src/main/packages/uml-component-diagram/uml-component/uml-component-component.ts index efb243fea..265026cca 100644 --- a/src/main/packages/uml-component-diagram/uml-component/uml-component-component.ts +++ b/src/main/packages/uml-component-diagram/uml-component/uml-component-component.ts @@ -1,8 +1,8 @@ import { ComponentElementType, ComponentRelationshipType } from '..'; import { IUMLComponent, UMLComponent } from '../../common/uml-component/uml-component'; -import { DeepPartial } from 'redux'; import * as Apollon from '../../../typings'; import { assign } from '../../../utils/fx/assign'; +import { DeepPartial } from '../../../typings'; export class UMLComponentComponent extends UMLComponent { static supportedRelationships = [ diff --git a/src/main/packages/uml-deployment-diagram/uml-deployment-artifact/uml-deployment-artifact.ts b/src/main/packages/uml-deployment-diagram/uml-deployment-artifact/uml-deployment-artifact.ts index 8fde3191d..7730fd7a8 100644 --- a/src/main/packages/uml-deployment-diagram/uml-deployment-artifact/uml-deployment-artifact.ts +++ b/src/main/packages/uml-deployment-diagram/uml-deployment-artifact/uml-deployment-artifact.ts @@ -1,4 +1,3 @@ -import { DeepPartial } from 'redux'; import { DeploymentElementType, DeploymentRelationshipType } from '..'; import { ILayer } from '../../../services/layouter/layer'; import { ILayoutable } from '../../../services/layouter/layoutable'; @@ -7,6 +6,7 @@ import { assign } from '../../../utils/fx/assign'; import { IBoundary } from '../../../utils/geometry/boundary'; import { calculateNameBounds } from '../../../utils/name-bounds'; import { UMLElementType } from '../../uml-element-type'; +import { DeepPartial } from '../../../typings'; export class UMLDeploymentArtifact extends UMLElement { static supportedRelationships = [ diff --git a/src/main/packages/uml-deployment-diagram/uml-deployment-component/uml-component.ts b/src/main/packages/uml-deployment-diagram/uml-deployment-component/uml-component.ts index 61b9e4a4c..7e0a490b9 100644 --- a/src/main/packages/uml-deployment-diagram/uml-deployment-component/uml-component.ts +++ b/src/main/packages/uml-deployment-diagram/uml-deployment-component/uml-component.ts @@ -1,9 +1,9 @@ -import { DeepPartial } from 'redux'; import { DeploymentElementType, DeploymentRelationshipType } from '..'; import { IUMLComponent } from '../../common/uml-component/uml-component'; import * as Apollon from '../../../typings'; import { assign } from '../../../utils/fx/assign'; import { UMLComponent } from '../../common/uml-component/uml-component'; +import { DeepPartial } from '../../../typings'; export class UMLDeploymentComponent extends UMLComponent { static supportedRelationships = [ diff --git a/src/main/packages/uml-deployment-diagram/uml-deployment-node/uml-deployment-node.ts b/src/main/packages/uml-deployment-diagram/uml-deployment-node/uml-deployment-node.ts index 9c298f449..aca288653 100644 --- a/src/main/packages/uml-deployment-diagram/uml-deployment-node/uml-deployment-node.ts +++ b/src/main/packages/uml-deployment-diagram/uml-deployment-node/uml-deployment-node.ts @@ -1,7 +1,7 @@ -import { DeepPartial } from 'redux'; import { DeploymentElementType, DeploymentRelationshipType } from '..'; import { IUMLContainer } from '../../../services/uml-container/uml-container'; import * as Apollon from '../../../typings'; +import { DeepPartial } from '../../../typings'; import { assign } from '../../../utils/fx/assign'; import { UMLPackage } from '../../common/uml-package/uml-package'; import { UMLElementType } from '../../uml-element-type'; diff --git a/src/main/packages/uml-petri-net/uml-petri-net-arc/uml-petri-net-arc.ts b/src/main/packages/uml-petri-net/uml-petri-net-arc/uml-petri-net-arc.ts index be5c89842..7aa0d0062 100644 --- a/src/main/packages/uml-petri-net/uml-petri-net-arc/uml-petri-net-arc.ts +++ b/src/main/packages/uml-petri-net/uml-petri-net-arc/uml-petri-net-arc.ts @@ -1,6 +1,6 @@ import { PetriNetRelationshipType } from '../index'; import { IUMLRelationship, UMLRelationship } from '../../../services/uml-relationship/uml-relationship'; -import { DeepPartial } from 'redux'; +import { DeepPartial } from '../../../typings'; export class UMLPetriNetArc extends UMLRelationship { static features = { ...UMLRelationship.features, straight: true }; diff --git a/src/main/packages/uml-petri-net/uml-petri-net-place/uml-petri-net-place.ts b/src/main/packages/uml-petri-net/uml-petri-net-place/uml-petri-net-place.ts index 03422f567..e99ed23c0 100644 --- a/src/main/packages/uml-petri-net/uml-petri-net-place/uml-petri-net-place.ts +++ b/src/main/packages/uml-petri-net/uml-petri-net-place/uml-petri-net-place.ts @@ -4,8 +4,9 @@ import { IUMLElement, UMLElement } from '../../../services/uml-element/uml-eleme import { UMLElementFeatures } from '../../../services/uml-element/uml-element-features'; import { IBoundary } from '../../../utils/geometry/boundary'; import { UMLElementType } from '../../uml-element-type'; -import { DeepPartial } from 'redux'; + import * as Apollon from '../../../typings'; +import { DeepPartial } from '../../../typings'; import { PetriNetElementType } from '../index'; import { assign } from '../../../utils/fx/assign'; diff --git a/src/main/packages/uml-petri-net/uml-petri-net-transition/uml-petri-net-transition.ts b/src/main/packages/uml-petri-net/uml-petri-net-transition/uml-petri-net-transition.ts index 5d54e6110..e67ed60d4 100644 --- a/src/main/packages/uml-petri-net/uml-petri-net-transition/uml-petri-net-transition.ts +++ b/src/main/packages/uml-petri-net/uml-petri-net-transition/uml-petri-net-transition.ts @@ -5,7 +5,7 @@ import { IUMLElement, UMLElement } from '../../../services/uml-element/uml-eleme import { UMLElementFeatures } from '../../../services/uml-element/uml-element-features'; import { IBoundary } from '../../../utils/geometry/boundary'; import { UMLElementType } from '../../uml-element-type'; -import { DeepPartial } from 'redux'; +import { DeepPartial } from '../../../typings'; export class UMLPetriNetTransition extends UMLElement { static features: UMLElementFeatures = { ...UMLElement.features }; diff --git a/src/main/packages/uml-reachability-graph/uml-reachability-graph-arc/uml-reachability-graph-arc.ts b/src/main/packages/uml-reachability-graph/uml-reachability-graph-arc/uml-reachability-graph-arc.ts index dd5a3af60..38d919722 100644 --- a/src/main/packages/uml-reachability-graph/uml-reachability-graph-arc/uml-reachability-graph-arc.ts +++ b/src/main/packages/uml-reachability-graph/uml-reachability-graph-arc/uml-reachability-graph-arc.ts @@ -1,7 +1,8 @@ import { ReachabilityGraphRelationshipType } from '..'; import { IUMLRelationship, UMLRelationship } from '../../../services/uml-relationship/uml-relationship'; -import { DeepPartial } from 'redux'; + import { UMLRelationshipCenteredDescription } from '../../../services/uml-relationship/uml-relationship-centered-description'; +import { DeepPartial } from '../../../typings'; export class UMLReachabilityGraphArc extends UMLRelationshipCenteredDescription { static features = { ...UMLRelationship.features }; diff --git a/src/main/packages/uml-reachability-graph/uml-reachability-graph-marking/uml-reachability-graph-marking.ts b/src/main/packages/uml-reachability-graph/uml-reachability-graph-marking/uml-reachability-graph-marking.ts index 7820020eb..cc1298db3 100644 --- a/src/main/packages/uml-reachability-graph/uml-reachability-graph-marking/uml-reachability-graph-marking.ts +++ b/src/main/packages/uml-reachability-graph/uml-reachability-graph-marking/uml-reachability-graph-marking.ts @@ -3,8 +3,9 @@ import { ILayoutable } from '../../../services/layouter/layoutable'; import { UMLElement } from '../../../services/uml-element/uml-element'; import { UMLElementType } from '../../uml-element-type'; import * as Apollon from '../../../typings'; +import { DeepPartial } from '../../../typings'; import { ReachabilityGraphElementType } from '..'; -import { DeepPartial } from 'redux'; + import { calculateNameBounds } from '../../../utils/name-bounds'; export class UMLReachabilityGraphMarking extends UMLElement { diff --git a/src/main/packages/uml-use-case-diagram/uml-use-case-actor/uml-use-case-actor.ts b/src/main/packages/uml-use-case-diagram/uml-use-case-actor/uml-use-case-actor.ts index c54185d54..a6809902c 100644 --- a/src/main/packages/uml-use-case-diagram/uml-use-case-actor/uml-use-case-actor.ts +++ b/src/main/packages/uml-use-case-diagram/uml-use-case-actor/uml-use-case-actor.ts @@ -1,4 +1,3 @@ -import { DeepPartial } from 'redux'; import { UseCaseElementType } from '..'; import { ILayer } from '../../../services/layouter/layer'; import { ILayoutable } from '../../../services/layouter/layoutable'; @@ -6,6 +5,7 @@ import { IUMLElement, UMLElement } from '../../../services/uml-element/uml-eleme import { assign } from '../../../utils/fx/assign'; import { IBoundary } from '../../../utils/geometry/boundary'; import { UMLElementType } from '../../uml-element-type'; +import { DeepPartial } from '../../../typings'; export class UMLUseCaseActor extends UMLElement { type: UMLElementType = UseCaseElementType.UseCaseActor; diff --git a/src/main/scenes/application.tsx b/src/main/scenes/application.tsx index 16c2d8d16..eb654fbd2 100644 --- a/src/main/scenes/application.tsx +++ b/src/main/scenes/application.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { DeepPartial } from 'redux'; + import { Canvas, CanvasComponent } from '../components/canvas/canvas'; import { CanvasContext, CanvasProvider } from '../components/canvas/canvas-context'; import { Editor } from '../components/canvas/editor'; @@ -16,7 +16,7 @@ import { ILayer } from '../services/layouter/layer'; import { Locale } from '../services/editor/editor-types'; import { Layout } from './application-styles'; import { RootContext, RootProvider } from '../components/root/root-context'; -import { UMLModel } from '../typings'; +import { DeepPartial, UMLModel } from '../typings'; import { Patcher } from '../services/patcher'; import { MouseEventListener } from '../components/canvas/mouse-eventlistener'; diff --git a/src/main/scenes/svg.tsx b/src/main/scenes/svg.tsx index 68d9ef6a8..69bac1499 100644 --- a/src/main/scenes/svg.tsx +++ b/src/main/scenes/svg.tsx @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { DeepPartial } from 'redux'; + import { defaults, Styles } from '../components/theme/styles'; import { Components } from '../packages/components'; import { UMLElementType } from '../packages/uml-element-type'; @@ -11,6 +11,7 @@ import { UMLContainer } from '../services/uml-container/uml-container'; import { UMLElement } from '../services/uml-element/uml-element'; import { UMLRelationship } from '../services/uml-relationship/uml-relationship'; import * as Apollon from '../typings'; +import { DeepPartial } from '../typings'; import { computeBoundingBoxForElements, IBoundary } from '../utils/geometry/boundary'; import { Point } from '../utils/geometry/point'; import { update } from '../utils/update'; diff --git a/src/main/services/editor/editor-repository.ts b/src/main/services/editor/editor-repository.ts index e03463177..730fa64cf 100644 --- a/src/main/services/editor/editor-repository.ts +++ b/src/main/services/editor/editor-repository.ts @@ -1,9 +1,9 @@ import { ApollonView, - SetSelectionBoxAction, ChangeViewAction, - SetZoomFactorAction, EditorActionTypes, + SetSelectionBoxAction, + SetZoomFactorAction, } from './editor-types'; export class EditorRepository { diff --git a/src/main/services/patcher/patch-verifier.ts b/src/main/services/patcher/patch-verifier.ts index f5826e53c..a819686be 100644 --- a/src/main/services/patcher/patch-verifier.ts +++ b/src/main/services/patcher/patch-verifier.ts @@ -1,4 +1,4 @@ -import { debounce, debounceTime, groupBy, mergeMap, Subject, tap } from 'rxjs'; +import { debounceTime, groupBy, mergeMap, Subject, tap } from 'rxjs'; import { Patch } from './patcher-types'; import { Operation, ReplaceOperation } from 'fast-json-patch'; diff --git a/src/main/services/patcher/patcher-middleware.ts b/src/main/services/patcher/patcher-middleware.ts index daca17428..8f4c4212f 100644 --- a/src/main/services/patcher/patcher-middleware.ts +++ b/src/main/services/patcher/patcher-middleware.ts @@ -1,9 +1,15 @@ -import { Middleware } from 'redux'; +import { Middleware, Dispatch, Action } from 'redux'; import { Patcher } from './patcher'; -export type PatcherMiddleware = Middleware<{}, T>; +export type PatcherMiddleware = Middleware<{}, T, Dispatch>; -export type PatcherMiddlewareOptions = { +/** + * Options for the patcher middleware. + * @template T The external schema of the state. + * @template U The internal schema of the state. + * @template A The action type the middleware is supposed to handle. + */ +export type PatcherMiddlewareOptions = { /** * Transforms the state before checking for changes. This is useful * when the internal store schema differs from the schema exposed to the outside. @@ -26,7 +32,7 @@ export type PatcherMiddlewareOptions = { }; const _DefaultOptions = { - transform: (state: any) => state, + transform: (state: T) => state, selectDiscrete: () => true, selectContinuous: () => false, }; @@ -34,26 +40,29 @@ const _DefaultOptions = { /** * Creates a middleware that checks for changes to the state using * given patcher. The patcher in turn notifies subscribers of the changes it detects. + * @template T The external schema of the state (exposed to users, for example via patches). + * @template A The action type the middleware is supposed to handle. + * @template U The internal schema of the state (as managed in the store). * @param patcher The patcher to use. * @param options Options for the middleware. */ -export function createPatcherMiddleware( +export function createPatcherMiddleware( patcher: Patcher, - options: PatcherMiddlewareOptions = _DefaultOptions, -): PatcherMiddleware { - const transform = options.transform || _DefaultOptions.transform; + options: PatcherMiddlewareOptions = _DefaultOptions as PatcherMiddlewareOptions, +): PatcherMiddleware { + const transform = options.transform || (_DefaultOptions.transform as (s: U) => T); const selectDiscrete = options.selectDiscrete || _DefaultOptions.selectDiscrete; const selectContinuous = options.selectContinuous || _DefaultOptions.selectContinuous; return (store) => { patcher.initialize(transform(store.getState())); - return (next) => (action: A) => { - const res = next(action as any); + return (next) => (action) => { + const res = next(action); - if (selectDiscrete(action)) { + if (selectDiscrete(action as A)) { patcher.check(transform(store.getState())); - } else if (selectContinuous(action)) { + } else if (selectContinuous(action as A)) { patcher.checkContinuous(transform(store.getState())); } diff --git a/src/main/services/patcher/patcher-reducer.ts b/src/main/services/patcher/patcher-reducer.ts index 9753d9241..d38da30b9 100644 --- a/src/main/services/patcher/patcher-reducer.ts +++ b/src/main/services/patcher/patcher-reducer.ts @@ -1,8 +1,13 @@ -import { Reducer } from 'redux'; +import { Action, Reducer, UnknownAction } from 'redux'; import { Patcher } from './patcher'; -import { PatcherActionTypes } from './patcher-types'; -import { deepClone } from 'fast-json-patch'; +import { Patch, PatchAction, PatcherActionTypes } from './patcher-types'; +import { SignedPatch } from './patch-verifier'; +/** + * Options for the patcher reducer. + * @template T The external schema of the state. + * @template U The internal schema of the state. + */ export type PatcherReducerOptions = { /** * Transforms the state after applying the patch. This is useful @@ -32,35 +37,39 @@ export type PatcherReducerOptions = { }; const _DefaultOptions = { - transform: (state: any) => state, - transformInverse: (state: any) => state, - merge: (oldState: any, newState: any) => ({ ...oldState, ...newState }), + transform: (state: T) => state, + transformInverse: (state: T) => state, + merge: (oldState: T, newState: T) => ({ ...oldState, ...newState }), }; /** * Creates a reducer that applies patches to the state using * given patcher. + * @template T The external schema of the state (exposed to users, for example via patches). + * @template A The action type the reducer is supposed to handle. + * @template U The internal schema of the state (as managed in the store). * @param patcher The patcher to use. * @param options Options for the reducer. */ -export function createPatcherReducer( +export function createPatcherReducer( patcher: Patcher, - options: PatcherReducerOptions = _DefaultOptions, -): Reducer { - const transform = options.transform || _DefaultOptions.transform; - const transformInverse = options.transformInverse || _DefaultOptions.transformInverse; + options: PatcherReducerOptions = _DefaultOptions as PatcherReducerOptions, +): Reducer { + const transform = options.transform || (_DefaultOptions.transform as (s: T) => U); + const transformInverse = options.transformInverse || (_DefaultOptions.transformInverse as (s: U) => T); const merge = options.merge || _DefaultOptions.merge; - return (state, action) => { - const { type, payload } = action; - if (type === PatcherActionTypes.PATCH) { - const res = patcher.patch(payload, transformInverse(state as U)); + return (state, action: PatchAction | UnknownAction) => { + const { type } = action; + if (type === PatcherActionTypes.PATCH && state) { + const { payload } = action as unknown as PatchAction; + const res = patcher.patch(payload as Patch | SignedPatch, transformInverse(state)); if (res.patched) { return merge((state ?? {}) as U, transform(res.result)); } } - return state; + return state as U; }; } diff --git a/src/main/services/patcher/patcher-saga.ts b/src/main/services/patcher/patcher-saga.ts index b147f805e..17ef99303 100644 --- a/src/main/services/patcher/patcher-saga.ts +++ b/src/main/services/patcher/patcher-saga.ts @@ -1,4 +1,4 @@ -import { call, debounce, delay, put, select, take } from 'redux-saga/effects'; +import { call, debounce, delay, put, select } from 'redux-saga/effects'; import { SagaIterator } from 'redux-saga'; import { run } from '../../utils/actions/sagas'; diff --git a/src/main/services/uml-container/uml-container.ts b/src/main/services/uml-container/uml-container.ts index fc9fb35ae..17f20db74 100644 --- a/src/main/services/uml-container/uml-container.ts +++ b/src/main/services/uml-container/uml-container.ts @@ -1,7 +1,7 @@ -import { DeepPartial } from 'redux'; import { UMLDiagramType } from '../../packages/diagram-type'; import { UMLElementType } from '../../packages/uml-element-type'; import * as Apollon from '../../typings'; +import { DeepPartial } from '../../typings'; import { assign } from '../../utils/fx/assign'; import { ILayer } from '../layouter/layer'; import { ILayoutable } from '../layouter/layoutable'; diff --git a/src/main/services/uml-diagram/uml-diagram.ts b/src/main/services/uml-diagram/uml-diagram.ts index c298e0508..a02532f6f 100644 --- a/src/main/services/uml-diagram/uml-diagram.ts +++ b/src/main/services/uml-diagram/uml-diagram.ts @@ -1,10 +1,10 @@ -import { DeepPartial } from 'redux'; import { UMLDiagramType } from '../../packages/diagram-type'; import { assign } from '../../utils/fx/assign'; import { IBoundary } from '../../utils/geometry/boundary'; import { ILayer } from '../layouter/layer'; import { ILayoutable } from '../layouter/layoutable'; import { IUMLContainer, UMLContainer } from '../uml-container/uml-container'; +import { DeepPartial } from '../../typings'; export const DIAGRAM_MARGIN = 40; diff --git a/src/main/services/uml-element/selectable/selectable-repository.ts b/src/main/services/uml-element/selectable/selectable-repository.ts index 2ab05f617..865c8198c 100644 --- a/src/main/services/uml-element/selectable/selectable-repository.ts +++ b/src/main/services/uml-element/selectable/selectable-repository.ts @@ -1,6 +1,6 @@ import { AsyncAction } from '../../../utils/actions/actions'; import { DeselectAction, SelectableActionTypes, SelectAction } from './selectable-types'; -import { SetSelectionBoxAction, EditorActionTypes } from '../../editor/editor-types'; +import { EditorActionTypes, SetSelectionBoxAction } from '../../editor/editor-types'; export const Selectable = { select: diff --git a/src/main/services/uml-element/uml-element.ts b/src/main/services/uml-element/uml-element.ts index 520e7fc59..b976354d2 100644 --- a/src/main/services/uml-element/uml-element.ts +++ b/src/main/services/uml-element/uml-element.ts @@ -1,8 +1,8 @@ -import { DeepPartial } from 'redux'; import { UMLDiagramType } from '../../packages/diagram-type'; import { UMLElementType } from '../../packages/uml-element-type'; import { UMLRelationshipType } from '../../packages/uml-relationship-type'; import * as Apollon from '../../typings'; +import { DeepPartial } from '../../typings'; import { assign } from '../../utils/fx/assign'; import { IBoundary } from '../../utils/geometry/boundary'; import { Point } from '../../utils/geometry/point'; diff --git a/src/main/services/uml-relationship/uml-relationship.ts b/src/main/services/uml-relationship/uml-relationship.ts index 978dc4618..2dadbeeba 100644 --- a/src/main/services/uml-relationship/uml-relationship.ts +++ b/src/main/services/uml-relationship/uml-relationship.ts @@ -1,6 +1,6 @@ -import { DeepPartial } from 'redux'; import { UMLRelationshipType } from '../../packages/uml-relationship-type'; import * as Apollon from '../../typings'; +import { DeepPartial } from '../../typings'; import { assign } from '../../utils/fx/assign'; import { IPath } from '../../utils/geometry/path'; import { ILayer } from '../layouter/layer'; @@ -109,7 +109,7 @@ export abstract class UMLRelationship extends UMLElement implements IUMLRelation * * @param override - Override existing properties. */ - cloneRelationship(override?: DeepPartial): T { + cloneRelationship(override?: Partial): T { const Constructor = this.constructor as new (values?: DeepPartial) => T; const values: IUMLRelationship = { ...this, ...override, id: uuid() }; diff --git a/src/main/typings.ts b/src/main/typings.ts index 122b3dc67..845720378 100644 --- a/src/main/typings.ts +++ b/src/main/typings.ts @@ -1,4 +1,3 @@ -import { DeepPartial } from 'redux'; import { Styles } from './components/theme/styles'; import { UMLDiagramType } from './packages/diagram-type'; import { UMLElementType } from './packages/uml-element-type'; @@ -189,3 +188,9 @@ export type SVG = { height: number; }; }; + +export type DeepPartial = T extends object + ? { + [P in keyof T]?: DeepPartial; + } + : T; diff --git a/src/main/utils/actions/actions.ts b/src/main/utils/actions/actions.ts index 4e1d8107a..074e035f7 100644 --- a/src/main/utils/actions/actions.ts +++ b/src/main/utils/actions/actions.ts @@ -3,12 +3,12 @@ import { PutEffect } from 'redux-saga/effects'; import { ThunkAction, ThunkDispatch } from 'redux-thunk'; import { ModelState } from '../../components/store/model-state'; -export interface Action extends ReduxAction { +export interface Action extends ReduxAction { payload: object; undoable: boolean; } -export interface RedoableAction extends Action { +export interface RedoableAction extends Action { redoable: true; } diff --git a/src/main/utils/fx/assign.ts b/src/main/utils/fx/assign.ts index 84d385c22..f6b56ef08 100644 --- a/src/main/utils/fx/assign.ts +++ b/src/main/utils/fx/assign.ts @@ -1,4 +1,4 @@ -import { DeepPartial } from 'redux'; +import { DeepPartial } from '../../typings'; export const assign = (target: T, source?: DeepPartial): T => { for (const key in source) { @@ -18,7 +18,7 @@ export const assign = (target: T, source?: Dee if (target === undefined) { target = {} as T; } - target[key] = source[key] as T[Extract]; + target[key] = source[key] as T[Extract, string>]; } } diff --git a/src/main/utils/update.ts b/src/main/utils/update.ts index 55b2ccb35..3c8626244 100644 --- a/src/main/utils/update.ts +++ b/src/main/utils/update.ts @@ -1,4 +1,4 @@ -import { DeepPartial } from 'redux'; +import { DeepPartial } from '../typings'; type update = (target: T, source: DeepPartial) => T; diff --git a/src/tests/unit/components/uml-element/assessable/assessable-test.tsx b/src/tests/unit/components/uml-element/assessable/assessable-test.tsx index 120159506..13d294b78 100644 --- a/src/tests/unit/components/uml-element/assessable/assessable-test.tsx +++ b/src/tests/unit/components/uml-element/assessable/assessable-test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { UMLClass } from '../../../../../main/packages/uml-class-diagram/uml-class/uml-class'; import { ModelState } from '../../../../../main/components/store/model-state'; -import { DeepPartial } from 'redux'; + import { UMLClassAttribute } from '../../../../../main/packages/uml-class-diagram/uml-class-attribute/uml-class-attribute'; import { UMLClassMethod } from '../../../../../main/packages/uml-class-diagram/uml-class-method/uml-class-method'; import { render } from '@testing-library/react'; @@ -13,6 +13,7 @@ import { assessable } from '../../../../../main/components/uml-element/assessabl import { IAssessment } from '../../../../../main/services/assessment/assessment'; import { Theme } from '../../../../../main/components/theme/theme'; import { UMLClassInheritance } from '../../../../../main/packages/uml-class-diagram/uml-class-inheritance/uml-class-inheritance'; +import { DeepPartial } from '../../../../../main'; class MockComponent extends React.Component { render() { diff --git a/src/tests/unit/components/uml-element/hoverable/hoverable-test.tsx b/src/tests/unit/components/uml-element/hoverable/hoverable-test.tsx index babda3af9..921422be5 100644 --- a/src/tests/unit/components/uml-element/hoverable/hoverable-test.tsx +++ b/src/tests/unit/components/uml-element/hoverable/hoverable-test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { UMLClass } from '../../../../../main/packages/uml-class-diagram/uml-class/uml-class'; import { ModelState } from '../../../../../main/components/store/model-state'; -import { DeepPartial } from 'redux'; + import { UMLClassAttribute } from '../../../../../main/packages/uml-class-diagram/uml-class-attribute/uml-class-attribute'; import { UMLClassMethod } from '../../../../../main/packages/uml-class-diagram/uml-class-method/uml-class-method'; import { fireEvent, render } from '@testing-library/react'; @@ -11,6 +11,7 @@ import { MockStoreEnhanced } from 'redux-mock-store'; import { Provider } from 'react-redux'; import { UMLElementRepository } from '../../../../../main/services/uml-element/uml-element-repository'; import { getMockedStore } from '../../../test-utils/test-utils'; +import { DeepPartial } from '../../../../../main'; class MockComponent extends React.Component { render() { diff --git a/src/tests/unit/components/uml-element/selectable/selectable-test.tsx b/src/tests/unit/components/uml-element/selectable/selectable-test.tsx index 2052cf1f0..e3b03320e 100644 --- a/src/tests/unit/components/uml-element/selectable/selectable-test.tsx +++ b/src/tests/unit/components/uml-element/selectable/selectable-test.tsx @@ -42,7 +42,7 @@ describe('test selectable HOC', () => { const elementToSelect = elements[0]; // element must be hovered to trigger select store = getMockedStore({ hovered: [elementToSelect.id] }, elements); - const expectedAction = UMLElementRepository.select(elementToSelect.id)(store.dispatch, store.getState, undefined); + const expectedAction = store.dispatch(UMLElementRepository.select(elementToSelect.id)); const { container } = render( @@ -95,12 +95,8 @@ describe('test selectable HOC', () => { // element must be hovered to trigger deselect // element must be already selected to trigger deselect store = getMockedStore({ selected: [alreadySelectedElement.id], hovered: [elementToSelect.id] }, elements); - const expectedAction1 = UMLElementRepository.deselect(alreadySelectedElement.id)( - store.dispatch, - store.getState, - undefined, - ); - const expectedAction2 = UMLElementRepository.select(elementToSelect.id)(store.dispatch, store.getState, undefined); + const expectedAction1 = store.dispatch(UMLElementRepository.deselect(alreadySelectedElement.id)); + const expectedAction2 = store.dispatch(UMLElementRepository.select(elementToSelect.id)); const { container } = render( @@ -126,7 +122,7 @@ describe('test selectable HOC', () => { // element must be hovered to trigger deselect // element must be already selected to trigger deselect store = getMockedStore({ selected: [alreadySelectedElement.id], hovered: [elementToSelect.id] }, elements); - const expectedAction = UMLElementRepository.select(elementToSelect.id)(store.dispatch, store.getState, undefined); + const expectedAction = store.dispatch(UMLElementRepository.select(elementToSelect.id)); const { container } = render( diff --git a/src/tests/unit/services/patcher/patcher-reducer-test.ts b/src/tests/unit/services/patcher/patcher-reducer-test.ts index 1d85ed807..9f679771b 100644 --- a/src/tests/unit/services/patcher/patcher-reducer-test.ts +++ b/src/tests/unit/services/patcher/patcher-reducer-test.ts @@ -1,6 +1,4 @@ -import { createPatcherReducer } from '../../../../main/services/patcher/patcher-reducer'; -import { Patcher } from '../../../../main/services/patcher/patcher'; -import { PatcherRepository } from '../../../../main/services/patcher'; +import { createPatcherReducer, Patcher, PatcherRepository } from '../../../../main/services/patcher'; describe('test patcher reducer.', () => { test('it invokes the patcher when receiving a patch action.', () => { @@ -8,7 +6,7 @@ describe('test patcher reducer.', () => { patcher.initialize({}); const reducer = createPatcherReducer(patcher); - const nextState = reducer({}, PatcherRepository.patch([{ op: 'add', path: '/x', value: 42 }])); + const nextState = reducer({}, PatcherRepository.patch([{ op: 'add', path: '/x', value: 42 }]) as any); expect(nextState).toEqual({ x: 42 }); expect(patcher.snapshot).toEqual({ x: 42 }); @@ -22,7 +20,7 @@ describe('test patcher reducer.', () => { patcher.initialize({}); const reducer = createPatcherReducer(patcher, { transform: cb, transformInverse: inv }); - const nextState = reducer({ y: 41 }, PatcherRepository.patch([{ op: 'add', path: '/x', value: 42 }])); + const nextState = reducer({ y: 41 }, PatcherRepository.patch([{ op: 'add', path: '/x', value: 42 }]) as any); expect(nextState).toEqual({ y: 42 }); }); @@ -32,7 +30,7 @@ describe('test patcher reducer.', () => { patcher.initialize({}); const reducer = createPatcherReducer(patcher); - const nextState = reducer({ y: 41 }, PatcherRepository.patch([{ op: 'add', path: '/x', value: 42 }])); + const nextState = reducer({ y: 41 }, PatcherRepository.patch([{ op: 'add', path: '/x', value: 42 }]) as any); expect(nextState).toEqual({ x: 42, y: 41 }); }); @@ -44,7 +42,7 @@ describe('test patcher reducer.', () => { patcher.initialize({}); const reducer = createPatcherReducer(patcher, { merge: cb }); - const nextState = reducer({ y: 41 }, PatcherRepository.patch([{ op: 'add', path: '/x', value: 42 }])); + const nextState = reducer({ y: 41 }, PatcherRepository.patch([{ op: 'add', path: '/x', value: 42 }]) as any); expect(nextState).toEqual({ x: 42, y: 41 }); }); diff --git a/src/tests/unit/services/patcher/patcher-saga-test.ts b/src/tests/unit/services/patcher/patcher-saga-test.ts index 2200d70fa..8070d1fa5 100644 --- a/src/tests/unit/services/patcher/patcher-saga-test.ts +++ b/src/tests/unit/services/patcher/patcher-saga-test.ts @@ -1,4 +1,4 @@ -import { call, debounce, delay, select, take } from 'redux-saga/effects'; +import { call, debounce, delay, select } from 'redux-saga/effects'; import { patchLayout } from '../../../../main/services/patcher/patcher-saga'; import { PatcherActionTypes, PatcherRepository } from '../../../../main/services/patcher'; diff --git a/src/tests/unit/test-utils/test-utils.tsx b/src/tests/unit/test-utils/test-utils.tsx index 33506fc9b..8efb0273d 100644 --- a/src/tests/unit/test-utils/test-utils.tsx +++ b/src/tests/unit/test-utils/test-utils.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { Store } from 'redux'; -import thunk, { ThunkDispatch } from 'redux-thunk'; -import createMockStore, { MockStoreEnhanced } from 'redux-mock-store'; +import { thunk, ThunkDispatch } from 'redux-thunk'; +import configureStore, { MockStoreEnhanced } from 'redux-mock-store'; import { ModelState, PartialModelState } from '../../../main/components/store/model-state'; import { UMLDiagram } from '../../../main/services/uml-diagram/uml-diagram'; import { ApollonMode } from '../../../main'; @@ -16,9 +16,6 @@ import '@testing-library/jest-dom'; export type DispatchExts = ThunkDispatch; -const middleware = [thunk]; -const mockStore = createMockStore(middleware); - const createModelStateFromPartialModelState = ( partialModelState?: PartialModelState, elements?: IUMLElement[], @@ -77,10 +74,8 @@ const createModelStateFromPartialModelState = ( export const getMockedStore = ( modelState?: PartialModelState, elements?: IUMLElement[], -): MockStoreEnhanced => { - // initial state - const storeState = createModelStateFromPartialModelState(modelState, elements); - return mockStore(storeState); +): MockStoreEnhanced => { + return configureStore([thunk as any])(createModelStateFromPartialModelState(modelState, elements)); }; const createSVG = (): SVGSVGElement => {