Handle operator registration properly
Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
parent
ae55829989
commit
28a7721b2b
|
@ -89,11 +89,12 @@ export default {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
& > *:not(.icon-delete) {
|
& > *:not(.icon-delete) {
|
||||||
width: 200px;
|
width: 180px;
|
||||||
}
|
}
|
||||||
& > .multiselect,
|
& > .multiselect,
|
||||||
& > input[type=text] {
|
& > input[type=text] {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input[type=text] {
|
input[type=text] {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="operation.isComplex && operation.fixedEntity !== ''">
|
<div v-if="operation.isComplex && operation.fixedEntity !== ''" class="isComplex">
|
||||||
<img class="option__icon" :src="entity.icon">
|
<img class="option__icon" :src="entity.icon">
|
||||||
<span class="option__title option__title_single">{{ operation.triggerHint }}</span>
|
<span class="option__title option__title_single">{{ operation.triggerHint }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -60,7 +60,19 @@ export default {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="scss">
|
||||||
|
.isComplex {
|
||||||
|
img {
|
||||||
|
vertical-align: top;
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
padding-top: 2px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
.multiselect::v-deep .multiselect__single {
|
.multiselect::v-deep .multiselect__single {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.colored {
|
.colored {
|
||||||
|
background-color: var(--color-primary-element);
|
||||||
* {
|
* {
|
||||||
color: var(--color-primary-text)
|
color: var(--color-primary-text)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="section rule" :style="{ borderLeftColor: operation.color }">
|
<div class="section rule" :style="{ borderLeftColor: operation.color }">
|
||||||
<!-- TODO: icon-confirm -->
|
<!-- TODO: icon-confirm -->
|
||||||
<div class="trigger icon-confirm">
|
<div class="trigger">
|
||||||
<p>
|
<p>
|
||||||
<span>{{ t('workflowengine', 'When') }}</span>
|
<span>{{ t('workflowengine', 'When') }}</span>
|
||||||
<Event :rule="rule" @update="updateRule" />
|
<Event :rule="rule" @update="updateRule" />
|
||||||
|
@ -12,10 +12,11 @@
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<span />
|
<span />
|
||||||
<di<input v-if="lastCheckComplete" type="button" class="check--add"
|
<input v-if="lastCheckComplete" type="button" class="check--add"
|
||||||
value="Add a new filter" @click="rule.checks.push({class: null, operator: null, value: null})">
|
value="Add a new filter" @click="rule.checks.push({class: null, operator: null, value: null})">
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flow-icon icon-confirm"></div>
|
||||||
<div class="action">
|
<div class="action">
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<Actions>
|
<Actions>
|
||||||
|
@ -26,15 +27,15 @@
|
||||||
Remove rule
|
Remove rule
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
</Actions>
|
</Actions>
|
||||||
<button v-tooltip="ruleStatus.tooltip" class="status-button icon" :class="ruleStatus.class"
|
|
||||||
@click="saveRule">
|
|
||||||
{{ ruleStatus.title }}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<Operation :operation="operation" :colored="false">
|
<Operation :operation="operation" :colored="false">
|
||||||
<component :is="operation.options" v-if="operation.options" v-model="rule.operation"
|
<component :is="operation.options" v-if="operation.options" v-model="rule.operation"
|
||||||
@input="updateOperation" />
|
@input="updateOperation" />
|
||||||
</Operation>
|
</Operation>
|
||||||
|
<button v-tooltip="ruleStatus.tooltip" class="status-button icon" :class="ruleStatus.class"
|
||||||
|
@click="saveRule">
|
||||||
|
{{ ruleStatus.title }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -152,6 +153,8 @@ export default {
|
||||||
|
|
||||||
.status-button {
|
.status-button {
|
||||||
transition: 0.5s ease all;
|
transition: 0.5s ease all;
|
||||||
|
display: block;
|
||||||
|
margin: auto;
|
||||||
}
|
}
|
||||||
.status-button.primary {
|
.status-button.primary {
|
||||||
padding-left: 32px;
|
padding-left: 32px;
|
||||||
|
@ -166,15 +169,19 @@ export default {
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flow-icon {
|
||||||
|
width: 44px;
|
||||||
|
}
|
||||||
|
|
||||||
.rule {
|
.rule {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
border-left: 5px solid #fff;
|
border-left: 5px solid var(--color-primary-element);
|
||||||
|
|
||||||
.trigger, .action {
|
.trigger, .action {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
min-height: 100px;
|
min-height: 100px;
|
||||||
max-width: 900px;
|
max-width: 700px;
|
||||||
}
|
}
|
||||||
.action {
|
.action {
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
|
@ -214,10 +221,24 @@ export default {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
padding-left: 6px;
|
padding-left: 6px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width: 200px;
|
width: 180px;
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width:1400px) {
|
||||||
|
.rule {
|
||||||
|
&, .trigger, .action {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
.flow-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<input v-model="newValue" type="text" placeholder="1 MB"
|
<input v-model="newValue" type="text" placeholder="1 MB"
|
||||||
@input="$emit('input', newValue)">
|
@input="update">
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -8,11 +8,13 @@ export default {
|
||||||
name: 'SizeValue',
|
name: 'SizeValue',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: String
|
type: String,
|
||||||
|
default: '1 MB'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
valid: false,
|
||||||
newValue: this.value
|
newValue: this.value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -20,6 +22,19 @@ export default {
|
||||||
value() {
|
value() {
|
||||||
this.newValue = this.value
|
this.newValue = this.value
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
validate() {
|
||||||
|
return this.newValue.match(/^[0-9]+[ ]?[kmgt]?b$/i) !== null
|
||||||
|
},
|
||||||
|
update() {
|
||||||
|
if (this.validate()) {
|
||||||
|
this.$emit('input', this.newValue)
|
||||||
|
this.valid = false
|
||||||
|
} else {
|
||||||
|
this.valid = false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
import ConvertToPdf from './../components/Operations/ConvertToPdf'
|
|
||||||
import Tag from './../components/Operations/Tag'
|
|
||||||
|
|
||||||
const ALL_CHECKS = [
|
const ALL_CHECKS = [
|
||||||
'OCA\\WorkflowEngine\\Check\\FileMimeType',
|
'OCA\\WorkflowEngine\\Check\\FileMimeType',
|
||||||
'OCA\\WorkflowEngine\\Check\\FileName',
|
'OCA\\WorkflowEngine\\Check\\FileName',
|
||||||
|
@ -13,27 +10,10 @@ const ALL_CHECKS = [
|
||||||
'OCA\\WorkflowEngine\\Check\\UserGroupMembership'
|
'OCA\\WorkflowEngine\\Check\\UserGroupMembership'
|
||||||
]
|
]
|
||||||
|
|
||||||
const Operators = OCP.InitialState.loadState('workflowengine', 'operators')
|
const Operators = {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend operators for testing
|
* Extend operators for testing
|
||||||
*/
|
*/
|
||||||
Operators['OCA\\FilesAccessControl\\Operation'] = {
|
|
||||||
...Operators['OCA\\FilesAccessControl\\Operation'],
|
|
||||||
color: 'var(--color-error)',
|
|
||||||
entities: [
|
|
||||||
'OCA\\WorkflowEngine\\Entity\\File'
|
|
||||||
],
|
|
||||||
operation: 'deny'
|
|
||||||
}
|
|
||||||
Operators['OCA\\WorkflowPDFConverter\\Operation'] = {
|
|
||||||
id: 'OCA\\WorkflowPDFConverter\\Operation',
|
|
||||||
name: 'Convert to PDF',
|
|
||||||
description: 'Generate a PDF file',
|
|
||||||
color: '#dc5047',
|
|
||||||
iconClass: 'icon-convert-pdf',
|
|
||||||
options: ConvertToPdf
|
|
||||||
}
|
|
||||||
|
|
||||||
Operators['OCA\\TestExample\\Operation1'] = {
|
Operators['OCA\\TestExample\\Operation1'] = {
|
||||||
id: 'OCA\\TestExample\\Operation1',
|
id: 'OCA\\TestExample\\Operation1',
|
||||||
|
@ -51,14 +31,6 @@ Operators['OCA\\TestExample\\Operation2'] = {
|
||||||
color: 'var(--color-warning)',
|
color: 'var(--color-warning)',
|
||||||
operation: 'deny'
|
operation: 'deny'
|
||||||
}
|
}
|
||||||
Operators['OCA\\FilesAutomatedTagging\\Operation'] = {
|
|
||||||
id: 'OCA\\FilesAutomatedTagging\\Operation',
|
|
||||||
name: 'Tag a file',
|
|
||||||
description: 'Assign a tag to a file',
|
|
||||||
iconClass: 'icon-tag-white',
|
|
||||||
color: 'var(--color-primary)',
|
|
||||||
options: Tag
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Operators,
|
Operators,
|
||||||
|
|
|
@ -24,7 +24,7 @@ import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
import axios from 'nextcloud-axios'
|
import axios from 'nextcloud-axios'
|
||||||
import { getApiUrl } from './helpers/api'
|
import { getApiUrl } from './helpers/api'
|
||||||
import { ALL_CHECKS, Operators } from './services/Operation'
|
import { ALL_CHECKS } from './services/Operation'
|
||||||
import confirmPassword from 'nextcloud-password-confirmation'
|
import confirmPassword from 'nextcloud-password-confirmation'
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
@ -33,8 +33,7 @@ const store = new Vuex.Store({
|
||||||
state: {
|
state: {
|
||||||
rules: [],
|
rules: [],
|
||||||
scope: OCP.InitialState.loadState('workflowengine', 'scope'),
|
scope: OCP.InitialState.loadState('workflowengine', 'scope'),
|
||||||
// TODO: move to backend data
|
operations: OCP.InitialState.loadState('workflowengine', 'operators'),
|
||||||
operations: Operators,
|
|
||||||
|
|
||||||
plugins: Vue.observable({
|
plugins: Vue.observable({
|
||||||
checks: {},
|
checks: {},
|
||||||
|
@ -74,7 +73,10 @@ const store = new Vuex.Store({
|
||||||
Vue.set(state.plugins.checks, plugin.class, plugin)
|
Vue.set(state.plugins.checks, plugin.class, plugin)
|
||||||
},
|
},
|
||||||
addPluginOperator(state, plugin) {
|
addPluginOperator(state, plugin) {
|
||||||
Vue.set(state.plugins.operators, plugin.class, plugin)
|
plugin = Object.assign(
|
||||||
|
{ color: 'var(--color-primary-element)' },
|
||||||
|
plugin, state.operations[plugin.id] || {})
|
||||||
|
Vue.set(state.operations, plugin.id, plugin)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -88,7 +90,8 @@ const store = new Vuex.Store({
|
||||||
let entity = null
|
let entity = null
|
||||||
let events = []
|
let events = []
|
||||||
if (rule.isComplex === false && rule.fixedEntity === '') {
|
if (rule.isComplex === false && rule.fixedEntity === '') {
|
||||||
entity = context.state.entities.find((item) => rule.entities[0] === item.id)
|
entity = context.state.entities.find((item) => rule.entities && rule.entities[0] === item.id)
|
||||||
|
entity = entity ? entity : Object.values(context.state.entities)[0]
|
||||||
events = [entity.events[0].eventName]
|
events = [entity.events[0].eventName]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import store from './store'
|
||||||
|
|
||||||
import Settings from './components/Workflow'
|
import Settings from './components/Workflow'
|
||||||
import FileValues from './components/Values/file'
|
import FileValues from './components/Values/file'
|
||||||
|
import {Operators} from './services/Operation';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A plugin for displaying a custom value field for checks
|
* A plugin for displaying a custom value field for checks
|
||||||
|
@ -21,7 +22,7 @@ import FileValues from './components/Values/file'
|
||||||
* A plugin for extending the admin page repesentation of a operator
|
* A plugin for extending the admin page repesentation of a operator
|
||||||
*
|
*
|
||||||
* @typedef {Object} OperatorPlugin
|
* @typedef {Object} OperatorPlugin
|
||||||
* @property {string} class - The PHP class name of the check
|
* @property {string} id - The PHP class name of the check
|
||||||
* @property {string} operation - Default value for the operation field
|
* @property {string} operation - Default value for the operation field
|
||||||
* @property {string} color - Custom color code to be applied for the operator selector
|
* @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
|
* @property {Vue} component - A vue component to handle the rendering of options
|
||||||
|
@ -40,6 +41,8 @@ import FileValues from './components/Values/file'
|
||||||
* Public javascript api for apps to register custom plugins
|
* Public javascript api for apps to register custom plugins
|
||||||
*/
|
*/
|
||||||
window.OCA.WorkflowEngine = Object.assign({}, OCA.WorkflowEngine, {
|
window.OCA.WorkflowEngine = Object.assign({}, OCA.WorkflowEngine, {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {CheckPlugin} Plugin
|
* @param {CheckPlugin} Plugin
|
||||||
|
@ -58,6 +61,7 @@ window.OCA.WorkflowEngine = Object.assign({}, OCA.WorkflowEngine, {
|
||||||
|
|
||||||
// Register shipped checks for file entity
|
// Register shipped checks for file entity
|
||||||
FileValues.forEach((checkPlugin) => window.OCA.WorkflowEngine.registerCheck(checkPlugin))
|
FileValues.forEach((checkPlugin) => window.OCA.WorkflowEngine.registerCheck(checkPlugin))
|
||||||
|
Object.values(Operators).forEach((operatorPlugin) => window.OCA.WorkflowEngine.registerOperator(operatorPlugin))
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
Vue.prototype.t = t
|
Vue.prototype.t = t
|
||||||
|
|
Loading…
Reference in New Issue