From 6bc1f3110ed361945f0590a48219daea800285f7 Mon Sep 17 00:00:00 2001 From: Kelani Tolulope Date: Tue, 28 Feb 2023 12:37:46 +0100 Subject: [PATCH] Add support for bulk record edit --- .../components/PageBlocks/RecordListBase.vue | 23 +- .../PageBlocks/RecordListConfigurator.vue | 3 + .../Public/Record/BulkEdit/index.vue | 202 ++++++++++++++++++ client/web/compose/src/mixins/record.js | 42 ++++ lib/js/src/api-clients/compose.ts | 36 ++++ .../compose/types/page-block/record-list.ts | 5 + locale/en/corteza-webapp-compose/block.yaml | 10 + .../corteza-webapp-compose/notification.yaml | 2 + 8 files changed, 321 insertions(+), 2 deletions(-) create mode 100644 client/web/compose/src/components/Public/Record/BulkEdit/index.vue diff --git a/client/web/compose/src/components/PageBlocks/RecordListBase.vue b/client/web/compose/src/components/PageBlocks/RecordListBase.vue index 109e0f651..b200e0463 100644 --- a/client/web/compose/src/components/PageBlocks/RecordListBase.vue +++ b/client/web/compose/src/components/PageBlocks/RecordListBase.vue @@ -128,7 +128,7 @@ -
+
+ + + + + diff --git a/client/web/compose/src/mixins/record.js b/client/web/compose/src/mixins/record.js index 1440afef3..c536418f9 100644 --- a/client/web/compose/src/mixins/record.js +++ b/client/web/compose/src/mixins/record.js @@ -262,6 +262,48 @@ export default { }) }, 500), + handleBulkUpdateSelectedRecords: throttle(function () { + const { moduleID, namespaceID } = this.module + const values = this.record.values.toJSON() + const records = this.selectedRecords + this.processing = true + + return this + .dispatchUiEvent('beforeFormSubmit') + .then(() => this.$ComposeAPI.recordPatch({ moduleID, namespaceID, records, values })) + .catch(err => { + const { details = undefined } = err + if (!!details && Array.isArray(details) && details.length > 0) { + this.errors = new validator.Validated() + this.errors.push(...details) + + throw new Error(this.$t('notification:record.validationErrors')) + } + + throw err + }) + .then(({ records }) => { + return records[0] + }) + .then((record) => { + this.updatePrompts() + return record + }) + .then((record) => { + if (record.valueErrors && record.valueErrors.set) { + this.toastWarning(this.$t('notification:record.validationWarnings')) + } else { + this.toastSuccess(this.$t('notification:record.bulkRecordUpdateSuccess')) + this.onReset() + this.onModalHide() + } + }) + .catch(this.toastErrorHandler(this.$t('notification:record.deleteBulkRecordUpdateFailed'))) + .finally(() => { + this.processing = false + }) + }, 500), + /** * Validates record and dispatches onFormSubmitError * diff --git a/lib/js/src/api-clients/compose.ts b/lib/js/src/api-clients/compose.ts index d2921331e..fbdb894b3 100644 --- a/lib/js/src/api-clients/compose.ts +++ b/lib/js/src/api-clients/compose.ts @@ -1655,6 +1655,42 @@ export default class Compose { return `/namespace/${namespaceID}/module/${moduleID}/record/${recordID}` } + // Partially update record values + async recordPatch (a: KV, extra: AxiosRequestConfig = {}): Promise { + const { + namespaceID, + moduleID, + records, + values, + } = (a as KV) || {} + if (!namespaceID) { + throw Error('field namespaceID is empty') + } + if (!moduleID) { + throw Error('field moduleID is empty') + } + const cfg: AxiosRequestConfig = { + ...extra, + method: 'patch', + url: this.recordPatchEndpoint({ + namespaceID, moduleID, + }), + } + cfg.data = { + records, + values, + } + return this.api().request(cfg).then(result => stdResolve(result)) + } + + recordPatchEndpoint (a: KV): string { + const { + namespaceID, + moduleID, + } = a || {} + return `/namespace/${namespaceID}/module/${moduleID}/record/` + } + // Delete record row from module section async recordBulkDelete (a: KV, extra: AxiosRequestConfig = {}): Promise { const { diff --git a/lib/js/src/compose/types/page-block/record-list.ts b/lib/js/src/compose/types/page-block/record-list.ts index f00d071d2..c6371c5c6 100644 --- a/lib/js/src/compose/types/page-block/record-list.ts +++ b/lib/js/src/compose/types/page-block/record-list.ts @@ -55,6 +55,8 @@ interface Options { // Ordered list of buttons to display in the block selectionButtons: Array