From ad976c66fd9a78e6d90224091634b04a25a08f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Tue, 6 Aug 2019 17:40:30 +0200 Subject: [PATCH 01/27] 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/admin.js | 2 +- apps/workflowengine/src/components/Check.vue | 104 +++++++++ apps/workflowengine/src/components/Event.vue | 84 +++++++ .../src/components/Operation.vue | 83 +++++++ .../components/Operations/ConvertToPdf.vue | 45 ++++ .../src/components/Operations/Tag.vue | 29 +++ apps/workflowengine/src/components/Rule.vue | 209 ++++++++++++++++++ .../src/components/Values/FileMimeType.vue | 39 ++++ .../src/components/Values/SizeValue.vue | 28 +++ .../src/components/Workflow.vue | 146 ++++++++++++ apps/workflowengine/src/filemimetypeplugin.js | 5 + apps/workflowengine/src/filesizeplugin.js | 5 +- apps/workflowengine/src/services/Operation.js | 141 ++++++++++++ apps/workflowengine/src/workflowengine.js | 9 +- 14 files changed, 926 insertions(+), 3 deletions(-) create mode 100644 apps/workflowengine/src/components/Check.vue create mode 100644 apps/workflowengine/src/components/Event.vue create mode 100644 apps/workflowengine/src/components/Operation.vue create mode 100644 apps/workflowengine/src/components/Operations/ConvertToPdf.vue create mode 100644 apps/workflowengine/src/components/Operations/Tag.vue create mode 100644 apps/workflowengine/src/components/Rule.vue create mode 100644 apps/workflowengine/src/components/Values/FileMimeType.vue create mode 100644 apps/workflowengine/src/components/Values/SizeValue.vue create mode 100644 apps/workflowengine/src/components/Workflow.vue create mode 100644 apps/workflowengine/src/services/Operation.js diff --git a/apps/workflowengine/src/admin.js b/apps/workflowengine/src/admin.js index 92f485a8b4c..fb2af941436 100644 --- a/apps/workflowengine/src/admin.js +++ b/apps/workflowengine/src/admin.js @@ -382,4 +382,4 @@ import OperationsTemplate from './templates/operations.handlebars'; 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 new file mode 100644 index 00000000000..c8c7c46aa87 --- /dev/null +++ b/apps/workflowengine/src/components/Check.vue @@ -0,0 +1,104 @@ + + + + + \ No newline at end of file diff --git a/apps/workflowengine/src/components/Event.vue b/apps/workflowengine/src/components/Event.vue new file mode 100644 index 00000000000..fd5097cecfc --- /dev/null +++ b/apps/workflowengine/src/components/Event.vue @@ -0,0 +1,84 @@ + + + + + \ No newline at end of file diff --git a/apps/workflowengine/src/components/Operation.vue b/apps/workflowengine/src/components/Operation.vue new file mode 100644 index 00000000000..f7a8f56cede --- /dev/null +++ b/apps/workflowengine/src/components/Operation.vue @@ -0,0 +1,83 @@ + + + + + \ No newline at end of file diff --git a/apps/workflowengine/src/components/Operations/ConvertToPdf.vue b/apps/workflowengine/src/components/Operations/ConvertToPdf.vue new file mode 100644 index 00000000000..62c53a4ee6c --- /dev/null +++ b/apps/workflowengine/src/components/Operations/ConvertToPdf.vue @@ -0,0 +1,45 @@ + + + + + \ No newline at end of file diff --git a/apps/workflowengine/src/components/Operations/Tag.vue b/apps/workflowengine/src/components/Operations/Tag.vue new file mode 100644 index 00000000000..74e4e4f977b --- /dev/null +++ b/apps/workflowengine/src/components/Operations/Tag.vue @@ -0,0 +1,29 @@ + + + + + \ No newline at end of file diff --git a/apps/workflowengine/src/components/Rule.vue b/apps/workflowengine/src/components/Rule.vue new file mode 100644 index 00000000000..818e15610fa --- /dev/null +++ b/apps/workflowengine/src/components/Rule.vue @@ -0,0 +1,209 @@ + + + + + \ No newline at end of file diff --git a/apps/workflowengine/src/components/Values/FileMimeType.vue b/apps/workflowengine/src/components/Values/FileMimeType.vue new file mode 100644 index 00000000000..70b8f0d984b --- /dev/null +++ b/apps/workflowengine/src/components/Values/FileMimeType.vue @@ -0,0 +1,39 @@ + + + + + \ No newline at end of file diff --git a/apps/workflowengine/src/components/Values/SizeValue.vue b/apps/workflowengine/src/components/Values/SizeValue.vue new file mode 100644 index 00000000000..bc4378702e1 --- /dev/null +++ b/apps/workflowengine/src/components/Values/SizeValue.vue @@ -0,0 +1,28 @@ + + + + + \ No newline at end of file diff --git a/apps/workflowengine/src/components/Workflow.vue b/apps/workflowengine/src/components/Workflow.vue new file mode 100644 index 00000000000..9993b328827 --- /dev/null +++ b/apps/workflowengine/src/components/Workflow.vue @@ -0,0 +1,146 @@ + + + + + \ No newline at end of file diff --git a/apps/workflowengine/src/filemimetypeplugin.js b/apps/workflowengine/src/filemimetypeplugin.js index 17c092d209f..6b929b2aad5 100644 --- a/apps/workflowengine/src/filemimetypeplugin.js +++ b/apps/workflowengine/src/filemimetypeplugin.js @@ -17,6 +17,7 @@ * along with this program. If not, see . * */ +import FileMimeType from './components/Values/FileMimeType' (function() { @@ -65,6 +66,10 @@ var regexRegex = /^\/(.*)\/([gui]{0,3})$/, result = regexRegex.exec(string); return result !== null; + }, + + component: function () { + return FileMimeType } }; })(); diff --git a/apps/workflowengine/src/filesizeplugin.js b/apps/workflowengine/src/filesizeplugin.js index 0efa9d00edf..ebd72dcd2f4 100644 --- a/apps/workflowengine/src/filesizeplugin.js +++ b/apps/workflowengine/src/filesizeplugin.js @@ -17,7 +17,7 @@ * along with this program. If not, see . * */ - +import SizeValue from './components/Values/SizeValue' (function() { OCA.WorkflowEngine = OCA.WorkflowEngine || {}; @@ -49,6 +49,9 @@ .tooltip({ placement: 'bottom' }); + }, + component: function () { + return SizeValue } }; })(); diff --git a/apps/workflowengine/src/services/Operation.js b/apps/workflowengine/src/services/Operation.js new file mode 100644 index 00000000000..1de7d2a95ad --- /dev/null +++ b/apps/workflowengine/src/services/Operation.js @@ -0,0 +1,141 @@ +import ConvertToPdf from './../components/Operations/ConvertToPdf' +import Tag from './../components/Operations/Tag' +class OperationService { + + constructor() { + this.operations = {} + } + registerOperation (operation) { + this.operations[operation.class] = Object.assign({ + color: 'var(--color-primary)' + }, operation) + } + + getAll() { + return this.operations + } + + get(className) { + return this.operations[className] + } + +} + +class EventService { + + constructor() { + this.events = {} + } + registerEvent(event) { + this.events[event.id] = event + } + + getAll() { + return this.events + } + + get(id) { + return this.events[id] + } + +} + +const operationService = new OperationService() +const eventService = new EventService() + + +const ALL_CHECKS = [ + 'OCA\\WorkflowEngine\\Check\\FileMimeType', + 'OCA\\WorkflowEngine\\Check\\FileName', + 'OCA\\WorkflowEngine\\Check\\FileSize', + 'OCA\\WorkflowEngine\\Check\\FileSystemTags', + 'OCA\\WorkflowEngine\\Check\\RequestRemoteAddress', + 'OCA\\WorkflowEngine\\Check\\RequestTime', + 'OCA\\WorkflowEngine\\Check\\RequestURL', + 'OCA\\WorkflowEngine\\Check\\RequestUserAgent', + 'OCA\\WorkflowEngine\\Check\\UserGroupMembership' +] + +/** + * TODO: move to separate apps + * TODO: fetch from initial state api + **/ +const EVENT_FILE_ACCESS = 'EVENT_FILE_ACCESS' +const EVENT_FILE_CHANGED = 'EVENT_FILE_CHANGED' +const EVENT_FILE_TAGGED = 'EVENT_FILE_TAGGED' + +eventService.registerEvent({ + id: EVENT_FILE_ACCESS, + name: 'File is accessed', + icon: 'icon-desktop', + checks: ALL_CHECKS, +}) + +eventService.registerEvent({ + id: EVENT_FILE_CHANGED, + name: 'File was updated', + icon: 'icon-folder', + checks: ALL_CHECKS, +}) + + +eventService.registerEvent({ + id: EVENT_FILE_TAGGED, + name: 'File was tagged', + icon: 'icon-tag', + checks: ALL_CHECKS, +}) + +operationService.registerOperation({ + class: 'OCA\\FilesAccessControl\\Operation', + title: 'Block access', + description: 'todo', + icon: 'icon-block', + color: 'var(--color-error)', + events: [ + EVENT_FILE_ACCESS + ], + operation: 'deny' +}) + +operationService.registerOperation({ + class: 'OCA\\FilesAutomatedTagging\\Operation', + title: 'Tag a file', + description: 'todo', + icon: 'icon-tag', + events: [ + EVENT_FILE_CHANGED, + EVENT_FILE_TAGGED + ], + options: Tag + +}) + +operationService.registerOperation({ + class: 'OCA\\WorkflowPDFConverter\\Operation', + title: 'Convert to PDF', + description: 'todo', + color: '#dc5047', + icon: 'icon-convert-pdf', + events: [ + EVENT_FILE_CHANGED, + //EVENT_FILE_TAGGED + ], + options: ConvertToPdf +}) + + +const legacyChecks = 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 +}, {}) + +export { + eventService, + operationService +} \ No newline at end of file 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 From e7e9166efe2771b91a0ffdbe96f82284787244b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Fri, 9 Aug 2019 12:28:59 +0200 Subject: [PATCH 02/27] Add endpoint to test operations before submitting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- apps/workflowengine/lib/Manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/workflowengine/lib/Manager.php b/apps/workflowengine/lib/Manager.php index efe6c387059..07438b2f7cb 100644 --- a/apps/workflowengine/lib/Manager.php +++ b/apps/workflowengine/lib/Manager.php @@ -425,7 +425,7 @@ class Manager implements IManager { * @param string $operation * @throws \UnexpectedValueException */ - protected function validateOperation($class, $name, array $checks, $operation, string $entity, array $events) { + public function validateOperation($class, $name, array $checks, $operation, string $entity, array $events) { try { /** @var IOperation $instance */ $instance = $this->container->query($class); From aed630ac0a63771c7a217a3c1d400a354929fafe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Mon, 19 Aug 2019 17:09:58 +0200 Subject: [PATCH 03/27] Adjust template id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- apps/workflowengine/templates/settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/workflowengine/templates/settings.php b/apps/workflowengine/templates/settings.php index 04f43bb2573..576642b543a 100644 --- a/apps/workflowengine/templates/settings.php +++ b/apps/workflowengine/templates/settings.php @@ -22,4 +22,4 @@ /** @var array $_ */ /** @var \OCP\IL10N $l */ ?> -
+
From 9f8ccf1036ff18d961949bfb644c9d445caa8a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Mon, 19 Aug 2019 17:13:33 +0200 Subject: [PATCH 04/27] Use entity/event definitions from backend 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 | 16 +- apps/workflowengine/src/components/Event.vue | 24 ++- .../src/components/Operation.vue | 25 +-- apps/workflowengine/src/components/Rule.vue | 8 +- .../src/components/Workflow.vue | 21 ++- apps/workflowengine/src/services/Operation.js | 170 +++++++++--------- 6 files changed, 142 insertions(+), 122 deletions(-) diff --git a/apps/workflowengine/src/components/Check.vue b/apps/workflowengine/src/components/Check.vue index c8c7c46aa87..8cfe5a89020 100644 --- a/apps/workflowengine/src/components/Check.vue +++ b/apps/workflowengine/src/components/Check.vue @@ -15,6 +15,7 @@ \ No newline at end of file + diff --git a/apps/workflowengine/src/services/Operation.js b/apps/workflowengine/src/services/Operation.js index 1de7d2a95ad..a24d97ef226 100644 --- a/apps/workflowengine/src/services/Operation.js +++ b/apps/workflowengine/src/services/Operation.js @@ -1,5 +1,41 @@ import ConvertToPdf from './../components/Operations/ConvertToPdf' import Tag from './../components/Operations/Tag' + +const ALL_CHECKS = [ + 'OCA\\WorkflowEngine\\Check\\FileMimeType', + 'OCA\\WorkflowEngine\\Check\\FileName', + 'OCA\\WorkflowEngine\\Check\\FileSize', + 'OCA\\WorkflowEngine\\Check\\FileSystemTags', + 'OCA\\WorkflowEngine\\Check\\RequestRemoteAddress', + 'OCA\\WorkflowEngine\\Check\\RequestTime', + 'OCA\\WorkflowEngine\\Check\\RequestURL', + 'OCA\\WorkflowEngine\\Check\\RequestUserAgent', + 'OCA\\WorkflowEngine\\Check\\UserGroupMembership' +] + +const Entities = OCP.InitialState.loadState('workflowengine', 'entities').map(entity => { + return { + ...entity, + // TODO: see if we should have this defined in the backend as well + checks: [...ALL_CHECKS] + } +}) + +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 +}, {}) + +/** + * Register operations + * TODO: should be provided by the backend + */ + class OperationService { constructor() { @@ -20,92 +56,63 @@ class OperationService { } } - -class EventService { - - constructor() { - this.events = {} - } - registerEvent(event) { - this.events[event.id] = event - } - - getAll() { - return this.events - } - - get(id) { - return this.events[id] - } - -} - const operationService = new OperationService() -const eventService = new EventService() - - -const ALL_CHECKS = [ - 'OCA\\WorkflowEngine\\Check\\FileMimeType', - 'OCA\\WorkflowEngine\\Check\\FileName', - 'OCA\\WorkflowEngine\\Check\\FileSize', - 'OCA\\WorkflowEngine\\Check\\FileSystemTags', - 'OCA\\WorkflowEngine\\Check\\RequestRemoteAddress', - 'OCA\\WorkflowEngine\\Check\\RequestTime', - 'OCA\\WorkflowEngine\\Check\\RequestURL', - 'OCA\\WorkflowEngine\\Check\\RequestUserAgent', - 'OCA\\WorkflowEngine\\Check\\UserGroupMembership' -] - -/** - * TODO: move to separate apps - * TODO: fetch from initial state api - **/ -const EVENT_FILE_ACCESS = 'EVENT_FILE_ACCESS' -const EVENT_FILE_CHANGED = 'EVENT_FILE_CHANGED' -const EVENT_FILE_TAGGED = 'EVENT_FILE_TAGGED' - -eventService.registerEvent({ - id: EVENT_FILE_ACCESS, - name: 'File is accessed', - icon: 'icon-desktop', - checks: ALL_CHECKS, -}) - -eventService.registerEvent({ - id: EVENT_FILE_CHANGED, - name: 'File was updated', - icon: 'icon-folder', - checks: ALL_CHECKS, -}) - - -eventService.registerEvent({ - id: EVENT_FILE_TAGGED, - name: 'File was tagged', - icon: 'icon-tag', - checks: ALL_CHECKS, -}) operationService.registerOperation({ class: 'OCA\\FilesAccessControl\\Operation', title: 'Block access', - description: 'todo', + description: 'Deny access to files when they are accessed', icon: 'icon-block', color: 'var(--color-error)', - events: [ - EVENT_FILE_ACCESS + entites: [ + 'WorkflowEngine_Entity_File' ], + events: [ + // TODO: this is probably handled differently since there is no regular event for files access control + 'WorkflowEngine_Entity_File::postTouch' + ], + operation: 'deny' +}) + +operationService.registerOperation({ + class: 'OCA\\TestExample\\Operation1', + title: 'Rename file', + description: '🚧 For UI mocking only', + icon: 'icon-address-white', + color: 'var(--color-success)', + entites: [], + events: [], + operation: 'deny' +}) +operationService.registerOperation({ + class: 'OCA\\TestExample\\Operation2', + title: 'Notify me', + description: '🚧 For UI mocking only', + icon: 'icon-comment-white', + color: 'var(--color-warning)', + entites: [], + events: [], + operation: 'deny' +}) +operationService.registerOperation({ + class: 'OCA\\TestExample\\Operation3', + title: 'Call a web hook', + description: '🚧 For UI mocking only', + icon: 'icon-category-integration icon-invert', + color: 'var(--color-primary)', + entites: [], + events: [], operation: 'deny' }) operationService.registerOperation({ class: 'OCA\\FilesAutomatedTagging\\Operation', title: 'Tag a file', - description: 'todo', - icon: 'icon-tag', + description: 'Assign a tag to a file', + icon: 'icon-tag-white', events: [ - EVENT_FILE_CHANGED, - EVENT_FILE_TAGGED + 'WorkflowEngine_Entity_File::postWrite', + //'WorkflowEngine_Entity_File::postTagged', ], options: Tag @@ -114,28 +121,23 @@ operationService.registerOperation({ operationService.registerOperation({ class: 'OCA\\WorkflowPDFConverter\\Operation', title: 'Convert to PDF', - description: 'todo', + description: 'Generate a PDF file', color: '#dc5047', icon: 'icon-convert-pdf', events: [ - EVENT_FILE_CHANGED, + 'WorkflowEngine_Entity_File::postWrite', //EVENT_FILE_TAGGED ], options: ConvertToPdf }) +console.debug('[InitialState] Entities', Entities) +console.debug('[WorkflowEngine] Checks', Checks) +console.debug('[WorkflowEngine] Operations', operationService.operations) -const legacyChecks = 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 -}, {}) export { - eventService, + Entities, + Checks, operationService -} \ No newline at end of file +} From 0f84696d10c62e1e522457b876d4583c08d5e197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Mon, 19 Aug 2019 17:15:34 +0200 Subject: [PATCH 05/27] Styling fixes 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/Rule.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/workflowengine/src/components/Rule.vue b/apps/workflowengine/src/components/Rule.vue index 43cbbced209..59d66e43091 100644 --- a/apps/workflowengine/src/components/Rule.vue +++ b/apps/workflowengine/src/components/Rule.vue @@ -191,7 +191,7 @@ & > span { min-width: 50px; text-align: right; - color: var(--color-text-light); + color: var(--color-text-maxcontrast); padding-right: 5px; } .multiselect { From aa00f401b39c2b63cba7e5e8f6cdec8528466069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Wed, 28 Aug 2019 18:27:37 +0200 Subject: [PATCH 06/27] Adjust to new backend URLs 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 | 2 +- apps/workflowengine/src/components/Event.vue | 16 +++++--- .../src/components/Operation.vue | 6 +++ apps/workflowengine/src/components/Rule.vue | 38 +++++++++++-------- .../src/components/Workflow.vue | 33 +++++++++------- apps/workflowengine/src/services/Operation.js | 4 +- 6 files changed, 62 insertions(+), 37 deletions(-) diff --git a/apps/workflowengine/src/components/Check.vue b/apps/workflowengine/src/components/Check.vue index 8cfe5a89020..86005dae268 100644 --- a/apps/workflowengine/src/components/Check.vue +++ b/apps/workflowengine/src/components/Check.vue @@ -48,7 +48,7 @@ this.currentOption = Checks[this.check.class] this.currentOperator = this.operators.find((operator) => operator.operator === this.check.operator) this.$nextTick(() => { - this.$refs.checkSelector.$el.focus() + //this.$refs.checkSelector.$el.focus() }) }, computed: { diff --git a/apps/workflowengine/src/components/Event.vue b/apps/workflowengine/src/components/Event.vue index caf5c7631bd..7b39ea571fb 100644 --- a/apps/workflowengine/src/components/Event.vue +++ b/apps/workflowengine/src/components/Event.vue @@ -28,12 +28,15 @@ required: true } }, + mounted() { + this.updateEvent(this.currentEvent) + }, computed: { currentEvent() { - if (typeof this.rule.event === 'undefined') { + if (!this.rule.event) { return this.allEvents.length > 0 ? this.allEvents[0] : null } - return this.allEvents.find(event => event.id === this.rule.event) + return this.allEvents.find(event => event.entity === this.rule.entity && event.event === this.rule.event) }, allEvents() { return this.operation.events.map((entityEventName) => { @@ -45,7 +48,7 @@ return { entity: entityId, id: entityEventName, - event: eventName, + events: eventName, name: Event.displayName, icon: Entity.icon, checks: Entity.checks, @@ -58,8 +61,11 @@ }, methods: { updateEvent(event) { - this.$set(this.rule, 'event', event.id) - this.$emit('update', this.rule) + if (this.rule.entity !== event.entity || this.rule.events !== '["' + event.event + '"]') { + this.$set(this.rule, 'entity', event.entity) + this.$set(this.rule, 'event', event.event) + this.$emit('update', this.rule) + } } } } diff --git a/apps/workflowengine/src/components/Operation.vue b/apps/workflowengine/src/components/Operation.vue index 3e5de3198ca..30f26eb6ec4 100644 --- a/apps/workflowengine/src/components/Operation.vue +++ b/apps/workflowengine/src/components/Operation.vue @@ -71,6 +71,12 @@ } } + .actions__item:not(.colored) { + .icon { + filter: invert(1); + } + } + /* TODO: those should be provided by the backend, remove once ready */ .icon-block { background-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8' standalone='no'%3F%3E%3Csvg xmlns='http://www.w3.org/2000/svg' height='32' width='32' version='1.1' viewBox='0 0 32 32'%3E%3Cpath fill='%23fff' d='m10.203 2-8.203 8.203v11.594l8.203 8.203h11.594l8.203-8.203v-11.594l-8.203-8.203h-11.594zm11.097 5.3092 3.345 3.3448-5.346 5.346 5.346 5.346-3.299 3.299-5.346-5.346-5.346 5.346-3.2992-3.299 5.3462-5.346-5.3462-5.346 3.2992-3.2992 5.346 5.3462 5.3-5.3918z'/%3E%3C/svg%3E"); diff --git a/apps/workflowengine/src/components/Rule.vue b/apps/workflowengine/src/components/Rule.vue index 59d66e43091..d1f5a088f51 100644 --- a/apps/workflowengine/src/components/Rule.vue +++ b/apps/workflowengine/src/components/Rule.vue @@ -1,5 +1,5 @@ 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 = 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 +}) -window.OCA.WorkflowEngine = OCA.WorkflowEngine Vue.use(Vuex) - Vue.prototype.t = t + const View = Vue.extend(Settings) new View({ store From ae55829989d84c6e3937982479bacb79576333cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Fri, 30 Aug 2019 16:18:19 +0200 Subject: [PATCH 11/27] 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 --- .../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 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 From 28a7721b2b485e2ad842d91001601e5e35f71b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Sat, 31 Aug 2019 11:53:15 +0200 Subject: [PATCH 12/27] 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 +++++++- .../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(-) 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/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' From 0b6706225b27a9953868fdd8d2d3344c0b71048b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Fri, 6 Sep 2019 16:24:21 +0200 Subject: [PATCH 20/27] Add moment-timezone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- package-lock.json | 8 ++++++++ package.json | 1 + 2 files changed, 9 insertions(+) diff --git a/package-lock.json b/package-lock.json index 157f490c41b..ac5f79c864c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5719,6 +5719,14 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" }, + "moment-timezone": { + "version": "0.5.26", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.26.tgz", + "integrity": "sha512-sFP4cgEKTCymBBKgoxZjYzlSovC20Y6J7y3nanDc5RoBIXKlZhoYwBoZGe3flwU6A372AcRwScH8KiwV6zjy1g==", + "requires": { + "moment": ">= 2.9.0" + } + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", diff --git a/package.json b/package.json index d02dd259982..09d0185e516 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "lodash": "^4.17.15", "marked": "^0.7.0", "moment": "^2.24.0", + "moment-timezone": "^0.5.26", "nextcloud-axios": "^0.2.1", "nextcloud-password-confirmation": "^0.4.2", "nextcloud-vue": "^0.12.3", From 24aec9b9d27378ab19ebe028f46f26bcf0a1b901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Mon, 9 Sep 2019 13:53:03 +0200 Subject: [PATCH 21/27] 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 +- .../src/components/Operation.vue | 17 +++++-- .../components/Operations/ConvertToPdf.vue | 46 ------------------- .../src/components/Operations/Tag.vue | 31 ------------- apps/workflowengine/src/components/Rule.vue | 10 ++-- .../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 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 @@ - + diff --git a/apps/workflowengine/src/components/Checks/FileSystemTag.vue b/apps/workflowengine/src/components/Checks/FileSystemTag.vue index ead4edf60c2..2875b64d48e 100644 --- a/apps/workflowengine/src/components/Checks/FileSystemTag.vue +++ b/apps/workflowengine/src/components/Checks/FileSystemTag.vue @@ -22,59 +22,59 @@ diff --git a/apps/workflowengine/src/components/Checks/file.js b/apps/workflowengine/src/components/Checks/file.js index 431a3f93580..80bd120079f 100644 --- a/apps/workflowengine/src/components/Checks/file.js +++ b/apps/workflowengine/src/components/Checks/file.js @@ -22,7 +22,7 @@ import FileMimeType from './FileMimeType' import { stringValidator, validateIPv4, validateIPv6 } from './../../helpers/validators' -import FileSystemTag from './FileSystemTag'; +import FileSystemTag from './FileSystemTag' const FileChecks = [ { class: 'OCA\\WorkflowEngine\\Check\\FileName', diff --git a/apps/workflowengine/src/components/Checks/request.js b/apps/workflowengine/src/components/Checks/request.js index ee574f9de90..1059bf45b5a 100644 --- a/apps/workflowengine/src/components/Checks/request.js +++ b/apps/workflowengine/src/components/Checks/request.js @@ -23,6 +23,7 @@ import RequestUserAgent from './RequestUserAgent' import RequestTime from './RequestTime' import RequestURL from './RequestURL' +import RequestUserGroup from './RequestUserGroup' const RequestChecks = [ { @@ -62,8 +63,8 @@ const RequestChecks = [ operators: [ { operator: 'is', name: t('workflowengine', 'is member of') }, { operator: '!is', name: t('workflowengine', 'is not member of') } - ] - // TODO: implement component + ], + component: RequestUserGroup } ] diff --git a/apps/workflowengine/src/css/multiselect.css b/apps/workflowengine/src/css/multiselect.css new file mode 100644 index 00000000000..8eb7583744b --- /dev/null +++ b/apps/workflowengine/src/css/multiselect.css @@ -0,0 +1,11 @@ +.multiselect::v-deep .multiselect__single { + display: flex; +} + +.option__icon { + min-width: 25px; +} + +input, .multiselect { + width: 100%; +} diff --git a/apps/workflowengine/src/mixins/valueMixin.js b/apps/workflowengine/src/mixins/valueMixin.js new file mode 100644 index 00000000000..e6ea5bbdcf4 --- /dev/null +++ b/apps/workflowengine/src/mixins/valueMixin.js @@ -0,0 +1,54 @@ +/* + * @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 valueMixin = { + props: { + value: { + type: String, + default: '' + }, + check: { + type: Object, + default: () => { return {} } + } + }, + data() { + return { + newValue: '' + } + }, + watch: { + value: { + immediate: true, + handler: function(value) { + this.updateInternalValue(value) + } + } + }, + methods: { + updateInternalValue(value) { + this.newValue = value + } + } +} + +export default valueMixin From 9e0078824e1303c78575c4287ce3f228659d8ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Mon, 9 Sep 2019 16:55:36 +0200 Subject: [PATCH 26/27] Add nextcloud-router MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- package-lock.json | 328 ++++++++-------------------------------------- package.json | 1 + 2 files changed, 55 insertions(+), 274 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac5f79c864c..3681b527582 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", "dev": true, "requires": { "@babel/highlight": "^7.0.0" @@ -35,73 +35,12 @@ "source-map": "^0.5.0" }, "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/generator": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.0.tgz", - "integrity": "sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA==", - "dev": true, - "requires": { - "@babel/types": "^7.6.0", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - } - }, "@babel/parser": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.0.tgz", "integrity": "sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==", "dev": true }, - "@babel/template": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", - "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.0" - } - }, - "@babel/traverse": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.0.tgz", - "integrity": "sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.0", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.0", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -132,17 +71,6 @@ "trim-right": "^1.0.1" }, "dependencies": { - "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -190,19 +118,6 @@ "@babel/helper-function-name": "^7.1.0", "@babel/types": "^7.5.5", "lodash": "^4.17.13" - }, - "dependencies": { - "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } } }, "@babel/helper-explode-assignable-expression": { @@ -251,19 +166,6 @@ "dev": true, "requires": { "@babel/types": "^7.5.5" - }, - "dependencies": { - "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } } }, "@babel/helper-module-imports": { @@ -287,19 +189,6 @@ "@babel/template": "^7.4.4", "@babel/types": "^7.5.5", "lodash": "^4.17.13" - }, - "dependencies": { - "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } } }, "@babel/helper-optimise-call-expression": { @@ -349,19 +238,6 @@ "@babel/helper-optimise-call-expression": "^7.0.0", "@babel/traverse": "^7.5.5", "@babel/types": "^7.5.5" - }, - "dependencies": { - "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } } }, "@babel/helper-simple-access": { @@ -404,92 +280,6 @@ "@babel/template": "^7.6.0", "@babel/traverse": "^7.6.0", "@babel/types": "^7.6.0" - }, - "dependencies": { - "@babel/generator": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.0.tgz", - "integrity": "sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA==", - "dev": true, - "requires": { - "@babel/types": "^7.6.0", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - } - }, - "@babel/parser": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.0.tgz", - "integrity": "sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==", - "dev": true - }, - "@babel/template": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", - "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.0" - } - }, - "@babel/traverse": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.0.tgz", - "integrity": "sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.0", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.0", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - } - } - }, - "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } } }, "@babel/highlight": { @@ -988,30 +778,25 @@ "invariant": "^2.2.2", "js-levenshtein": "^1.1.3", "semver": "^5.5.0" - }, - "dependencies": { - "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } } }, "@babel/template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", - "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", + "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4" + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.0" + }, + "dependencies": { + "@babel/parser": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.0.tgz", + "integrity": "sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==", + "dev": true + } } }, "@babel/traverse": { @@ -1031,32 +816,12 @@ "lodash": "^4.17.13" }, "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, "@babel/parser": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.0.tgz", "integrity": "sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==", "dev": true }, - "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -1069,13 +834,13 @@ } }, "@babel/types": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.0.tgz", - "integrity": "sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", + "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", "dev": true, "requires": { "esutils": "^2.0.2", - "lodash": "^4.17.11", + "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } }, @@ -3048,9 +2813,9 @@ } }, "electron-to-chromium": { - "version": "1.3.252", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.252.tgz", - "integrity": "sha512-NWJ5TztDnjExFISZHFwpoJjMbLUifsNBnx7u2JI0gCw6SbKyQYYWWtBHasO/jPtHym69F4EZuTpRNGN11MT/jg==", + "version": "1.3.254", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.254.tgz", + "integrity": "sha512-7I5/OkgR6JKy6RFLJeru0kc0RMmmMu1UnkHBKInFKRrg1/4EQKIqOaUqITSww/SZ1LqWwp1qc/LLoIGy449eYw==", "dev": true }, "elliptic": { @@ -3178,9 +2943,9 @@ "dev": true }, "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "eventemitter3": { @@ -3549,9 +3314,9 @@ } }, "follow-redirects": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.9.0.tgz", - "integrity": "sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.8.1.tgz", + "integrity": "sha512-micCIbldHioIegeKs41DoH0KS3AXfFzgS30qVkM6z/XOE/GJgvmsoc839NUqa1B9udYe9dQxgv7KFwng6+p/dw==", "requires": { "debug": "^3.0.0" } @@ -5651,9 +5416,9 @@ } }, "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "mississippi": { "version": "3.0.0", @@ -5790,6 +5555,21 @@ "resolved": "https://registry.npmjs.org/nextcloud-password-confirmation/-/nextcloud-password-confirmation-0.4.2.tgz", "integrity": "sha512-DZXsfdk3iCsRWtd0lsYM1nqQ/oD9YlQ2WbC4qRZo20enUQLjJWZ8lYhKftXowmYL41t7spThnznJ7ihMG2/vUQ==" }, + "nextcloud-router": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/nextcloud-router/-/nextcloud-router-0.0.9.tgz", + "integrity": "sha512-w0i4xqFwJJuXNWFf9AB9huCWW5XmwdJHSHa7oXlOLTAvP9WxwU3KCm/mcKy8Eb0cT0ElRPg72HLUxl7oyEWoBQ==", + "requires": { + "core-js": "^3.1.4" + }, + "dependencies": { + "core-js": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.2.1.tgz", + "integrity": "sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw==" + } + } + }, "nextcloud-vue": { "version": "0.12.3", "resolved": "https://registry.npmjs.org/nextcloud-vue/-/nextcloud-vue-0.12.3.tgz", @@ -5936,9 +5716,9 @@ } }, "node-releases": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.29.tgz", - "integrity": "sha512-R5bDhzh6I+tpi/9i2hrrvGJ3yKPYzlVOORDkXhnZuwi5D3q1I5w4vYy24PJXTcLk9Q0kws9TO77T75bcK8/ysQ==", + "version": "1.1.30", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.30.tgz", + "integrity": "sha512-BHcr1g6NeUH12IL+X3Flvs4IOnl1TL0JczUhEZjDE+FXXPQcVCNr8NEPb01zqGxzhTpdyJL5GXemaCW7aw6Khw==", "dev": true, "requires": { "semver": "^5.3.0" @@ -6444,9 +6224,9 @@ "integrity": "sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA==" }, "portfinder": { - "version": "1.0.24", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.24.tgz", - "integrity": "sha512-ekRl7zD2qxYndYflwiryJwMioBI7LI7rVXg3EnLK3sjkouT5eOuhS3gS255XxBksa30VG8UPZYZCdgfGOfkSUg==", + "version": "1.0.23", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.23.tgz", + "integrity": "sha512-B729mL/uLklxtxuiJKfQ84WPxNw5a7Yhx3geQZdcA4GjNjZSTSSMMWyoennMVnTWSmAR0lMdzWYN0JLnHrg1KQ==", "requires": { "async": "^1.5.2", "debug": "^2.2.0", @@ -9284,7 +9064,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { diff --git a/package.json b/package.json index 09d0185e516..022db976dab 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "moment-timezone": "^0.5.26", "nextcloud-axios": "^0.2.1", "nextcloud-password-confirmation": "^0.4.2", + "nextcloud-router": "0.0.9", "nextcloud-vue": "^0.12.3", "nextcloud-vue-collections": "^0.5.6", "query-string": "^5.1.1", From 7683208dfa4cf5f0ff196ee0cabdacf8046592eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Tue, 10 Sep 2019 09:44:20 +0200 Subject: [PATCH 27/27] Workflow vue cleanup 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/FileSystemTag.vue | 11 +---------- .../Checks/MultiselectTag/MultiselectTag.vue | 11 ++++------- .../src/components/Checks/RequestTime.vue | 6 +----- .../src/components/Checks/RequestURL.vue | 17 +++++++++-------- .../src/components/Checks/RequestUserAgent.vue | 17 +++++++++-------- .../src/components/Checks/file.js | 3 ++- 7 files changed, 28 insertions(+), 41 deletions(-) diff --git a/apps/workflowengine/src/components/Check.vue b/apps/workflowengine/src/components/Check.vue index 905c2c989b1..06667b1a7ee 100644 --- a/apps/workflowengine/src/components/Check.vue +++ b/apps/workflowengine/src/components/Check.vue @@ -14,8 +14,8 @@ - - + + diff --git a/apps/workflowengine/src/components/Checks/FileSystemTag.vue b/apps/workflowengine/src/components/Checks/FileSystemTag.vue index 2875b64d48e..e2f66b30a4b 100644 --- a/apps/workflowengine/src/components/Checks/FileSystemTag.vue +++ b/apps/workflowengine/src/components/Checks/FileSystemTag.vue @@ -42,7 +42,6 @@ export default { }, data() { return { - valid: false, newValue: [] } }, @@ -62,16 +61,8 @@ export default { this.newValue = null } }, - validate() { - return true - }, update() { - if (this.validate()) { - this.$emit('input', this.newValue || '') - this.valid = false - } else { - this.valid = false - } + this.$emit('input', this.newValue || '') } } } diff --git a/apps/workflowengine/src/components/Checks/MultiselectTag/MultiselectTag.vue b/apps/workflowengine/src/components/Checks/MultiselectTag/MultiselectTag.vue index a046861b132..88b56a1d4e9 100644 --- a/apps/workflowengine/src/components/Checks/MultiselectTag/MultiselectTag.vue +++ b/apps/workflowengine/src/components/Checks/MultiselectTag/MultiselectTag.vue @@ -28,8 +28,7 @@ :custom-label="tagLabel" class="multiselect-vue" :multiple="multiple" :close-on-select="false" :tag-width="60" - :disabled="disabled" @input="update" - @search-change="asyncFind"> + :disabled="disabled" @input="update"> {{ t('core', 'No results') }}