|
@@ -7,7 +7,7 @@
|
|
|
</h1>
|
|
|
|
|
|
<template v-if="labels !== false">
|
|
|
- <label-tree-view v-for="label in labelTree" :key="label.identifier"
|
|
|
+ <label-tree-view v-for="label in sortedLabels" :key="label.identifier"
|
|
|
:label="label"
|
|
|
:targetable="true"
|
|
|
indent="2rem"/>
|
|
@@ -45,15 +45,15 @@ export default {
|
|
|
|
|
|
// subscribe to changes
|
|
|
this.$root.socket.on('connect', this.getLabels);
|
|
|
- this.$root.socket.on('create-label', this.addLabelToList);
|
|
|
- this.$root.socket.on('remove-label', this.removeLabelFromList);
|
|
|
- this.$root.socket.on('edit-label', this.editLabelInList);
|
|
|
+ this.$root.socket.on('create-label', this.addLabel);
|
|
|
+ this.$root.socket.on('remove-label', this.removeLabel);
|
|
|
+ this.$root.socket.on('edit-label', this.editLabel);
|
|
|
},
|
|
|
destroyed: function () {
|
|
|
this.$root.socket.off('connect', this.getLabels);
|
|
|
- this.$root.socket.off('create-label', this.addLabelToList);
|
|
|
- this.$root.socket.off('remove-label', this.removeLabelFromList);
|
|
|
- this.$root.socket.off('edit-label', this.editLabelInList);
|
|
|
+ this.$root.socket.off('create-label', this.addLabel);
|
|
|
+ this.$root.socket.off('remove-label', this.removeLabel);
|
|
|
+ this.$root.socket.off('edit-label', this.editLabel);
|
|
|
},
|
|
|
data: function () {
|
|
|
return {
|
|
@@ -63,85 +63,95 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
- // TODO remove
|
|
|
sortedLabels: function () {
|
|
|
return [...this.labels].sort((a, b) => a.name < b.name ? -1 : +1);
|
|
|
- },
|
|
|
- labelTree: function () {
|
|
|
- const labels = [...this.labels].sort((a, b) => a.name < b.name ? +1 : -1);
|
|
|
-
|
|
|
- const tree = [];
|
|
|
- const references = {};
|
|
|
-
|
|
|
- while (labels.length > 0) {
|
|
|
- const length = labels.length;
|
|
|
-
|
|
|
- for (let i = labels.length - 1; i >= 0; i--) {
|
|
|
- if (labels[i]['parent_id'] === null) {
|
|
|
- const label = Object.assign({
|
|
|
- // parent: null,
|
|
|
- children: []
|
|
|
- }, labels.splice(i, 1)[0]);
|
|
|
-
|
|
|
- tree.push(label);
|
|
|
- references[label.identifier] = label;
|
|
|
- } else if (labels[i]['parent_id'] in references) {
|
|
|
- const parent = references[labels[i]['parent_id']];
|
|
|
- const label = Object.assign({
|
|
|
- // parent: parent,
|
|
|
- children: []
|
|
|
- }, labels.splice(i, 1)[0]);
|
|
|
-
|
|
|
- parent.children.push(label);
|
|
|
- references[label.identifier] = label;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (labels.length === length) {
|
|
|
- // TODO show in ui
|
|
|
- console.log('I could not parse all items. Sorry!')
|
|
|
- return tree;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return tree;
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
getLabels: function () {
|
|
|
- this.$root.socket.get(`/projects/${this.$root.project.identifier}/labels`)
|
|
|
+ this.$root.socket.get(`/projects/${this.$root.project.identifier}/labels/tree`)
|
|
|
.then(response => response.json())
|
|
|
.then(labels => {
|
|
|
- this.labels = [];
|
|
|
- labels.forEach(this.addLabelToList);
|
|
|
+ this.labels = labels;
|
|
|
});
|
|
|
},
|
|
|
- addLabelToList: function (label) {
|
|
|
+ findLabel: function (labels, identifier) {
|
|
|
+ for (let label of labels) {
|
|
|
+ if (label.identifier === identifier)
|
|
|
+ return label;
|
|
|
+
|
|
|
+ const child = this.findLabel(label.children, identifier);
|
|
|
+ if (child)
|
|
|
+ return child;
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ },
|
|
|
+ addLabel: function (label) {
|
|
|
+ // abort if label is not part of this project
|
|
|
if (label['project_id'] !== this.$root.project.identifier)
|
|
|
return;
|
|
|
|
|
|
- for (let l of this.labels)
|
|
|
+ // prepare some values
|
|
|
+ let labels = this.labels;
|
|
|
+
|
|
|
+ if (!label.children)
|
|
|
+ label.children = [];
|
|
|
+
|
|
|
+ // label is not on root level
|
|
|
+ if (label.parent_id !== null) {
|
|
|
+ const parent = this.findLabel(labels, label.parent_id);
|
|
|
+
|
|
|
+ if (parent) {
|
|
|
+ labels = parent.children;
|
|
|
+ } else {
|
|
|
+ console.warn('could not find parent');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // abort if label is already contained
|
|
|
+ for (let l of labels)
|
|
|
if (l.identifier === label.identifier)
|
|
|
return;
|
|
|
|
|
|
- this.labels.push(label);
|
|
|
+ // add label
|
|
|
+ labels.push(label);
|
|
|
},
|
|
|
- removeLabelFromList: function (label) {
|
|
|
- for (let i = 0; i < this.labels.length; i++) {
|
|
|
- if (this.labels[i].identifier === label.identifier) {
|
|
|
- this.labels.splice(i, 1);
|
|
|
+ removeLabel: function (label) {
|
|
|
+ let labels = this.labels;
|
|
|
+
|
|
|
+ // label is not on root level
|
|
|
+ if (label.parent_id !== null) {
|
|
|
+ const parent = this.findLabel(labels, label.parent_id);
|
|
|
+
|
|
|
+ if (parent) {
|
|
|
+ labels = parent.children;
|
|
|
+ } else {
|
|
|
+ console.warn('could not find parent');
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
- },
|
|
|
- editLabelInList: function (label) {
|
|
|
- for (let i = 0; i < this.labels.length; i++) {
|
|
|
- if (this.labels[i].identifier === label.identifier) {
|
|
|
- this.$set(this.labels, i, label);
|
|
|
+
|
|
|
+ // remove label from list
|
|
|
+ for (let i = 0; i < labels.length; i++) {
|
|
|
+ if (labels[i].identifier === label.identifier) {
|
|
|
+ labels.splice(i, 1);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
+ editLabel: function (label) {
|
|
|
+ // remove label if it is already contained
|
|
|
+ const l = this.findLabel(this.labels, label.identifier);
|
|
|
+ if (l) {
|
|
|
+ this.removeLabel(l);
|
|
|
+ label.children = l.children;
|
|
|
+ }
|
|
|
+
|
|
|
+ // add label on it's new position
|
|
|
+ this.addLabel(label);
|
|
|
+ },
|
|
|
createLabel: function () {
|
|
|
if (!this.createLabelValue)
|
|
|
return;
|
|
@@ -181,22 +191,4 @@ h1.target {
|
|
|
width: 4rem;
|
|
|
height: 4rem;
|
|
|
}
|
|
|
-
|
|
|
-/*
|
|
|
-/deep/ .element {
|
|
|
- border: none;
|
|
|
-}
|
|
|
-
|
|
|
-/deep/ .element:not(:first-child) {
|
|
|
- margin-left: 0.1rem;
|
|
|
-}
|
|
|
-
|
|
|
-/deep/ .element:not(:last-child) {
|
|
|
- margin-right: 0.1rem;
|
|
|
-}
|
|
|
-
|
|
|
-.no-elements {
|
|
|
- margin-top: 0.5rem;
|
|
|
-}
|
|
|
-*/
|
|
|
</style>
|