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%;
|
||||
padding-right: 20px;
|
||||
& > *:not(.icon-delete) {
|
||||
width: 200px;
|
||||
width: 180px;
|
||||
}
|
||||
& > .multiselect,
|
||||
& > input[type=text] {
|
||||
margin-right: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
input[type=text] {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<div v-if="operation.isComplex && operation.fixedEntity !== ''">
|
||||
<div v-if="operation.isComplex && operation.fixedEntity !== ''" class="isComplex">
|
||||
<img class="option__icon" :src="entity.icon">
|
||||
<span class="option__title option__title_single">{{ operation.triggerHint }}</span>
|
||||
</div>
|
||||
|
@ -60,7 +60,19 @@ export default {
|
|||
}
|
||||
</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 {
|
||||
display: flex;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ export default {
|
|||
}
|
||||
|
||||
.colored {
|
||||
background-color: var(--color-primary-element);
|
||||
* {
|
||||
color: var(--color-primary-text)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="section rule" :style="{ borderLeftColor: operation.color }">
|
||||
<!-- TODO: icon-confirm -->
|
||||
<div class="trigger icon-confirm">
|
||||
<div class="trigger">
|
||||
<p>
|
||||
<span>{{ t('workflowengine', 'When') }}</span>
|
||||
<Event :rule="rule" @update="updateRule" />
|
||||
|
@ -12,10 +12,11 @@
|
|||
</p>
|
||||
<p>
|
||||
<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})">
|
||||
</p>
|
||||
</div>
|
||||
<div class="flow-icon icon-confirm"></div>
|
||||
<div class="action">
|
||||
<div class="buttons">
|
||||
<Actions>
|
||||
|
@ -26,15 +27,15 @@
|
|||
Remove rule
|
||||
</ActionButton>
|
||||
</Actions>
|
||||
<button v-tooltip="ruleStatus.tooltip" class="status-button icon" :class="ruleStatus.class"
|
||||
@click="saveRule">
|
||||
{{ ruleStatus.title }}
|
||||
</button>
|
||||
</div>
|
||||
<Operation :operation="operation" :colored="false">
|
||||
<component :is="operation.options" v-if="operation.options" v-model="rule.operation"
|
||||
@input="updateOperation" />
|
||||
</Operation>
|
||||
<button v-tooltip="ruleStatus.tooltip" class="status-button icon" :class="ruleStatus.class"
|
||||
@click="saveRule">
|
||||
{{ ruleStatus.title }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -152,6 +153,8 @@ export default {
|
|||
|
||||
.status-button {
|
||||
transition: 0.5s ease all;
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
.status-button.primary {
|
||||
padding-left: 32px;
|
||||
|
@ -166,15 +169,19 @@ export default {
|
|||
border: none;
|
||||
}
|
||||
|
||||
.flow-icon {
|
||||
width: 44px;
|
||||
}
|
||||
|
||||
.rule {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
border-left: 5px solid #fff;
|
||||
border-left: 5px solid var(--color-primary-element);
|
||||
|
||||
.trigger, .action {
|
||||
flex-grow: 1;
|
||||
min-height: 100px;
|
||||
max-width: 900px;
|
||||
max-width: 700px;
|
||||
}
|
||||
.action {
|
||||
max-width: 400px;
|
||||
|
@ -214,10 +221,24 @@ export default {
|
|||
background-color: transparent;
|
||||
padding-left: 6px;
|
||||
margin: 0;
|
||||
width: 200px;
|
||||
width: 180px;
|
||||
border-radius: var(--border-radius);
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
@media (max-width:1400px) {
|
||||
.rule {
|
||||
&, .trigger, .action {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
.flow-icon {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<input v-model="newValue" type="text" placeholder="1 MB"
|
||||
@input="$emit('input', newValue)">
|
||||
@input="update">
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -8,11 +8,13 @@ export default {
|
|||
name: 'SizeValue',
|
||||
props: {
|
||||
value: {
|
||||
type: String
|
||||
type: String,
|
||||
default: '1 MB'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
valid: false,
|
||||
newValue: this.value
|
||||
}
|
||||
},
|
||||
|
@ -20,6 +22,19 @@ export default {
|
|||
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>
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
import ConvertToPdf from './../components/Operations/ConvertToPdf'
|
||||
import Tag from './../components/Operations/Tag'
|
||||
|
||||
const ALL_CHECKS = [
|
||||
'OCA\\WorkflowEngine\\Check\\FileMimeType',
|
||||
'OCA\\WorkflowEngine\\Check\\FileName',
|
||||
|
@ -13,27 +10,10 @@ const ALL_CHECKS = [
|
|||
'OCA\\WorkflowEngine\\Check\\UserGroupMembership'
|
||||
]
|
||||
|
||||
const Operators = OCP.InitialState.loadState('workflowengine', 'operators')
|
||||
|
||||
const Operators = {}
|
||||
/**
|
||||
* 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'] = {
|
||||
id: 'OCA\\TestExample\\Operation1',
|
||||
|
@ -51,14 +31,6 @@ Operators['OCA\\TestExample\\Operation2'] = {
|
|||
color: 'var(--color-warning)',
|
||||
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 {
|
||||
Operators,
|
||||
|
|
|
@ -24,7 +24,7 @@ import Vue from 'vue'
|
|||
import Vuex from 'vuex'
|
||||
import axios from 'nextcloud-axios'
|
||||
import { getApiUrl } from './helpers/api'
|
||||
import { ALL_CHECKS, Operators } from './services/Operation'
|
||||
import { ALL_CHECKS } from './services/Operation'
|
||||
import confirmPassword from 'nextcloud-password-confirmation'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
@ -33,8 +33,7 @@ const store = new Vuex.Store({
|
|||
state: {
|
||||
rules: [],
|
||||
scope: OCP.InitialState.loadState('workflowengine', 'scope'),
|
||||
// TODO: move to backend data
|
||||
operations: Operators,
|
||||
operations: OCP.InitialState.loadState('workflowengine', 'operators'),
|
||||
|
||||
plugins: Vue.observable({
|
||||
checks: {},
|
||||
|
@ -74,7 +73,10 @@ const store = new Vuex.Store({
|
|||
Vue.set(state.plugins.checks, plugin.class, 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: {
|
||||
|
@ -88,7 +90,8 @@ const store = new Vuex.Store({
|
|||
let entity = null
|
||||
let events = []
|
||||
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]
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ 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
|
||||
|
@ -21,7 +22,7 @@ import FileValues from './components/Values/file'
|
|||
* 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} id - 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
|
||||
|
@ -40,6 +41,8 @@ import FileValues from './components/Values/file'
|
|||
* Public javascript api for apps to register custom plugins
|
||||
*/
|
||||
window.OCA.WorkflowEngine = Object.assign({}, OCA.WorkflowEngine, {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {CheckPlugin} Plugin
|
||||
|
@ -58,6 +61,7 @@ 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))
|
||||
|
||||
Vue.use(Vuex)
|
||||
Vue.prototype.t = t
|
||||
|
|
Loading…
Reference in New Issue