From 6d25ca7c1c09a3f5dcdd7f5f53bdb60b6ae7d3c8 Mon Sep 17 00:00:00 2001 From: Sergey Fedyanin Date: Wed, 13 Sep 2023 12:56:04 -0700 Subject: [PATCH 1/4] feat: add ability to subset submissions for export --- .../src/components/forms/ExportSubmissions.vue | 12 ++++++++++-- .../src/components/forms/SubmissionsTable.vue | 11 +++++++++++ app/frontend/src/services/formService.js | 2 ++ app/frontend/src/store/modules/form.js | 8 ++++++++ app/src/forms/common/models/views/submissionData.js | 5 +++++ app/src/forms/form/exportService.js | 1 + 6 files changed, 37 insertions(+), 2 deletions(-) diff --git a/app/frontend/src/components/forms/ExportSubmissions.vue b/app/frontend/src/components/forms/ExportSubmissions.vue index 78635af8f..7b5cec3b0 100644 --- a/app/frontend/src/components/forms/ExportSubmissions.vue +++ b/app/frontend/src/components/forms/ExportSubmissions.vue @@ -408,6 +408,7 @@ export default { 'submissionList', 'isRTL', 'lang', + 'selectedSubmissions', ]), ...mapGetters('auth', ['email']), @@ -426,7 +427,11 @@ export default { }, methods: { ...mapActions('notifications', ['addNotification']), - ...mapActions('form', ['fetchForm', 'fetchFormCSVExportFields']), + ...mapActions('form', [ + 'fetchForm', + 'fetchFormCSVExportFields', + 'selectSubmissions', + ]), async changeVersions(value) { this.versionRequired = false; value !== '' @@ -502,7 +507,8 @@ export default { // drafts: true }, fieldToExport, - emailExport + emailExport, + this.selectedSubmissions ); if (response && response.data && !emailExport) { @@ -530,6 +536,8 @@ export default { `${this.form.id}: ${error}`, }); } + // empty selected submissions for export if there are so + this.selectSubmissions(''); }, async updateVersions() { diff --git a/app/frontend/src/components/forms/SubmissionsTable.vue b/app/frontend/src/components/forms/SubmissionsTable.vue index 914678657..e890c6545 100644 --- a/app/frontend/src/components/forms/SubmissionsTable.vue +++ b/app/frontend/src/components/forms/SubmissionsTable.vue @@ -604,6 +604,15 @@ export default { } }, }, + watch: { + selectedSubmissions(newValue) { + if (newValue && newValue.length > 0) { + this.selectSubmissions( + newValue.map((val) => val.submissionId).join(',') + ); + } + }, + }, methods: { ...mapActions('form', [ 'fetchForm', @@ -617,6 +626,7 @@ export default { 'restoreMultiSubmissions', 'deleteSubmission', 'updateFormPreferencesForCurrentUser', + 'selectSubmissions', ]), ...mapActions('notifications', ['addNotification']), onShowColumnDialog() { @@ -778,6 +788,7 @@ export default { }) .finally(() => { this.selectedSubmissions = []; + this.selectSubmissions(''); }); }, diff --git a/app/frontend/src/services/formService.js b/app/frontend/src/services/formService.js index ac1f0768b..5cba66d45 100644 --- a/app/frontend/src/services/formService.js +++ b/app/frontend/src/services/formService.js @@ -400,6 +400,7 @@ export default { preference, fields, emailExport = false, + selectedSubmissions, options = {} ) { return appAxios().post( @@ -412,6 +413,7 @@ export default { preference: preference, fields: fields, emailExport, + selectedSubmissions, ...options, }, { diff --git a/app/frontend/src/store/modules/form.js b/app/frontend/src/store/modules/form.js index 12b3a48f5..a11683998 100644 --- a/app/frontend/src/store/modules/form.js +++ b/app/frontend/src/store/modules/form.js @@ -101,6 +101,7 @@ export default { isRTL: false, subscriptionData: genInitialSubscribeDetails(), totalSubmissions: 0, + selectedSubmissions: '', }, getters: { getField, // vuex-map-fields @@ -125,6 +126,7 @@ export default { isRTL: (state) => state.isRTL, subscriptionData: (state) => state.subscriptionData, totalSubmissions: (state) => state.totalSubmissions, + selectedSubmissions: (state) => state.selectedSubmissions, }, mutations: { updateField, // vuex-map-fields @@ -198,6 +200,9 @@ export default { SET_TOTALSUBMISSIONS(state, totalSubmissions) { state.totalSubmissions = totalSubmissions; }, + SET_SELECTED_SUBMISSIONS(state, selectedSubmissions) { + state.selectedSubmissions = selectedSubmissions; + }, }, actions: { // @@ -1027,5 +1032,8 @@ export default { ); } }, + selectSubmissions({ commit }, selected) { + commit('SET_SELECTED_SUBMISSIONS', selected); + }, }, }; diff --git a/app/src/forms/common/models/views/submissionData.js b/app/src/forms/common/models/views/submissionData.js index d3728e545..fcc289331 100644 --- a/app/src/forms/common/models/views/submissionData.js +++ b/app/src/forms/common/models/views/submissionData.js @@ -45,6 +45,11 @@ class SubmissionData extends Model { query.where('draft', false); } }, + filterSubmissionIds(query, value) { + if (value && value !== '') { + query.whereIn('submissionId', value.split(',')); + } + }, orderDefault(builder) { builder.orderBy('createdAt', 'DESC'); }, diff --git a/app/src/forms/form/exportService.js b/app/src/forms/form/exportService.js index 4ba31b5df..e532b8171 100644 --- a/app/src/forms/form/exportService.js +++ b/app/src/forms/form/exportService.js @@ -264,6 +264,7 @@ const service = { .modify('filterStatus', params.status) .modify('filterDeleted', params.deleted) .modify('filterDrafts', params.drafts) + .modify('filterSubmissionIds', params.selectedSubmissions) .modify('orderDefault') .then((submissionData) => { if (submissionData == undefined || submissionData == null || submissionData.length == 0) return []; From a8336de510c5280a637b2ac8865ababa65d70661 Mon Sep 17 00:00:00 2001 From: Sergey Fedyanin Date: Mon, 18 Sep 2023 23:30:13 -0700 Subject: [PATCH 2/4] fix: unit tests --- app/tests/unit/forms/form/exportService.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/tests/unit/forms/form/exportService.spec.js b/app/tests/unit/forms/form/exportService.spec.js index 2b7076172..c99f0ef98 100644 --- a/app/tests/unit/forms/form/exportService.spec.js +++ b/app/tests/unit/forms/form/exportService.spec.js @@ -486,7 +486,7 @@ describe('_getSubmissions', () => { } exportService._getSubmissions(form, params, params.version); expect(MockModel.query).toHaveBeenCalledTimes(1); - expect(MockModel.modify).toHaveBeenCalledTimes(7); + expect(MockModel.modify).toHaveBeenCalledTimes(8); expect(MockModel.modify).toHaveBeenCalledWith('filterUpdatedAt', preference && preference.updatedMinDate, preference && preference.updatedMaxDate); }); @@ -502,7 +502,7 @@ describe('_getSubmissions', () => { exportService._submissionsColumns = jest.fn().mockReturnThis(); exportService._getSubmissions(form, params, params.version); expect(MockModel.query).toHaveBeenCalledTimes(1); - expect(MockModel.modify).toHaveBeenCalledTimes(7); + expect(MockModel.modify).toHaveBeenCalledTimes(8); }); it('Should pass this test with preference passed to _getSubmissions', async () => { @@ -528,7 +528,7 @@ describe('_getSubmissions', () => { } exportService._getSubmissions(form, params, params.version); expect(MockModel.query).toHaveBeenCalledTimes(1); - expect(MockModel.modify).toHaveBeenCalledTimes(7); + expect(MockModel.modify).toHaveBeenCalledTimes(8); expect(MockModel.modify).toHaveBeenCalledWith('filterUpdatedAt', preference && preference.updatedMinDate, preference && preference.updatedMaxDate); }); }); From 3ea0d22fde351be803af6fbbf65a5f532b6a5798 Mon Sep 17 00:00:00 2001 From: Sergey Fedyanin Date: Wed, 27 Sep 2023 11:15:09 -0700 Subject: [PATCH 3/4] fix: do not filter by version if selected submission ids provided --- app/src/forms/common/models/views/submissionData.js | 7 ++++--- app/src/forms/form/exportService.js | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/forms/common/models/views/submissionData.js b/app/src/forms/common/models/views/submissionData.js index fcc289331..29d971e70 100644 --- a/app/src/forms/common/models/views/submissionData.js +++ b/app/src/forms/common/models/views/submissionData.js @@ -7,9 +7,10 @@ class SubmissionData extends Model { static get modifiers() { return { - filterVersion(query, value) { - if (value) { - query.where('version', value); + filterVersion(query, version, selectedSubmissions) { + // DO NOT need to filter by version if we filter by particular selected ids + if (version && (!selectedSubmissions || selectedSubmissions === '')) { + query.where('version', version); } }, filterCreatedAt(query, minDate, maxDate) { diff --git a/app/src/forms/form/exportService.js b/app/src/forms/form/exportService.js index e532b8171..ea67f61c6 100644 --- a/app/src/forms/form/exportService.js +++ b/app/src/forms/form/exportService.js @@ -258,7 +258,7 @@ const service = { return SubmissionData.query() .select(service._submissionsColumns(form, params)) .where('formId', form.id) - .modify('filterVersion', version) + .modify('filterVersion', version, params.selectedSubmissions) .modify('filterCreatedAt', preference && preference.minDate, preference && preference.maxDate) .modify('filterUpdatedAt', preference && preference.updatedMinDate, preference && preference.updatedMaxDate) .modify('filterStatus', params.status) From d0914fc72e32403329b6a0e641c58dd2c5dbcdcd Mon Sep 17 00:00:00 2001 From: Sergey Fedyanin Date: Tue, 31 Oct 2023 08:40:07 -0700 Subject: [PATCH 4/4] feat: add version selection for submission list --- .../components/forms/ExportSubmissions.vue | 11 +++++-- .../src/components/forms/SubmissionsTable.vue | 33 +++++++++++++++++-- app/frontend/src/store/modules/form.js | 10 ++++++ 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/app/frontend/src/components/forms/ExportSubmissions.vue b/app/frontend/src/components/forms/ExportSubmissions.vue index f1e750b7c..1efd97dfc 100644 --- a/app/frontend/src/components/forms/ExportSubmissions.vue +++ b/app/frontend/src/components/forms/ExportSubmissions.vue @@ -62,7 +62,7 @@ - + {{ $t('trans.exportSubmissions.formVersion') }} @@ -409,6 +409,7 @@ export default { 'isRTL', 'lang', 'selectedSubmissions', + 'selectedVersion', ]), ...mapGetters('auth', ['email']), @@ -431,6 +432,7 @@ export default { 'fetchForm', 'fetchFormCSVExportFields', 'selectSubmissions', + 'selectVersion', ]), async changeVersions(value) { this.versionRequired = false; @@ -539,6 +541,7 @@ export default { } // empty selected submissions for export if there are so this.selectSubmissions(''); + this.selectVersion(null); }, async updateVersions() { @@ -561,7 +564,11 @@ export default { this.versions.push( ...this.form.versions.map((version) => version.version) ); - this.versionSelected = this.versions[0]; + if (this.selectedVersion) { + this.versionSelected = this.selectedVersion; + } else { + this.versionSelected = this.versions[0]; + } await this.refreshFormFields(this.versionSelected); } }, diff --git a/app/frontend/src/components/forms/SubmissionsTable.vue b/app/frontend/src/components/forms/SubmissionsTable.vue index 55ddf801c..3c8bf8b12 100644 --- a/app/frontend/src/components/forms/SubmissionsTable.vue +++ b/app/frontend/src/components/forms/SubmissionsTable.vue @@ -101,6 +101,17 @@ +
+ + {{ $t('trans.exportSubmissions.formVersion') }} + + +