diff --git a/app/src/components/shared/sharedFilter/SharedTable.ts b/app/src/components/shared/sharedFilter/SharedTable.ts index 73ad71979c6c0e5677713c59359ebef2547da91a..76cadfcc8728577f3c97c38642d9ac057f2b0616 100644 --- a/app/src/components/shared/sharedFilter/SharedTable.ts +++ b/app/src/components/shared/sharedFilter/SharedTable.ts @@ -311,9 +311,10 @@ export default class SharedTable extends mixins(TableOptionMixin, CancelTokenMix * current locale. */ public readonly findingTableHeaders: ExtendDataTableHeader[] = [ + { get text() { return i18n.t("sharedTable.sharedTableHeader.transectName").toString(); }, sortable: false, value: "transect", display: true }, + { get text() { return i18n.t("transectManagement.tableHeader.transectCode").toString(); }, sortable: true, value: "transectCode", display: true }, { get text() { return i18n.t("sharedTable.sharedTableHeader.species").toString(); }, sortable: false, value: "species", display: true }, { get text() { return i18n.t("sharedTable.sharedTableHeader.date").toString(); }, sortable: true, value: "date", display: true }, - { get text() { return i18n.t("sharedTable.sharedTableHeader.transect").toString(); }, sortable: false, value: "transect", display: true }, { get text() { return i18n.t("sharedTable.sharedTableHeader.section").toString(); }, sortable: false, value: "section", display: true }, { get text() { return i18n.t("sharedTable.sharedTableHeader.state").toString(); }, sortable: false, value: "state", display: true }, { get text() { return i18n.t("sharedTable.sharedTableHeader.outOfMethod").toString(); }, sortable: true, value: "outOfMethodText", display: true }, @@ -349,7 +350,6 @@ export default class SharedTable extends mixins(TableOptionMixin, CancelTokenMix */ public readonly transectTableHeaders: ExtendDataTableHeader[] = [ { get text() { return i18n.t("transectManagement.tableHeader.transectCode").toString(); }, sortable: true, value: "transectCode", display: true }, - { get text() { return i18n.t("transectManagement.tableHeader.transectId").toString(); }, sortable: true, value: "id", display: true }, { get text() { return i18n.t("transectManagement.tableHeader.name").toString(); }, sortable: true, value: "name", display: true }, { get text() { return i18n.t("transectManagement.tableHeader.date").toString(); }, sortable: true, value: "createdAt", display: true }, { get text() { return i18n.t("transectManagement.tableHeader.transectStatus").toString(); }, sortable: true, value: "status", display: true }, @@ -751,6 +751,7 @@ export default class SharedTable extends mixins(TableOptionMixin, CancelTokenMix transect: item.sectionEvent && item.sectionEvent.section && item.sectionEvent.section.transect ? item.sectionEvent.section.transect.name : null, transectId: item.sectionEvent?.section?.transect ? item.sectionEvent.section.transect._id : null, + transectCode: item.sectionEvent?.section?.transect ? item.sectionEvent.section.transect.transectCode : null, isQsFinal: item.aggregate.isQsFinal, createdBy: item.createdBy, isFinal: false, @@ -917,34 +918,53 @@ export default class SharedTable extends mixins(TableOptionMixin, CancelTokenMix ]); } case FilterCriteriaType.TRANSECT: { - return Vue.observable([ - FilterFactory.createMultiSelectFilter({ - key: "TransectsProposal", - field: "status_is_list", + let transectItems: Array<SelectItem<string>> = []; + const proposalFilter = FilterFactory.createMultiSelectFilter({ + key: "TransectsProposal", + field: "status_is_list", + get label() { + return self.$t("sharedFilter.fcTransectProposal").toString(); + }, + items: [{ + value: "-1", get label() { - return self.$t("sharedFilter.fcTransectProposal").toString(); + return self.$t("transectProposal.proposal.invalid").toString(); }, - items: [{ - value: "-1", - get label() { - return self.$t("transectProposal.proposal.invalid").toString(); - }, - }, { - value: "1", - get label() { - return self.$t("transectProposal.proposal.confirmed").toString(); - }, - }, { - value: "2", - get label() { - return self.$t("transectProposal.proposal.rejected").toString(); - }, - }], - }) + }, { + value: "1", + get label() { + return self.$t("transectProposal.proposal.confirmed").toString(); + }, + }, { + value: "2", + get label() { + return self.$t("transectProposal.proposal.rejected").toString(); + }, + }], + }) + const codeFilter = FilterFactory.createMultiSelectFilter({ + key: "TransectCode", + field: "transectCode_is_list", + allowAutocomplete: true, + get label() { + return self.$t("sharedFilter.fcTransectCode").toString(); + }, + get items() { + return transectItems; + } + }) + this.filterLoading = true; + Promise.all([ + FilterService.getInstance().getTransectCodes().then((items) => transectItems = items), + ]).finally(() => this.filterLoading = false); + return Vue.observable([ + proposalFilter, + codeFilter ]); } case FilterCriteriaType.FINDING: { - let transectItems: Array<SelectItem<string>> = []; + let transectNameItems: Array<SelectItem<string>> = []; + let transectCodeItems: Array<SelectItem<string>> = []; let observerItems: Array<SelectItem<string>> = []; const dateFilter = FilterFactory.createDateRangeFilter({ key: "FindingsDate", @@ -977,7 +997,7 @@ export default class SharedTable extends mixins(TableOptionMixin, CancelTokenMix return self.$t("sharedFilter.fcTransectName").toString(); }, get items() { - return transectItems; + return transectNameItems; }, allowAutocomplete: true, }); @@ -1099,20 +1119,33 @@ export default class SharedTable extends mixins(TableOptionMixin, CancelTokenMix }, ], }); + const codeFilter = FilterFactory.createMultiSelectFilter({ + key: "TransectCode", + field: "aggregate_transectCode_is_list", + allowAutocomplete: true, + get label() { + return self.$t("sharedFilter.fcTransectCode").toString(); + }, + get items() { + return transectCodeItems; + } + }) this.filterLoading = true; Promise.all([ - FilterService.getInstance().getTransects().then((items) => transectItems = items), + FilterService.getInstance().getTransectNames().then((items) => transectNameItems = items), + FilterService.getInstance().getTransectCodes().then((items) => transectCodeItems = items), FilterService.getInstance().getObserverList().then((items) => observerItems = items), ]).finally(() => this.filterLoading = false); return Vue.observable([ dateFilter, transectNameFilter, + codeFilter, observerFilter, geniusFilter, speciesFilter, abundanceFilter, pictureFilter, - qaStatusFilter, + qaStatusFilter ]); } case FilterCriteriaType.INSPECTION: { @@ -1204,7 +1237,7 @@ export default class SharedTable extends mixins(TableOptionMixin, CancelTokenMix this.filterLoading = true; Promise.all([ - FilterService.getInstance().getTransects().then((items) => transectItems = items), + FilterService.getInstance().getTransectNames().then((items) => transectItems = items), FilterService.getInstance().getObserverList().then((items) => observerItems = items), ]).finally(() => this.filterLoading = false); return Vue.observable([ diff --git a/app/src/helper/filter.service.ts b/app/src/helper/filter.service.ts index 4f3e24d363bf483d1f69a8b2cdbdfdbdb9564300..f11ab663e05712bb5552c7dc72b3f0d96944c25e 100644 --- a/app/src/helper/filter.service.ts +++ b/app/src/helper/filter.service.ts @@ -70,10 +70,10 @@ export class FilterService { } /** - * Loads all transect for the filter. + * Loads all transect names for the filter. */ // TODO move to store and preload. - public async getTransects(): Promise<Array<SelectItem<string>>> { + public async getTransectNames(): Promise<Array<SelectItem<string>>> { // will fail to show more than 100 transects. const response = await TransectService.getInstance().getAllTransects(1, 100, "id_order", "asc"); if (!response?.data?.data?.transects?.collection) { @@ -85,6 +85,21 @@ export class FilterService { })); } + /** + * Loads all transect codes for the filter. + */ + public async getTransectCodes(): Promise<Array<SelectItem<string>>> { + // will fail to show more than 100 transects. + const response = await TransectService.getInstance().getAllTransects(1, 100, "id_order", "asc"); + if (!response?.data?.data?.transects?.collection) { + throw new Error("Could not get transects"); + } + return response.data.data.transects.collection.map((transect) => ({ + label: transect.transectCode, + value: transect.transectCode, + })); + } + /** * Query the id of the object to fetch based on the filter history items ids. * @param filterHistoryItems the id of the used filter history items. diff --git a/app/src/helper/observation.service.ts b/app/src/helper/observation.service.ts index bf6ef2ff7044f422657458441a9ea2a1b802e29c..e3f44d73ae735e16da0daf494d743ff6ff94074a 100644 --- a/app/src/helper/observation.service.ts +++ b/app/src/helper/observation.service.ts @@ -84,6 +84,7 @@ export class ObservationService { createdAt name icc2 + transectCode } } } diff --git a/app/src/i18n/de.json b/app/src/i18n/de.json index e9cb0f0cc364358f9aac697d39d6b55bb4b30c29..84c4c5ea13498be445116c7e8dacf500e6f281ac 100644 --- a/app/src/i18n/de.json +++ b/app/src/i18n/de.json @@ -386,6 +386,7 @@ "filterHistoryInfoAlert": "Benutzerdefinierte Filterkriterien werden jetzt verwendet.", "fcDate": "Datum", "fcTransectName": "Transektname", + "fcTransectCode": "Transektcode", "fcGenus": "Gattung", "fcSpecies": "Art", "fcObserver": "Beobachter", @@ -459,6 +460,7 @@ "comment": "Kommentar", "date": "Datum", "transect": "Transekt", + "transectName": "Transekt Name", "startDate": "Startdatum", "startTime": "Startzeit", "observer": "Beobachter", diff --git a/app/src/i18n/en.json b/app/src/i18n/en.json index 620a98bd74f9292af5d2432eab5394fbde09e6fa..7438d5635e421f8efa73c6ec8c2111bb318ae811 100644 --- a/app/src/i18n/en.json +++ b/app/src/i18n/en.json @@ -386,6 +386,7 @@ "filterHistoryInfoAlert": "Custom filter criteria are now used.", "fcDate": "Date", "fcTransectName": "Transect name", + "fcTransectCode": "Transect code", "fcGenus": "Genus", "fcSpecies": "Species", "fcObserver": "Observer", @@ -460,6 +461,7 @@ "date": "Date", "transect": "Transect", "startDate": "Start date", + "transectName": "Transect name", "startTime": "Start time", "observer": "Observer", "transectId": "TransectID", diff --git a/app/tests/unit/SharedTable.spec.ts b/app/tests/unit/SharedTable.spec.ts index 0270a57a9e652ef4ed8cfcba3c08b44eed1be52d..5d42373ac0de3ba35e3ba3ca67ab7ad8914b5a2e 100644 --- a/app/tests/unit/SharedTable.spec.ts +++ b/app/tests/unit/SharedTable.spec.ts @@ -49,7 +49,7 @@ describe("SharedTable.vue", () => { localI18n = setupI18n(localVue); localI18n.locale = Locales.DE; axiosMock = new MockAdapter(axios); - sinon.stub(FilterService.getInstance(), "getTransects").returns(Promise.resolve([])); + sinon.stub(FilterService.getInstance(), "getTransectNames").returns(Promise.resolve([])); sinon.stub(FilterService.getInstance(), "getUserRoles").returns([]); sinon.stub(FilterService.getInstance(), "getObserverList").returns(Promise.resolve([])); sinon.stub(FilterService.getInstance(), "getUserList").returns(Promise.resolve([])); @@ -1318,7 +1318,7 @@ describe("SharedTable.unit.vue", () => { router = new VueRouter(); i18n = setupI18n(localVue); i18n.locale = Locales.DE; - sinon.stub(FilterService.getInstance(), "getTransects").returns(Promise.resolve([])); + sinon.stub(FilterService.getInstance(), "getTransectNames").returns(Promise.resolve([])); sinon.stub(FilterService.getInstance(), "getUserRoles").returns([]); sinon.stub(FilterService.getInstance(), "getObserverList").returns(Promise.resolve([])); sinon.stub(FilterService.getInstance(), "getUserList").returns(Promise.resolve([]));