3
0

Implement drag and drop sorting for workflow expressions

This commit is contained in:
Mumbi Francis
2023-04-05 13:29:51 +03:00
committed by Jože Fortun
parent 16d0420a9d
commit 7d7155d68e
5 changed files with 137 additions and 98 deletions

View File

@@ -29,6 +29,7 @@
"vue-router": "3.1.5",
"vue-select": "^3.11.2",
"vue2-ace-editor": "^0.0.15",
"vuedraggable": "^2.23.0",
"vuex": "^3.6.2"
},
"devDependencies": {

View File

@@ -114,18 +114,16 @@ export default {
return [
{
key: 'target',
thClass: 'pl-3 py-2',
tdClass: 'text-truncate pointer',
formatter: (value, key, item) => {
label: this.$t('steps:expressions.configurator.target'),
thClass: 'pl-3',
formatter: (item) => {
return `${item.target}(${item.type})`
},
},
{
key: 'expr',
label: this.$t('steps:expressions.configurator.expression'),
thClass: 'py-2 pr-3',
tdClass: 'position-relative pointer',
thClass: 'mr-3',
},
]
},

View File

@@ -403,18 +403,19 @@ export default {
return [
{
key: 'target',
thClass: 'pl-3 py-2',
label: this.$t('steps:function.configurator.target'),
thClass: 'pl-3',
tdClass: 'text-truncate pointer',
},
{
key: 'type',
thClass: 'py-2',
label: this.$t('steps:function.configurator.type'),
tdClass: 'text-truncate pointer',
},
{
key: 'expr',
label: this.$t('steps:function.configurator.result'),
thClass: 'pr-3 py-2',
thClass: 'mr-3',
tdClass: 'position-relative pointer',
},
]

View File

@@ -1,107 +1,122 @@
<template>
<b-table
id="expression-table"
fixed
borderless
hover
head-row-variant="secondary"
details-td-class="bg-white"
class="mb-4"
:items="items"
:fields="fields"
thead-tr-class="border-thick"
:tbody-tr-class="rowClass"
@row-clicked="item => $set(item, '_showDetails', !item._showDetails)"
>
<template #cell(target)="{ value }">
<var>{{ value }}</var>
</template>
<div class="table-responsive">
<b-row class="header pl-3">
<b-col
v-for="(field, index) in fields"
:key="index"
:class="`py-2 ${field.thClass}`"
>
<label>{{ field.label }}</label>
</b-col>
</b-row>
<template #cell(type)="{ value }">
<var>{{ value }}</var>
</template>
<template #[`cell(${valueField})`]="{ value, item, index }">
<draggable
:list="items"
@end="$root.$emit('change-detected')"
>
<div
class="d-flex justify-content-between align-items-center"
v-for="(item, index) in items"
:key="index"
>
<b-row
class="d-flex justify-content-between align-items-center pointer expr-item"
@click="$set(item, '_showDetails', !item._showDetails)"
>
<b-col
v-for="(field, i) in fields"
:key="i"
class="text-truncate"
:class="{ 'ml-2 pl-3': field.key === 'target', 'mr-3 expr-column': field.key === 'expr' }"
>
<template v-if="field.key === 'expr'">
<div class="d-flex justify-content-between align-items-center">
<div :class="{ 'w-75': item._showDetails}">
<samp>{{ item[field.key] }}</samp>
</div>
</div>
<b-button
v-if="item._showDetails"
variant="outline-danger"
class="position-absolute trash border-0"
@click="$emit('remove', index)"
>
<font-awesome-icon
:icon="['far', 'trash-alt']"
/>
</b-button>
</template>
<template v-else>
<var>{{ field.formatter ? field.formatter(item) : item[field.key] }}</var>
</template>
</b-col>
</b-row>
<div
class="text-truncate"
:class="{ 'w-75': item._showDetails}"
>
<samp>{{ value }}</samp>
</div>
<b-button
v-if="item._showDetails"
variant="outline-danger"
class="position-absolute trash border-0"
@click="$emit('remove', index)"
class="mb-3 px-3"
>
<font-awesome-icon
:icon="['far', 'trash-alt']"
/>
</b-button>
<div class="arrow-up" />
<b-card
class="bg-light"
body-class="px-4 pb-3"
>
<b-form-group
label-class="text-primary"
>
<b-form-input
v-model="item.target"
placeholder="Target"
@input="$root.$emit('change-detected')"
/>
</b-form-group>
<b-form-group
label-class="text-primary"
:description="getTypeDescription(item.type)"
>
<vue-select
v-model="item.type"
:options="types"
:get-option-key="getOptionKey"
:clearable="false"
:filter="varFilter"
:calculate-position="calculateDropdownPosition"
@input="$root.$emit('change-detected')"
/>
</b-form-group>
<b-form-group
class="mb-0"
>
<expression-editor
:value.sync="item[valueField]"
lang="javascript"
show-line-numbers
@open="$emit('open-editor', index)"
@input="$root.$emit('change-detected')"
/>
</b-form-group>
</b-card>
</div>
</div>
</template>
<template #row-details="{ item, index }">
<div class="arrow-up" />
<b-card
class="bg-light"
body-class="px-4 pb-3"
>
<b-form-group
label-class="text-primary"
>
<b-form-input
v-model="item.target"
placeholder="Target"
@input="$root.$emit('change-detected')"
/>
</b-form-group>
<b-form-group
label-class="text-primary"
:description="getTypeDescription(item.type)"
>
<vue-select
v-model="item.type"
:options="types"
:get-option-key="getOptionKey"
:clearable="false"
:filter="varFilter"
:calculate-position="calculateDropdownPosition"
@input="$root.$emit('change-detected')"
/>
</b-form-group>
<b-form-group
class="mb-0"
>
<expression-editor
:value.sync="item[valueField]"
lang="javascript"
show-line-numbers
@open="$emit('open-editor', index)"
@input="$root.$emit('change-detected')"
/>
</b-form-group>
</b-card>
</template>
</b-table>
</draggable>
</div>
</template>
<script>
import ExpressionEditor from './ExpressionEditor.vue'
import { objectSearchMaker } from '../lib/filter'
import { VueSelect } from 'vue-select'
import draggable from 'vuedraggable'
export default {
components: {
ExpressionEditor,
VueSelect,
draggable,
},
props: {
@@ -129,10 +144,6 @@ export default {
methods: {
varFilter: objectSearchMaker('text'),
rowClass (item, type) {
return item._showDetails && type === 'row' ? 'border-thick' : 'border-thick-transparent'
},
getTypeDescription (type) {
// This will be moved to backend field type information
const typeDescriptions = {
@@ -148,3 +159,29 @@ export default {
},
}
</script>
<style lang="scss" scoped>
.header {
background-color: #d8dfe3;
&:hover {
background-color: #c9d3d8;
}
label {
margin: 0;
}
}
.table-responsive {
overflow: hidden;
}
.expr-item:hover {
background-color: #F3F3F5;
}
.expr-column {
padding: 0.75rem;
}
</style>

View File

@@ -27,6 +27,7 @@ expressions:
add-expression: + Add Expression
expression: Expression
expression-placeholder: Expression...
target: Target
label: Expressions
short: Expressions
tooltip: Define and mutate scope variables
@@ -39,6 +40,7 @@ function:
option-select: Select an option
result: Result
results: Results
target: Target
add-result: + Add result
search-workflow: Search for a workflow
select-function: Select function