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:
D. Berge
2022-03-09 17:50:55 +01:00
parent 14a2f57c8d
commit c86cbdc493

View File

@@ -65,26 +65,30 @@
<v-treeview
:items="filteredItems"
:open.sync="open"
item-key="serial"
item-key="_serial"
item-text="_text"
item-children="_children"
:open-on-click="true"
>
<template v-slot:label="{item}">
<div @dblclick.stop.prevent="toggleChildren(item)">
{{item.name}}
<v-chip v-if="item.children && itemCount(item)"
small
<div @dblclick.stop.prevent="toggleChildren(item)" v-if="item._kind=='test'">
<b>{{item._text}}</b>
<v-chip class="ml-2" v-if="item._children && itemCount(item)"
x-small
color="warning"
v-text="itemCount(item)"
>
</v-chip>
<v-chip v-for="label of item.labels"
class="mx-1"
small
:color="labels[label] && labels[label].view.colour"
:title="labels[label] && labels[label].view.description"
:close="writeaccess && label == 'QCAccepted'"
@click:close="unaccept(item)">
@click:close="unaccept(item)"
>
{{label}}
</v-chip>
@@ -121,6 +125,20 @@
</v-btn>
</v-hover>
</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>
</template>
@@ -174,12 +192,10 @@ export default {
sequences () {
function getSeq (item) {
return "_id" in item
? Array.isArray(item._id)
? Number(item._id[0])
: Number(item._id)
: "children" in item
? item.children.map(i => getSeq(i)).flat()
return item?._kind == "sequence"
? item.sequence
: item?._children?.length
? item._children.map(i => getSeq(i)).flat()
: undefined;
}
@@ -192,8 +208,8 @@ export default {
const values = [];
function filterResults (item) {
if (item.children) {
for (const child of item.children) {
if (item._children) {
for (const child of item._children) {
filterResults(child);
}
} else if (item._id && item.id) {
@@ -253,17 +269,17 @@ export default {
itemCount (item, count = 0) {
let sum = count;
if (item.children) {
sum += item.children.map(child => this.itemCount(child)).reduce( (a, b) => a+b, 0 )
if (item._children) {
sum += item._children.map(child => this.itemCount(child)).reduce( (a, b) => a+b, 0 )
} else {
sum++;
}
return sum;
},
accepted (item) {
if (item.children) {
return item.children.every(child => this.accepted(child));
if (item._children) {
return item._children.every(child => this.accepted(child));
}
if (item.labels) {
@@ -273,8 +289,8 @@ export default {
},
accept (item) {
if (item.children) {
for (const child of item.children) {
if (item._children) {
for (const child of item._children) {
this.accept(child);
}
return;
@@ -288,8 +304,8 @@ export default {
},
unaccept (item) {
if (item.children) {
for (const child of item.children) {
if (item._children) {
for (const child of item._children) {
this.unaccept(child);
}
return;
@@ -319,7 +335,6 @@ export default {
for (const path of sequences) {
const url = `/project/${this.$route.params.project}/meta/raw/sequences/${path}`;
const promise = this.api([url]).then(res => {
console.log("Apply QC labels (seq)", res);
for (const item of res) {
const obj = this.resultObjects.find(o => o.sequence == item.sequence &&
o.point == item.point &&
@@ -337,7 +352,6 @@ export default {
for (const path of points) {
const url = `/project/${this.$route.params.project}/meta/raw/points/${path}`;
const promise = this.api([url]).then(res => {
console.log("Apply QC labels (point)", res);
for (const item of res) {
const obj = this.resultObjects.find(o => o.sequence == item.sequence &&
o.point == item.point &&
@@ -358,27 +372,25 @@ export default {
async saveLabels () {
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, {
method: "PUT",
body: this.resultObjects.filter(r => typeof r.value !== "undefined")
}]);
console.log("RES", res);
this.isDirty = false;
},
filterByText(item, queryText) {
if (!queryText || !item) return item;
if (item.children) {
if (item._children) {
const newItem = Object.assign({}, item);
newItem.children = item.children.map( child => this.filterByText(child, queryText) ).filter(i => !!i)
if (newItem.children.length > 0) {
newItem._children = item._children.map( child => this.filterByText(child, queryText) ).filter(i => !!i)
if (newItem._children.length > 0) {
return newItem;
}
}
if (item.name && item.name.toLowerCase().indexOf(queryText.toLowerCase()) > -1) {
if (item._text && item._text.toLowerCase().indexOf(queryText.toLowerCase()) > -1) {
return item;
}
},
@@ -386,16 +398,17 @@ export default {
filterBySequence(item, sequences) {
if (!sequences || !sequences.length) return item;
if (item._id) {
if ( (item._id.length > 1 && sequences.includes(item._id[0])) || sequences.includes(item) ) {
return item;
}
if (item._kind == "sequence" && (sequences.includes(item.sequence) || sequences.includes(item))) {
return item;
}
if (item.children) {
const newItem = Object.assign({}, item);
newItem.children = item.children.map( child => this.filterBySequence(child, sequences) ).filter(i => !!i);
if (newItem.children.length > 0) {
if (item._children) {
const newItem = {...item};
newItem._children = item._children.map(child =>
this.filterBySequence(child, sequences)
).filter(i => !!i);
if (newItem._children.length) {
return newItem;
}
}
@@ -403,71 +416,60 @@ export default {
toggleChildren (item, state) {
const open = typeof state == 'undefined'
? !this.open.includes(item.serial)
? !this.open.includes(item._serial)
: state;
if (item.children) {
item.children.forEach(child => this.toggleChildren(child, open));
if (item._children) {
item._children.forEach(child => this.toggleChildren(child, open));
}
if (open) {
if (!this.open.includes(item.serial)) {
this.open.push(item.serial);
if (!this.open.includes(item._serial)) {
this.open.push(item._serial);
}
} else {
const index = this.open.indexOf(item.serial);
const index = this.open.indexOf(item._serial);
if (index > -1) {
this.open.splice(index, 1);
}
}
},
transform (item, testId) {
item.serial = ++this.itemIndex;
if (item.id) {
testId = item.id;
} else {
item.id = testId;
}
if (item.check) {
switch (item.iterate) {
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) {
for (const child of item.children) {
this.transform(child, testId);
}
if (item.check) {
item.children = item.check.concatenate(item.children);
}
transform (item, qcId) {
item._serial = ++this.itemIndex;
if (item.name && (item.check || item.children)) {
// This is probably a test
qcId ??= item.id;
item._kind = "test";
item._text = item.name;
item._children = [];
if (item.children) {
// Child tests
item._children = item.children.map(i => this.transform(i, qcId));
}
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;
},
@@ -482,12 +484,12 @@ export default {
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]);
if (res) {
this.items = res.results.map(i => this.transform(i)) || [];
this.items = res.map(i => this.transform(i)) || [];
this.updatedOn = res.updatedOn;
await this.getQCLabels();
} else {