diff --git a/src/stores/RelationStore.js b/src/stores/RelationStore.js index 12eaa42e5..14958993a 100644 --- a/src/stores/RelationStore.js +++ b/src/stores/RelationStore.js @@ -1,7 +1,6 @@ import { destroy, getParentOfType, getRoot, isAlive, types } from 'mobx-state-tree'; import { guidGenerator } from '../core/Helpers'; -import { RelationsModel } from '../tags/control/Relations'; import Tree, { TRAVERSE_SKIP } from '../core/Tree'; import Area from '../regions/Area'; import { isDefined } from '../utils/utilities'; @@ -20,11 +19,11 @@ const Relation = types // labels labels: types.maybeNull(types.array(types.string)), - - showMeta: types.optional(types.boolean, false), - - visible: true, }) + .volatile(() => ({ + showMeta: false, + visible: true, + })) .views(self => ({ get parent() { return getParentOfType(self, RelationStore); @@ -108,11 +107,16 @@ const Relation = types const RelationStore = types .model('RelationStore', { relations: types.array(Relation), - showConnections: types.optional(types.boolean, true), - highlighted: types.maybeNull(types.safeReference(Relation)), - control: types.maybeNull(types.safeReference(RelationsModel)), }) + .volatile(() => ({ + showConnections: true, + _highlighted: null, + control: null, + })) .views(self => ({ + get highlighted() { + return self.relations.find(r => r.id === self._highlighted); + }, get size() { return self.relations.length; }, @@ -214,11 +218,11 @@ const RelationStore = types }, setHighlight(relation) { - self.highlighted = relation; + self._highlighted = relation.id; }, removeHighlight() { - self.highlighted = null; + self._highlighted = null; }, })); diff --git a/tests/functional/specs/relations/basic.cy.ts b/tests/functional/specs/relations/basic.cy.ts index 1d7a3c266..2efab6bef 100644 --- a/tests/functional/specs/relations/basic.cy.ts +++ b/tests/functional/specs/relations/basic.cy.ts @@ -2,7 +2,7 @@ import { ImageView, LabelStudio, Relations, ToolBar } from '@heartexlabs/ls-test import { imageConfigWithRelations, simpleImageConfig, - simpleImageData, + simpleImageData, simpleImageResult, simpleImageResultWithRelation, simpleImageResultWithRelations, simpleImageResultWithRelationsAndLabels, simpleImageResultWithRelationsAndLabelsAlt } from '../../data/relations/basic'; @@ -164,4 +164,156 @@ describe('Relations: Basic', () => { // check that relations in the input are changed according to the first annotation result Relations.hasRelationLabels(['Blue label', 'Red label'], 0); }); + + it('Should create correct step in history by adding relation', () => { + LabelStudio.params() + .config(simpleImageConfig) + .data(simpleImageData) + .withResult(simpleImageResult) + .init(); + + ImageView.waitForImage(); + + Relations.hasRelations(0); + + ImageView.clickAtRelative(.30, .30); + Relations.toggleCreationWithHotkey(); + ImageView.clickAtRelative(.60, .60); + + cy.window().then((win) => { + expect(win.Htx.annotationStore.selected.history.history.length).to.equal(2); + }); + + cy.get('body').type('{ctrl+z}'); + Relations.hasRelations(0); + cy.get('body').type('{ctrl+shift+z}'); + Relations.hasRelations(1); + cy.window().then((win) => { + expect(win.Htx.annotationStore.selected.history.history.length).to.equal(2); + }); + }); + + it('Should create correct step in history by deleting relation', () => { + LabelStudio.params() + .config(simpleImageConfig) + .data(simpleImageData) + .withResult(simpleImageResultWithRelation) + .init(); + + ImageView.waitForImage(); + + Relations.hasRelations(1); + cy.window().then((win) => { + expect(win.Htx.annotationStore.selected.history.history.length).to.equal(1); + }); + + Relations.deleteRelationAction(0); + + Relations.hasRelations(0); + cy.window().then((win) => { + expect(win.Htx.annotationStore.selected.history.history.length).to.equal(2); + }); + + cy.get('body').type('{ctrl+z}'); + Relations.hasRelations(1); + cy.window().then((win) => { + expect(win.Htx.annotationStore.selected.history.history.length).to.equal(2); + }); + + cy.get('body').type('{ctrl+shift+z}'); + Relations.hasRelations(0); + cy.window().then((win) => { + expect(win.Htx.annotationStore.selected.history.history.length).to.equal(2); + }); + }); + + it('Should create correct step in history by changing relation direction', () => { + LabelStudio.params() + .config(simpleImageConfig) + .data(simpleImageData) + .withResult(simpleImageResultWithRelation) + .init(); + + ImageView.waitForImage(); + + Relations.hasRelations(1); + cy.window().then((win) => { + expect(win.Htx.annotationStore.selected.history.history.length).to.equal(1); + }); + + Relations.toggleRelationDirection(0); + + Relations.hasRelations(1); + cy.window().then((win) => { + expect(win.Htx.annotationStore.selected.history.history.length).to.equal(2); + }); + }); + + it('Should create correct step in history by adding label to relation', () => { + LabelStudio.params() + .config(imageConfigWithRelations) + .data(simpleImageData) + .withResult(simpleImageResultWithRelation) + .init(); + + ImageView.waitForImage(); + + Relations.hasRelations(1); + Relations.hoverOverRelation(0); + Relations.clickShowRelationLabels(0); + Relations.addLabelToRelation('Blue label', 0); + Relations.hasRelationLabels(['Blue label'], 0); + cy.window().then((win) => { + expect(win.Htx.annotationStore.selected.history.history.length).to.equal(2); + }); + + cy.get('body').type('{ctrl+z}'); + Relations.hasRelationLabels([], 0); + cy.window().then((win) => { + expect(win.Htx.annotationStore.selected.history.history.length).to.equal(2); + }); + + cy.get('body').type('{ctrl+shift+z}'); + Relations.hasRelationLabels(['Blue label'], 0); + cy.window().then((win) => { + expect(win.Htx.annotationStore.selected.history.history.length).to.equal(2); + }); + }); + + it('Should not create step in history by highlighting relation', () => { + LabelStudio.params() + .config(simpleImageConfig) + .data(simpleImageData) + .withResult(simpleImageResultWithRelation) + .init(); + + ImageView.waitForImage(); + + Relations.hoverOverRelation(0); + Relations.stopHoveringOverRelation(0); + + cy.window().then((win) => { + expect(win.Htx.annotationStore.selected.history.history.length).to.equal(1); + }); + }); + + it('Should not create step in history by hiding relation', () => { + LabelStudio.params() + .config(simpleImageConfig) + .data(simpleImageData) + .withResult(simpleImageResultWithRelation) + .init(); + + ImageView.waitForImage(); + + Relations.hasRelations(1); + cy.window().then((win) => { + expect(win.Htx.annotationStore.selected.history.history.length).to.equal(1); + }); + + Relations.hideRelationAction(0); + cy.window().then((win) => { + expect(win.Htx.annotationStore.selected.history.history.length).to.equal(1); + }); + }); });