diff --git a/src/components/renderer/form-button.vue b/src/components/renderer/form-button.vue index aa3116351..86a67fbb0 100644 --- a/src/components/renderer/form-button.vue +++ b/src/components/renderer/form-button.vue @@ -10,7 +10,7 @@ :disabled="showSpinner" > - {{ showSpinner ? (!loadingLabel ? 'Loading...': loadingLabel) : label }} + {{ showSpinner ? (!loadingLabel ? "Loading..." : loadingLabel) : label }} @@ -19,17 +19,31 @@ import Mustache from 'mustache'; import { mapActions, mapState } from "vuex"; import { getValidPath } from '@/mixins'; +import Worker from "@/workers/worker.js?worker&inline"; export default { mixins: [getValidPath], - props: ['variant', 'label', 'event', 'eventData', 'name', 'fieldValue', 'value', 'tooltip', 'transientData', 'loading', 'loadingLabel', 'handler'], + props: [ + "variant", + "label", + "event", + "eventData", + "name", + "fieldValue", + "value", + "tooltip", + "transientData", + "loading", + "loadingLabel", + "handler" + ], data() { return { showSpinner: false }; }, computed: { - ...mapState('globalErrorsModule', ['valid']), + ...mapState("globalErrorsModule", ["valid"]), classList() { let variant = this.variant || 'primary'; return { @@ -106,15 +120,35 @@ export default { async runHandler() { if (this.handler) { try { - const data = this.getScreenDataReference(null, (screen, name, value) => { - // Enable the data reference to be updated by the handler - screen.$set(screen.vdata, name, value); + const data = this.getScreenDataReference( + null, + (screen, name, value) => { + // Enable the data reference to be updated by the handler + screen.$set(screen.vdata, name, value); + } + ); + + const rawData = data[Symbol.for("__v_raw")]; + + const worker = new Worker(); + worker.postMessage({ + fn: this.handler, + data: rawData, }); - await new Function(['toRaw'], this.handler).apply(data, [(item) => { - return item[Symbol.for('__v_raw')]; - }]); + + worker.onmessage = (e) => { + if (e.data.error) { + console.error("Worker error:", e.data.error); + } else if (e.data.result) { + + // Update the data with the result + Object.keys(e.data.result).forEach(key => { + rawData[key] = e.data.result[key]; + }); + } + }; } catch (error) { - console.error('❌ There is an error in the button handler', error); + console.error("❌ There is an error in the button handler", error); } } } diff --git a/src/workers/worker.js b/src/workers/worker.js new file mode 100644 index 000000000..a985bb771 --- /dev/null +++ b/src/workers/worker.js @@ -0,0 +1,16 @@ +// worker.js +self.onmessage = function (e) { + const { fn, data } = e.data; + + try { + // Execute the handler as a function with data as the context + const func = new Function("data", fn); + // const func = new Function('data', `return (${fn})(data)`) + const result = func(data); + + self.postMessage({ result }); + } catch (error) { + console.error("Error executing handler:", error); + self.postMessage({ error: error.message }); + } +}; diff --git a/tests/e2e/fixtures/button_click_handler.json b/tests/e2e/fixtures/button_click_handler.json index 504cac5a5..6bb22c4a4 100644 --- a/tests/e2e/fixtures/button_click_handler.json +++ b/tests/e2e/fixtures/button_click_handler.json @@ -690,7 +690,7 @@ "name": "button_with_handler", "fieldValue": null, "tooltip": {}, - "handler": "this.form_input_2=\"value changed by handler\";" + "handler": "return {\n form_input_2: \"value changed by handler\",\n}" }, "inspector": [ { @@ -1392,7 +1392,7 @@ "name": "record_list_button_with_handler", "fieldValue": null, "tooltip": {}, - "handler": "this.form_input_1=\"value changed by handler\";console.log('handler executed')" + "handler": "console.log('handler executed');\nreturn {\n form_input_1: \"value changed by handler\",\n}" }, "inspector": [ { @@ -1818,4 +1818,4 @@ ], "screen_categories": [], "scripts": [] -} \ No newline at end of file +}