aboutsummaryrefslogtreecommitdiffstats
path: root/apps/workflowengine/src/components/Rule.vue
diff options
context:
space:
mode:
Diffstat (limited to 'apps/workflowengine/src/components/Rule.vue')
-rw-r--r--apps/workflowengine/src/components/Rule.vue155
1 files changed, 92 insertions, 63 deletions
diff --git a/apps/workflowengine/src/components/Rule.vue b/apps/workflowengine/src/components/Rule.vue
index c59c4568f19..1c321fd014c 100644
--- a/apps/workflowengine/src/components/Rule.vue
+++ b/apps/workflowengine/src/components/Rule.vue
@@ -1,3 +1,7 @@
+<!--
+ - SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
<template>
<div v-if="operation" class="section rule" :style="{ borderLeftColor: operation.color || '' }">
<div class="trigger">
@@ -18,30 +22,36 @@
<input v-if="lastCheckComplete"
type="button"
class="check--add"
- value="Add a new filter"
- @click="rule.checks.push({class: null, operator: null, value: ''})">
+ :value="t('workflowengine', 'Add a new filter')"
+ @click="onAddFilter">
</p>
</div>
<div class="flow-icon icon-confirm" />
<div class="action">
<Operation :operation="operation" :colored="false">
+ <component :is="operation.element"
+ v-if="operation.element"
+ :model-value="inputValue"
+ @update:model-value="updateOperationByEvent" />
<component :is="operation.options"
- v-if="operation.options"
+ v-else-if="operation.options"
v-model="rule.operation"
@input="updateOperation" />
</Operation>
<div class="buttons">
- <button class="status-button icon"
- :class="ruleStatus.class"
- @click="saveRule">
- {{ ruleStatus.title }}
- </button>
- <button v-if="rule.id < -1 || dirty" @click="cancelRule">
+ <NcButton v-if="rule.id < -1 || dirty" @click="cancelRule">
{{ t('workflowengine', 'Cancel') }}
- </button>
- <button v-else-if="!dirty" @click="deleteRule">
+ </NcButton>
+ <NcButton v-else-if="!dirty" @click="deleteRule">
{{ t('workflowengine', 'Delete') }}
- </button>
+ </NcButton>
+ <NcButton :type="ruleStatus.type"
+ @click="saveRule">
+ <template #icon>
+ <component :is="ruleStatus.icon" :size="20" />
+ </template>
+ {{ ruleStatus.title }}
+ </NcButton>
</div>
<p v-if="error" class="error-message">
{{ error }}
@@ -51,17 +61,27 @@
</template>
<script>
-import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip'
-import Actions from '@nextcloud/vue/dist/Components/Actions'
-import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
-import Event from './Event'
-import Check from './Check'
-import Operation from './Operation'
+import NcActions from '@nextcloud/vue/components/NcActions'
+import NcActionButton from '@nextcloud/vue/components/NcActionButton'
+import NcButton from '@nextcloud/vue/components/NcButton'
+import Tooltip from '@nextcloud/vue/directives/Tooltip'
+import IconArrowRight from 'vue-material-design-icons/ArrowRight.vue'
+import IconCheckMark from 'vue-material-design-icons/Check.vue'
+import IconClose from 'vue-material-design-icons/Close.vue'
+
+import Event from './Event.vue'
+import Check from './Check.vue'
+import Operation from './Operation.vue'
export default {
name: 'Rule',
components: {
- Operation, Check, Event, Actions, ActionButton,
+ Check,
+ Event,
+ NcActionButton,
+ NcActions,
+ NcButton,
+ Operation,
},
directives: {
Tooltip,
@@ -79,9 +99,14 @@ export default {
error: null,
dirty: this.rule.id < 0,
originalRule: null,
+ element: null,
+ inputValue: '',
}
},
computed: {
+ /**
+ * @return {OperatorPlugin}
+ */
operation() {
return this.$store.getters.getOperationForRule(this.rule)
},
@@ -89,14 +114,15 @@ export default {
if (this.error || !this.rule.valid || this.rule.checks.length === 0 || this.rule.checks.some((check) => check.invalid === true)) {
return {
title: t('workflowengine', 'The configuration is invalid'),
- class: 'icon-close-white invalid',
+ icon: IconClose,
+ type: 'warning',
tooltip: { placement: 'bottom', show: true, content: this.error },
}
}
if (!this.dirty) {
- return { title: t('workflowengine', 'Active'), class: 'icon icon-checkmark' }
+ return { title: t('workflowengine', 'Active'), icon: IconCheckMark, type: 'success' }
}
- return { title: t('workflowengine', 'Save'), class: 'icon-confirm-white primary' }
+ return { title: t('workflowengine', 'Save'), icon: IconArrowRight, type: 'primary' }
},
lastCheckComplete() {
@@ -106,13 +132,25 @@ export default {
},
mounted() {
this.originalRule = JSON.parse(JSON.stringify(this.rule))
+ if (this.operation?.element) {
+ this.inputValue = this.rule.operation
+ } else if (this.operation?.options) {
+ // keeping this in an else for apps that try to be backwards compatible and may ship both
+ // to be removed in 03/2028
+ console.warn('Developer warning: `OperatorPlugin.options` is deprecated. Use `OperatorPlugin.element` instead.')
+ }
},
methods: {
async updateOperation(operation) {
this.$set(this.rule, 'operation', operation)
- await this.updateRule()
+ this.updateRule()
},
- validate(state) {
+ async updateOperationByEvent(event) {
+ this.inputValue = event.detail[0]
+ this.$set(this.rule, 'operation', event.detail[0])
+ this.updateRule()
+ },
+ validate(/* state */) {
this.error = null
this.$store.dispatch('updateRule', this.rule)
},
@@ -147,11 +185,13 @@ export default {
if (this.rule.id < 0) {
this.$store.dispatch('removeRule', this.rule)
} else {
+ this.inputValue = this.originalRule.operation
this.$store.dispatch('updateRule', this.originalRule)
this.originalRule = JSON.parse(JSON.stringify(this.rule))
this.dirty = false
}
},
+
async removeCheck(check) {
const index = this.rule.checks.findIndex(item => item === check)
if (index > -1) {
@@ -159,50 +199,32 @@ export default {
}
this.$store.dispatch('updateRule', this.rule)
},
+
+ onAddFilter() {
+ // eslint-disable-next-line vue/no-mutating-props
+ this.rule.checks.push({ class: null, operator: null, value: '' })
+ },
},
}
</script>
<style scoped lang="scss">
- button.icon {
- padding-left: 32px;
- background-position: 10px center;
- }
.buttons {
- display: block;
- overflow: hidden;
+ display: flex;
+ justify-content: end;
button {
- float: right;
- height: 34px;
+ margin-inline-start: 5px;
+ }
+ button:last-child{
+ margin-inline-end: 10px;
}
}
.error-message {
float: right;
- margin-right: 10px;
- }
-
- .status-button {
- transition: 0.5s ease all;
- display: block;
- margin: 3px 10px 3px auto;
- }
- .status-button.primary {
- padding-left: 32px;
- background-position: 10px center;
- }
- .status-button:not(.primary) {
- background-color: var(--color-main-background);
- }
- .status-button.invalid {
- background-color: var(--color-warning);
- color: #fff;
- border: none;
- }
- .status-button.icon-checkmark {
- border: 1px solid var(--color-success);
+ margin-inline-end: 10px;
}
.flow-icon {
@@ -212,12 +234,13 @@ export default {
.rule {
display: flex;
flex-wrap: wrap;
- border-left: 5px solid var(--color-primary-element);
+ border-inline-start: 5px solid var(--color-primary-element);
- .trigger, .action {
+ .trigger,
+ .action {
flex-grow: 1;
min-height: 100px;
- max-width: 700px;
+ max-width: 920px;
}
.action {
max-width: 400px;
@@ -225,19 +248,20 @@ export default {
}
.icon-confirm {
background-position: right 27px;
- padding-right: 20px;
- margin-right: 20px;
+ padding-inline-end: 20px;
+ margin-inline-end: 20px;
}
}
+
.trigger p, .action p {
min-height: 34px;
display: flex;
& > span {
min-width: 50px;
- text-align: right;
+ text-align: end;
color: var(--color-text-maxcontrast);
- padding-right: 10px;
+ padding-inline-end: 10px;
padding-top: 6px;
}
.multiselect {
@@ -245,20 +269,25 @@ export default {
max-width: 300px;
}
}
+
.trigger p:first-child span {
padding-top: 3px;
}
+ .trigger p:last-child {
+ padding-top: 8px;
+ }
+
.check--add {
background-position: 7px center;
background-color: transparent;
- padding-left: 6px;
+ padding-inline-start: 6px;
margin: 0;
width: 180px;
border-radius: var(--border-radius);
color: var(--color-text-maxcontrast);
font-weight: normal;
- text-align: left;
+ text-align: start;
font-size: 1em;
}