diff options
Diffstat (limited to 'apps/workflowengine/src/components/Check.vue')
-rw-r--r-- | apps/workflowengine/src/components/Check.vue | 122 |
1 files changed, 79 insertions, 43 deletions
diff --git a/apps/workflowengine/src/components/Check.vue b/apps/workflowengine/src/components/Check.vue index 2ea267878fa..136f6d21280 100644 --- a/apps/workflowengine/src/components/Check.vue +++ b/apps/workflowengine/src/components/Check.vue @@ -1,24 +1,36 @@ +<!-- + - SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors + - SPDX-License-Identifier: AGPL-3.0-or-later +--> <template> <div v-click-outside="hideDelete" class="check" @click="showDelete"> - <Multiselect ref="checkSelector" + <NcSelect ref="checkSelector" v-model="currentOption" :options="options" label="name" - track-by="class" - :allow-empty="false" + :clearable="false" :placeholder="t('workflowengine', 'Select a filter')" @input="updateCheck" /> - <Multiselect v-model="currentOperator" + <NcSelect v-model="currentOperator" :disabled="!currentOption" :options="operators" class="comparator" label="name" - track-by="operator" - :allow-empty="false" + :clearable="false" :placeholder="t('workflowengine', 'Select a comparator')" @input="updateCheck" /> + <component :is="currentElement" + v-if="currentElement" + ref="checkComponent" + :disabled="!currentOption" + :operator="check.operator" + :model-value="check.value" + class="option" + @update:model-value="updateCheck" + @valid="(valid=true) && validate()" + @invalid="!(valid=false) && validate()" /> <component :is="currentOption.component" - v-if="currentOperator && currentComponent" + v-else-if="currentOperator && currentComponent" v-model="check.value" :disabled="!currentOption" :check="check" @@ -34,24 +46,33 @@ :placeholder="valuePlaceholder" class="option" @input="updateCheck"> - <Actions v-if="deleteVisible || !currentOption"> - <ActionButton icon="icon-close" @click="$emit('remove')" /> - </Actions> + <NcActions v-if="deleteVisible || !currentOption"> + <NcActionButton :title="t('workflowengine', 'Remove filter')" @click="$emit('remove')"> + <template #icon> + <CloseIcon :size="20" /> + </template> + </NcActionButton> + </NcActions> </div> </template> <script> -import Multiselect from '@nextcloud/vue/dist/Components/Multiselect' -import Actions from '@nextcloud/vue/dist/Components/Actions' -import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' +import NcActions from '@nextcloud/vue/components/NcActions' +import NcActionButton from '@nextcloud/vue/components/NcActionButton' +import NcSelect from '@nextcloud/vue/components/NcSelect' + +import CloseIcon from 'vue-material-design-icons/Close.vue' import ClickOutside from 'vue-click-outside' export default { name: 'Check', components: { - ActionButton, - Actions, - Multiselect, + NcActionButton, + NcActions, + NcSelect, + + // Icons + CloseIcon, }, directives: { ClickOutside, @@ -87,6 +108,12 @@ export default { } return operators }, + currentElement() { + if (!this.check.class) { + return false + } + return this.checks[this.check.class].element + }, currentComponent() { if (!this.currentOption) { return [] } return this.checks[this.currentOption.class].component @@ -108,6 +135,15 @@ export default { this.currentOption = this.checks[this.check.class] this.currentOperator = this.operators.find((operator) => operator.operator === this.check.operator) + if (this.currentElement) { + // If we do not set it, the check`s value would remain empty. Unsure why Vue behaves this way. + this.$refs.checkComponent.modelValue = undefined + } else if (this.currentOption?.component) { + // 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: `CheckPlugin.options` is deprecated. Use `CheckPlugin.element` instead.') + } + if (this.check.class === null) { this.$nextTick(() => this.$refs.checkSelector.$el.focus()) } @@ -125,15 +161,22 @@ export default { if (this.currentOption && this.currentOption.validate) { this.valid = !!this.currentOption.validate(this.check) } + // eslint-disable-next-line vue/no-mutating-props this.check.invalid = !this.valid this.$emit('validate', this.valid) }, - updateCheck() { - const matchingOperator = this.operators.findIndex((operator) => this.check.operator === operator.operator) + updateCheck(event) { + const selectedOperator = event?.operator || this.currentOperator?.operator || this.check.operator + const matchingOperator = this.operators.findIndex((operator) => selectedOperator === operator.operator) if (this.check.class !== this.currentOption.class || matchingOperator === -1) { this.currentOperator = this.operators[0] } + if (event?.detail) { + this.check.value = event.detail[0] + } + // eslint-disable-next-line vue/no-mutating-props this.check.class = this.currentOption.class + // eslint-disable-next-line vue/no-mutating-props this.check.operator = this.currentOperator.operator this.validate() @@ -148,46 +191,39 @@ export default { .check { display: flex; flex-wrap: wrap; + align-items: flex-start; // to not stretch components vertically width: 100%; - padding-right: 20px; + padding-inline-end: 20px; + & > *:not(.close) { width: 180px; } & > .comparator { - min-width: 130px; - width: 130px; + min-width: 200px; + width: 200px; } & > .option { - min-width: 230px; - width: 230px; + min-width: 260px; + width: 260px; + min-height: 48px; + + & > input[type=text] { + min-height: 48px; + } } - & > .multiselect, + & > .v-select, + & > .button-vue, & > input[type=text] { - margin-right: 5px; + margin-inline-end: 5px; margin-bottom: 5px; } - - .multiselect::v-deep .multiselect__content-wrapper li>span, - .multiselect::v-deep .multiselect__single { - display: block; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } } + input[type=text] { margin: 0; } - ::placeholder { - font-size: 10px; - } - button.action-item.action-item--single.icon-close { - height: 44px; - width: 44px; - margin-top: -5px; - margin-bottom: -5px; - } + .invalid { - border: 1px solid var(--color-error) !important; + border-color: var(--color-error) !important; } </style> |