From b337bf7a53673395009e1186a3ac85ff2001d7f9 Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Thu, 12 Sep 2024 02:02:27 +0200 Subject: [PATCH] [#341] Added `return` block to `ProcedureEditor`. --- .../src/components/Action/ActionsList.vue | 213 +++++++++++++++--- .../src/components/Action/ConditionTile.vue | 14 +- ...nditionEditor.vue => ExpressionEditor.vue} | 33 ++- .../webapp/src/components/Action/Mixin.vue | 10 + .../src/components/Action/ReturnTile.vue | 138 ++++++++++++ 5 files changed, 362 insertions(+), 46 deletions(-) rename platypush/backend/http/webapp/src/components/Action/{ConditionEditor.vue => ExpressionEditor.vue} (73%) create mode 100644 platypush/backend/http/webapp/src/components/Action/ReturnTile.vue diff --git a/platypush/backend/http/webapp/src/components/Action/ActionsList.vue b/platypush/backend/http/webapp/src/components/Action/ActionsList.vue index 84a9371b9c..d366e87f6d 100644 --- a/platypush/backend/http/webapp/src/components/Action/ActionsList.vue +++ b/platypush/backend/http/webapp/src/components/Action/ActionsList.vue @@ -9,13 +9,12 @@
@@ -26,12 +25,18 @@ :is-else="true" v-else-if="elses[index]" /> + +
-
+
-
- +
+
-
- +
+
+ +
+ +
+ +
+ +
+ +
@@ -63,6 +79,7 @@ import AddTile from "./AddTile" import ConditionBlock from "./ConditionBlock" import ListItem from "./ListItem" import Mixin from "./Mixin" +import ReturnTile from "./ReturnTile" import Utils from "@/Utils" export default { @@ -88,6 +105,7 @@ export default { AddTile, ConditionBlock, ListItem, + ReturnTile, }, props: { @@ -132,6 +150,7 @@ export default { data() { return { + collapseAddButtons: true, newValue: [], dragIndices: undefined, initialValue: undefined, @@ -192,6 +211,14 @@ export default { } } + if ( + this.getCondition(action) && + this.newValue[index + 1] && + this.isElse(this.newValue[index + 1]) + ) { + data.props.hasElse = true + } + if (this.isActionsBlock(action)) { data.props.indent = this.indent + 1 } @@ -274,6 +301,91 @@ export default { return this.dragIndices?.[0] }, + returnIndex() { + const ret = this.newValue?.reduce?.((acc, action, index) => { + if (acc >= 0) + return acc + + if (this.isReturn(action)) + return index + + return acc + }, -1) + + return ret >= 0 ? ret : null + }, + + returnValue() { + if (this.returnIndex == null) + return '' + + const ret = this.newValue[this.returnIndex] + if (ret == null) + return '' + + let retValue = null + if (Array.isArray(ret)) + retValue = ret.length === 1 ? ret[0].match(/^return\s*(.*)$/)?.[1] : ret + else + retValue = ret.return + + return retValue || '' + }, + + showAddButtons() { + return ( + this.newValue.length === 0 || !this.collapseAddButtons + ) + }, + + showAddButtonsExpander() { + return ( + !this.readOnly && + this.newValue?.length > 0 && + Object.entries(this.visibleAddButtons).filter( + ([key, value]) => value && key != 'action' + ).length > 1 + ) + }, + + stopIndex() { + return this.returnIndex + }, + + visibleActions() { + return this.newValue.reduce((acc, action, index) => { + if (this.stopIndex != null && index > this.stopIndex) + return acc + + if ( + this.conditions[index] || + this.elses[index] || + this.isAction(action) || + this.isReturn(action) + ) { + acc[index] = action + } + + return acc + }, {}) + }, + + visibleAddButtons() { + return { + action: !this.readOnly && !this.collapsed && this.stopIndex == null, + return: !this.readOnly && !this.collapsed && this.stopIndex == null, + condition: !this.readOnly && !this.collapsed && this.stopIndex == null, + else: ( + !this.readOnly && + !this.collapsed && + this.parent && + this.getCondition(this.parent) && + !this.hasElse && + this.stopIndex == null + ), + } + }, + visibleTopSpacers() { const dragIndex = this.dragIndex return this.newValue.reduce((acc, tile, index) => { @@ -361,25 +473,22 @@ export default { } event.stopPropagation() + let dropIndices = [] if (!event.detail?.length) { - event = new CustomEvent( - 'drop', { - bubbles: false, - cancelable: true, - detail: [dropIndex], - } - ) + dropIndices = [dropIndex] } else { - event = new CustomEvent( - 'drop', { - bubbles: false, - cancelable: true, - detail: [dropIndex, ...event.detail], - } - ) + dropIndices = [dropIndex, ...event.detail] } + event = new CustomEvent( + 'drop', { + bubbles: false, + cancelable: true, + detail: dropIndices, + } + ) + if (this.indent > 0) { // If the current drop location is within a nested block, then we need to // bubble up the drop event to the parent block, until we reach the top block. @@ -389,7 +498,6 @@ export default { // If we are at the root level, then we have the full picture of the underlying // data structure, and we can perform the drop operation directly. - const dropIndices = event.detail const dragIndex = this.dragIndices.slice(-1)[0] dropIndex = event.detail.slice(-1)[0] @@ -435,12 +543,12 @@ export default { let parent = this.newValue while (parent && indices.length > 1) { parent = parent[indices.shift()] - } - if (parent) { - const blockKey = this.getKey(parent) - if (blockKey) { - parent = parent[blockKey] + if (parent) { + const blockKey = this.getKey(parent) + if (blockKey) { + parent = parent[blockKey] + } } } @@ -462,11 +570,29 @@ export default { }, addAction(action) { - this.newValue.push(action) + this.newValue.push( + { + ...action, + action: action.name || action.action, + } + ) }, addCondition() { this.newValue.push({ 'if ${True}': [] }) + this.selectLastExprEditor() + }, + + addReturn() { + this.newValue.push({ 'return': null }) + this.selectLastExprEditor() + }, + + editReturn(value) { + this.newValue[this.returnIndex] = { 'return': value?.length ? value : null } + }, + + selectLastExprEditor() { this.$nextTick(() => { const newTile = this.$refs[`action-tile-${this.newValue.length - 1}`]?.[0] if (!newTile) { @@ -480,12 +606,12 @@ export default { newTileElement.click() this.$nextTick(() => { - const conditionEditor = newTile.$el?.querySelector('.condition-editor-container') - if (!conditionEditor) { + const exprEditor = newTile.$el?.querySelector('.expr-editor-container') + if (!exprEditor) { return } - const input = conditionEditor.querySelector('input[type="text"]') + const input = exprEditor.querySelector('input[type="text"]') if (!input) { return } @@ -611,5 +737,28 @@ export default { } } } + + .add-buttons-expander { + width: 100%; + height: 1em; + margin: -0.5em 0 0.5em 0; + + button { + width: 100%; + height: 100%; + background: none; + display: flex; + align-items: center; + justify-content: center; + border: none; + margin: 0; + padding: 0.5em 0 0 0; + + &:hover { + color: $default-hover-fg; + } + } + display: flex; + } } diff --git a/platypush/backend/http/webapp/src/components/Action/ConditionTile.vue b/platypush/backend/http/webapp/src/components/Action/ConditionTile.vue index c88bf4c0ed..4493b34c38 100644 --- a/platypush/backend/http/webapp/src/components/Action/ConditionTile.vue +++ b/platypush/backend/http/webapp/src/components/Action/ConditionTile.vue @@ -46,17 +46,19 @@ - + + Condition +
diff --git a/platypush/backend/http/webapp/src/components/Action/ReturnTile.vue b/platypush/backend/http/webapp/src/components/Action/ReturnTile.vue new file mode 100644 index 0000000000..a4fce9f216 --- /dev/null +++ b/platypush/backend/http/webapp/src/components/Action/ReturnTile.vue @@ -0,0 +1,138 @@ + + +