Bin
2025-12-17 bc6aa38242b0a7dea4b18bc90e2d78740436a58b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { getParent, types } from "mobx-state-tree";
 
/**
 * Controls visibility of the element depending on other tags.
 * `visibleWhen` is required parameter, can refer to choices or regions, both selected or unselected:
 * - region-selected, can specify tag and label value, both are optional
 * - choice-selected, can specify tag, and with tag specified can specify choice value
 * - no-region-selected, can't specify anything else
 * - choice-unselected, can specify tag, and with tag specified can specify choice value
 * Can be applied to `View` and `Choices` tags.
 */
const VisibilityMixin = types
  .model({
    visiblewhen: types.maybeNull(types.string),
    whentagname: types.maybeNull(types.string),
    whenchoicevalue: types.maybeNull(types.string),
    whenlabelvalue: types.maybeNull(types.string),
    whenrole: types.maybeNull(types.string),
  })
  .views((self) => ({
    get isVisible() {
      if (getParent(self, 2)?.isVisible === false) {
        return false;
      }
 
      if (self.visiblewhen) {
        const fns = {
          "region-selected": ({ tagName, labelValue, roleValue }) => {
            const area = self.annotation.highlightedNode;
 
            if (!area || (tagName && area.labeling?.from_name.name !== tagName)) {
              return false;
            }
 
            if (labelValue) return labelValue.split(",").some((v) => area.hasLabel(v));
 
            if (roleValue) return roleValue.split(",").some((v) => area.chatmessage?.role === v);
 
            return true;
          },
 
          "choice-selected": ({ tagName, choiceValue }) => {
            if (!tagName) {
              for (const choices of self.annotation.names.values()) {
                if (choices.type === "choices" && choices.selectedValues && choices.selectedValues().length) {
                  return true;
                }
              }
              return false;
            }
 
            const tag = self.annotation.names.get(tagName);
 
            if (!tag?.hasChoiceSelection && !choiceValue?.length) return false;
            if (tag.isVisible === false) return false;
 
            return tag.hasChoiceSelection(choiceValue?.split(","), tag.selectedValues());
          },
 
          "no-region-selected": () => !self.annotation.highlightedNode,
          "choice-unselected": (params) => !fns["choice-selected"](params),
        };
 
        if (Object.keys(fns).includes(self.visiblewhen)) {
          const res = fns[self.visiblewhen]({
            tagName: self.whentagname,
            choiceValue: self.whenchoicevalue,
            labelValue: self.whenlabelvalue,
            roleValue: self.whenrole,
          });
 
          return res !== false;
        }
      } else if (self.whenchoicevalue) {
        for (const choices of self.annotation.names.values()) {
          const choicesList = choices?.selectedValues?.();
 
          if (choicesList?.length) {
            for (const obj of choicesList) {
              if (obj === self.whenchoicevalue) return true;
            }
          }
        }
 
        return false;
      }
 
      return true;
    },
  }));
 
export default VisibilityMixin;