import { types } from "mobx-state-tree";
|
import isMatch from "lodash/isMatch";
|
import InfoModal from "../../components/Infomodal/Infomodal";
|
import { AnnotationMixin } from "../../mixins/AnnotationMixin";
|
import { FF_DEV_3391, isFF } from "../../utils/feature-flags";
|
import { BaseTag } from "../TagBase";
|
|
const ObjectBase = types
|
.model({
|
...(isFF(FF_DEV_3391)
|
? {
|
id: types.identifier,
|
name: types.string,
|
}
|
: {
|
name: types.identifier,
|
}),
|
// TODO there should be a better way to force an update
|
_needsUpdate: types.optional(types.number, 0),
|
})
|
.volatile(() => ({
|
isObjectTag: true,
|
supportSuggestions: false,
|
}))
|
.views((self) => ({
|
/**
|
* A list of all related regions
|
* it is using for validation purposes
|
*/
|
get allRegs() {
|
return self.annotation?.regionStore.regions.filter((r) => r.object === self) || [];
|
},
|
/**
|
* A list of regions related to the current object state
|
* (it could be overridden)
|
*/
|
get regs() {
|
return self.allRegs;
|
},
|
findRegion(params) {
|
let obj = null;
|
|
if (self._regionsCache && self._regionsCache.length) {
|
obj = self._regionsCache.find(({ region }) => isMatch(region, params));
|
}
|
|
return obj || self.regions.find((r) => isMatch(r, params));
|
},
|
get isReady() {
|
return true;
|
},
|
}))
|
.actions((self) => {
|
const props = {};
|
|
function addProp(name, value) {
|
props[name] = value;
|
self._needsUpdate = self._needsUpdate + 1;
|
}
|
|
function getProps() {
|
return props;
|
}
|
|
// @todo maybe not a best place for this method?
|
// check that maxUsages was not exceeded for labels
|
// and if it was - don't allow to create new region and unselect all regions
|
// unselect labels which was exceeded maxUsages
|
// return all states left untouched - available labels and others
|
function getAvailableStates() {
|
// `checkMaxUsages` may unselect labels with already reached `maxUsages`
|
const checkAndCollect = (list, s) => (s.checkMaxUsages ? list.concat(s.checkMaxUsages()) : list);
|
const allStates = self.states() || [];
|
const exceeded = allStates.reduce(checkAndCollect, []).filter((e) => e.selected);
|
exceeded.forEach((e) => e.setSelected(false));
|
|
const states = self.activeStates() || [];
|
|
if (states.length === 0) {
|
if (exceeded.length) {
|
const label = exceeded[0];
|
|
InfoModal.warning(`You can't use ${label.value} more than ${label.maxUsages} time(s)`);
|
}
|
self.annotation.unselectAll();
|
}
|
return states;
|
}
|
|
return {
|
addProp,
|
getProps,
|
getAvailableStates,
|
};
|
});
|
|
export default types.compose(ObjectBase, BaseTag, AnnotationMixin);
|