From 62ec8d2272a8f50b7ec5a0f84b8e81921c263de0 Mon Sep 17 00:00:00 2001 From: Eugene Ghanizadeh Khoub Date: Sun, 19 Nov 2023 22:29:13 +0100 Subject: [PATCH 1/4] add support for remote selection --- src/main/apollon-editor.ts | 24 +++++++++ src/main/components/store/model-state.ts | 2 + .../components/uml-element/canvas-element.tsx | 9 ++-- .../uml-element/canvas-relationship.tsx | 15 ++++++ .../packages/uml-element-selector-type.ts | 1 - src/main/services/actions.ts | 2 + src/main/services/reducer.ts | 2 + .../remote-selectable-types.ts | 37 +++++++++++++ .../remote-selection-reducer.ts | 50 ++++++++++++++++++ .../remote-selection-repository.ts | 52 +++++++++++++++++++ .../uml-element/uml-element-repository.ts | 2 + src/main/services/uml-element/uml-element.ts | 4 -- src/main/typings.ts | 1 - src/tests/unit/test-utils/test-utils.tsx | 1 + 14 files changed, 193 insertions(+), 9 deletions(-) create mode 100644 src/main/services/uml-element/remote-selectable/remote-selectable-types.ts create mode 100644 src/main/services/uml-element/remote-selectable/remote-selection-reducer.ts create mode 100644 src/main/services/uml-element/remote-selectable/remote-selection-repository.ts diff --git a/src/main/apollon-editor.ts b/src/main/apollon-editor.ts index 70fe69f74..bcd80357f 100644 --- a/src/main/apollon-editor.ts +++ b/src/main/apollon-editor.ts @@ -330,6 +330,30 @@ export class ApollonEditor { return id; } + /** + * Displays given elements and relationships as selected or deselected by + * a given remote selector, identified by a name and a color. + * @param selectorName name of the remote selector + * @param selectorColor color of the remote selector + * @param select ids of elements and relationships to be selected + * @param deselect ids of elements and relationships to be deselected + */ + remoteSelect(selectorName: string, selectorColor: string, select: string[], deselect?: string[]) { + this.store?.dispatch( + UMLElementRepository.remoteSelectDeselect({ name: selectorName, color: selectorColor }, select, deselect || []), + ); + } + + /** + * Allows a given set of remote selectors for remotely selecting and deselecting + * elements and relationships, removing all other selectors. This won't have an effect + * on future remote selections. + * @param allowedSelectors allowed remote selectors + */ + pruneRemoteSelectors(allowedSelectors: { name: string; color: string }[]) { + this.store?.dispatch(UMLElementRepository.pruneRemoteSelectors(allowedSelectors)); + } + /** * Removes error subscription, so that the corresponding callback is no longer executed when an error occurs. * @param subscriptionId subscription identifier diff --git a/src/main/components/store/model-state.ts b/src/main/components/store/model-state.ts index f99d8687e..858fa2551 100644 --- a/src/main/components/store/model-state.ts +++ b/src/main/components/store/model-state.ts @@ -27,6 +27,7 @@ import { UMLDiagram } from '../../services/uml-diagram/uml-diagram'; import { CopyState } from '../../services/copypaste/copy-types'; import { LastActionState } from '../../services/last-action/last-action-types'; import { arrayToInclusionMap, inclusionMapToArray } from './util'; +import { RemoteSelectionState } from '../../services/uml-element/remote-selectable/remote-selectable-types'; export type PartialModelState = Omit, 'editor'> & { editor?: Partial }; @@ -35,6 +36,7 @@ export interface ModelState { diagram: UMLDiagramState; hovered: HoverableState; selected: SelectableState; + remoteSelection: RemoteSelectionState; moving: MovableState; resizing: ResizableState; connecting: ConnectableState; diff --git a/src/main/components/uml-element/canvas-element.tsx b/src/main/components/uml-element/canvas-element.tsx index dac51641d..59386cd7f 100644 --- a/src/main/components/uml-element/canvas-element.tsx +++ b/src/main/components/uml-element/canvas-element.tsx @@ -10,6 +10,7 @@ import { UMLElementRepository } from '../../services/uml-element/uml-element-rep import { ModelState } from '../store/model-state'; import { withTheme, withThemeProps } from '../theme/styles'; import { UMLElementComponentProps } from './uml-element-component-props'; +import { UMLElementSelectorType } from '../../packages/uml-element-selector-type'; const STROKE = 5; @@ -19,6 +20,7 @@ type OwnProps = { child?: ComponentClass } & UMLElemen type StateProps = { hovered: boolean; selected: boolean; + remoteSelectors: UMLElementSelectorType[]; moving: boolean; interactive: boolean; interactable: boolean; @@ -36,6 +38,7 @@ const enhance = compose>( (state, props) => ({ hovered: state.hovered[0] === props.id, selected: state.selected.includes(props.id), + remoteSelectors: state.remoteSelection[props.id] || [], moving: state.moving.includes(props.id), interactive: state.interactive.includes(props.id), interactable: state.editor.view === ApollonView.Exporting || state.editor.view === ApollonView.Highlight, @@ -51,6 +54,7 @@ class CanvasElementComponent extends Component { const { hovered, selected, + remoteSelectors, moving, interactive, interactable, @@ -79,7 +83,6 @@ class CanvasElementComponent extends Component { ? element.fillColor : theme.color.background; - const selectedByList = element.selectedBy || []; return ( { pointerEvents="none" /> )} - {selectedByList.length > 0 && ( + {remoteSelectors.length > 0 && ( - {selectedByList.map((selectedBy, index) => { + {remoteSelectors.map((selectedBy, index) => { const indicatorPosition = 'translate(' + (element.bounds.width + STROKE) + ' ' + index * 32 + ')'; return ( diff --git a/src/main/components/uml-element/canvas-relationship.tsx b/src/main/components/uml-element/canvas-relationship.tsx index 0cde1c676..6b833cc2f 100644 --- a/src/main/components/uml-element/canvas-relationship.tsx +++ b/src/main/components/uml-element/canvas-relationship.tsx @@ -14,12 +14,14 @@ import { getClientEventCoordinates } from '../../utils/touch-event'; import { ModelState } from '../store/model-state'; import { withTheme, withThemeProps } from '../theme/styles'; import { UMLElementComponentProps } from './uml-element-component-props'; +import { UMLElementSelectorType } from '../../packages/uml-element-selector-type'; type OwnProps = UMLElementComponentProps & SVGProps; type StateProps = { hovered: boolean; selected: boolean; + remoteSelectors: UMLElementSelectorType[]; interactive: boolean; interactable: boolean; reconnecting: boolean; @@ -55,6 +57,7 @@ const enhance = compose>( (state, props) => ({ hovered: state.hovered[0] === props.id, selected: state.selected.includes(props.id), + remoteSelectors: state.remoteSelection[props.id] || [], interactive: state.interactive.includes(props.id), interactable: state.editor.view === ApollonView.Exporting || state.editor.view === ApollonView.Highlight, reconnecting: !!state.reconnecting[props.id], @@ -77,6 +80,7 @@ export class CanvasRelationshipComponent extends Component { const { hovered, selected, + remoteSelectors, interactive, interactable, reconnecting, @@ -127,6 +131,17 @@ export class CanvasRelationshipComponent extends Component { pointerEvents={disabled ? 'none' : 'stroke'} > + {remoteSelectors.length > 0 && + remoteSelectors.map((selector) => ( + + ))} {children} {midPoints.map((point, index) => { diff --git a/src/main/packages/uml-element-selector-type.ts b/src/main/packages/uml-element-selector-type.ts index 3e8d20ef9..f96117409 100644 --- a/src/main/packages/uml-element-selector-type.ts +++ b/src/main/packages/uml-element-selector-type.ts @@ -1,5 +1,4 @@ export type UMLElementSelectorType = { - elementId: string; name: string; color: string; }; diff --git a/src/main/services/actions.ts b/src/main/services/actions.ts index 2ea92a7c3..4d6a2a3ea 100644 --- a/src/main/services/actions.ts +++ b/src/main/services/actions.ts @@ -11,6 +11,7 @@ import { MovingActions } from './uml-element/movable/moving-types'; import { ResizableActions } from './uml-element/resizable/resizable-types'; import { ResizingActions } from './uml-element/resizable/resizing-types'; import { SelectableActions } from './uml-element/selectable/selectable-types'; +import { RemoteSelectionActions } from './uml-element/remote-selectable/remote-selectable-types'; import { UMLElementActions } from './uml-element/uml-element-types'; import { UpdatableActions } from './uml-element/updatable/updatable-types'; import { ReconnectableActions } from './uml-relationship/reconnectable/reconnectable-types'; @@ -36,6 +37,7 @@ export type Actions = | ResizableActions | ResizingActions | SelectableActions + | RemoteSelectionActions | UpdatableActions | AssessmentActions | UndoActions diff --git a/src/main/services/reducer.ts b/src/main/services/reducer.ts index c641b849f..0c848226d 100644 --- a/src/main/services/reducer.ts +++ b/src/main/services/reducer.ts @@ -21,6 +21,7 @@ import { ReconnectableReducer } from './uml-relationship/reconnectable/reconnect import { UMLRelationshipReducer } from './uml-relationship/uml-relationship-reducer'; import { CopyReducer } from './copypaste/copy-reducer'; import { LastActionReducer } from './last-action/last-action-reducer'; +import { RemoteSelectionReducer } from './uml-element/remote-selectable/remote-selection-reducer'; const reduce = (intial: S, ...reducerList: Reducer[]): Reducer => @@ -40,6 +41,7 @@ export const reducers: ReducersMapObject = { updating: UpdatableReducer, copy: CopyReducer, lastAction: LastActionReducer, + remoteSelection: RemoteSelectionReducer, elements: reduce( {}, UMLContainerReducer, diff --git a/src/main/services/uml-element/remote-selectable/remote-selectable-types.ts b/src/main/services/uml-element/remote-selectable/remote-selectable-types.ts new file mode 100644 index 000000000..242d69e10 --- /dev/null +++ b/src/main/services/uml-element/remote-selectable/remote-selectable-types.ts @@ -0,0 +1,37 @@ +import { UMLElementSelectorType } from '../../../packages/uml-element-selector-type'; +import { Action } from '../../../utils/actions/actions'; +import { UMLElementState } from '../uml-element-types'; + +export const enum RemoteSelectionActionTypes { + SELECTION_CHANGE = '@@element/remote-selection/CHANGE', + PRUNE_SELECTORS = '@@element/remote-selection/PRUNE_SELECTORS', +} + +export const enum RemoteSelectionChangeTypes { + SELECT = '@@element/remote-selection/SELECT', + DESELECT = '@@element/remote-selection/DESELECT', +} + +export interface RemoteSelectionChange { + type: RemoteSelectionChangeTypes.SELECT | RemoteSelectionChangeTypes.DESELECT; + id: string; +} + +export type RemoteSelectionChangeAction = Action & { + payload: { + changes: RemoteSelectionChange[]; + selector: UMLElementSelectorType; + }; +}; + +export type RemoteSelectionPruneSelectorsAction = Action & { + payload: { + allowedSelectors: UMLElementSelectorType[]; + }; +}; + +export type RemoteSelectionState = { + [id: string]: UMLElementSelectorType[]; +}; + +export type RemoteSelectionActions = RemoteSelectionChangeAction | RemoteSelectionPruneSelectorsAction; diff --git a/src/main/services/uml-element/remote-selectable/remote-selection-reducer.ts b/src/main/services/uml-element/remote-selectable/remote-selection-reducer.ts new file mode 100644 index 000000000..c3974624b --- /dev/null +++ b/src/main/services/uml-element/remote-selectable/remote-selection-reducer.ts @@ -0,0 +1,50 @@ +import { Reducer } from 'redux'; +import { + RemoteSelectionActionTypes, + RemoteSelectionChangeTypes, + RemoteSelectionState, +} from './remote-selectable-types'; +import { Actions } from '../../actions'; +import { UMLElementSelectorType } from '../../../packages/uml-element-selector-type'; + +const sameSelector = (a: UMLElementSelectorType, b: UMLElementSelectorType) => { + return a.name === b.name && a.color === b.color; +}; + +export const RemoteSelectionReducer: Reducer = (state = {}, action) => { + switch (action.type) { + case RemoteSelectionActionTypes.SELECTION_CHANGE: + const { payload } = action; + const { selector, changes } = payload; + + return changes.reduce((selection, change) => { + const { id } = change; + const selectors: UMLElementSelectorType[] = [...(selection[id] ?? [])]; + + if (change.type === RemoteSelectionChangeTypes.SELECT && !selectors.some((s) => sameSelector(s, selector))) { + selectors.push(selector); + } else if (change.type === RemoteSelectionChangeTypes.DESELECT) { + const index = selectors.findIndex((s) => sameSelector(s, selector)); + if (index >= 0) { + selectors.splice(index, 1); + } + } + + return { + ...selection, + [id]: selectors, + }; + }, state); + + case RemoteSelectionActionTypes.PRUNE_SELECTORS: + const { allowedSelectors } = action.payload; + + return Object.fromEntries( + Object.entries(state).map(([id, selectors]) => { + return [id, selectors.filter((s) => allowedSelectors.some((selector) => sameSelector(s, selector)))]; + }), + ); + } + + return state; +}; diff --git a/src/main/services/uml-element/remote-selectable/remote-selection-repository.ts b/src/main/services/uml-element/remote-selectable/remote-selection-repository.ts new file mode 100644 index 000000000..f1f61e9ca --- /dev/null +++ b/src/main/services/uml-element/remote-selectable/remote-selection-repository.ts @@ -0,0 +1,52 @@ +import { UMLElementSelectorType } from '../../../packages/uml-element-selector-type'; +import { + RemoteSelectionActionTypes, + RemoteSelectionChangeTypes, + RemoteSelectionChange, + RemoteSelectionChangeAction, + RemoteSelectionPruneSelectorsAction, +} from './remote-selectable-types'; + +export const RemoteSelectable = { + remoteSelectionChange: ( + selector: UMLElementSelectorType, + changes: RemoteSelectionChange[], + ): RemoteSelectionChangeAction => ({ + type: RemoteSelectionActionTypes.SELECTION_CHANGE, + payload: { + selector, + changes, + }, + undoable: false, + }), + + remoteSelect: (selector: UMLElementSelectorType, ids: string[]): RemoteSelectionChangeAction => + RemoteSelectable.remoteSelectionChange( + selector, + ids.map((id) => ({ type: RemoteSelectionChangeTypes.SELECT, id })), + ), + + remoteDeselect: (selector: UMLElementSelectorType, ids: string[]): RemoteSelectionChangeAction => + RemoteSelectable.remoteSelectionChange( + selector, + ids.map((id) => ({ type: RemoteSelectionChangeTypes.DESELECT, id })), + ), + + remoteSelectDeselect: ( + selector: UMLElementSelectorType, + select: string[], + deselect: string[], + ): RemoteSelectionChangeAction => + RemoteSelectable.remoteSelectionChange(selector, [ + ...select.map((id) => ({ type: RemoteSelectionChangeTypes.SELECT, id })), + ...deselect.map((id) => ({ type: RemoteSelectionChangeTypes.DESELECT, id })), + ]), + + pruneRemoteSelectors: (allowedSelectors: UMLElementSelectorType[]): RemoteSelectionPruneSelectorsAction => ({ + type: RemoteSelectionActionTypes.PRUNE_SELECTORS, + payload: { + allowedSelectors, + }, + undoable: false, + }), +}; diff --git a/src/main/services/uml-element/uml-element-repository.ts b/src/main/services/uml-element/uml-element-repository.ts index b07438800..2e1af06cc 100644 --- a/src/main/services/uml-element/uml-element-repository.ts +++ b/src/main/services/uml-element/uml-element-repository.ts @@ -4,6 +4,7 @@ import { Interactable } from './interactable/interactable-repository'; import { Movable } from './movable/movable-repository'; import { Resizable } from './resizable/resizable-repository'; import { Selectable } from './selectable/selectable-repository'; +import { RemoteSelectable } from './remote-selectable/remote-selection-repository'; import { UMLElementCommonRepository } from './uml-element-common-repository'; import { Updatable } from './updatable/updatable-repository'; @@ -11,6 +12,7 @@ export const UMLElementRepository = { ...UMLElementCommonRepository, ...Hoverable, ...Selectable, + ...RemoteSelectable, ...Movable, ...Resizable, ...Connectable, diff --git a/src/main/services/uml-element/uml-element.ts b/src/main/services/uml-element/uml-element.ts index 11189385d..2d3d6aa45 100644 --- a/src/main/services/uml-element/uml-element.ts +++ b/src/main/services/uml-element/uml-element.ts @@ -33,7 +33,6 @@ export interface IUMLElement { textColor?: string; /** Note to show for element's assessment */ assessmentNote?: string; - selectedBy?: UMLElementSelectorType[]; isManuallyLayouted?: boolean; } @@ -91,7 +90,6 @@ export abstract class UMLElement implements IUMLElement, ILayoutable { strokeColor?: string; textColor?: string; assessmentNote?: string; - selectedBy?: UMLElementSelectorType[]; resizeFrom: ResizeFrom = ResizeFrom.BOTTOMRIGHT; constructor(values?: DeepPartial) { @@ -123,7 +121,6 @@ export abstract class UMLElement implements IUMLElement, ILayoutable { strokeColor: this.strokeColor, textColor: this.textColor, assessmentNote: this.assessmentNote, - selectedBy: this.selectedBy, }; } @@ -139,7 +136,6 @@ export abstract class UMLElement implements IUMLElement, ILayoutable { this.strokeColor = values.strokeColor; this.textColor = values.textColor; this.assessmentNote = values.assessmentNote; - this.selectedBy = values.selectedBy; } abstract render(canvas: ILayer): ILayoutable[]; diff --git a/src/main/typings.ts b/src/main/typings.ts index 97e08226f..b09faf0e7 100644 --- a/src/main/typings.ts +++ b/src/main/typings.ts @@ -55,7 +55,6 @@ export type UMLModelElement = { strokeColor?: string; textColor?: string; assessmentNote?: string; - selectedBy?: UMLElementSelectorType[]; }; export type UMLElement = UMLModelElement & { diff --git a/src/tests/unit/test-utils/test-utils.tsx b/src/tests/unit/test-utils/test-utils.tsx index 590d17024..33506fc9b 100644 --- a/src/tests/unit/test-utils/test-utils.tsx +++ b/src/tests/unit/test-utils/test-utils.tsx @@ -34,6 +34,7 @@ const createModelStateFromPartialModelState = ( reconnecting: partialModelState?.reconnecting ? partialModelState.reconnecting : {}, resizing: partialModelState?.resizing ? partialModelState.resizing : [], selected: partialModelState?.selected ? partialModelState.selected : [], + remoteSelection: partialModelState?.remoteSelection ? partialModelState.remoteSelection : {}, updating: partialModelState?.updating ? partialModelState.updating : [], hovered: partialModelState?.hovered ? partialModelState.hovered : [], editor: { From 8448377e4db118283c4890b816958a1db356f4f8 Mon Sep 17 00:00:00 2001 From: Eugene Ghanizadeh Khoub Date: Mon, 20 Nov 2023 01:13:23 +0100 Subject: [PATCH 2/4] make codacy happy? --- src/main/apollon-editor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/apollon-editor.ts b/src/main/apollon-editor.ts index bcd80357f..b05789cb4 100644 --- a/src/main/apollon-editor.ts +++ b/src/main/apollon-editor.ts @@ -338,7 +338,7 @@ export class ApollonEditor { * @param select ids of elements and relationships to be selected * @param deselect ids of elements and relationships to be deselected */ - remoteSelect(selectorName: string, selectorColor: string, select: string[], deselect?: string[]) { + remoteSelect(selectorName: string, selectorColor: string, select: string[], deselect?: string[]): void { this.store?.dispatch( UMLElementRepository.remoteSelectDeselect({ name: selectorName, color: selectorColor }, select, deselect || []), ); @@ -350,7 +350,7 @@ export class ApollonEditor { * on future remote selections. * @param allowedSelectors allowed remote selectors */ - pruneRemoteSelectors(allowedSelectors: { name: string; color: string }[]) { + pruneRemoteSelectors(allowedSelectors: { name: string; color: string }[]): void { this.store?.dispatch(UMLElementRepository.pruneRemoteSelectors(allowedSelectors)); } From c1eac4753735057a9c45a4b2c0e022f2a53294c4 Mon Sep 17 00:00:00 2001 From: Eugene Ghanizadeh Khoub Date: Mon, 20 Nov 2023 08:45:04 +0100 Subject: [PATCH 3/4] add tests --- src/tests/unit/apollon-editor-test.tsx | 41 +++++++++++++++++++ .../remote-selectable-service-test.ts | 33 +++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/tests/unit/services/uml-element/remote-selectable/remote-selectable-service-test.ts diff --git a/src/tests/unit/apollon-editor-test.tsx b/src/tests/unit/apollon-editor-test.tsx index 6c740d98b..c359f216a 100644 --- a/src/tests/unit/apollon-editor-test.tsx +++ b/src/tests/unit/apollon-editor-test.tsx @@ -441,6 +441,47 @@ describe('test apollon editor ', () => { }, 500); }, 500); }); + + it('remoteSelection.', () => { + const state = ModelState.fromModel(testClassDiagram as any); + const elements = Object.keys(state.elements!).map((id) => state.elements![id]); + const store = getRealStore(state, elements); + // inject store + Object.defineProperty(editor, 'store', { value: store }); + + const elA = 'c10b995a-036c-4e9e-aa67-0570ada5cb6a'; + const elB = '4d3509e-0dce-458b-bf62-f3555497a5a4'; + const john = { name: 'john', color: 'red' }; + const jane = { name: 'jane', color: 'blue' }; + + act(() => { + editor.remoteSelect(john.name, john.color, [elA]); + }); + + expect(store.getState().remoteSelection[elA]).toEqual([john]); + + act(() => { + editor.remoteSelect(jane.name, jane.color, [elA, elB]); + }); + + expect(store.getState().remoteSelection[elA]).toEqual([john, jane]); + expect(store.getState().remoteSelection[elB]).toEqual([jane]); + + act(() => { + editor.remoteSelect(john.name, john.color, [elB], [elA]); + }); + + expect(store.getState().remoteSelection[elA]).toEqual([jane]); + expect(store.getState().remoteSelection[elB]).toEqual([jane, john]); + + act(() => { + editor.pruneRemoteSelectors([john]); + }); + + expect(store.getState().remoteSelection[elA]).toEqual([]); + expect(store.getState().remoteSelection[elB]).toEqual([john]); + }); + it('set type to UseCaseDiagram', () => { act(() => { editor.type = UMLDiagramType.UseCaseDiagram; diff --git a/src/tests/unit/services/uml-element/remote-selectable/remote-selectable-service-test.ts b/src/tests/unit/services/uml-element/remote-selectable/remote-selectable-service-test.ts new file mode 100644 index 000000000..5fba9cced --- /dev/null +++ b/src/tests/unit/services/uml-element/remote-selectable/remote-selectable-service-test.ts @@ -0,0 +1,33 @@ +import { getRealStore } from '../../../test-utils/test-utils'; +import { UMLClass } from '../../../../../main/packages/uml-class-diagram/uml-class/uml-class'; +import { RemoteSelectable } from '../../../../../main/services/uml-element/remote-selectable/remote-selection-repository'; + + +describe('test redux state upon changing remote selection.', () => { + test('elements can be selected.', () => { + const classA = new UMLClass({ name: 'ClassA' }); + const classB = new UMLClass({ name: 'ClassB' }); + + const john = { name: 'John', color: 'red' }; + const jane = { name: 'Jane', color: 'blue' }; + + const store = getRealStore({}, [classA, classB]); + + expect(store.getState().remoteSelection).toEqual({}); + + store.dispatch(RemoteSelectable.remoteSelect(john, [classA.id])); + expect(store.getState().remoteSelection).toEqual({ [classA.id]: [john] }); + + store.dispatch(RemoteSelectable.remoteSelect(jane, [classA.id, classB.id])); + expect(store.getState().remoteSelection).toEqual({ [classA.id]: [john, jane], [classB.id]: [jane] }); + + store.dispatch(RemoteSelectable.remoteDeselect(jane, [classA.id])); + expect(store.getState().remoteSelection).toEqual({ [classA.id]: [john], [classB.id]: [jane] }); + + store.dispatch(RemoteSelectable.remoteSelectDeselect(john, [classB.id], [classA.id])); + expect(store.getState().remoteSelection).toEqual({ [classA.id]: [], [classB.id]: [jane, john] }); + + store.dispatch(RemoteSelectable.pruneRemoteSelectors([jane])); + expect(store.getState().remoteSelection).toEqual({ [classA.id]: [], [classB.id]: [jane] }); + }); +}); From 8949879162ba9caa48530c8d658cb4265a325317 Mon Sep 17 00:00:00 2001 From: Eugene Ghanizadeh Khoub Date: Mon, 20 Nov 2023 09:07:29 +0100 Subject: [PATCH 4/4] make it prettier --- .../remote-selectable/remote-selectable-service-test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tests/unit/services/uml-element/remote-selectable/remote-selectable-service-test.ts b/src/tests/unit/services/uml-element/remote-selectable/remote-selectable-service-test.ts index 5fba9cced..6d4998901 100644 --- a/src/tests/unit/services/uml-element/remote-selectable/remote-selectable-service-test.ts +++ b/src/tests/unit/services/uml-element/remote-selectable/remote-selectable-service-test.ts @@ -2,7 +2,6 @@ import { getRealStore } from '../../../test-utils/test-utils'; import { UMLClass } from '../../../../../main/packages/uml-class-diagram/uml-class/uml-class'; import { RemoteSelectable } from '../../../../../main/services/uml-element/remote-selectable/remote-selection-repository'; - describe('test redux state upon changing remote selection.', () => { test('elements can be selected.', () => { const classA = new UMLClass({ name: 'ClassA' });