forked from platypush/platypush
[#341] Added UI for while
loops in procedure editor.
This commit is contained in:
parent
ab07fc0fa3
commit
dfbbea93fd
4 changed files with 141 additions and 39 deletions
|
@ -29,7 +29,7 @@
|
|||
v-on="componentsData[index].on"
|
||||
:collapsed="collapsedBlocks[index]"
|
||||
:dragging="isDragging"
|
||||
v-else-if="fors[index]" />
|
||||
v-else-if="loops[index]" />
|
||||
|
||||
<BreakTile :active="isDragging"
|
||||
:readOnly="readOnly"
|
||||
|
@ -86,8 +86,12 @@
|
|||
<AddTile icon="fas fa-question" title="Add Else" @click="$emit('add-else')" />
|
||||
</div>
|
||||
|
||||
<div class="row item action add-for-container" v-if="visibleAddButtons.loop">
|
||||
<AddTile icon="fas fa-arrow-rotate-left" title="Add Loop" @click="addLoop" />
|
||||
<div class="row item action add-for-container" v-if="visibleAddButtons.for">
|
||||
<AddTile icon="fas fa-arrow-rotate-left" title="Add For Loop" @click="addForLoop" />
|
||||
</div>
|
||||
|
||||
<div class="row item action add-while-container" v-if="visibleAddButtons.while">
|
||||
<AddTile icon="fas fa-arrow-rotate-left" title="Add While Loop" @click="addWhileLoop" />
|
||||
</div>
|
||||
|
||||
<div class="row item action add-break-container" v-if="visibleAddButtons.break">
|
||||
|
@ -265,9 +269,15 @@ export default {
|
|||
data.props.indent = this.indent + 1
|
||||
}
|
||||
|
||||
const loop = this.getFor(action)
|
||||
if (loop) {
|
||||
data.props.async = loop.async
|
||||
const forLoop = this.getFor(action)
|
||||
if (forLoop) {
|
||||
data.props.async = forLoop.async
|
||||
data.props.type = 'for'
|
||||
}
|
||||
|
||||
const whileLoop = this.getWhile(action)
|
||||
if (whileLoop) {
|
||||
data.props.type = 'while'
|
||||
}
|
||||
|
||||
return data
|
||||
|
@ -338,6 +348,23 @@ export default {
|
|||
}, {}) || {}
|
||||
},
|
||||
|
||||
whiles() {
|
||||
return this.newValue?.reduce?.((acc, action, index) => {
|
||||
if (this.getWhile(action)) {
|
||||
acc[index] = action
|
||||
}
|
||||
|
||||
return acc
|
||||
}, {}) || {}
|
||||
},
|
||||
|
||||
loops() {
|
||||
return [...Object.keys(this.fors), ...Object.keys(this.whiles)].reduce((acc, index) => {
|
||||
acc[index] = this.newValue[index]
|
||||
return acc
|
||||
}, {})
|
||||
},
|
||||
|
||||
hasChanges() {
|
||||
return this.newStringValue !== this.stringValue
|
||||
},
|
||||
|
@ -389,14 +416,17 @@ export default {
|
|||
|
||||
showAddButtons() {
|
||||
return (
|
||||
this.newValue.length === 0 || !this.collapseAddButtons
|
||||
(this.indent === 0 && this.newValue.length === 0) || !this.collapseAddButtons
|
||||
)
|
||||
},
|
||||
|
||||
showAddButtonsExpander() {
|
||||
return (
|
||||
!this.readOnly &&
|
||||
this.newValue?.length > 0 &&
|
||||
(
|
||||
this.newValue?.length > 0 ||
|
||||
this.indent > 0
|
||||
) &&
|
||||
Object.entries(this.visibleAddButtons).filter(
|
||||
([key, value]) => value && key != 'action'
|
||||
).length > 1
|
||||
|
@ -431,6 +461,7 @@ export default {
|
|||
this.conditions[index] ||
|
||||
this.elses[index] ||
|
||||
this.fors[index] ||
|
||||
this.whiles[index] ||
|
||||
this.isAction(action) ||
|
||||
this.isReturn(action) ||
|
||||
this.isBreak(action) ||
|
||||
|
@ -448,7 +479,8 @@ export default {
|
|||
action: this.allowAddButtons,
|
||||
return: this.allowAddButtons,
|
||||
condition: this.allowAddButtons,
|
||||
loop: this.allowAddButtons,
|
||||
for: this.allowAddButtons,
|
||||
while: this.allowAddButtons,
|
||||
else: (
|
||||
this.allowAddButtons &&
|
||||
this.parent &&
|
||||
|
@ -663,11 +695,16 @@ export default {
|
|||
this.selectLastExprEditor()
|
||||
},
|
||||
|
||||
addLoop() {
|
||||
addForLoop() {
|
||||
this.newValue.push({ 'for _ in ${range(10)}': [] })
|
||||
this.selectLastExprEditor()
|
||||
},
|
||||
|
||||
addWhileLoop() {
|
||||
this.newValue.push({ 'while ${True}': [] })
|
||||
this.selectLastExprEditor()
|
||||
},
|
||||
|
||||
addBreak() {
|
||||
this.newValue.push('break')
|
||||
},
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
</template>
|
||||
|
||||
<template #after>
|
||||
<EndBlockTile value="end for"
|
||||
<EndBlockTile :value="`end ${type}`"
|
||||
icon="fas fa-arrow-rotate-right"
|
||||
:active="active"
|
||||
:spacer-bottom="spacerBottom"
|
||||
|
@ -64,6 +64,11 @@ export default {
|
|||
required: true,
|
||||
},
|
||||
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
|
@ -117,8 +122,36 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
changeHandler() {
|
||||
if (this.type === 'for') {
|
||||
return this.onForChange
|
||||
}
|
||||
|
||||
if (this.type === 'while') {
|
||||
return this.onWhileChange
|
||||
}
|
||||
|
||||
return () => {}
|
||||
},
|
||||
|
||||
isDragging() {
|
||||
return this.dragging_ || this.dragging
|
||||
},
|
||||
|
||||
key() {
|
||||
return this.getKey(this.value)
|
||||
},
|
||||
|
||||
loop() {
|
||||
if (this.type === 'for') {
|
||||
return this.getFor(this.key)
|
||||
}
|
||||
|
||||
if (this.type === 'while') {
|
||||
return {condition: this.getWhile(this.key)}
|
||||
}
|
||||
|
||||
return {}
|
||||
},
|
||||
|
||||
loopTileConf() {
|
||||
|
@ -129,10 +162,11 @@ export default {
|
|||
readOnly: this.readOnly,
|
||||
spacerBottom: this.spacerBottom,
|
||||
spacerTop: this.spacerTop,
|
||||
type: this.type,
|
||||
},
|
||||
|
||||
on: {
|
||||
change: this.onLoopChange,
|
||||
change: this.changeHandler,
|
||||
delete: (event) => this.$emit('delete', event),
|
||||
drag: this.onDragStart,
|
||||
dragend: this.onDragEnd,
|
||||
|
@ -144,14 +178,6 @@ export default {
|
|||
},
|
||||
}
|
||||
},
|
||||
|
||||
isDragging() {
|
||||
return this.dragging_ || this.dragging
|
||||
},
|
||||
|
||||
key() {
|
||||
return this.getKey(this.value)
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
@ -163,7 +189,7 @@ export default {
|
|||
this.$emit('input', { [this.key]: value })
|
||||
},
|
||||
|
||||
onLoopChange(loop) {
|
||||
onForChange(loop) {
|
||||
const iterable = loop?.iterable?.trim()
|
||||
const iterator = loop?.iterator?.trim()
|
||||
const async_ = loop?.async || false
|
||||
|
@ -177,6 +203,16 @@ export default {
|
|||
this.$emit('input', { [loop]: this.value[this.key] })
|
||||
},
|
||||
|
||||
onWhileChange(condition) {
|
||||
condition = condition?.trim()
|
||||
if (!this.key || this.readOnly || !condition?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const loop = `while \${${condition}}`
|
||||
this.$emit('input', { [loop]: this.value[this.key] })
|
||||
},
|
||||
|
||||
onDragStart(event) {
|
||||
if (this.readOnly) {
|
||||
return
|
||||
|
|
|
@ -17,12 +17,17 @@
|
|||
<span class="icon">
|
||||
<i class="fas fa-arrow-rotate-left" />
|
||||
</span>
|
||||
<span class="name">
|
||||
<span class="name" v-if="type === 'for'">
|
||||
<span class="keyword">for<span v-if="async">k</span></span>
|
||||
<span class="code" v-text="iterator" />
|
||||
<span class="keyword"> in </span> [
|
||||
<span class="code" v-text="iterable" /> ]
|
||||
</span>
|
||||
|
||||
<span class="name" v-else-if="type === 'while'">
|
||||
<span class="keyword">while</span> [
|
||||
<span class="code" v-text="condition" /> ]
|
||||
</span>
|
||||
</div>
|
||||
</Tile>
|
||||
|
||||
|
@ -33,17 +38,23 @@
|
|||
<LoopEditor :iterator="iterator"
|
||||
:iterable="iterable"
|
||||
:async="async"
|
||||
ref="loopEditor"
|
||||
@change="onLoopChange"
|
||||
v-if="showLoopEditor">
|
||||
v-if="showLoopEditor && type === 'for'">
|
||||
Loop
|
||||
</LoopEditor>
|
||||
|
||||
<ExpressionEditor :value="condition"
|
||||
@input.prevent.stop="onConditionChange"
|
||||
v-else-if="showLoopEditor && type === 'while'">
|
||||
Loop Condition
|
||||
</ExpressionEditor>
|
||||
</Modal>
|
||||
</div>
|
||||
</ListItem>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ExpressionEditor from "./ExpressionEditor"
|
||||
import ListItem from "./ListItem"
|
||||
import LoopEditor from "./LoopEditor"
|
||||
import Modal from "@/components/Modal"
|
||||
|
@ -64,6 +75,7 @@ export default {
|
|||
],
|
||||
|
||||
components: {
|
||||
ExpressionEditor,
|
||||
LoopEditor,
|
||||
ListItem,
|
||||
Modal,
|
||||
|
@ -71,16 +83,6 @@ export default {
|
|||
},
|
||||
|
||||
props: {
|
||||
iterator: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
|
||||
iterable: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
|
@ -91,9 +93,16 @@ export default {
|
|||
default: false,
|
||||
},
|
||||
|
||||
isElse: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
condition: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
iterator: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
iterable: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
readOnly: {
|
||||
|
@ -110,6 +119,11 @@ export default {
|
|||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
@ -154,6 +168,21 @@ export default {
|
|||
},
|
||||
|
||||
methods: {
|
||||
onConditionChange(event) {
|
||||
this.showLoopEditor = false
|
||||
if (this.readOnly) {
|
||||
return
|
||||
}
|
||||
|
||||
const condition = event.target.value?.trim()
|
||||
if (!condition?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
event.target.value = condition
|
||||
this.$emit('change', condition)
|
||||
},
|
||||
|
||||
onLoopChange(event) {
|
||||
this.showLoopEditor = false
|
||||
if (this.readOnly) {
|
||||
|
|
|
@ -33,7 +33,7 @@ export default {
|
|||
},
|
||||
|
||||
isActionsBlock(value) {
|
||||
return this.getCondition(value) || this.isElse(value) || this.getFor(value)
|
||||
return this.getCondition(value) || this.isElse(value) || this.getFor(value) || this.getWhile(value)
|
||||
},
|
||||
|
||||
isBreak(value) {
|
||||
|
|
Loading…
Reference in a new issue