tree.vue 2.9 KB
Newer Older
schneider210's avatar
schneider210 committed
1
<template>
2
  <div class="item">
3
    <q-tree
4
      class="item-content"
schneider210's avatar
schneider210 committed
5
      node-key="label"
6
      :expanded.sync="expanded"
dindigala's avatar
dindigala committed
7
      :icon="fasCaretRight"
8
      :nodes="tree"
9
      :selected-color="$q.dark.isActive ? 'grey' : ''"
10
      :selected.sync="selected"
11
      :style="treeStyle"
nwindis's avatar
nwindis committed
12
13
    >
      <template
schneider210's avatar
schneider210 committed
14
        #default-body="{node}"
15
      >
nwindis's avatar
nwindis committed
16
17
18
19
        <div
          v-if="!node.children"
          :id="`selectedItem-${node['label']}`"
        />
20
      </template>
21
22

      <template #default-header="prop">
23
24
25
26
        <div
          :id="prop.node['label']"
          class="row items-center"
        >
27
28
29
          <div> {{ prop.node.labelSheet? $t(labels.item):'' }} {{ prop.node['label-key'] }}</div>
        </div>
      </template>
schneider210's avatar
schneider210 committed
30
31
32
33
34
    </q-tree>
  </div>
</template>

<script>
dindigala's avatar
dindigala committed
35
36
import { fasCaretRight } from '@quasar/extras/fontawesome-v5';
import treestore from '@/stores/treestore.js';
schneider210's avatar
schneider210 committed
37
38
39
40

export default {
  name: 'Treeview',
  props: {
41
42
43
44
    labels: {
      type: Object,
      default: () => {},
    },
schneider210's avatar
schneider210 committed
45
46
47
48
49
50
51
52
    manifests: {
      type: Array,
      default: () => [],
    },
    tree: {
      type: Array,
      default: () => [],
    },
schneider210's avatar
schneider210 committed
53
54
55
  },
  data() {
    return {
56
      expanded: [],
57
      height: 0,
dindigala's avatar
dindigala committed
58
      selected: null,
59
      sequenceindex: 0,
schneider210's avatar
schneider210 committed
60
61
    };
  },
62
63
64
65
66
  computed: {
    treeStyle() {
      return `max-height:${this.height}px;`;
    },
  },
schneider210's avatar
schneider210 committed
67
  created() {
dindigala's avatar
dindigala committed
68
    this.fasCaretRight = fasCaretRight;
schneider210's avatar
schneider210 committed
69
70
  },
  mounted() {
71
72
    this.handleTreePanelHeight();

dindigala's avatar
dindigala committed
73
74
    // select tree node
    this.selected = treestore.state.selectedItemTree || this.manifests[0].sequence[0].id;
75

dindigala's avatar
dindigala committed
76
77
78
79
80
81
82
    // expand the first level
    this.expanded.push(this.tree[0].label);
    // expand second label - dynamic
    const finalSeqIdx = treestore.state.seqTree || 0;

    this.expanded.push(this.manifests[finalSeqIdx].label);

83
    this.$root.$on('update-item', (item) => {
84
85
      this.selected = item;
    });
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

    this.$root.$on('update-sequence-index', (index) => {
      if (index !== this.sequenceindex) {
        this.sequenceindex = index;

        if (!this.expanded.includes(this.manifests[index].label)) {
          this.expanded.push(this.manifests[index].label);
        }
      }
    });

    this.$root.$on('update-tree-knots', (label) => {
      if (this.expanded.includes(label)) {
        const index = this.expanded.indexOf(label);

        if (index > -1) {
          this.expanded.splice(index, 1);
        }
      } else {
        this.expanded.push(label);
      }
    });
schneider210's avatar
schneider210 committed
108
  },
109
110
111
112
113
  methods: {
    handleTreePanelHeight() {
      const el = document.querySelector('.item-content');

      if (el && this.height !== el.clientHeight) {
114
        this.height = el.clientHeight - (document.querySelector('.tabs-container')?.clientHeight || 0); // Tab spacing height.
115
116
117
      }
    },
  },
schneider210's avatar
schneider210 committed
118
119
};
</script>
120
121
122
123
124
125
126
127
128
129

<style scoped>
.item {
  display: flex;
  flex: 1;
  flex-direction: column;
}

.item-content {
  display: flex;
130
  flex: 0 0 auto;
131
  flex-direction: column;
132
  overflow: auto;
133
134
}
</style>