From 478c1d9541977963e3073772a6c50ced90aed876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Emarianfoo=E2=80=9C?= <13335743+marianfoo@users.noreply.github.com> Date: Thu, 21 Dec 2023 15:58:58 +0100 Subject: [PATCH 1/2] feat: new config to continue batch processing on errors --- .../src/Component.gen.d.ts | 5 ++ .../src/Component.ts | 2 + .../src/controller/SpreadsheetUpload.ts | 3 + .../src/controller/odata/OData.ts | 63 +++++++++++-------- .../ui5-cc-spreadsheetimporter/src/types.d.ts | 1 + 5 files changed, 47 insertions(+), 27 deletions(-) diff --git a/packages/ui5-cc-spreadsheetimporter/src/Component.gen.d.ts b/packages/ui5-cc-spreadsheetimporter/src/Component.gen.d.ts index b55c2960..24188d9b 100644 --- a/packages/ui5-cc-spreadsheetimporter/src/Component.gen.d.ts +++ b/packages/ui5-cc-spreadsheetimporter/src/Component.gen.d.ts @@ -33,6 +33,7 @@ declare module "./Component" { readAllSheets?: boolean | PropertyBindingInfo | `{${string}}`; readSheet?: any | PropertyBindingInfo | `{${string}}`; spreadsheetRowPropertyName?: string | PropertyBindingInfo; + continueOnError?: boolean | PropertyBindingInfo | `{${string}}`; debug?: boolean | PropertyBindingInfo | `{${string}}`; componentContainerData?: object | PropertyBindingInfo | `{${string}}`; checkBeforeRead?: (event: Component$CheckBeforeReadEvent) => void; @@ -143,6 +144,10 @@ declare module "./Component" { getSpreadsheetRowPropertyName(): string; setSpreadsheetRowPropertyName(spreadsheetRowPropertyName: string): this; + // property: continueOnError + getContinueOnError(): boolean; + setContinueOnError(continueOnError: boolean): this; + // property: debug getDebug(): boolean; setDebug(debug: boolean): this; diff --git a/packages/ui5-cc-spreadsheetimporter/src/Component.ts b/packages/ui5-cc-spreadsheetimporter/src/Component.ts index 5bc4fb7e..d7920899 100644 --- a/packages/ui5-cc-spreadsheetimporter/src/Component.ts +++ b/packages/ui5-cc-spreadsheetimporter/src/Component.ts @@ -57,6 +57,7 @@ export default class Component extends UIComponent { readAllSheets: { type: "boolean", defaultValue: false }, readSheet: { type: "any", defaultValue: 0 }, spreadsheetRowPropertyName: { type: "string" }, + continueOnError: { type: "boolean", defaultValue: false }, debug: { type: "boolean", defaultValue: false }, componentContainerData: { type: "object" } //Pro Configurations @@ -134,6 +135,7 @@ export default class Component extends UIComponent { this.setUseTableSelector(oCompData?.useTableSelector); this.setHideSampleData(oCompData?.hideSampleData); this.setComponentContainerData(oCompData?.componentContainerData); + this.setContinueOnError(oCompData?.continueOnError); if (oCompData?.availableOptions && oCompData?.availableOptions.length > 0) { // if availableOptions is set show the Options Menu this.setShowOptions(true); diff --git a/packages/ui5-cc-spreadsheetimporter/src/controller/SpreadsheetUpload.ts b/packages/ui5-cc-spreadsheetimporter/src/controller/SpreadsheetUpload.ts index 05b5e6d7..bcb4eb57 100644 --- a/packages/ui5-cc-spreadsheetimporter/src/controller/SpreadsheetUpload.ts +++ b/packages/ui5-cc-spreadsheetimporter/src/controller/SpreadsheetUpload.ts @@ -242,6 +242,9 @@ export default class SpreadsheetUpload extends ManagedObject { if (options.hasOwnProperty("readSheet")) { this.component.setReadSheet(options.readSheet); } + if (options.hasOwnProperty("continueOnError")) { + this.component.setContinueOnError(options.continueOnError); + } // Special case for showOptions if (options.availableOptions && options.availableOptions.length > 0) { diff --git a/packages/ui5-cc-spreadsheetimporter/src/controller/odata/OData.ts b/packages/ui5-cc-spreadsheetimporter/src/controller/odata/OData.ts index f5fc1c48..6ff2aba1 100644 --- a/packages/ui5-cc-spreadsheetimporter/src/controller/odata/OData.ts +++ b/packages/ui5-cc-spreadsheetimporter/src/controller/odata/OData.ts @@ -59,36 +59,45 @@ export default abstract class OData extends ManagedObject { // Loop over the sliced array for (const batch of slicedPayloadArray) { // loop over data from spreadsheet file - for (const payload of batch) { - // Extension method to manipulate payload - try { - await Util.fireEventAsync("changeBeforeCreate", { payload: payload }, component); - } catch (error) { - Log.error("Error while calling the changeBeforeCreate event", error as Error, "SpreadsheetUpload: callOdata"); + try { + for (const payload of batch) { + // Extension method to manipulate payload + try { + await Util.fireEventAsync("changeBeforeCreate", { payload: payload }, component); + } catch (error) { + Log.error("Error while calling the changeBeforeCreate event", error as Error, "SpreadsheetUpload: callOdata"); + } + this.createAsync(model, binding, payload); + } + // wait for all drafts to be created + await this.submitChanges(model); + let errorsFoundLocal = await this.checkForErrors(model, binding, component.getShowBackendErrorMessages()); + if (errorsFoundLocal) { + this.busyDialog.close(); + spreadsheetUploadController.errorsFound = true; + break; + } else { + await this.waitForCreation(); } - this.createAsync(model, binding, payload); - } - // wait for all drafts to be created - await this.submitChanges(model); - let errorsFoundLocal = await this.checkForErrors(model, binding, component.getShowBackendErrorMessages()); - if (errorsFoundLocal) { - this.busyDialog.close(); - spreadsheetUploadController.errorsFound = true; - break; - } else { - await this.waitForCreation(); - } - // check for and activate all drafts and wait for all draft to be created - if (component.getActivateDraft() && !errorsFoundLocal) { - await this.waitForDraft(); - } + // check for and activate all drafts and wait for all draft to be created + if (component.getActivateDraft() && !errorsFoundLocal) { + await this.waitForDraft(); + } - this.resetContexts(); - currentProgressPercent = currentProgressPercent + (batch.length / payloadArray.length) * 100; - currentProgressValue = currentProgressValue + batch.length; - (this.busyDialog.getModel("busyModel") as JSONModel).setProperty("/progressPercent", currentProgressPercent); - (this.busyDialog.getModel("busyModel") as JSONModel).setProperty("/progressText", `${currentProgressValue} / ${payloadArray.length}`); + this.resetContexts(); + currentProgressPercent = currentProgressPercent + (batch.length / payloadArray.length) * 100; + currentProgressValue = currentProgressValue + batch.length; + (this.busyDialog.getModel("busyModel") as JSONModel).setProperty("/progressPercent", currentProgressPercent); + (this.busyDialog.getModel("busyModel") as JSONModel).setProperty("/progressText", `${currentProgressValue} / ${payloadArray.length}`); + } catch (error) { + if (component.getContinueOnError()) { + Log.error("Error while calling the odata service", error as Error, "SpreadsheetUpload: callOdata"); + } else { + // throw error to stop processing + throw error; + } + } } spreadsheetUploadController.refreshBinding(context, binding, tableObject.getId()); this.busyDialog.close(); diff --git a/packages/ui5-cc-spreadsheetimporter/src/types.d.ts b/packages/ui5-cc-spreadsheetimporter/src/types.d.ts index d2ceb71c..644f329a 100644 --- a/packages/ui5-cc-spreadsheetimporter/src/types.d.ts +++ b/packages/ui5-cc-spreadsheetimporter/src/types.d.ts @@ -103,6 +103,7 @@ export interface ComponentData { spreadsheetTemplateFile?: string; useTableSelector?: boolean; sampleData?: object; + continueOnError?: boolean; } // Pro Types From 15fa9e83c446ac7f03df2b408f3e190f23cb5bc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Emarianfoo=E2=80=9C?= <13335743+marianfoo@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:02:06 +0100 Subject: [PATCH 2/2] docs: update --- docs/pages/Configuration.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/pages/Configuration.md b/docs/pages/Configuration.md index f1b62f90..2084f614 100644 --- a/docs/pages/Configuration.md +++ b/docs/pages/Configuration.md @@ -32,6 +32,7 @@ These options are available and explained in detail below: | `useTableSelector` | Open a Table Selector dialog if multiple tables in view | boolean | | `spreadsheetRowPropertyName` | If you want to sent the spreadsheet row to the backend | string | | `componentContainerData` | Open a Table Selector dialog if multiple tables in view | boolean | +| `continueOnError` | If a error occurs in batch processing, continue | boolean | | `debug` | Option to show more console statements and set Log Level to Debug | boolean | ### `columns` @@ -431,6 +432,15 @@ settings="{ }" /> ```` +### `continueOnError` + +**default:** `false` + +This option defines whether the batch processing should continue if a error occurs. +If you have for example set `batchSize`to 2 and have 4 rows and a error occurs in the first batch of two rows, the processing will stop. If you set this flag to `true` the processing will continue and the second batch of two rows will be processed. +This may lead to errors in the backend, because the first batch of two rows was not processed correctly. +Use this option with caution. + ### `debug`