---
apps/workflowengine/src/components/Check.vue | 41 +++++++++++--
apps/workflowengine/src/components/Rule.vue | 4 +-
.../src/components/Values/FileMimeType.vue | 71 +++++++++++++++++++---
apps/workflowengine/src/components/Values/file.js | 30 +++++++++
apps/workflowengine/src/store.js | 6 +-
apps/workflowengine/src/workflowengine.js | 2 +
6 files changed, 140 insertions(+), 14 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 8583288016f..bd3c471fc3c 100644
--- a/apps/workflowengine/src/components/Check.vue
+++ b/apps/workflowengine/src/components/Check.vue
@@ -6,9 +6,9 @@
-
-
+
+
@@ -34,6 +34,10 @@ export default {
check: {
type: Object,
required: true
+ },
+ rule: {
+ type: Object,
+ required: true
}
},
data() {
@@ -41,7 +45,8 @@ export default {
deleteVisible: false,
currentOption: null,
currentOperator: null,
- options: []
+ options: [],
+ valid: true,
}
},
computed: {
@@ -56,6 +61,11 @@ export default {
if (!this.currentOption) { return [] }
const currentComponent = this.Checks[this.currentOption.class].component
return currentComponent
+ },
+ valuePlaceholder() {
+ if (this.currentOption && this.currentOption.placeholder) {
+ return this.currentOption.placeholder(this.check)
+ }
}
},
mounted() {
@@ -63,6 +73,11 @@ export default {
this.currentOption = this.Checks[this.check.class]
this.currentOperator = this.operators.find((operator) => operator.operator === this.check.operator)
},
+ watch: {
+ 'check.operator': function () {
+ this.validate()
+ }
+ },
methods: {
showDelete() {
this.deleteVisible = true
@@ -70,12 +85,27 @@ export default {
hideDelete() {
this.deleteVisible = false
},
+ validate() {
+ if (this.currentOption && this.currentOption.validate) {
+ if(this.currentOption.validate(this.check)) {
+ this.valid = true
+ } else {
+ this.valid = false
+ }
+ }
+ this.$store.dispatch('setValid', { rule: this.rule, valid: this.rule.valid && this.valid })
+ return this.valid
+ },
updateCheck() {
if (this.check.class !== this.currentOption.class) {
this.currentOperator = this.operators[0]
}
this.check.class = this.currentOption.class
this.check.operator = this.currentOperator.operator
+
+ if (!this.validate()) {
+ return
+ }
this.$emit('update', this.check)
}
}
@@ -107,4 +137,7 @@ export default {
margin-top: -5px;
margin-bottom: -5px;
}
+ .invalid {
+ border: 1px solid var(--color-error) !important;
+ }
diff --git a/apps/workflowengine/src/components/Rule.vue b/apps/workflowengine/src/components/Rule.vue
index f1551d985ca..88129525eb3 100644
--- a/apps/workflowengine/src/components/Rule.vue
+++ b/apps/workflowengine/src/components/Rule.vue
@@ -8,7 +8,7 @@
{{ t('workflowengine', 'and') }}
-
+
@@ -74,7 +74,7 @@ export default {
return this.$store.getters.getOperationForRule(this.rule)
},
ruleStatus() {
- if (this.error) {
+ if (this.error || !this.rule.valid) {
return {
title: t('workflowengine', 'The configuration is invalid'),
class: 'icon-close-white invalid',
diff --git a/apps/workflowengine/src/components/Values/FileMimeType.vue b/apps/workflowengine/src/components/Values/FileMimeType.vue
index 75729af8073..56d8aa6098e 100644
--- a/apps/workflowengine/src/components/Values/FileMimeType.vue
+++ b/apps/workflowengine/src/components/Values/FileMimeType.vue
@@ -1,47 +1,104 @@
-
+
+
+
+
+
+ {{ props.option.label }}
+
+
+
+ {{ props.option.label }}
+
+
+
+
diff --git a/apps/workflowengine/src/components/Values/file.js b/apps/workflowengine/src/components/Values/file.js
index 4a473dbc13c..fa6851cc5c2 100644
--- a/apps/workflowengine/src/components/Values/file.js
+++ b/apps/workflowengine/src/components/Values/file.js
@@ -40,6 +40,36 @@ const FileChecks = Object.values(OCA.WorkflowEngine.Plugins).map((plugin) => {
// new way of registering checks
+
+const validateRegex = function(string) {
+ var regexRegex = /^\/(.*)\/([gui]{0,3})$/
+ var result = regexRegex.exec(string)
+ return result !== null
+}
+
+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: (check) => {
+ if (check.operator === 'matches' || check.operator === '!matches') {
+ return validateRegex(check.value)
+ }
+ return true
+ }
+})
+
FileChecks.push({
class: 'OCA\\WorkflowEngine\\Check\\FileMimeType',
name: t('workflowengine', 'File MIME type'),
diff --git a/apps/workflowengine/src/store.js b/apps/workflowengine/src/store.js
index b38bef0e6ea..a6af51b65d8 100644
--- a/apps/workflowengine/src/store.js
+++ b/apps/workflowengine/src/store.js
@@ -58,7 +58,7 @@ const store = new Vuex.Store({
},
mutations: {
addRule(state, rule) {
- state.rules.push(rule)
+ state.rules.push({ ...rule, valid: true })
},
updateRule(state, rule) {
const index = state.rules.findIndex((item) => rule.id === item.id)
@@ -129,6 +129,10 @@ const store = new Vuex.Store({
await confirmPassword()
await axios.delete(getApiUrl(`/${rule.id}`))
context.commit('removeRule', rule)
+ },
+ setValid (context, { rule, valid }) {
+ rule.valid = valid
+ context.commit('updateRule', rule)
}
},
getters: {
diff --git a/apps/workflowengine/src/workflowengine.js b/apps/workflowengine/src/workflowengine.js
index cae85c3c24a..6f96f454262 100644
--- a/apps/workflowengine/src/workflowengine.js
+++ b/apps/workflowengine/src/workflowengine.js
@@ -16,6 +16,8 @@ import {Operators} from './services/Operation';
* 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
+ * @property {callable} placeholder - Return a placeholder of no custom component is used
+ * @property {callable} validate - validate a check if no custom component is used
**/
/**
--
cgit v1.2.3
From d6b3af9d776c224015f9e9d8a4d858acae6f8560 Mon Sep 17 00:00:00 2001
From: Julius Härtl
Date: Fri, 6 Sep 2019 13:47:11 +0200
Subject: Load checks from the 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 | 6 ++---
apps/workflowengine/src/components/Rule.vue | 2 +-
apps/workflowengine/src/services/Operation.js | 38 ---------------------------
apps/workflowengine/src/store.js | 26 +++++++++++-------
apps/workflowengine/src/workflowengine.js | 25 ++++++++++++++++--
5 files changed, 44 insertions(+), 53 deletions(-)
delete mode 100644 apps/workflowengine/src/services/Operation.js
(limited to 'apps/workflowengine/src/workflowengine.js')
diff --git a/apps/workflowengine/src/components/Check.vue b/apps/workflowengine/src/components/Check.vue
index bd3c471fc3c..e521dffbb29 100644
--- a/apps/workflowengine/src/components/Check.vue
+++ b/apps/workflowengine/src/components/Check.vue
@@ -50,9 +50,9 @@ export default {
}
},
computed: {
- ...mapState({
- Checks: (state) => state.plugins.checks
- }),
+ Checks() {
+ return this.$store.getters.getChecksForEntity(this.rule.entity)
+ },
operators() {
if (!this.currentOption) { return [] }
return this.Checks[this.currentOption.class].operators
diff --git a/apps/workflowengine/src/components/Rule.vue b/apps/workflowengine/src/components/Rule.vue
index fab79109516..36616e9910a 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/services/Operation.js b/apps/workflowengine/src/services/Operation.js
deleted file mode 100644
index 58c20d6db14..00000000000
--- a/apps/workflowengine/src/services/Operation.js
+++ /dev/null
@@ -1,38 +0,0 @@
-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 Operators = {}
-/**
- * Extend operators for testing
- */
-
-Operators['OCA\\TestExample\\Operation1'] = {
- id: 'OCA\\TestExample\\Operation1',
- name: 'Rename file',
- description: '🚧 For UI mocking only',
- iconClass: 'icon-address-white',
- color: 'var(--color-success)',
- operation: 'deny'
-}
-Operators['OCA\\TestExample\\Operation2'] = {
- id: 'OCA\\TestExample\\Operation2',
- name: 'Notify me',
- description: '🚧 For UI mocking only',
- iconClass: 'icon-comment-white',
- color: 'var(--color-warning)',
- operation: 'deny'
-}
-
-export {
- Operators,
- ALL_CHECKS
-}
diff --git a/apps/workflowengine/src/store.js b/apps/workflowengine/src/store.js
index a6af51b65d8..75e53149ea2 100644
--- a/apps/workflowengine/src/store.js
+++ b/apps/workflowengine/src/store.js
@@ -24,7 +24,6 @@ import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'nextcloud-axios'
import { getApiUrl } from './helpers/api'
-import { ALL_CHECKS } from './services/Operation'
import confirmPassword from 'nextcloud-password-confirmation'
Vue.use(Vuex)
@@ -40,13 +39,7 @@ const store = new Vuex.Store({
operators: {}
}),
- entities: OCP.InitialState.loadState('workflowengine', 'entities').map(entity => {
- return {
- ...entity,
- // TODO: move to backend data once checks are provided
- checks: [...ALL_CHECKS]
- }
- }),
+ entities: OCP.InitialState.loadState('workflowengine', 'entities'),
events: OCP.InitialState.loadState('workflowengine', 'entities')
.map((entity) => entity.events.map(event => {
return {
@@ -54,7 +47,8 @@ const store = new Vuex.Store({
entity,
...event
}
- })).flat()
+ })).flat(),
+ checks: OCP.InitialState.loadState('workflowengine', 'checks')
},
mutations: {
addRule(state, rule) {
@@ -149,6 +143,20 @@ const store = new Vuex.Store({
},
getEventsForOperation(state) {
return (operation) => state.events
+ },
+ /**
+ * Return all available checker plugins for a given entity class
+ */
+ getChecksForEntity(state) {
+ return (entity) => {
+ return state.checks
+ .filter((check) => check.supportedEntities.indexOf(entity) > -1 || check.supportedEntities.length === 0)
+ .map((check) => state.plugins.checks[check.id])
+ .reduce((obj, item) => {
+ obj[item.class] = item
+ return obj
+ }, {})
+ }
}
}
})
diff --git a/apps/workflowengine/src/workflowengine.js b/apps/workflowengine/src/workflowengine.js
index 6f96f454262..e05ac0a5053 100644
--- a/apps/workflowengine/src/workflowengine.js
+++ b/apps/workflowengine/src/workflowengine.js
@@ -4,7 +4,6 @@ import store from './store'
import Settings from './components/Workflow'
import FileValues from './components/Values/file'
-import {Operators} from './services/Operation';
/**
* A plugin for displaying a custom value field for checks
@@ -63,7 +62,29 @@ window.OCA.WorkflowEngine = Object.assign({}, OCA.WorkflowEngine, {
// Register shipped checks for file entity
FileValues.forEach((checkPlugin) => window.OCA.WorkflowEngine.registerCheck(checkPlugin))
-Object.values(Operators).forEach((operatorPlugin) => window.OCA.WorkflowEngine.registerOperator(operatorPlugin))
+
+/**
+ * FIXME: remove before merge as this is for UI testing only
+ */
+const demo = [
+ {
+ id: 'OCA\\TestExample\\Operation1',
+ name: 'Rename file',
+ description: '🚧 For UI mocking only',
+ iconClass: 'icon-address-white',
+ color: 'var(--color-success)',
+ operation: 'deny'
+ },
+ {
+ id: 'OCA\\TestExample\\Operation2',
+ name: 'Notify me',
+ description: '🚧 For UI mocking only',
+ iconClass: 'icon-comment-white',
+ color: 'var(--color-warning)',
+ operation: 'deny'
+ }
+]
+demo.forEach((operatorPlugin) => window.OCA.WorkflowEngine.registerOperator(operatorPlugin))
Vue.use(Vuex)
Vue.prototype.t = t
--
cgit v1.2.3
From 98666a9f4d79a1d2bb8e9be318946e99bdcaa8b8 Mon Sep 17 00:00:00 2001
From: Julius Härtl
Date: Fri, 6 Sep 2019 16:23:45 +0200
Subject: Move over checker plugins
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 | 5 +-
.../src/components/Checks/FileMimeType.vue | 103 ++++++++++++++++
.../src/components/Checks/FileSystemTag.vue | 68 +++++++++++
.../src/components/Checks/RequestTime.vue | 94 +++++++++++++++
.../src/components/Checks/RequestUserAgent.vue | 122 +++++++++++++++++++
apps/workflowengine/src/components/Checks/file.js | 102 ++++++++++++++++
apps/workflowengine/src/components/Checks/index.js | 26 ++++
.../src/components/Checks/request.js | 70 +++++++++++
apps/workflowengine/src/components/Event.vue | 2 +-
apps/workflowengine/src/components/Rule.vue | 4 +-
.../src/components/Values/FileMimeType.vue | 104 ----------------
.../src/components/Values/SizeValue.vue | 44 -------
apps/workflowengine/src/components/Values/file.js | 133 ---------------------
apps/workflowengine/src/helpers/validators.js | 49 ++++++++
apps/workflowengine/src/workflowengine.js | 16 ++-
15 files changed, 648 insertions(+), 294 deletions(-)
create mode 100644 apps/workflowengine/src/components/Checks/FileMimeType.vue
create mode 100644 apps/workflowengine/src/components/Checks/FileSystemTag.vue
create mode 100644 apps/workflowengine/src/components/Checks/RequestTime.vue
create mode 100644 apps/workflowengine/src/components/Checks/RequestUserAgent.vue
create mode 100644 apps/workflowengine/src/components/Checks/file.js
create mode 100644 apps/workflowengine/src/components/Checks/index.js
create mode 100644 apps/workflowengine/src/components/Checks/request.js
delete mode 100644 apps/workflowengine/src/components/Values/FileMimeType.vue
delete mode 100644 apps/workflowengine/src/components/Values/SizeValue.vue
delete mode 100644 apps/workflowengine/src/components/Values/file.js
create mode 100644 apps/workflowengine/src/helpers/validators.js
(limited to 'apps/workflowengine/src/workflowengine.js')
diff --git a/apps/workflowengine/src/components/Check.vue b/apps/workflowengine/src/components/Check.vue
index e521dffbb29..508b8a4a1f4 100644
--- a/apps/workflowengine/src/components/Check.vue
+++ b/apps/workflowengine/src/components/Check.vue
@@ -16,9 +16,10 @@
+
+
diff --git a/apps/workflowengine/src/components/Checks/FileSystemTag.vue b/apps/workflowengine/src/components/Checks/FileSystemTag.vue
new file mode 100644
index 00000000000..b8c24bf118a
--- /dev/null
+++ b/apps/workflowengine/src/components/Checks/FileSystemTag.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
diff --git a/apps/workflowengine/src/components/Checks/RequestTime.vue b/apps/workflowengine/src/components/Checks/RequestTime.vue
new file mode 100644
index 00000000000..2f09693232a
--- /dev/null
+++ b/apps/workflowengine/src/components/Checks/RequestTime.vue
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/workflowengine/src/components/Checks/RequestUserAgent.vue b/apps/workflowengine/src/components/Checks/RequestUserAgent.vue
new file mode 100644
index 00000000000..676a4c23178
--- /dev/null
+++ b/apps/workflowengine/src/components/Checks/RequestUserAgent.vue
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+ {{ props.option.label }}
+
+
+
+ {{ props.option.label }}
+
+
+
+
+
+
+
+
+
diff --git a/apps/workflowengine/src/components/Checks/file.js b/apps/workflowengine/src/components/Checks/file.js
new file mode 100644
index 00000000000..146ac045cee
--- /dev/null
+++ b/apps/workflowengine/src/components/Checks/file.js
@@ -0,0 +1,102 @@
+/*
+ * @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 FileMimeType from './FileMimeType';
+import { stringValidator, validateIPv4, validateIPv6} from './../../helpers/validators'
+const FileChecks = [
+ {
+ 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
+ },
+
+ {
+ 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
+ },
+
+ {
+ 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
+ },
+
+ {
+ 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)
+ }
+ },
+
+ {
+ class: 'OCA\\WorkflowEngine\\Check\\FileSystemTags',
+ name: t('workflowengine', 'File system tag'),
+ operators: [
+ { operator: 'is', name: t('workflowengine', 'is tagged with') },
+ { operator: '!is', name: t('workflowengine', 'is not tagged with') }
+ ]
+ }
+]
+
+export default FileChecks
diff --git a/apps/workflowengine/src/components/Checks/index.js b/apps/workflowengine/src/components/Checks/index.js
new file mode 100644
index 00000000000..d20472111b5
--- /dev/null
+++ b/apps/workflowengine/src/components/Checks/index.js
@@ -0,0 +1,26 @@
+/*
+ * @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 FileChecks from './file'
+import RequestChecks from './request'
+
+export default [...FileChecks, ...RequestChecks]
diff --git a/apps/workflowengine/src/components/Checks/request.js b/apps/workflowengine/src/components/Checks/request.js
new file mode 100644
index 00000000000..d2e4eaa3565
--- /dev/null
+++ b/apps/workflowengine/src/components/Checks/request.js
@@ -0,0 +1,70 @@
+/*
+ * @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 RequestUserAgent from './RequestUserAgent';
+import RequestTime from './RequestTime';
+
+const RequestChecks = [
+ {
+ class: 'OCA\\WorkflowEngine\\Check\\RequestURL',
+ name: t('workflowengine', 'Request URL'),
+ 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') }
+ ],
+ // TODO: implement component
+ },
+ {
+ class: 'OCA\\WorkflowEngine\\Check\\RequestTime',
+ name: t('workflowengine', 'Request time'),
+ operators: [
+ { operator: 'in', name: t('workflowengine', 'between') },
+ { operator: '!in', name: t('workflowengine', 'not between') }
+ ],
+ // TODO: implement component
+ component: RequestTime
+ },
+ {
+ class: 'OCA\\WorkflowEngine\\Check\\RequestUserAgent',
+ name: t('workflowengine', 'Request user agent'),
+ 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: RequestUserAgent
+ },
+ {
+ class: 'OCA\\WorkflowEngine\\Check\\UserGroupMembership',
+ name: t('workflowengine', 'User group membership'),
+ operators: [
+ { operator: 'is', name: t('workflowengine', 'is member of') },
+ { operator: '!is', name: t('workflowengine', 'is not member of') }
+ ],
+ // TODO: implement component
+ }
+]
+
+export default RequestChecks
diff --git a/apps/workflowengine/src/components/Event.vue b/apps/workflowengine/src/components/Event.vue
index 5ff59882b9a..ea153758c74 100644
--- a/apps/workflowengine/src/components/Event.vue
+++ b/apps/workflowengine/src/components/Event.vue
@@ -20,7 +20,7 @@
-
-
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 @@
-
- item.id))" />
-
-
-
-
-
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 @@
-
{{ t('workflowengine', 'When') }}
@@ -21,10 +20,10 @@
@@ -204,6 +203,7 @@ export default {
}
}
.trigger p, .action p {
+ min-height: 34px;
display: flex;
align-items: center;
@@ -211,7 +211,9 @@ export default {
min-width: 50px;
text-align: right;
color: var(--color-text-maxcontrast);
- padding-right: 5px;
+ padding-right: 10px;
+ padding-top: 7px;
+ margin-bottom: auto;
}
.multiselect {
flex-grow: 1;
diff --git a/apps/workflowengine/src/components/Workflow.vue b/apps/workflowengine/src/components/Workflow.vue
index 986b6f5197c..b4fab5a058c 100644
--- a/apps/workflowengine/src/components/Workflow.vue
+++ b/apps/workflowengine/src/components/Workflow.vue
@@ -80,15 +80,11 @@ export default {
flex-wrap: wrap;
max-width: 900px;
.actions__item {
- max-width: 290px;
+ max-width: 280px;
flex-basis: 250px;
}
}
- .actions__more {
- text-align: center;
- }
-
button.icon {
padding-left: 32px;
background-position: 10px center;
diff --git a/apps/workflowengine/src/workflowengine.js b/apps/workflowengine/src/workflowengine.js
index 149f9d4aa85..2eb8161fc87 100644
--- a/apps/workflowengine/src/workflowengine.js
+++ b/apps/workflowengine/src/workflowengine.js
@@ -61,29 +61,6 @@ window.OCA.WorkflowEngine = Object.assign({}, OCA.WorkflowEngine, {
// Register shipped checks
ShippedChecks.forEach((checkPlugin) => window.OCA.WorkflowEngine.registerCheck(checkPlugin))
-/**
- * FIXME: remove before merge as this is for UI testing only
- */
-const demo = [
- {
- id: 'OCA\\TestExample\\Operation1',
- 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: 'Send a Nextcloud Notification',
- iconClass: 'icon-comment-white',
- color: 'var(--color-warning)',
- operation: 'deny'
- }
-]
-demo.forEach((operatorPlugin) => window.OCA.WorkflowEngine.registerOperator(operatorPlugin))
-
Vue.use(Vuex)
Vue.prototype.t = t
diff --git a/apps/workflowengine/webpack.js b/apps/workflowengine/webpack.js
index 76e46261f93..bbd5efa9799 100644
--- a/apps/workflowengine/webpack.js
+++ b/apps/workflowengine/webpack.js
@@ -7,17 +7,5 @@ module.exports = {
publicPath: '/js/',
filename: 'workflowengine.js',
jsonpFunction: 'webpackJsonpWorkflowengine'
- },
- module: {
- rules: [
- {
- test: /\.handlebars/,
- loader: "handlebars-loader",
- query: {
- extensions: '.handlebars',
- helperDirs: path.join(__dirname, 'src/hbs_helpers'),
- }
- }
- ]
}
}
--
cgit v1.2.3