mirror of
https://gitlab.com/wgp/dougal/software.git
synced 2025-12-06 11:27:09 +00:00
Refactor QC view to use new API endpoint.
This provides essentially the same user experience as the old endpoint, with one exception as of this commit: * The user is not able to “accept” or “unaccept” QC events.
This commit is contained in:
@@ -65,26 +65,30 @@
|
|||||||
<v-treeview
|
<v-treeview
|
||||||
:items="filteredItems"
|
:items="filteredItems"
|
||||||
:open.sync="open"
|
:open.sync="open"
|
||||||
item-key="serial"
|
item-key="_serial"
|
||||||
|
item-text="_text"
|
||||||
|
item-children="_children"
|
||||||
:open-on-click="true"
|
:open-on-click="true"
|
||||||
>
|
>
|
||||||
|
|
||||||
<template v-slot:label="{item}">
|
<template v-slot:label="{item}">
|
||||||
<div @dblclick.stop.prevent="toggleChildren(item)">
|
<div @dblclick.stop.prevent="toggleChildren(item)" v-if="item._kind=='test'">
|
||||||
{{item.name}}
|
<b>{{item._text}}</b>
|
||||||
<v-chip v-if="item.children && itemCount(item)"
|
<v-chip class="ml-2" v-if="item._children && itemCount(item)"
|
||||||
small
|
x-small
|
||||||
color="warning"
|
color="warning"
|
||||||
v-text="itemCount(item)"
|
v-text="itemCount(item)"
|
||||||
>
|
>
|
||||||
</v-chip>
|
</v-chip>
|
||||||
|
|
||||||
<v-chip v-for="label of item.labels"
|
<v-chip v-for="label of item.labels"
|
||||||
class="mx-1"
|
class="mx-1"
|
||||||
small
|
small
|
||||||
:color="labels[label] && labels[label].view.colour"
|
:color="labels[label] && labels[label].view.colour"
|
||||||
:title="labels[label] && labels[label].view.description"
|
:title="labels[label] && labels[label].view.description"
|
||||||
:close="writeaccess && label == 'QCAccepted'"
|
:close="writeaccess && label == 'QCAccepted'"
|
||||||
@click:close="unaccept(item)">
|
@click:close="unaccept(item)"
|
||||||
|
>
|
||||||
{{label}}
|
{{label}}
|
||||||
</v-chip>
|
</v-chip>
|
||||||
|
|
||||||
@@ -121,6 +125,20 @@
|
|||||||
</v-btn>
|
</v-btn>
|
||||||
</v-hover>
|
</v-hover>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div :title="item.remarks" @dblclick.stop.prevent="toggleChildren(item)" v-else-if="item._kind=='sequence'">
|
||||||
|
{{item._text}}
|
||||||
|
|
||||||
|
<v-chip class="ml-2" v-if="item._children && itemCount(item)"
|
||||||
|
x-small
|
||||||
|
color="primary"
|
||||||
|
v-text="itemCount(item)"
|
||||||
|
>
|
||||||
|
</v-chip>
|
||||||
|
</div>
|
||||||
|
<div class="text--secondary" v-else>
|
||||||
|
{{item._text}}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -174,12 +192,10 @@ export default {
|
|||||||
|
|
||||||
sequences () {
|
sequences () {
|
||||||
function getSeq (item) {
|
function getSeq (item) {
|
||||||
return "_id" in item
|
return item?._kind == "sequence"
|
||||||
? Array.isArray(item._id)
|
? item.sequence
|
||||||
? Number(item._id[0])
|
: item?._children?.length
|
||||||
: Number(item._id)
|
? item._children.map(i => getSeq(i)).flat()
|
||||||
: "children" in item
|
|
||||||
? item.children.map(i => getSeq(i)).flat()
|
|
||||||
: undefined;
|
: undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,8 +208,8 @@ export default {
|
|||||||
const values = [];
|
const values = [];
|
||||||
|
|
||||||
function filterResults (item) {
|
function filterResults (item) {
|
||||||
if (item.children) {
|
if (item._children) {
|
||||||
for (const child of item.children) {
|
for (const child of item._children) {
|
||||||
filterResults(child);
|
filterResults(child);
|
||||||
}
|
}
|
||||||
} else if (item._id && item.id) {
|
} else if (item._id && item.id) {
|
||||||
@@ -253,8 +269,8 @@ export default {
|
|||||||
|
|
||||||
itemCount (item, count = 0) {
|
itemCount (item, count = 0) {
|
||||||
let sum = count;
|
let sum = count;
|
||||||
if (item.children) {
|
if (item._children) {
|
||||||
sum += item.children.map(child => this.itemCount(child)).reduce( (a, b) => a+b, 0 )
|
sum += item._children.map(child => this.itemCount(child)).reduce( (a, b) => a+b, 0 )
|
||||||
} else {
|
} else {
|
||||||
sum++;
|
sum++;
|
||||||
}
|
}
|
||||||
@@ -262,8 +278,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
accepted (item) {
|
accepted (item) {
|
||||||
if (item.children) {
|
if (item._children) {
|
||||||
return item.children.every(child => this.accepted(child));
|
return item._children.every(child => this.accepted(child));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.labels) {
|
if (item.labels) {
|
||||||
@@ -273,8 +289,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
accept (item) {
|
accept (item) {
|
||||||
if (item.children) {
|
if (item._children) {
|
||||||
for (const child of item.children) {
|
for (const child of item._children) {
|
||||||
this.accept(child);
|
this.accept(child);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -288,8 +304,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
unaccept (item) {
|
unaccept (item) {
|
||||||
if (item.children) {
|
if (item._children) {
|
||||||
for (const child of item.children) {
|
for (const child of item._children) {
|
||||||
this.unaccept(child);
|
this.unaccept(child);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -319,7 +335,6 @@ export default {
|
|||||||
for (const path of sequences) {
|
for (const path of sequences) {
|
||||||
const url = `/project/${this.$route.params.project}/meta/raw/sequences/${path}`;
|
const url = `/project/${this.$route.params.project}/meta/raw/sequences/${path}`;
|
||||||
const promise = this.api([url]).then(res => {
|
const promise = this.api([url]).then(res => {
|
||||||
console.log("Apply QC labels (seq)", res);
|
|
||||||
for (const item of res) {
|
for (const item of res) {
|
||||||
const obj = this.resultObjects.find(o => o.sequence == item.sequence &&
|
const obj = this.resultObjects.find(o => o.sequence == item.sequence &&
|
||||||
o.point == item.point &&
|
o.point == item.point &&
|
||||||
@@ -337,7 +352,6 @@ export default {
|
|||||||
for (const path of points) {
|
for (const path of points) {
|
||||||
const url = `/project/${this.$route.params.project}/meta/raw/points/${path}`;
|
const url = `/project/${this.$route.params.project}/meta/raw/points/${path}`;
|
||||||
const promise = this.api([url]).then(res => {
|
const promise = this.api([url]).then(res => {
|
||||||
console.log("Apply QC labels (point)", res);
|
|
||||||
for (const item of res) {
|
for (const item of res) {
|
||||||
const obj = this.resultObjects.find(o => o.sequence == item.sequence &&
|
const obj = this.resultObjects.find(o => o.sequence == item.sequence &&
|
||||||
o.point == item.point &&
|
o.point == item.point &&
|
||||||
@@ -358,27 +372,25 @@ export default {
|
|||||||
async saveLabels () {
|
async saveLabels () {
|
||||||
const url = `/project/${this.$route.params.project}/meta`;
|
const url = `/project/${this.$route.params.project}/meta`;
|
||||||
|
|
||||||
console.log("Saving", this.resultObjects.filter(r => typeof r.value !== "undefined"));
|
|
||||||
const res = await this.api([url, {
|
const res = await this.api([url, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: this.resultObjects.filter(r => typeof r.value !== "undefined")
|
body: this.resultObjects.filter(r => typeof r.value !== "undefined")
|
||||||
}]);
|
}]);
|
||||||
console.log("RES", res);
|
|
||||||
this.isDirty = false;
|
this.isDirty = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
filterByText(item, queryText) {
|
filterByText(item, queryText) {
|
||||||
if (!queryText || !item) return item;
|
if (!queryText || !item) return item;
|
||||||
|
|
||||||
if (item.children) {
|
if (item._children) {
|
||||||
const newItem = Object.assign({}, item);
|
const newItem = Object.assign({}, item);
|
||||||
newItem.children = item.children.map( child => this.filterByText(child, queryText) ).filter(i => !!i)
|
newItem._children = item._children.map( child => this.filterByText(child, queryText) ).filter(i => !!i)
|
||||||
if (newItem.children.length > 0) {
|
if (newItem._children.length > 0) {
|
||||||
return newItem;
|
return newItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.name && item.name.toLowerCase().indexOf(queryText.toLowerCase()) > -1) {
|
if (item._text && item._text.toLowerCase().indexOf(queryText.toLowerCase()) > -1) {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -386,16 +398,17 @@ export default {
|
|||||||
filterBySequence(item, sequences) {
|
filterBySequence(item, sequences) {
|
||||||
if (!sequences || !sequences.length) return item;
|
if (!sequences || !sequences.length) return item;
|
||||||
|
|
||||||
if (item._id) {
|
if (item._kind == "sequence" && (sequences.includes(item.sequence) || sequences.includes(item))) {
|
||||||
if ( (item._id.length > 1 && sequences.includes(item._id[0])) || sequences.includes(item) ) {
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (item.children) {
|
if (item._children) {
|
||||||
const newItem = Object.assign({}, item);
|
const newItem = {...item};
|
||||||
newItem.children = item.children.map( child => this.filterBySequence(child, sequences) ).filter(i => !!i);
|
newItem._children = item._children.map(child =>
|
||||||
if (newItem.children.length > 0) {
|
this.filterBySequence(child, sequences)
|
||||||
|
).filter(i => !!i);
|
||||||
|
|
||||||
|
if (newItem._children.length) {
|
||||||
return newItem;
|
return newItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -403,71 +416,60 @@ export default {
|
|||||||
|
|
||||||
toggleChildren (item, state) {
|
toggleChildren (item, state) {
|
||||||
const open = typeof state == 'undefined'
|
const open = typeof state == 'undefined'
|
||||||
? !this.open.includes(item.serial)
|
? !this.open.includes(item._serial)
|
||||||
: state;
|
: state;
|
||||||
|
|
||||||
if (item.children) {
|
if (item._children) {
|
||||||
item.children.forEach(child => this.toggleChildren(child, open));
|
item._children.forEach(child => this.toggleChildren(child, open));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open) {
|
if (open) {
|
||||||
if (!this.open.includes(item.serial)) {
|
if (!this.open.includes(item._serial)) {
|
||||||
this.open.push(item.serial);
|
this.open.push(item._serial);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const index = this.open.indexOf(item.serial);
|
const index = this.open.indexOf(item._serial);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
this.open.splice(index, 1);
|
this.open.splice(index, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
transform (item, testId) {
|
transform (item, qcId) {
|
||||||
item.serial = ++this.itemIndex;
|
item._serial = ++this.itemIndex;
|
||||||
if (item.id) {
|
if (item.name && (item.check || item.children)) {
|
||||||
testId = item.id;
|
// This is probably a test
|
||||||
} else {
|
qcId ??= item.id;
|
||||||
item.id = testId;
|
|
||||||
}
|
item._kind = "test";
|
||||||
if (item.check) {
|
item._text = item.name;
|
||||||
switch (item.iterate) {
|
item._children = [];
|
||||||
case "sequences":
|
|
||||||
item.check = item.check.map(check => ({
|
|
||||||
_id: check._id,
|
|
||||||
name: `Sequence ${check._id}: ${check.results}`
|
|
||||||
}));
|
|
||||||
break;
|
|
||||||
case "shots":
|
|
||||||
default:
|
|
||||||
const bySequence = {};
|
|
||||||
for (const check of item.check) {
|
|
||||||
if (!bySequence[check._id[0]]) {
|
|
||||||
bySequence[check._id[0]] = [];
|
|
||||||
}
|
|
||||||
bySequence[check._id[0]].push({
|
|
||||||
_id: check._id,
|
|
||||||
name: `Point ${check._id[1]}: ${check.results}`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
item.check = Object.keys(bySequence).map(seq => ({
|
|
||||||
_id: seq,
|
|
||||||
name: `Sequence: ${seq}`,
|
|
||||||
children: bySequence[seq]
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
if (!("children" in item)) {
|
|
||||||
item.children = item.check;
|
|
||||||
delete item.check;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (item.children) {
|
if (item.children) {
|
||||||
for (const child of item.children) {
|
// Child tests
|
||||||
this.transform(child, testId);
|
item._children = item.children.map(i => this.transform(i, qcId));
|
||||||
}
|
}
|
||||||
if (item.check) {
|
|
||||||
item.children = item.check.concatenate(item.children);
|
if (item.sequences) {
|
||||||
|
// In theory an item could have both subtests and its own results
|
||||||
|
// so we don't do an if … else but two independent ifs.
|
||||||
|
item._children = item._children.concat(item.sequences.map(i => this.transform(i, qcId)));
|
||||||
}
|
}
|
||||||
|
} else if (item.sequence && item.line) {
|
||||||
|
// This is probably a sequence
|
||||||
|
|
||||||
|
item._kind = "sequence";
|
||||||
|
item._text = `Sequence ${item.sequence}${item.meta?.qc && item.meta.qc[qcId] ? (": "+item.meta.qc[qcId]) : ""}`;
|
||||||
|
|
||||||
|
if (item.shots && item.shots.length) {
|
||||||
|
item._children = item.shots.map(i => this.transform(i, qcId));
|
||||||
}
|
}
|
||||||
|
} else if (item.sequence && item.point) {
|
||||||
|
// This is probably a shotpoint
|
||||||
|
|
||||||
|
item._kind = "point";
|
||||||
|
item._text = `Point ${item.point}: ${item.remarks}`
|
||||||
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -482,12 +484,12 @@ export default {
|
|||||||
|
|
||||||
async getQCData () {
|
async getQCData () {
|
||||||
|
|
||||||
const url = `/project/${this.$route.params.project}/info/qc`;
|
const url = `/project/${this.$route.params.project}/qc/results`;
|
||||||
|
|
||||||
const res = await this.api([url]);
|
const res = await this.api([url]);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
this.items = res.results.map(i => this.transform(i)) || [];
|
this.items = res.map(i => this.transform(i)) || [];
|
||||||
this.updatedOn = res.updatedOn;
|
this.updatedOn = res.updatedOn;
|
||||||
await this.getQCLabels();
|
await this.getQCLabels();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user