From 205b74905d8bf5a0e03c11344df47a4e9bfa54f3 Mon Sep 17 00:00:00 2001
From: Lars Kollmann <kollmann@infai.org>
Date: Thu, 28 Oct 2021 11:03:13 +0200
Subject: [PATCH] #381 add dynamic icon for propose/set qaStatus, add function
 to set qastatus via dialog, refactoring,...

---
 .../shared/sharedFilter/SharedTable.ts        | 53 ++++++++++---------
 .../shared/sharedFilter/SharedTable.vue       | 28 ++++++----
 2 files changed, 46 insertions(+), 35 deletions(-)

diff --git a/app/src/components/shared/sharedFilter/SharedTable.ts b/app/src/components/shared/sharedFilter/SharedTable.ts
index 74402ac34..9127cef2b 100644
--- a/app/src/components/shared/sharedFilter/SharedTable.ts
+++ b/app/src/components/shared/sharedFilter/SharedTable.ts
@@ -68,7 +68,7 @@ export default class SharedTable extends Vue {
     private items: Array<{}> = [];
     // TODO: make selectedTableItems typesafe/generic for Inspections and Observations
     private selectedTableItems: Array<ObservationItem> = [];
-    private singleQAStatusToBeSet: {} = {};
+    private singleQAStatusToBeSet: ObservationItem | null = null;
     // TODO: make selectedImageItems typesafe/generic for Inspections and Observations
     private selectedImageItems: Array<ObservationItem> = [];
     private dataButton = false;
@@ -84,12 +84,12 @@ export default class SharedTable extends Vue {
     private showQADialogForDataTable = false;
     private showQADialogForImageGallery = false;
     private qaDialogTitle: VueI18n.TranslateResult = "";
-    private setQAStatus = false;
+    private setQAStatusFinal = false;
     private applyFilterHistory = false;
     private showInspectionDiagrams = false;
     private applyFilterButtonColor = "secondary";
     private selectedQsStatus = FilterHelperClass.getInstance().getQAStatusItemByID("-1");
-    private selectedSpecies: SpeciesListItem = this.getEmptySpeciesItem();
+    private selectedSpecies: SpeciesListItem | null = null;
     private qsStatusComment = "";
     private selectedFilterHistoryDiagram: SelectedFilterHistoryDiagram = {
         type: this.inspectionType ? ["CreatedInspections", "VisitedTransects"] : ["CountSpecies", "ObservationIndex", "CountSpeciesBreakdown"],
@@ -316,13 +316,12 @@ export default class SharedTable extends Vue {
             return;
         }
         for (const item of this.data.data.observations.collection) {
-            const dateTimeFrom = item.aggregate.dateTimeFrom ? item.aggregate.dateTimeFrom : "";
             const newItem: ObservationItem = {
                 _id: item._id,
                 id: item.id,
                 speciesId: item.species,
                 species: this.getSpeciesName(item.species),
-                date: this.handleDate(dateTimeFrom),
+                date: this.handleDate(item.aggregate.dateTimeFrom ? item.aggregate.dateTimeFrom : ""),
                 state: item.isDead,
                 gender: item.sex,
                 comment: item.comment,
@@ -339,6 +338,7 @@ export default class SharedTable extends Vue {
                 genderText: item.sex ? item.sex : this.handleObservationGender(item.developmentalStage._id),
                 transect: item.sectionEvent && item.sectionEvent.section && item.sectionEvent.section.transect ?
                     item.sectionEvent.section.transect.name : null,
+                isQsFinal: item.aggregate.isQsFinal,
             };
             if (item.sectionEvent) {
                 if (item.sectionEvent.inspection) {
@@ -395,6 +395,7 @@ export default class SharedTable extends Vue {
                         speciesId: item.species,
                         speciesFullName: this.getSpeciesFullName(item.species, store.getters.getSpeciesList),
                         genderText: item.sex ? item.sex : this.handleObservationGender(item.developmentalStage._id),
+                        isQsFinal: item.aggregate.isQsFinal,
                     });
                 }
             }
@@ -431,7 +432,7 @@ export default class SharedTable extends Vue {
      * called when on the table item, the set-qa-state-icon is clicked (not the btn above the table)
      * sets the title to $t('sharedTable.setQsState')
      */
-    private clickQAStatus(item: FindingsTableItem): void {
+    private clickQAStatus(item: ObservationItem): void {
         if (this.isAdmin || this.isCountryLead || this.isProjectLead || this.isRegionalLead) {
             this.singleQAStatusToBeSet = item;
             this.qaDialogTitle = this.$t("sharedTable.setQAStatus");
@@ -444,10 +445,10 @@ export default class SharedTable extends Vue {
      * setQAState: defines if it is about the set-QA-State, false when it is about the proposal-QA-State dialog
      * sets the qAStatusDialogTitle variable to title
      */
-    private openQAStateDialog(setQAState: boolean) {
+    private openQAStateDialog(setQAStatusFinal: boolean) {
         this.hideAlerts();
-        this.setQAStatus = setQAState;
-        this.qaDialogTitle = setQAState ? i18n.t('sharedTable.setQAStatus') : i18n.t('sharedTable.proposeQAStatus');
+        this.setQAStatusFinal = setQAStatusFinal;
+        this.qaDialogTitle = setQAStatusFinal ? i18n.t('sharedTable.setQAStatus') : i18n.t('sharedTable.proposeQAStatus');
         this.showQADialogForDataTable = this.dataButton;
         this.showQADialogForImageGallery = this.imageButton;
     }
@@ -460,30 +461,31 @@ export default class SharedTable extends Vue {
         this.showQADialogForDataTable = false;
         this.showQADialogForImageGallery = false;
         this.selectedQsStatus = FilterHelperClass.getInstance().getQAStatusItemByID("-1");
-        this.selectedSpecies = this.getEmptySpeciesItem();
+        this.selectedSpecies = null;
         this.qsStatusComment = "";
-        this.singleQAStatusToBeSet = {};
+        this.singleQAStatusToBeSet = null;
     }
 
     private async clickOkInQAStateDialog() {
         this.hideAlerts();
         this.qaResponseErrorMessage = "";
         this.isQADialogLoading = true;
-        if (this.setQAStatus) {
-            // TODO set QA-Status
-            // DataView(Table)
-            // ImageView
+
+        if (this.singleQAStatusToBeSet) {
+            // just set single qs-status
+            if (!this.isQAObservationCreatedWithoutErrors(await this.createQSObservation(this.getQAObservationItem(this.singleQAStatusToBeSet), this.setQAStatusFinal))) {
+                return;
+            }
         } else {
-            // Propose QA-Status
             // DataView(Table)
             for (const item of this.selectedTableItems) {
-                if (!this.isQAObservationCreatedWithoutErrors(await this.createQSObservation(this.getQAObservationItem(item)))) {
+                if (!this.isQAObservationCreatedWithoutErrors(await this.createQSObservation(this.getQAObservationItem(item), this.setQAStatusFinal))) {
                     return;
                 }
             }
             // ImageView
             for (const item of this.selectedImageItems) {
-                if (!this.isQAObservationCreatedWithoutErrors(await this.createQSObservation(this.getQAObservationItem(item)))) {
+                if (!this.isQAObservationCreatedWithoutErrors(await this.createQSObservation(this.getQAObservationItem(item), this.setQAStatusFinal))) {
                     return;
                 }
             }
@@ -510,8 +512,9 @@ export default class SharedTable extends Vue {
             sex: observation.gender,
             isDead: observation.isDead,
             qsStatus: parseInt(this.selectedQsStatus.id, 10),
-            qsSpecies: this.selectedSpecies.ptnameId < 0 ? observation.speciesId : this.selectedSpecies.ptnameId,
+            qsSpecies: this.selectedSpecies === null ? observation.speciesId : this.selectedSpecies.ptnameId,
             qsComment: this.qsStatusComment,
+            isQsFinal: observation.isQsFinal,
         }
     }
 
@@ -575,6 +578,10 @@ export default class SharedTable extends Vue {
         return FilterHelperClass.getInstance().getQAStatusIconColor(qsState);
     }
 
+    private getQsStatusIcon(isQSFinal: boolean): string {
+        return FilterHelperClass.getInstance().getQAStatusIcon(isQSFinal);
+    }
+
     private getSpeciesName(speciesID): string {
         const speciesList = store.getters.getSpeciesList;
         let species = "";
@@ -729,10 +736,6 @@ export default class SharedTable extends Vue {
         this.selectedImage = imageUrl.imageRefUrl;
     }
 
-    private getEmptySpeciesItem(): SpeciesListItem {
-        return {species: "", id: "", ptnameId: -1, author: "", family: "", superFamily: "", fullName: "", genus: "", projectId: 0, rank: 0};
-    }
-
     private isValidInspectionData(data: AxiosResponse): boolean {
         return data && data.data && data.data.inspections && data.data.inspections.collection;
     }
@@ -749,7 +752,7 @@ export default class SharedTable extends Vue {
         return item.imageRefs && item.imageRefs.collection && item.imageRefs.collection.length;
     }
 
-    private createQSObservation = async (qsObservation: QSObservationItem) => {
-        return await ObservationService.getInstance().createQSObservation(qsObservation);
+    private createQSObservation = async (qsObservation: QSObservationItem, isQsFinal: boolean) => {
+        return await ObservationService.getInstance().createQSObservation(qsObservation, isQsFinal);
     }
 }
diff --git a/app/src/components/shared/sharedFilter/SharedTable.vue b/app/src/components/shared/sharedFilter/SharedTable.vue
index dcdd3e0dd..42b5931af 100644
--- a/app/src/components/shared/sharedFilter/SharedTable.vue
+++ b/app/src/components/shared/sharedFilter/SharedTable.vue
@@ -153,7 +153,7 @@
                     <template v-slot:item.actions="{item}">
                         <v-btn v-if="findingType"
                             data-testid="qAStatusActionsBtn" icon :color="getQsStatusIconColor(item.qsStatus)" @click="clickQAStatus(item)">
-                            <v-icon>mdi-circle</v-icon>
+                            <v-icon>{{ getQsStatusIcon(item.isQsFinal) }}</v-icon>
                         </v-btn>
                         <v-btn color="black" elevation="0" @click="editItem(item.inspectionId)" icon>
                             <v-icon>mdi-pencil</v-icon>
@@ -165,11 +165,11 @@
                             <v-card :disabled="isQADialogLoading">
                                 <v-card-title class="headline">{{ qaDialogTitle }}</v-card-title>
                                 <v-card-text>
-                                    <div v-if="singleQAStatusToBeSet.id">
-                                        <v-icon :color="getQsStatusIconColor(singleQAStatusToBeSet.qsStatus)">mdi-circle</v-icon> {{ singleQAStatusToBeSet.species }}
+                                    <div v-if="singleQAStatusToBeSet">
+                                        <v-icon :color="getQsStatusIconColor(singleQAStatusToBeSet.qsStatus)">{{ getQsStatusIcon(singleQAStatusToBeSet.isQsFinal) }}</v-icon> {{ singleQAStatusToBeSet.species }}
                                     </div>
                                     <div v-else v-for="(item, index) in selectedTableItems" :key="index">
-                                        <v-icon :color="getQsStatusIconColor(item.qsStatus)">mdi-circle</v-icon> {{item.species}}
+                                        <v-icon :color="getQsStatusIconColor(item.qsStatus)">{{ getQsStatusIcon(item.isQsFinal) }}</v-icon> {{item.species}}
                                     </div>
                                     <v-divider class="mt-2"></v-divider>
                                     <div class="mt-2">
@@ -183,10 +183,14 @@
                                             :label="$t('sharedTable.newQsStatus')"
                                             data-testid="newQsStatusSelectDataTable">
                                             <template v-slot:selection="{item}">
-                                                {{ item.value }} <v-icon :color="item.color">mdi-circle</v-icon>
+                                                {{ item.value }} <v-icon :color="item.color">{{
+                                                    getQsStatusIcon(setQAStatusFinal)
+                                                }}</v-icon>
                                             </template>
                                             <template v-slot:item="{item}">
-                                                {{ item.value }} <v-icon :color="item.color">mdi-circle</v-icon>
+                                                {{ item.value }} <v-icon :color="item.color">{{
+                                                    getQsStatusIcon(setQAStatusFinal)
+                                                }}</v-icon>
                                             </template>
                                         </v-select>
                                         <v-autocomplete
@@ -280,7 +284,7 @@
                             <v-card-title class="headline">{{ qaDialogTitle }}</v-card-title>
                             <v-card-text>
                                 <div v-for="(item, index) in selectedImageItems" :key="index">
-                                    <v-icon :color="getQsStatusIconColor(item.qsStatus)">mdi-circle</v-icon> {{item.transect}} {{item.date}}
+                                    <v-icon :color="getQsStatusIconColor(item.qsStatus)">{{ getQsStatusIcon(item.isQsFinal) }}</v-icon> {{item.transect}} {{item.date}}
                                     <div class="ml-7 mb-4">{{item.genderText}} {{item.speciesFullName}}</div>
                                 </div>
                                 <v-divider class="mt-2"></v-divider>
@@ -295,10 +299,14 @@
                                         :label="$t('sharedTable.newQsStatus')"
                                         data-testid="newQsStatusSelectQAPictureTable">
                                         <template v-slot:selection="{item}">
-                                            {{ item.value }} <v-icon :color="item.color">mdi-circle</v-icon>
+                                            {{ item.value }} <v-icon :color="item.color">{{
+                                                getQsStatusIcon(setQAStatusFinal)
+                                            }}</v-icon>
                                         </template>
                                         <template v-slot:item="{item}">
-                                            {{ item.value }} <v-icon :color="item.color">mdi-circle</v-icon>
+                                            {{ item.value }} <v-icon :color="item.color">{{
+                                                getQsStatusIcon(setQAStatusFinal)
+                                            }}</v-icon>
                                         </template>
                                     </v-select>
                                     <v-autocomplete
@@ -444,7 +452,7 @@
                                                 <v-col cols="11">
                                                     <v-expansion-panel-header>
                                                         <h4>{{ item.date }} - {{ item.transect }}
-                                                            <v-icon :color="getQsStatusIconColor(item.qsStatus)">mdi-circle</v-icon>
+                                                            <v-icon :color="getQsStatusIconColor(item.qsStatus)">{{ getQsStatusIcon(item.isQsFinal) }}</v-icon>
                                                         </h4>
                                                         <div class="text-end">
                                                             <!-- is only needed because without, the hover circle of v-btn becomes an oval-->
-- 
GitLab