From ad976c66fd9a78e6d90224091634b04a25a08f40 Mon Sep 17 00:00:00 2001 From: Julius Härtl Date: Tue, 6 Aug 2019 17:40:30 +0200 Subject: Unified workflow management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- apps/workflowengine/src/workflowengine.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'apps/workflowengine/src/workflowengine.js') diff --git a/apps/workflowengine/src/workflowengine.js b/apps/workflowengine/src/workflowengine.js index 207d2311bcc..6c7af2a446e 100644 --- a/apps/workflowengine/src/workflowengine.js +++ b/apps/workflowengine/src/workflowengine.js @@ -1,4 +1,3 @@ -import './admin' import './filemimetypeplugin' import './filenameplugin' import './filesizeplugin' @@ -10,3 +9,11 @@ import './requestuseragentplugin' import './usergroupmembershipplugin' window.OCA.WorkflowEngine = OCA.WorkflowEngine + +import Vue from 'vue'; + +Vue.prototype.t = t; + +import Settings from './components/Workflow'; +const View = Vue.extend(Settings) +new View({}).$mount('#workflowengine') \ No newline at end of file -- cgit v1.2.3 From bd281daa47152dc09c0f6c2bbc9e5a308d1748bd Mon Sep 17 00:00:00 2001 From: Julius Härtl Date: Thu, 29 Aug 2019 16:50:33 +0200 Subject: Move to vuex store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- apps/workflowengine/src/admin.js | 385 --------------------- apps/workflowengine/src/components/Check.vue | 134 ++++--- apps/workflowengine/src/components/Event.vue | 105 +++--- apps/workflowengine/src/components/Operation.vue | 39 +-- .../src/components/Operations/ConvertToPdf.vue | 59 ++-- .../src/components/Operations/Tag.vue | 28 +- apps/workflowengine/src/components/Rule.vue | 216 ++++++------ .../src/components/Values/FileMimeType.vue | 56 +-- .../src/components/Values/SizeValue.vue | 37 +- apps/workflowengine/src/components/Workflow.vue | 116 +++---- apps/workflowengine/src/filemimetypeplugin.js | 77 ----- apps/workflowengine/src/filenameplugin.js | 78 ----- apps/workflowengine/src/filesizeplugin.js | 59 ---- apps/workflowengine/src/filesystemtagsplugin.js | 78 ----- .../workflowengine/src/hbs_helpers/getOperators.js | 7 - apps/workflowengine/src/hbs_helpers/selectItem.js | 7 - .../src/legacy/filemimetypeplugin.js | 77 +++++ apps/workflowengine/src/legacy/filenameplugin.js | 78 +++++ apps/workflowengine/src/legacy/filesizeplugin.js | 59 ++++ .../src/legacy/filesystemtagsplugin.js | 78 +++++ .../src/legacy/requestremoteaddressplugin.js | 83 +++++ .../workflowengine/src/legacy/requesttimeplugin.js | 196 +++++++++++ apps/workflowengine/src/legacy/requesturlplugin.js | 116 +++++++ .../src/legacy/requestuseragentplugin.js | 119 +++++++ .../src/legacy/usergroupmembershipplugin.js | 75 ++++ .../src/requestremoteaddressplugin.js | 83 ----- apps/workflowengine/src/requesttimeplugin.js | 196 ----------- apps/workflowengine/src/requesturlplugin.js | 117 ------- apps/workflowengine/src/requestuseragentplugin.js | 119 ------- apps/workflowengine/src/services/Operation.js | 134 ++----- .../src/templates/operation.handlebars | 45 --- .../src/templates/operations.handlebars | 2 - .../src/usergroupmembershipplugin.js | 75 ---- apps/workflowengine/src/workflowengine.js | 34 +- 34 files changed, 1309 insertions(+), 1858 deletions(-) delete mode 100644 apps/workflowengine/src/admin.js delete mode 100644 apps/workflowengine/src/filemimetypeplugin.js delete mode 100644 apps/workflowengine/src/filenameplugin.js delete mode 100644 apps/workflowengine/src/filesizeplugin.js delete mode 100644 apps/workflowengine/src/filesystemtagsplugin.js delete mode 100644 apps/workflowengine/src/hbs_helpers/getOperators.js delete mode 100644 apps/workflowengine/src/hbs_helpers/selectItem.js create mode 100644 apps/workflowengine/src/legacy/filemimetypeplugin.js create mode 100644 apps/workflowengine/src/legacy/filenameplugin.js create mode 100644 apps/workflowengine/src/legacy/filesizeplugin.js create mode 100644 apps/workflowengine/src/legacy/filesystemtagsplugin.js create mode 100644 apps/workflowengine/src/legacy/requestremoteaddressplugin.js create mode 100644 apps/workflowengine/src/legacy/requesttimeplugin.js create mode 100644 apps/workflowengine/src/legacy/requesturlplugin.js create mode 100644 apps/workflowengine/src/legacy/requestuseragentplugin.js create mode 100644 apps/workflowengine/src/legacy/usergroupmembershipplugin.js delete mode 100644 apps/workflowengine/src/requestremoteaddressplugin.js delete mode 100644 apps/workflowengine/src/requesttimeplugin.js delete mode 100644 apps/workflowengine/src/requesturlplugin.js delete mode 100644 apps/workflowengine/src/requestuseragentplugin.js delete mode 100644 apps/workflowengine/src/templates/operation.handlebars delete mode 100644 apps/workflowengine/src/templates/operations.handlebars delete mode 100644 apps/workflowengine/src/usergroupmembershipplugin.js (limited to 'apps/workflowengine/src/workflowengine.js') diff --git a/apps/workflowengine/src/admin.js b/apps/workflowengine/src/admin.js deleted file mode 100644 index fb2af941436..00000000000 --- a/apps/workflowengine/src/admin.js +++ /dev/null @@ -1,385 +0,0 @@ -/** - * @copyright Copyright (c) 2016 Morris Jobke - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -import OperationTemplate from './templates/operation.handlebars'; -import OperationsTemplate from './templates/operations.handlebars'; - -(function() { - OCA.WorkflowEngine = _.extend(OCA.WorkflowEngine || {}, { - availablePlugins: [], - availableChecks: [], - - getCheckByClass: function(className) { - var length = OCA.WorkflowEngine.availableChecks.length; - for (var i = 0; i < length; i++) { - if (OCA.WorkflowEngine.availableChecks[i]['class'] === className) { - return OCA.WorkflowEngine.availableChecks[i]; - } - } - return undefined; - } - }); - - /** - * 888b d888 888 888 - * 8888b d8888 888 888 - * 88888b.d88888 888 888 - * 888Y88888P888 .d88b. .d88888 .d88b. 888 .d8888b - * 888 Y888P 888 d88""88b d88" 888 d8P Y8b 888 88K - * 888 Y8P 888 888 888 888 888 88888888 888 "Y8888b. - * 888 " 888 Y88..88P Y88b 888 Y8b. 888 X88 - * 888 888 "Y88P" "Y88888 "Y8888 888 88888P' - */ - - /** - * @class OCA.WorkflowEngine.Operation - */ - OCA.WorkflowEngine.Operation = - OC.Backbone.Model.extend({ - defaults: { - 'class': 'OCA\\WorkflowEngine\\Operation', - 'name': '', - 'checks': [], - 'operation': '' - } - }); - - /** - * .d8888b. 888 888 888 d8b - * d88P Y88b 888 888 888 Y8P - * 888 888 888 888 888 - * 888 .d88b. 888 888 .d88b. .d8888b 888888 888 .d88b. 88888b. .d8888b - * 888 d88""88b 888 888 d8P Y8b d88P" 888 888 d88""88b 888 "88b 88K - * 888 888 888 888 888 888 88888888 888 888 888 888 888 888 888 "Y8888b. - * Y88b d88P Y88..88P 888 888 Y8b. Y88b. Y88b. 888 Y88..88P 888 888 X88 - * "Y8888P" "Y88P" 888 888 "Y8888 "Y8888P "Y888 888 "Y88P" 888 888 88888P' - */ - - /** - * @class OCA.WorkflowEngine.OperationsCollection - * - * collection for all configurated operations - */ - OCA.WorkflowEngine.OperationsCollection = - OC.Backbone.Collection.extend({ - model: OCA.WorkflowEngine.Operation, - url: OC.generateUrl('apps/workflowengine/operations') - }); - - /** - * 888 888 d8b - * 888 888 Y8P - * 888 888 - * Y88b d88P 888 .d88b. 888 888 888 .d8888b - * Y88b d88P 888 d8P Y8b 888 888 888 88K - * Y88o88P 888 88888888 888 888 888 "Y8888b. - * Y888P 888 Y8b. Y88b 888 d88P X88 - * Y8P 888 "Y8888 "Y8888888P" 88888P' - */ - - /** - * @class OCA.WorkflowEngine.OperationView - * - * this creates the view for a single operation - */ - OCA.WorkflowEngine.OperationView = - OC.Backbone.View.extend({ - templateId: '#operation-template', - events: { - 'change .check-class': 'checkChanged', - 'change .check-operator': 'checkChanged', - 'change .check-value': 'checkChanged', - 'change .operation-name': 'operationChanged', - 'change .operation-operation': 'operationChanged', - 'click .button-reset': 'reset', - 'click .button-save': 'save', - 'click .button-add': 'add', - 'click .button-delete': 'delete', - 'click .button-delete-check': 'deleteCheck' - }, - originalModel: null, - hasChanged: false, - message: '', - errorMessage: '', - saving: false, - groups: [], - template: function(vars) { - return OperationTemplate(_.extend( - { - shortRuleDescTXT: t('workflowengine', 'Short rule description'), - addRuleTXT: t('workflowengine', 'Add rule'), - resetTXT: t('workflowengine', 'Reset'), - saveTXT: t('workflowengine', 'Save'), - savingTXT: t('workflowengine', 'Saving…') - }, - vars - )); - }, - initialize: function() { - // this creates a new copy of the object to definitely have a new reference and being able to reset the model - this.originalModel = JSON.parse(JSON.stringify(this.model)); - this.model.on('change', function() { - console.log('model changed'); - this.hasChanged = true; - this.render(); - }, this); - - if (this.model.get('id') === undefined) { - this.hasChanged = true; - } - var self = this; - $.ajax({ - url: OC.linkToOCS('cloud/groups', 2) + 'details', - dataType: 'json', - quietMillis: 100, - }).success(function(data) { - if (data.ocs.data.groups && data.ocs.data.groups.length > 0) { - - data.ocs.data.groups.forEach(function(group) { - self.groups.push({ id: group.id, displayname: group.displayname }); - }); - self.render(); - - } else { - OC.Notification.error(t('workflowengine', 'Group list is empty'), { type: 'error' }); - console.log(data); - } - }).error(function(data) { - OC.Notification.error(t('workflowengine', 'Unable to retrieve the group list'), { type: 'error' }); - console.log(data); - }); - }, - delete: function() { - if (OC.PasswordConfirmation.requiresPasswordConfirmation()) { - OC.PasswordConfirmation.requirePasswordConfirmation(_.bind(this.delete, this)); - return; - } - - this.model.destroy(); - this.remove(); - }, - reset: function() { - this.hasChanged = false; - // silent is need to not trigger the change event which resets the hasChanged attribute - this.model.set(this.originalModel, { silent: true }); - this.render(); - }, - save: function() { - if (OC.PasswordConfirmation.requiresPasswordConfirmation()) { - OC.PasswordConfirmation.requirePasswordConfirmation(_.bind(this.save, this)); - return; - } - - var success = function(model, response, options) { - this.saving = false; - this.originalModel = JSON.parse(JSON.stringify(this.model)); - - this.message = t('workflowengine', 'Saved'); - this.errorMessage = ''; - this.render(); - }; - var error = function(model, response, options) { - this.saving = false; - this.hasChanged = true; - - this.message = t('workflowengine', 'Saving failed:'); - this.errorMessage = response.responseText; - this.render(); - }; - this.hasChanged = false; - this.saving = true; - this.render(); - this.model.save(null, { success: success, error: error, context: this }); - }, - add: function() { - var checks = _.clone(this.model.get('checks')), - classname = OCA.WorkflowEngine.availableChecks[0]['class'], - operators = OCA.WorkflowEngine.availableChecks[0]['operators']; - - checks.push({ - 'class': classname, - 'operator': operators[0]['operator'], - 'value': '' - }); - this.model.set({ 'checks': checks }); - }, - checkChanged: function(event) { - var value = event.target.value, - id = $(event.target.parentElement).data('id'), - // this creates a new copy of the object to definitely have a new reference - checks = JSON.parse(JSON.stringify(this.model.get('checks'))), - key = null; - - for (var i = 0; i < event.target.classList.length; i++) { - var className = event.target.classList[i]; - if (className.substr(0, 'check-'.length) === 'check-') { - key = className.substr('check-'.length); - break; - } - } - - if (key === null) { - console.warn('checkChanged triggered but element doesn\'t have any "check-" class'); - return; - } - - if (!_.has(checks[id], key)) { - console.warn('key "' + key + '" is not available in check', check); - return; - } - - checks[id][key] = value; - // if the class is changed most likely also the operators have changed - // with this we set the operator to the first possible operator - if (key === 'class') { - var check = OCA.WorkflowEngine.getCheckByClass(value); - if (!_.isUndefined(check)) { - checks[id]['operator'] = check['operators'][0]['operator']; - checks[id]['value'] = ''; - } - } - // model change will trigger render - this.model.set({ 'checks': checks }); - }, - deleteCheck: function(event) { - console.log(arguments); - var id = $(event.target.parentElement).data('id'), - checks = JSON.parse(JSON.stringify(this.model.get('checks'))); - - // splice removes 1 element at index `id` - checks.splice(id, 1); - // model change will trigger render - this.model.set({ 'checks': checks }); - }, - operationChanged: function(event) { - var value = event.target.value, - key = null; - - for (var i = 0; i < event.target.classList.length; i++) { - var className = event.target.classList[i]; - if (className.substr(0, 'operation-'.length) === 'operation-') { - key = className.substr('operation-'.length); - break; - } - } - - if (key === null) { - console.warn('operationChanged triggered but element doesn\'t have any "operation-" class'); - return; - } - - if (key !== 'name' && key !== 'operation') { - console.warn('key "' + key + '" is no valid attribute'); - return; - } - - // model change will trigger render - this.model.set(key, value); - }, - render: function() { - this.$el.html(this.template({ - operation: this.model.toJSON(), - classes: OCA.WorkflowEngine.availableChecks, - hasChanged: this.hasChanged, - message: this.message, - errorMessage: this.errorMessage, - saving: this.saving - })); - - var checks = this.model.get('checks'); - _.each(this.$el.find('.check'), function(element) { - var $element = $(element), - id = $element.data('id'), - check = checks[id], - valueElement = $element.find('.check-value').first(); - var self = this; - - _.each(OCA.WorkflowEngine.availablePlugins, function(plugin) { - if (_.isFunction(plugin.render)) { - plugin.render(valueElement, check, self.groups); - } - }); - }, this); - - if (this.message !== '') { - // hide success messages after some time - _.delay(function(elements) { - $(elements).css('opacity', 0); - }, 7000, this.$el.find('.msg.success')); - this.message = ''; - } - - return this.$el; - } - }); - - /** - * @class OCA.WorkflowEngine.OperationsView - * - * this creates the view for configured operations - */ - OCA.WorkflowEngine.OperationsView = - OC.Backbone.View.extend({ - templateId: '#operations-template', - collection: null, - $el: null, - events: { - 'click .button-add-operation': 'add' - }, - template: function(vars) { - return OperationsTemplate(_.extend( - { - addRuleGroupTXT: t('workflowengine', 'Add rule group') - }, - vars - )); - }, - initialize: function(classname) { - if (!OCA.WorkflowEngine.availablePlugins.length) { - OCA.WorkflowEngine.availablePlugins = OC.Plugins.getPlugins('OCA.WorkflowEngine.CheckPlugins'); - _.each(OCA.WorkflowEngine.availablePlugins, function(plugin) { - if (_.isFunction(plugin.getCheck)) { - OCA.WorkflowEngine.availableChecks.push(plugin.getCheck(classname)); - } - }); - } - - this.collection.fetch({ - data: { - 'class': classname - } - }); - this.collection.once('sync', this.render, this); - }, - add: function() { - var operation = this.collection.create(); - this.renderOperation(operation); - }, - renderOperation: function(subView) { - var operationsElement = this.$el.find('.operations'); - operationsElement.append(subView.$el); - subView.render(); - }, - render: function() { - this.$el.html(this.template()); - this.collection.each(this.renderOperation, this); - } - }); -})(); \ No newline at end of file diff --git a/apps/workflowengine/src/components/Check.vue b/apps/workflowengine/src/components/Check.vue index 86005dae268..b2e8e13c29b 100644 --- a/apps/workflowengine/src/components/Check.vue +++ b/apps/workflowengine/src/components/Check.vue @@ -1,86 +1,82 @@ \ No newline at end of file + diff --git a/apps/workflowengine/src/components/Operations/Tag.vue b/apps/workflowengine/src/components/Operations/Tag.vue index 74e4e4f977b..7a27e2b572d 100644 --- a/apps/workflowengine/src/components/Operations/Tag.vue +++ b/apps/workflowengine/src/components/Operations/Tag.vue @@ -1,22 +1,24 @@ \ No newline at end of file + diff --git a/apps/workflowengine/src/components/Rule.vue b/apps/workflowengine/src/components/Rule.vue index d1f5a088f51..8a446dd7ae9 100644 --- a/apps/workflowengine/src/components/Rule.vue +++ b/apps/workflowengine/src/components/Rule.vue @@ -4,143 +4,144 @@

{{ t('workflowengine', 'When') }} - +

{{ t('workflowengine', 'and') }} - +

- - + +

- Cancel rule creation - Remove rule + + Cancel rule creation + + + Remove rule + - +
- - + +
\ No newline at end of file + diff --git a/apps/workflowengine/src/components/Values/SizeValue.vue b/apps/workflowengine/src/components/Values/SizeValue.vue index bc4378702e1..03b28f18947 100644 --- a/apps/workflowengine/src/components/Values/SizeValue.vue +++ b/apps/workflowengine/src/components/Values/SizeValue.vue @@ -1,28 +1,29 @@ \ No newline at end of file + diff --git a/apps/workflowengine/src/components/Workflow.vue b/apps/workflowengine/src/components/Workflow.vue index 0525722666e..986b6f5197c 100644 --- a/apps/workflowengine/src/components/Workflow.vue +++ b/apps/workflowengine/src/components/Workflow.vue @@ -4,93 +4,68 @@

{{ t('workflowengine', 'Workflows') }}

- + -
+
- - + + - diff --git a/apps/workflowengine/src/components/Rule.vue b/apps/workflowengine/src/components/Rule.vue index 8a446dd7ae9..6a8757c5b3f 100644 --- a/apps/workflowengine/src/components/Rule.vue +++ b/apps/workflowengine/src/components/Rule.vue @@ -12,7 +12,7 @@

-

@@ -174,9 +174,10 @@ export default { .trigger, .action { flex-grow: 1; min-height: 100px; - max-width: 700px; + max-width: 900px; } .action { + max-width: 400px; position: relative; .buttons { position: absolute; @@ -212,7 +213,8 @@ export default { background-position: 7px center; background-color: transparent; padding-left: 6px; - width: 160px; + margin: 0; + width: 200px; border-radius: var(--border-radius); font-weight: normal; text-align: left; diff --git a/apps/workflowengine/src/components/Values/FileMimeType.vue b/apps/workflowengine/src/components/Values/FileMimeType.vue index 9913dc1e858..75729af8073 100644 --- a/apps/workflowengine/src/components/Values/FileMimeType.vue +++ b/apps/workflowengine/src/components/Values/FileMimeType.vue @@ -1,5 +1,5 @@ diff --git a/apps/workflowengine/src/legacy/filemimetypeplugin.js b/apps/workflowengine/src/legacy/filemimetypeplugin.js index 2b29c4fcbb8..e58bdec26d3 100644 --- a/apps/workflowengine/src/legacy/filemimetypeplugin.js +++ b/apps/workflowengine/src/legacy/filemimetypeplugin.js @@ -17,8 +17,6 @@ * along with this program. If not, see . * */ -import FileMimeType from './../components/Values/FileMimeType' - (function() { OCA.WorkflowEngine = OCA.WorkflowEngine || {} @@ -66,12 +64,6 @@ import FileMimeType from './../components/Values/FileMimeType' var regexRegex = /^\/(.*)\/([gui]{0,3})$/ var result = regexRegex.exec(string) return result !== null - }, - - component: function() { - return FileMimeType } } })() - -OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.FileMimeTypePlugin) diff --git a/apps/workflowengine/src/services/Operation.js b/apps/workflowengine/src/services/Operation.js index 99dca212f4c..ed996593cb4 100644 --- a/apps/workflowengine/src/services/Operation.js +++ b/apps/workflowengine/src/services/Operation.js @@ -13,16 +13,6 @@ const ALL_CHECKS = [ 'OCA\\WorkflowEngine\\Check\\UserGroupMembership' ] -const Checks = Object.values(OCA.WorkflowEngine.Plugins).map((plugin) => { - if (plugin.component) { - return { ...plugin.getCheck(), component: plugin.component } - } - return plugin.getCheck() -}).reduce((obj, item) => { - obj[item.class] = item - return obj -}, {}) - const Operators = OCP.InitialState.loadState('workflowengine', 'operators') /** @@ -71,7 +61,6 @@ Operators['OCA\\FilesAutomatedTagging\\Operation'] = { } export { - Checks, Operators, ALL_CHECKS } diff --git a/apps/workflowengine/src/store.js b/apps/workflowengine/src/store.js index ec9d736dd08..34cee256757 100644 --- a/apps/workflowengine/src/store.js +++ b/apps/workflowengine/src/store.js @@ -35,6 +35,12 @@ const store = new Vuex.Store({ scope: OCP.InitialState.loadState('workflowengine', 'scope'), // TODO: move to backend data operations: Operators, + + plugins: Vue.observable({ + checks: {}, + operators: {} + }), + entities: OCP.InitialState.loadState('workflowengine', 'entities').map(entity => { return { ...entity, @@ -63,6 +69,12 @@ const store = new Vuex.Store({ removeRule(state, rule) { const index = state.rules.findIndex((item) => rule.id === item.id) state.rules.splice(index, 1) + }, + addPluginCheck(state, plugin) { + Vue.set(state.plugins.checks, plugin.class, plugin) + }, + addPluginOperator(state, plugin) { + Vue.set(state.plugins.operators, plugin.class, plugin) } }, actions: { diff --git a/apps/workflowengine/src/workflowengine.js b/apps/workflowengine/src/workflowengine.js index 866f049b0bf..bdf30397883 100644 --- a/apps/workflowengine/src/workflowengine.js +++ b/apps/workflowengine/src/workflowengine.js @@ -14,11 +14,41 @@ import Vuex from 'vuex' import store from './store' import Settings from './components/Workflow' +import FileMimeType from './components/Values/FileMimeType'; -window.OCA.WorkflowEngine = OCA.WorkflowEngine -Vue.use(Vuex) +window.OCA.WorkflowEngine = Object.assign({}, OCA.WorkflowEngine, { + registerCheck: function (Plugin) { + store.commit('addPluginCheck', Plugin) + }, + registerOperator: function (Plugin) { + store.commit('addPluginOperator', Plugin) + } +}) + +// Load legacy plugins for now and register them in the new plugin system +Object.values(OCA.WorkflowEngine.Plugins).map((plugin) => { + if (plugin.component) { + return { ...plugin.getCheck(), component: plugin.component() } + } + return plugin.getCheck() +}).forEach((legacyCheckPlugin) => window.OCA.WorkflowEngine.registerCheck(legacyCheckPlugin)) + +// new way of registering checks +window.OCA.WorkflowEngine.registerCheck({ + class: 'OCA\\WorkflowEngine\\Check\\FileMimeType', + name: t('workflowengine', 'File MIME type'), + operators: [ + { operator: 'is', name: t('workflowengine', 'is') }, + { operator: '!is', name: t('workflowengine', 'is not') }, + { operator: 'matches', name: t('workflowengine', 'matches') }, + { operator: '!matches', name: t('workflowengine', 'does not match') } + ], + component: FileMimeType +}) +Vue.use(Vuex) Vue.prototype.t = t + const View = Vue.extend(Settings) new View({ store -- cgit v1.2.3 From ae55829989d84c6e3937982479bacb79576333cb Mon Sep 17 00:00:00 2001 From: Julius Härtl Date: Fri, 30 Aug 2019 16:18:19 +0200 Subject: Document plugins to be used by integrators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- apps/workflowengine/src/components/Values/file.js | 67 ++++++++++++++++++++ apps/workflowengine/src/workflowengine.js | 77 +++++++++++++---------- 2 files changed, 112 insertions(+), 32 deletions(-) create mode 100644 apps/workflowengine/src/components/Values/file.js (limited to 'apps/workflowengine/src/workflowengine.js') diff --git a/apps/workflowengine/src/components/Values/file.js b/apps/workflowengine/src/components/Values/file.js new file mode 100644 index 00000000000..4a473dbc13c --- /dev/null +++ b/apps/workflowengine/src/components/Values/file.js @@ -0,0 +1,67 @@ +/* + * @copyright Copyright (c) 2019 Julius Härtl + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +import './../../legacy/filenameplugin' +import './../../legacy/filesystemtagsplugin' +import './../../legacy/requestremoteaddressplugin' +import './../../legacy/requesttimeplugin' +import './../../legacy/requesturlplugin' +import './../../legacy/requestuseragentplugin' +import './../../legacy/usergroupmembershipplugin' + +import FileMimeType from './FileMimeType'; +import SizeValue from './SizeValue'; + +const FileChecks = Object.values(OCA.WorkflowEngine.Plugins).map((plugin) => { + if (plugin.component) { + return { ...plugin.getCheck(), component: plugin.component() } + } + return plugin.getCheck() +}) + + +// new way of registering checks +FileChecks.push({ + class: 'OCA\\WorkflowEngine\\Check\\FileMimeType', + name: t('workflowengine', 'File MIME type'), + operators: [ + { operator: 'is', name: t('workflowengine', 'is') }, + { operator: '!is', name: t('workflowengine', 'is not') }, + { operator: 'matches', name: t('workflowengine', 'matches') }, + { operator: '!matches', name: t('workflowengine', 'does not match') } + ], + component: FileMimeType +}) + +FileChecks.push({ + class: 'OCA\\WorkflowEngine\\Check\\FileSize', + name: t('workflowengine', 'File size (upload)'), + operators: [ + { operator: 'less', name: t('workflowengine', 'less') }, + { operator: '!greater', name: t('workflowengine', 'less or equals') }, + { operator: '!less', name: t('workflowengine', 'greater or equals') }, + { operator: 'greater', name: t('workflowengine', 'greater') } + ], + component: SizeValue +}) + +export default FileChecks diff --git a/apps/workflowengine/src/workflowengine.js b/apps/workflowengine/src/workflowengine.js index bdf30397883..6e22852b829 100644 --- a/apps/workflowengine/src/workflowengine.js +++ b/apps/workflowengine/src/workflowengine.js @@ -1,50 +1,63 @@ -import './legacy/filemimetypeplugin' -import './legacy/filenameplugin' -import './legacy/filesizeplugin' -import './legacy/filesystemtagsplugin' -import './legacy/requestremoteaddressplugin' -import './legacy/requesttimeplugin' -import './legacy/requesturlplugin' -import './legacy/requestuseragentplugin' -import './legacy/usergroupmembershipplugin' - import Vue from 'vue' import Vuex from 'vuex' - import store from './store' import Settings from './components/Workflow' -import FileMimeType from './components/Values/FileMimeType'; +import FileValues from './components/Values/file' + +/** + * A plugin for displaying a custom value field for checks + * + * @typedef {Object} CheckPlugin + * @property {string} class - The PHP class name of the check + * @property {Comparison[]} operators - A list of possible comparison operations running on the check + * @property {Vue} component - A vue component to handle the rendering of options + * The component should handle the v-model directive properly, + * so it needs a value property to receive data and emit an input + * event once the data has changed + **/ + +/** + * A plugin for extending the admin page repesentation of a operator + * + * @typedef {Object} OperatorPlugin + * @property {string} class - The PHP class name of the check + * @property {string} operation - Default value for the operation field + * @property {string} color - Custom color code to be applied for the operator selector + * @property {Vue} component - A vue component to handle the rendering of options + * The component should handle the v-model directive properly, + * so it needs a value property to receive data and emit an input + * event once the data has changed + */ +/** + * @typedef {Object} Comparison + * @property {string} operator - value the comparison should have, e.g. !less, greater + * @property {string} name - Translated readable text, e.g. less or equals + **/ + +/** + * Public javascript api for apps to register custom plugins + */ window.OCA.WorkflowEngine = Object.assign({}, OCA.WorkflowEngine, { + /** + * + * @param {CheckPlugin} Plugin + */ registerCheck: function (Plugin) { store.commit('addPluginCheck', Plugin) }, + /** + * + * @param {OperatorPlugin} Plugin + */ registerOperator: function (Plugin) { store.commit('addPluginOperator', Plugin) } }) -// Load legacy plugins for now and register them in the new plugin system -Object.values(OCA.WorkflowEngine.Plugins).map((plugin) => { - if (plugin.component) { - return { ...plugin.getCheck(), component: plugin.component() } - } - return plugin.getCheck() -}).forEach((legacyCheckPlugin) => window.OCA.WorkflowEngine.registerCheck(legacyCheckPlugin)) - -// new way of registering checks -window.OCA.WorkflowEngine.registerCheck({ - class: 'OCA\\WorkflowEngine\\Check\\FileMimeType', - name: t('workflowengine', 'File MIME type'), - operators: [ - { operator: 'is', name: t('workflowengine', 'is') }, - { operator: '!is', name: t('workflowengine', 'is not') }, - { operator: 'matches', name: t('workflowengine', 'matches') }, - { operator: '!matches', name: t('workflowengine', 'does not match') } - ], - component: FileMimeType -}) +// Register shipped checks for file entity +FileValues.forEach((checkPlugin) => window.OCA.WorkflowEngine.registerCheck(checkPlugin)) Vue.use(Vuex) Vue.prototype.t = t -- cgit v1.2.3 From 28a7721b2b485e2ad842d91001601e5e35f71b70 Mon Sep 17 00:00:00 2001 From: Julius Härtl Date: Sat, 31 Aug 2019 11:53:15 +0200 Subject: Handle operator registration properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- apps/workflowengine/src/components/Check.vue | 3 +- apps/workflowengine/src/components/Event.vue | 16 +++++++-- apps/workflowengine/src/components/Operation.vue | 1 + apps/workflowengine/src/components/Rule.vue | 39 +++++++++++++++++----- .../src/components/Values/SizeValue.vue | 19 +++++++++-- apps/workflowengine/src/services/Operation.js | 30 +---------------- apps/workflowengine/src/store.js | 13 +++++--- apps/workflowengine/src/workflowengine.js | 6 +++- 8 files changed, 78 insertions(+), 49 deletions(-) (limited to 'apps/workflowengine/src/workflowengine.js') diff --git a/apps/workflowengine/src/components/Check.vue b/apps/workflowengine/src/components/Check.vue index 5f8140f2222..8583288016f 100644 --- a/apps/workflowengine/src/components/Check.vue +++ b/apps/workflowengine/src/components/Check.vue @@ -89,11 +89,12 @@ export default { width: 100%; padding-right: 20px; & > *:not(.icon-delete) { - width: 200px; + width: 180px; } & > .multiselect, & > input[type=text] { margin-right: 5px; + margin-bottom: 5px; } } input[type=text] { diff --git a/apps/workflowengine/src/components/Event.vue b/apps/workflowengine/src/components/Event.vue index 2621b8ca3ba..5ff59882b9a 100644 --- a/apps/workflowengine/src/components/Event.vue +++ b/apps/workflowengine/src/components/Event.vue @@ -1,6 +1,6 @@ - - diff --git a/apps/workflowengine/src/components/Values/SizeValue.vue b/apps/workflowengine/src/components/Values/SizeValue.vue deleted file mode 100644 index 3e59b70453f..00000000000 --- a/apps/workflowengine/src/components/Values/SizeValue.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - - - diff --git a/apps/workflowengine/src/components/Values/file.js b/apps/workflowengine/src/components/Values/file.js deleted file mode 100644 index 2d8ca936391..00000000000 --- a/apps/workflowengine/src/components/Values/file.js +++ /dev/null @@ -1,133 +0,0 @@ -/* - * @copyright Copyright (c) 2019 Julius Härtl - * - * @author Julius Härtl - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -import './../../legacy/filesystemtagsplugin' -import './../../legacy/requesttimeplugin' -import './../../legacy/requesturlplugin' -import './../../legacy/requestuseragentplugin' -import './../../legacy/usergroupmembershipplugin' - -import FileMimeType from './FileMimeType'; - -const FileChecks = Object.values(OCA.WorkflowEngine.Plugins).map((plugin) => { - if (plugin.component) { - return { ...plugin.getCheck(), component: plugin.component() } - } - return plugin.getCheck() -}) - - -// new way of registering checks - -const validateRegex = function(string) { - var regexRegex = /^\/(.*)\/([gui]{0,3})$/ - var result = regexRegex.exec(string) - return result !== null -} - -const validateIPv4 = function(string) { - var regexRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/(3[0-2]|[1-2][0-9]|[1-9])$/ - var result = regexRegex.exec(string) - return result !== null -} - -const validateIPv6 = function(string) { - var regexRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9])$/ - var result = regexRegex.exec(string) - return result !== null -} - -const stringValidator = (check) => { - if (check.operator === 'matches' || check.operator === '!matches') { - return validateRegex(check.value) - } - return true -} - - -FileChecks.push({ - class: 'OCA\\WorkflowEngine\\Check\\FileName', - name: t('workflowengine', 'File name'), - operators: [ - { operator: 'is', name: t('workflowengine', 'is') }, - { operator: '!is', name: t('workflowengine', 'is not') }, - { operator: 'matches', name: t('workflowengine', 'matches') }, - { operator: '!matches', name: t('workflowengine', 'does not match') } - ], - placeholder: (check) => { - if (check.operator === 'matches' || check.operator === '!matches') { - return '/^dummy-.+$/i' - } - return 'filename.txt' - }, - validate: stringValidator -}) - -FileChecks.push({ - class: 'OCA\\WorkflowEngine\\Check\\FileMimeType', - name: t('workflowengine', 'File MIME type'), - operators: [ - { operator: 'is', name: t('workflowengine', 'is') }, - { operator: '!is', name: t('workflowengine', 'is not') }, - { operator: 'matches', name: t('workflowengine', 'matches') }, - { operator: '!matches', name: t('workflowengine', 'does not match') } - ], - component: FileMimeType -}) - -FileChecks.push({ - class: 'OCA\\WorkflowEngine\\Check\\FileSize', - name: t('workflowengine', 'File size (upload)'), - operators: [ - { operator: 'less', name: t('workflowengine', 'less') }, - { operator: '!greater', name: t('workflowengine', 'less or equals') }, - { operator: '!less', name: t('workflowengine', 'greater or equals') }, - { operator: 'greater', name: t('workflowengine', 'greater') } - ], - placeholder: (check) => '5 MB', - validate: (check) => check.value.match(/^[0-9]+[ ]?[kmgt]?b$/i) !== null -}) - -FileChecks.push({ - class: 'OCA\\WorkflowEngine\\Check\\RequestRemoteAddress', - name: t('workflowengine', 'Request remote address'), - operators: [ - { operator: 'matchesIPv4', name: t('workflowengine', 'matches IPv4') }, - { operator: '!matchesIPv4', name: t('workflowengine', 'does not match IPv4') }, - { operator: 'matchesIPv6', name: t('workflowengine', 'matches IPv6') }, - { operator: '!matchesIPv6', name: t('workflowengine', 'does not match IPv6') } - ], - placeholder: (check) => { - if (check.operator === 'matchesIPv6' || check.operator === '!matchesIPv6') { - return '::1/128'; - } - return '127.0.0.1/32' - }, - validate: (check) => { - if (check.operator === 'matchesIPv6' || check.operator === '!matchesIPv6') { - return validateIPv6(check.value) - } - return validateIPv4(check.value) - } -}) - -export default FileChecks diff --git a/apps/workflowengine/src/helpers/validators.js b/apps/workflowengine/src/helpers/validators.js new file mode 100644 index 00000000000..033ce2ec7fe --- /dev/null +++ b/apps/workflowengine/src/helpers/validators.js @@ -0,0 +1,49 @@ +/* + * @copyright Copyright (c) 2019 Julius Härtl + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + + +const validateRegex = function(string) { + var regexRegex = /^\/(.*)\/([gui]{0,3})$/ + var result = regexRegex.exec(string) + return result !== null +} + +const validateIPv4 = function(string) { + var regexRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/(3[0-2]|[1-2][0-9]|[1-9])$/ + var result = regexRegex.exec(string) + return result !== null +} + +const validateIPv6 = function(string) { + var regexRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9])$/ + var result = regexRegex.exec(string) + return result !== null +} + +const stringValidator = (check) => { + if (check.operator === 'matches' || check.operator === '!matches') { + return validateRegex(check.value) + } + return true +} + +export { validateRegex, stringValidator, validateIPv4, validateIPv6 } diff --git a/apps/workflowengine/src/workflowengine.js b/apps/workflowengine/src/workflowengine.js index e05ac0a5053..149f9d4aa85 100644 --- a/apps/workflowengine/src/workflowengine.js +++ b/apps/workflowengine/src/workflowengine.js @@ -1,9 +1,8 @@ import Vue from 'vue' import Vuex from 'vuex' import store from './store' - import Settings from './components/Workflow' -import FileValues from './components/Values/file' +import ShippedChecks from './components/Checks' /** * A plugin for displaying a custom value field for checks @@ -43,7 +42,6 @@ import FileValues from './components/Values/file' */ window.OCA.WorkflowEngine = Object.assign({}, OCA.WorkflowEngine, { - /** * * @param {CheckPlugin} Plugin @@ -60,8 +58,8 @@ window.OCA.WorkflowEngine = Object.assign({}, OCA.WorkflowEngine, { } }) -// Register shipped checks for file entity -FileValues.forEach((checkPlugin) => window.OCA.WorkflowEngine.registerCheck(checkPlugin)) +// Register shipped checks +ShippedChecks.forEach((checkPlugin) => window.OCA.WorkflowEngine.registerCheck(checkPlugin)) /** * FIXME: remove before merge as this is for UI testing only @@ -69,16 +67,16 @@ FileValues.forEach((checkPlugin) => window.OCA.WorkflowEngine.registerCheck(chec const demo = [ { id: 'OCA\\TestExample\\Operation1', - name: 'Rename file', - description: '🚧 For UI mocking only', - iconClass: 'icon-address-white', + name: 'Convert to PDF', + description: 'Convert a file to PDF using Libreoffice', + iconClass: 'icon-convert-pdf', color: 'var(--color-success)', operation: 'deny' }, { id: 'OCA\\TestExample\\Operation2', name: 'Notify me', - description: '🚧 For UI mocking only', + description: 'Send a Nextcloud Notification', iconClass: 'icon-comment-white', color: 'var(--color-warning)', operation: 'deny' -- cgit v1.2.3 From 24aec9b9d27378ab19ebe028f46f26bcf0a1b901 Mon Sep 17 00:00:00 2001 From: Julius Härtl Date: Mon, 9 Sep 2019 13:53:03 +0200 Subject: Frontend polishing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- apps/workflowengine/src/components/Check.vue | 4 ++ .../src/components/Checks/RequestTime.vue | 2 +- .../src/components/Checks/request.js | 4 +- apps/workflowengine/src/components/Operation.vue | 17 ++++++-- .../src/components/Operations/ConvertToPdf.vue | 46 ---------------------- .../src/components/Operations/Tag.vue | 31 --------------- apps/workflowengine/src/components/Rule.vue | 10 +++-- apps/workflowengine/src/components/Workflow.vue | 6 +-- apps/workflowengine/src/workflowengine.js | 23 ----------- apps/workflowengine/webpack.js | 12 ------ 10 files changed, 27 insertions(+), 128 deletions(-) delete mode 100644 apps/workflowengine/src/components/Operations/ConvertToPdf.vue delete mode 100644 apps/workflowengine/src/components/Operations/Tag.vue (limited to 'apps/workflowengine/src/workflowengine.js') diff --git a/apps/workflowengine/src/components/Check.vue b/apps/workflowengine/src/components/Check.vue index 508b8a4a1f4..8f7fbca2865 100644 --- a/apps/workflowengine/src/components/Check.vue +++ b/apps/workflowengine/src/components/Check.vue @@ -138,6 +138,10 @@ export default { margin-top: -5px; margin-bottom: -5px; } + button.action-item.action-item--single.icon-delete { + height: 34px; + width: 34px; + } .invalid { border: 1px solid var(--color-error) !important; } diff --git a/apps/workflowengine/src/components/Checks/RequestTime.vue b/apps/workflowengine/src/components/Checks/RequestTime.vue index 2f09693232a..9ea211874fe 100644 --- a/apps/workflowengine/src/components/Checks/RequestTime.vue +++ b/apps/workflowengine/src/components/Checks/RequestTime.vue @@ -74,7 +74,7 @@ export default { display: flex; flex-grow: 1; flex-wrap: wrap; - max-width: 200px; + max-width: 180px; .multiselect { width: 100%; diff --git a/apps/workflowengine/src/components/Checks/request.js b/apps/workflowengine/src/components/Checks/request.js index d2e4eaa3565..8b36b89a9e8 100644 --- a/apps/workflowengine/src/components/Checks/request.js +++ b/apps/workflowengine/src/components/Checks/request.js @@ -42,7 +42,6 @@ const RequestChecks = [ { operator: 'in', name: t('workflowengine', 'between') }, { operator: '!in', name: t('workflowengine', 'not between') } ], - // TODO: implement component component: RequestTime }, { @@ -54,7 +53,8 @@ const RequestChecks = [ { operator: 'matches', name: t('workflowengine', 'matches') }, { operator: '!matches', name: t('workflowengine', 'does not match') } ], - component: RequestUserAgent + // TODO: implement component + // component: RequestUserAgent }, { class: 'OCA\\WorkflowEngine\\Check\\UserGroupMembership', diff --git a/apps/workflowengine/src/components/Operation.vue b/apps/workflowengine/src/components/Operation.vue index 45b0f24223d..3cd7378f0df 100644 --- a/apps/workflowengine/src/components/Operation.vue +++ b/apps/workflowengine/src/components/Operation.vue @@ -5,7 +5,9 @@

{{ operation.name }}

{{ operation.description }} - +
+ +
@@ -28,13 +30,14 @@ export default { diff --git a/apps/workflowengine/src/components/Operations/ConvertToPdf.vue b/apps/workflowengine/src/components/Operations/ConvertToPdf.vue deleted file mode 100644 index 5fa1676e092..00000000000 --- a/apps/workflowengine/src/components/Operations/ConvertToPdf.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - - diff --git a/apps/workflowengine/src/components/Operations/Tag.vue b/apps/workflowengine/src/components/Operations/Tag.vue deleted file mode 100644 index 7a27e2b572d..00000000000 --- a/apps/workflowengine/src/components/Operations/Tag.vue +++ /dev/null @@ -1,31 +0,0 @@ - - - - - diff --git a/apps/workflowengine/src/components/Rule.vue b/apps/workflowengine/src/components/Rule.vue index 82e19dbe82b..c5c6094879a 100644 --- a/apps/workflowengine/src/components/Rule.vue +++ b/apps/workflowengine/src/components/Rule.vue @@ -1,6 +1,5 @@