Move to vuex store
Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
parent
aa00f401b3
commit
bd281daa47
|
@ -1,385 +0,0 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2016 Morris Jobke <hey@morrisjobke.de>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import OperationTemplate from './templates/operation.handlebars';
|
||||
import OperationsTemplate from './templates/operations.handlebars';
|
||||
|
||||
(function() {
|
||||
OCA.WorkflowEngine = _.extend(OCA.WorkflowEngine || {}, {
|
||||
availablePlugins: [],
|
||||
availableChecks: [],
|
||||
|
||||
getCheckByClass: function(className) {
|
||||
var length = OCA.WorkflowEngine.availableChecks.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (OCA.WorkflowEngine.availableChecks[i]['class'] === className) {
|
||||
return OCA.WorkflowEngine.availableChecks[i];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 888b d888 888 888
|
||||
* 8888b d8888 888 888
|
||||
* 88888b.d88888 888 888
|
||||
* 888Y88888P888 .d88b. .d88888 .d88b. 888 .d8888b
|
||||
* 888 Y888P 888 d88""88b d88" 888 d8P Y8b 888 88K
|
||||
* 888 Y8P 888 888 888 888 888 88888888 888 "Y8888b.
|
||||
* 888 " 888 Y88..88P Y88b 888 Y8b. 888 X88
|
||||
* 888 888 "Y88P" "Y88888 "Y8888 888 88888P'
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class OCA.WorkflowEngine.Operation
|
||||
*/
|
||||
OCA.WorkflowEngine.Operation =
|
||||
OC.Backbone.Model.extend({
|
||||
defaults: {
|
||||
'class': 'OCA\\WorkflowEngine\\Operation',
|
||||
'name': '',
|
||||
'checks': [],
|
||||
'operation': ''
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* .d8888b. 888 888 888 d8b
|
||||
* d88P Y88b 888 888 888 Y8P
|
||||
* 888 888 888 888 888
|
||||
* 888 .d88b. 888 888 .d88b. .d8888b 888888 888 .d88b. 88888b. .d8888b
|
||||
* 888 d88""88b 888 888 d8P Y8b d88P" 888 888 d88""88b 888 "88b 88K
|
||||
* 888 888 888 888 888 888 88888888 888 888 888 888 888 888 888 "Y8888b.
|
||||
* Y88b d88P Y88..88P 888 888 Y8b. Y88b. Y88b. 888 Y88..88P 888 888 X88
|
||||
* "Y8888P" "Y88P" 888 888 "Y8888 "Y8888P "Y888 888 "Y88P" 888 888 88888P'
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class OCA.WorkflowEngine.OperationsCollection
|
||||
*
|
||||
* collection for all configurated operations
|
||||
*/
|
||||
OCA.WorkflowEngine.OperationsCollection =
|
||||
OC.Backbone.Collection.extend({
|
||||
model: OCA.WorkflowEngine.Operation,
|
||||
url: OC.generateUrl('apps/workflowengine/operations')
|
||||
});
|
||||
|
||||
/**
|
||||
* 888 888 d8b
|
||||
* 888 888 Y8P
|
||||
* 888 888
|
||||
* Y88b d88P 888 .d88b. 888 888 888 .d8888b
|
||||
* Y88b d88P 888 d8P Y8b 888 888 888 88K
|
||||
* Y88o88P 888 88888888 888 888 888 "Y8888b.
|
||||
* Y888P 888 Y8b. Y88b 888 d88P X88
|
||||
* Y8P 888 "Y8888 "Y8888888P" 88888P'
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class OCA.WorkflowEngine.OperationView
|
||||
*
|
||||
* this creates the view for a single operation
|
||||
*/
|
||||
OCA.WorkflowEngine.OperationView =
|
||||
OC.Backbone.View.extend({
|
||||
templateId: '#operation-template',
|
||||
events: {
|
||||
'change .check-class': 'checkChanged',
|
||||
'change .check-operator': 'checkChanged',
|
||||
'change .check-value': 'checkChanged',
|
||||
'change .operation-name': 'operationChanged',
|
||||
'change .operation-operation': 'operationChanged',
|
||||
'click .button-reset': 'reset',
|
||||
'click .button-save': 'save',
|
||||
'click .button-add': 'add',
|
||||
'click .button-delete': 'delete',
|
||||
'click .button-delete-check': 'deleteCheck'
|
||||
},
|
||||
originalModel: null,
|
||||
hasChanged: false,
|
||||
message: '',
|
||||
errorMessage: '',
|
||||
saving: false,
|
||||
groups: [],
|
||||
template: function(vars) {
|
||||
return OperationTemplate(_.extend(
|
||||
{
|
||||
shortRuleDescTXT: t('workflowengine', 'Short rule description'),
|
||||
addRuleTXT: t('workflowengine', 'Add rule'),
|
||||
resetTXT: t('workflowengine', 'Reset'),
|
||||
saveTXT: t('workflowengine', 'Save'),
|
||||
savingTXT: t('workflowengine', 'Saving…')
|
||||
},
|
||||
vars
|
||||
));
|
||||
},
|
||||
initialize: function() {
|
||||
// this creates a new copy of the object to definitely have a new reference and being able to reset the model
|
||||
this.originalModel = JSON.parse(JSON.stringify(this.model));
|
||||
this.model.on('change', function() {
|
||||
console.log('model changed');
|
||||
this.hasChanged = true;
|
||||
this.render();
|
||||
}, this);
|
||||
|
||||
if (this.model.get('id') === undefined) {
|
||||
this.hasChanged = true;
|
||||
}
|
||||
var self = this;
|
||||
$.ajax({
|
||||
url: OC.linkToOCS('cloud/groups', 2) + 'details',
|
||||
dataType: 'json',
|
||||
quietMillis: 100,
|
||||
}).success(function(data) {
|
||||
if (data.ocs.data.groups && data.ocs.data.groups.length > 0) {
|
||||
|
||||
data.ocs.data.groups.forEach(function(group) {
|
||||
self.groups.push({ id: group.id, displayname: group.displayname });
|
||||
});
|
||||
self.render();
|
||||
|
||||
} else {
|
||||
OC.Notification.error(t('workflowengine', 'Group list is empty'), { type: 'error' });
|
||||
console.log(data);
|
||||
}
|
||||
}).error(function(data) {
|
||||
OC.Notification.error(t('workflowengine', 'Unable to retrieve the group list'), { type: 'error' });
|
||||
console.log(data);
|
||||
});
|
||||
},
|
||||
delete: function() {
|
||||
if (OC.PasswordConfirmation.requiresPasswordConfirmation()) {
|
||||
OC.PasswordConfirmation.requirePasswordConfirmation(_.bind(this.delete, this));
|
||||
return;
|
||||
}
|
||||
|
||||
this.model.destroy();
|
||||
this.remove();
|
||||
},
|
||||
reset: function() {
|
||||
this.hasChanged = false;
|
||||
// silent is need to not trigger the change event which resets the hasChanged attribute
|
||||
this.model.set(this.originalModel, { silent: true });
|
||||
this.render();
|
||||
},
|
||||
save: function() {
|
||||
if (OC.PasswordConfirmation.requiresPasswordConfirmation()) {
|
||||
OC.PasswordConfirmation.requirePasswordConfirmation(_.bind(this.save, this));
|
||||
return;
|
||||
}
|
||||
|
||||
var success = function(model, response, options) {
|
||||
this.saving = false;
|
||||
this.originalModel = JSON.parse(JSON.stringify(this.model));
|
||||
|
||||
this.message = t('workflowengine', 'Saved');
|
||||
this.errorMessage = '';
|
||||
this.render();
|
||||
};
|
||||
var error = function(model, response, options) {
|
||||
this.saving = false;
|
||||
this.hasChanged = true;
|
||||
|
||||
this.message = t('workflowengine', 'Saving failed:');
|
||||
this.errorMessage = response.responseText;
|
||||
this.render();
|
||||
};
|
||||
this.hasChanged = false;
|
||||
this.saving = true;
|
||||
this.render();
|
||||
this.model.save(null, { success: success, error: error, context: this });
|
||||
},
|
||||
add: function() {
|
||||
var checks = _.clone(this.model.get('checks')),
|
||||
classname = OCA.WorkflowEngine.availableChecks[0]['class'],
|
||||
operators = OCA.WorkflowEngine.availableChecks[0]['operators'];
|
||||
|
||||
checks.push({
|
||||
'class': classname,
|
||||
'operator': operators[0]['operator'],
|
||||
'value': ''
|
||||
});
|
||||
this.model.set({ 'checks': checks });
|
||||
},
|
||||
checkChanged: function(event) {
|
||||
var value = event.target.value,
|
||||
id = $(event.target.parentElement).data('id'),
|
||||
// this creates a new copy of the object to definitely have a new reference
|
||||
checks = JSON.parse(JSON.stringify(this.model.get('checks'))),
|
||||
key = null;
|
||||
|
||||
for (var i = 0; i < event.target.classList.length; i++) {
|
||||
var className = event.target.classList[i];
|
||||
if (className.substr(0, 'check-'.length) === 'check-') {
|
||||
key = className.substr('check-'.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (key === null) {
|
||||
console.warn('checkChanged triggered but element doesn\'t have any "check-" class');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_.has(checks[id], key)) {
|
||||
console.warn('key "' + key + '" is not available in check', check);
|
||||
return;
|
||||
}
|
||||
|
||||
checks[id][key] = value;
|
||||
// if the class is changed most likely also the operators have changed
|
||||
// with this we set the operator to the first possible operator
|
||||
if (key === 'class') {
|
||||
var check = OCA.WorkflowEngine.getCheckByClass(value);
|
||||
if (!_.isUndefined(check)) {
|
||||
checks[id]['operator'] = check['operators'][0]['operator'];
|
||||
checks[id]['value'] = '';
|
||||
}
|
||||
}
|
||||
// model change will trigger render
|
||||
this.model.set({ 'checks': checks });
|
||||
},
|
||||
deleteCheck: function(event) {
|
||||
console.log(arguments);
|
||||
var id = $(event.target.parentElement).data('id'),
|
||||
checks = JSON.parse(JSON.stringify(this.model.get('checks')));
|
||||
|
||||
// splice removes 1 element at index `id`
|
||||
checks.splice(id, 1);
|
||||
// model change will trigger render
|
||||
this.model.set({ 'checks': checks });
|
||||
},
|
||||
operationChanged: function(event) {
|
||||
var value = event.target.value,
|
||||
key = null;
|
||||
|
||||
for (var i = 0; i < event.target.classList.length; i++) {
|
||||
var className = event.target.classList[i];
|
||||
if (className.substr(0, 'operation-'.length) === 'operation-') {
|
||||
key = className.substr('operation-'.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (key === null) {
|
||||
console.warn('operationChanged triggered but element doesn\'t have any "operation-" class');
|
||||
return;
|
||||
}
|
||||
|
||||
if (key !== 'name' && key !== 'operation') {
|
||||
console.warn('key "' + key + '" is no valid attribute');
|
||||
return;
|
||||
}
|
||||
|
||||
// model change will trigger render
|
||||
this.model.set(key, value);
|
||||
},
|
||||
render: function() {
|
||||
this.$el.html(this.template({
|
||||
operation: this.model.toJSON(),
|
||||
classes: OCA.WorkflowEngine.availableChecks,
|
||||
hasChanged: this.hasChanged,
|
||||
message: this.message,
|
||||
errorMessage: this.errorMessage,
|
||||
saving: this.saving
|
||||
}));
|
||||
|
||||
var checks = this.model.get('checks');
|
||||
_.each(this.$el.find('.check'), function(element) {
|
||||
var $element = $(element),
|
||||
id = $element.data('id'),
|
||||
check = checks[id],
|
||||
valueElement = $element.find('.check-value').first();
|
||||
var self = this;
|
||||
|
||||
_.each(OCA.WorkflowEngine.availablePlugins, function(plugin) {
|
||||
if (_.isFunction(plugin.render)) {
|
||||
plugin.render(valueElement, check, self.groups);
|
||||
}
|
||||
});
|
||||
}, this);
|
||||
|
||||
if (this.message !== '') {
|
||||
// hide success messages after some time
|
||||
_.delay(function(elements) {
|
||||
$(elements).css('opacity', 0);
|
||||
}, 7000, this.$el.find('.msg.success'));
|
||||
this.message = '';
|
||||
}
|
||||
|
||||
return this.$el;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @class OCA.WorkflowEngine.OperationsView
|
||||
*
|
||||
* this creates the view for configured operations
|
||||
*/
|
||||
OCA.WorkflowEngine.OperationsView =
|
||||
OC.Backbone.View.extend({
|
||||
templateId: '#operations-template',
|
||||
collection: null,
|
||||
$el: null,
|
||||
events: {
|
||||
'click .button-add-operation': 'add'
|
||||
},
|
||||
template: function(vars) {
|
||||
return OperationsTemplate(_.extend(
|
||||
{
|
||||
addRuleGroupTXT: t('workflowengine', 'Add rule group')
|
||||
},
|
||||
vars
|
||||
));
|
||||
},
|
||||
initialize: function(classname) {
|
||||
if (!OCA.WorkflowEngine.availablePlugins.length) {
|
||||
OCA.WorkflowEngine.availablePlugins = OC.Plugins.getPlugins('OCA.WorkflowEngine.CheckPlugins');
|
||||
_.each(OCA.WorkflowEngine.availablePlugins, function(plugin) {
|
||||
if (_.isFunction(plugin.getCheck)) {
|
||||
OCA.WorkflowEngine.availableChecks.push(plugin.getCheck(classname));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.collection.fetch({
|
||||
data: {
|
||||
'class': classname
|
||||
}
|
||||
});
|
||||
this.collection.once('sync', this.render, this);
|
||||
},
|
||||
add: function() {
|
||||
var operation = this.collection.create();
|
||||
this.renderOperation(operation);
|
||||
},
|
||||
renderOperation: function(subView) {
|
||||
var operationsElement = this.$el.find('.operations');
|
||||
operationsElement.append(subView.$el);
|
||||
subView.render();
|
||||
},
|
||||
render: function() {
|
||||
this.$el.html(this.template());
|
||||
this.collection.each(this.renderOperation, this);
|
||||
}
|
||||
});
|
||||
})();
|
|
@ -1,86 +1,82 @@
|
|||
<template>
|
||||
<div class="check" @click="showDelete" v-click-outside="hideDelete">
|
||||
<Multiselect v-model="currentOption" :options="options" label="name"
|
||||
track-by="class" :allow-empty="false" :placeholder="t('workflowengine', 'Select a filter')"
|
||||
@input="updateCheck" ref="checkSelector"></Multiselect>
|
||||
<Multiselect v-if="currentOption" v-model="currentOperator" @input="updateCheck"
|
||||
:options="operators" label="name" track-by="operator"
|
||||
:allow-empty="false" :placeholder="t('workflowengine', 'Select a comparator')"></Multiselect>
|
||||
<component v-if="currentOperator && currentComponent" :is="currentOption.component()" v-model="check.value" />
|
||||
<input v-else-if="currentOperator" type="text" v-model="check.value" @input="updateCheck" />
|
||||
<div v-click-outside="hideDelete" class="check" @click="showDelete">
|
||||
<Multiselect ref="checkSelector" v-model="currentOption" :options="options"
|
||||
label="name" track-by="class" :allow-empty="false"
|
||||
:placeholder="t('workflowengine', 'Select a filter')" @input="updateCheck" />
|
||||
<Multiselect v-if="currentOption" v-model="currentOperator" :options="operators"
|
||||
label="name" track-by="operator" :allow-empty="false"
|
||||
:placeholder="t('workflowengine', 'Select a comparator')" @input="updateCheck" />
|
||||
<component :is="currentOption.component()" v-if="currentOperator && currentComponent" v-model="check.value" />
|
||||
<input v-else-if="currentOperator" v-model="check.value" type="text"
|
||||
@input="updateCheck">
|
||||
<Actions>
|
||||
<ActionButton icon="icon-delete" v-if="deleteVisible || !currentOption" @click="$emit('remove')" />
|
||||
<ActionButton v-if="deleteVisible || !currentOption" icon="icon-delete" @click="$emit('remove')" />
|
||||
</Actions>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Checks } from '../services/Operation';
|
||||
import { Multiselect, Actions, ActionButton } from 'nextcloud-vue'
|
||||
import ClickOutside from 'vue-click-outside';
|
||||
import { Checks } from '../services/Operation'
|
||||
import { Multiselect, Actions, ActionButton } from 'nextcloud-vue'
|
||||
import ClickOutside from 'vue-click-outside'
|
||||
|
||||
export default {
|
||||
name: 'Check',
|
||||
components: {
|
||||
ActionButton,
|
||||
Actions,
|
||||
Multiselect
|
||||
export default {
|
||||
name: 'Check',
|
||||
components: {
|
||||
ActionButton,
|
||||
Actions,
|
||||
Multiselect
|
||||
},
|
||||
directives: {
|
||||
ClickOutside
|
||||
},
|
||||
props: {
|
||||
check: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
deleteVisible: false,
|
||||
currentOption: null,
|
||||
currentOperator: null,
|
||||
options: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
operators() {
|
||||
if (!this.currentOption) { return [] }
|
||||
return Checks[this.currentOption.class].operators
|
||||
},
|
||||
directives: {
|
||||
ClickOutside
|
||||
currentComponent() {
|
||||
if (!this.currentOption) { return [] }
|
||||
const currentComponent = Checks[this.currentOption.class].component
|
||||
return currentComponent && currentComponent()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.options = Object.values(Checks)
|
||||
this.currentOption = Checks[this.check.class]
|
||||
this.currentOperator = this.operators.find((operator) => operator.operator === this.check.operator)
|
||||
},
|
||||
methods: {
|
||||
showDelete() {
|
||||
this.deleteVisible = true
|
||||
},
|
||||
props: {
|
||||
check: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
deleteVisible: false,
|
||||
currentOption: null,
|
||||
currentOperator: null,
|
||||
options: [],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.options = Object.values(Checks)
|
||||
this.currentOption = Checks[this.check.class]
|
||||
this.currentOperator = this.operators.find((operator) => operator.operator === this.check.operator)
|
||||
this.$nextTick(() => {
|
||||
//this.$refs.checkSelector.$el.focus()
|
||||
})
|
||||
},
|
||||
computed: {
|
||||
operators() {
|
||||
if (!this.currentOption)
|
||||
return []
|
||||
return Checks[this.currentOption.class].operators
|
||||
},
|
||||
currentComponent() {
|
||||
if (!this.currentOption)
|
||||
return []
|
||||
let currentComponent = Checks[this.currentOption.class].component
|
||||
return currentComponent && currentComponent()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showDelete() {
|
||||
this.deleteVisible = true
|
||||
},
|
||||
hideDelete() {
|
||||
this.deleteVisible = false
|
||||
},
|
||||
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
|
||||
this.$emit('update', this.check)
|
||||
hideDelete() {
|
||||
this.deleteVisible = false
|
||||
},
|
||||
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
|
||||
this.$emit('update', this.check)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,74 +1,63 @@
|
|||
<template>
|
||||
<div>
|
||||
<Multiselect :value="currentEvent" :options="allEvents" label="name" track-by="id" :allow-empty="false" :disabled="allEvents.length <= 1" @input="updateEvent">
|
||||
<template slot="singleLabel" slot-scope="props">
|
||||
<img class="option__icon" :src="props.option.icon" />
|
||||
<span class="option__title option__title_single">{{ props.option.name }}</span>
|
||||
</template>
|
||||
<template slot="option" slot-scope="props">
|
||||
<img class="option__icon" :src="props.option.icon" />
|
||||
<span class="option__title">{{ props.option.name }}</span>
|
||||
</template>
|
||||
</Multiselect>
|
||||
<div v-if="operation.isComplex && operation.fixedEntity !== ''">
|
||||
<img class="option__icon" :src="entity.icon">
|
||||
<span class="option__title option__title_single">{{ entity.name }}</span>
|
||||
</div>
|
||||
<Multiselect v-else :value="currentEvent" :options="allEvents"
|
||||
label="eventName" track-by="id" :allow-empty="false"
|
||||
:disabled="allEvents.length <= 1" @input="updateEvent">
|
||||
<template slot="singleLabel" slot-scope="props">
|
||||
<img class="option__icon" :src="props.option.entity.icon">
|
||||
<span class="option__title option__title_single">{{ props.option.displayName }}</span>
|
||||
</template>
|
||||
<template slot="option" slot-scope="props">
|
||||
<img class="option__icon" :src="props.option.entity.icon">
|
||||
<span class="option__title">{{ props.option.displayName }}</span>
|
||||
</template>
|
||||
</Multiselect>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Multiselect } from 'nextcloud-vue'
|
||||
import { Entities, operationService } from '../services/Operation'
|
||||
import { Multiselect } from 'nextcloud-vue'
|
||||
|
||||
export default {
|
||||
name: "Event",
|
||||
components: {
|
||||
Multiselect
|
||||
export default {
|
||||
name: 'Event',
|
||||
components: {
|
||||
Multiselect
|
||||
},
|
||||
props: {
|
||||
rule: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
entity() {
|
||||
return this.$store.getters.getEntityForOperation(this.operation)
|
||||
},
|
||||
props: {
|
||||
rule: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.updateEvent(this.currentEvent)
|
||||
},
|
||||
computed: {
|
||||
currentEvent() {
|
||||
if (!this.rule.event) {
|
||||
return this.allEvents.length > 0 ? this.allEvents[0] : null
|
||||
}
|
||||
return this.allEvents.find(event => event.entity === this.rule.entity && event.event === this.rule.event)
|
||||
},
|
||||
allEvents() {
|
||||
return this.operation.events.map((entityEventName) => {
|
||||
const parts = entityEventName.split('::')
|
||||
const entityId = parts[0]
|
||||
const eventName = parts[1]
|
||||
const Entity = Entities.find((entity) => entity.id === entityId)
|
||||
const Event = Entity.events.find((event) => event.eventName === eventName)
|
||||
return {
|
||||
entity: entityId,
|
||||
id: entityEventName,
|
||||
events: eventName,
|
||||
name: Event.displayName,
|
||||
icon: Entity.icon,
|
||||
checks: Entity.checks,
|
||||
}
|
||||
})
|
||||
},
|
||||
operation() {
|
||||
return operationService.get(this.rule.class)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateEvent(event) {
|
||||
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)
|
||||
}
|
||||
operation() {
|
||||
return this.$store.getters.getOperationForRule(this.rule)
|
||||
},
|
||||
allEvents() {
|
||||
return this.$store.getters.getEventsForOperation(this.operation)
|
||||
},
|
||||
currentEvent() {
|
||||
if (!this.rule.events) {
|
||||
return this.allEvents.length > 0 ? this.allEvents[0] : null
|
||||
}
|
||||
return this.allEvents.find(event => event.entity.id === this.rule.entity && this.rule.events.indexOf(event.eventName) !== -1)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateEvent(event) {
|
||||
this.$set(this.rule, 'entity', event.entity.id)
|
||||
this.$set(this.rule, 'events', [event.eventName])
|
||||
this.$store.dispatch('updateRule', this.rule)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -1,34 +1,26 @@
|
|||
<template>
|
||||
<div class="actions__item" :class="{'colored': !!color}" :style="{ backgroundColor: color }">
|
||||
<div class="icon" :class="icon"></div>
|
||||
<h3>{{ title }}</h3>
|
||||
<small>{{ description }}</small>
|
||||
<div class="actions__item" :class="{'colored': colored}" :style="{ backgroundColor: colored ? operation.color : 'transparent' }">
|
||||
<div class="icon" :class="operation.iconClass" :style="{ backgroundImage: operation.iconClass ? '' : `url(${operation.icon})` }" />
|
||||
<h3>{{ operation.name }}</h3>
|
||||
<small>{{ operation.description }}</small>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Operation",
|
||||
props: {
|
||||
icon: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
export default {
|
||||
name: 'Operation',
|
||||
props: {
|
||||
operation: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
colored: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
@ -50,6 +42,7 @@
|
|||
background-position: center center;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
h3, small {
|
||||
padding: 6px;
|
||||
|
|
|
@ -1,38 +1,39 @@
|
|||
<template>
|
||||
<multiselect :options="options" track-by="id" label="text" v-model="value"></multiselect>
|
||||
<Multiselect v-model="value" :options="options" track-by="id"
|
||||
label="text" @input="$emit('input', value.id)" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const pdfConvertOptions = [
|
||||
{
|
||||
id: 'keep;preserve',
|
||||
text: t('workflow_pdf_converter', 'Keep original, preserve existing PDFs'),
|
||||
},
|
||||
{
|
||||
id: 'keep;overwrite',
|
||||
text: t('workflow_pdf_converter', 'Keep original, overwrite existing PDF'),
|
||||
},
|
||||
{
|
||||
id: 'delete;preserve',
|
||||
text: t('workflow_pdf_converter', 'Delete original, preserve existing PDFs'),
|
||||
},
|
||||
{
|
||||
id: 'delete;overwrite',
|
||||
text: t('workflow_pdf_converter', 'Delete original, overwrite existing PDF'),
|
||||
},
|
||||
]
|
||||
import { Multiselect } from 'nextcloud-vue'
|
||||
|
||||
import { Multiselect } from 'nextcloud-vue'
|
||||
export default {
|
||||
name: "ConvertToPdf",
|
||||
components: {Multiselect},
|
||||
data() {
|
||||
return {
|
||||
options: pdfConvertOptions,
|
||||
value: pdfConvertOptions[0]
|
||||
}
|
||||
const pdfConvertOptions = [
|
||||
{
|
||||
id: 'keep;preserve',
|
||||
text: t('workflow_pdf_converter', 'Keep original, preserve existing PDFs')
|
||||
},
|
||||
{
|
||||
id: 'keep;overwrite',
|
||||
text: t('workflow_pdf_converter', 'Keep original, overwrite existing PDF')
|
||||
},
|
||||
{
|
||||
id: 'delete;preserve',
|
||||
text: t('workflow_pdf_converter', 'Delete original, preserve existing PDFs')
|
||||
},
|
||||
{
|
||||
id: 'delete;overwrite',
|
||||
text: t('workflow_pdf_converter', 'Delete original, overwrite existing PDF')
|
||||
}
|
||||
]
|
||||
export default {
|
||||
name: 'ConvertToPdf',
|
||||
components: { Multiselect },
|
||||
data() {
|
||||
return {
|
||||
options: pdfConvertOptions,
|
||||
value: pdfConvertOptions[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
@ -42,4 +43,4 @@
|
|||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
@ -1,22 +1,24 @@
|
|||
<template>
|
||||
<multiselect :options="options" v-model="value" track-by="id" label="title" :multiple="true" :tagging="true" @input="$emit('input', value.map(item => item.id))"></multiselect>
|
||||
<Multiselect v-model="value" :options="options" track-by="id"
|
||||
label="title" :multiple="true" :tagging="true"
|
||||
@input="$emit('input', value.map(item => item.id))" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// TODO: fetch tags from endpoint
|
||||
const tags = [{id: 3, title: 'foo'}, {id: 4, title: 'bar'}]
|
||||
// TODO: fetch tags from endpoint
|
||||
import { Multiselect } from 'nextcloud-vue'
|
||||
|
||||
import { Multiselect } from 'nextcloud-vue'
|
||||
export default {
|
||||
name: "Tag",
|
||||
components: {Multiselect},
|
||||
data() {
|
||||
return {
|
||||
options: tags,
|
||||
value: null
|
||||
}
|
||||
const tags = [{ id: 3, title: 'foo' }, { id: 4, title: 'bar' }]
|
||||
export default {
|
||||
name: 'Tag',
|
||||
components: { Multiselect },
|
||||
data() {
|
||||
return {
|
||||
options: tags,
|
||||
value: null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
@ -26,4 +28,4 @@
|
|||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
@ -4,143 +4,144 @@
|
|||
<div class="trigger icon-confirm">
|
||||
<p>
|
||||
<span>{{ t('workflowengine', 'When') }}</span>
|
||||
<Event :rule="rule" @update="updateRule"></Event>
|
||||
<Event :rule="rule" @update="updateRule" />
|
||||
</p>
|
||||
<p v-for="check in rule.checks">
|
||||
<span>{{ t('workflowengine', 'and') }}</span>
|
||||
<Check :check="check" @update="updateRule" @remove="removeCheck(check)"></Check>
|
||||
<Check :check="check" @update="updateRule" @remove="removeCheck(check)" />
|
||||
</p>
|
||||
<p>
|
||||
<span> </span>
|
||||
<input v-if="lastCheckComplete" type="button" class="check--add" @click="rule.checks.push({class: null, operator: null, value: null})" value="Add a new filter"/>
|
||||
<span />
|
||||
<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="action">
|
||||
<div class="buttons">
|
||||
<Actions>
|
||||
<ActionButton v-if="rule.id === -1" icon="icon-close" @click="$emit('cancel')">Cancel rule creation</ActionButton>
|
||||
<ActionButton v-else icon="icon-close" @click="deleteRule">Remove rule</ActionButton>
|
||||
<ActionButton v-if="rule.id < -1" icon="icon-close" @click="cancelRule">
|
||||
Cancel rule creation
|
||||
</ActionButton>
|
||||
<ActionButton v-else icon="icon-close" @click="deleteRule">
|
||||
Remove rule
|
||||
</ActionButton>
|
||||
</Actions>
|
||||
<button class="status-button icon" :class="ruleStatus.class" v-tooltip="ruleStatus.tooltip" @click="saveRule">{{ ruleStatus.title }}</button>
|
||||
<button v-tooltip="ruleStatus.tooltip" class="status-button icon" :class="ruleStatus.class"
|
||||
@click="saveRule">
|
||||
{{ ruleStatus.title }}
|
||||
</button>
|
||||
</div>
|
||||
<Operation :icon="operation.icon" :title="operation.title" :description="operation.description">
|
||||
<component v-if="operation.options" :is="operation.options" v-model="operation.operation" @input="updateOperation" />
|
||||
<Operation :operation="operation" :colored="false">
|
||||
<component :is="operation.options" v-if="operation.options" v-model="rule.operation"
|
||||
@input="updateOperation" />
|
||||
</Operation>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Actions, ActionButton, Tooltip } from 'nextcloud-vue'
|
||||
import Event from './Event'
|
||||
import Check from './Check'
|
||||
import Operation from './Operation'
|
||||
import { operationService } from '../services/Operation'
|
||||
import axios from 'nextcloud-axios'
|
||||
import confirmPassword from 'nextcloud-password-confirmation'
|
||||
import {getApiUrl} from '../helpers/api';
|
||||
import { Actions, ActionButton, Tooltip } from 'nextcloud-vue'
|
||||
import Event from './Event'
|
||||
import Check from './Check'
|
||||
import Operation from './Operation'
|
||||
|
||||
export default {
|
||||
name: 'Rule',
|
||||
components: {
|
||||
Operation, Check, Event, Actions, ActionButton
|
||||
export default {
|
||||
name: 'Rule',
|
||||
components: {
|
||||
Operation, Check, Event, Actions, ActionButton
|
||||
},
|
||||
directives: {
|
||||
Tooltip
|
||||
},
|
||||
props: {
|
||||
rule: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editing: false,
|
||||
checks: [],
|
||||
error: null,
|
||||
dirty: this.rule.id < 0,
|
||||
checking: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
operation() {
|
||||
return this.$store.getters.getOperationForRule(this.rule)
|
||||
},
|
||||
directives: {
|
||||
Tooltip
|
||||
ruleStatus() {
|
||||
if (this.error) {
|
||||
return {
|
||||
title: t('workflowengine', 'The configuration is invalid'),
|
||||
class: 'icon-close-white invalid',
|
||||
tooltip: { placement: 'bottom', show: true, content: this.error }
|
||||
}
|
||||
}
|
||||
if (!this.dirty || this.checking) {
|
||||
return { title: 'Active', class: 'icon icon-checkmark' }
|
||||
}
|
||||
return { title: 'Save', class: 'icon-confirm-white primary' }
|
||||
|
||||
},
|
||||
props: {
|
||||
rule: {
|
||||
type: Object,
|
||||
required: true,
|
||||
lastCheckComplete() {
|
||||
const lastCheck = this.rule.checks[this.rule.checks.length - 1]
|
||||
return typeof lastCheck === 'undefined' || lastCheck.class !== null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async updateOperation(operation) {
|
||||
this.$set(this.rule, 'operation', operation)
|
||||
await this.updateRule()
|
||||
},
|
||||
async updateRule() {
|
||||
this.checking = true
|
||||
if (!this.dirty) {
|
||||
this.dirty = true
|
||||
}
|
||||
try {
|
||||
// TODO: add new verify endpoint
|
||||
// let result = await axios.post(OC.generateUrl(`/apps/workflowengine/operations/test`), this.rule)
|
||||
this.error = null
|
||||
this.checking = false
|
||||
this.$store.dispatch('updateRule', this.rule)
|
||||
} catch (e) {
|
||||
console.error('Failed to update operation', e)
|
||||
this.error = e.response.ocs.meta.message
|
||||
this.checking = false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
editing: false,
|
||||
operationService,
|
||||
checks: [],
|
||||
error: null,
|
||||
dirty: this.rule.id === -1,
|
||||
checking: false
|
||||
async saveRule() {
|
||||
try {
|
||||
await this.$store.dispatch('pushUpdateRule', this.rule)
|
||||
this.dirty = false
|
||||
this.error = null
|
||||
} catch (e) {
|
||||
console.error('Failed to save operation')
|
||||
this.error = e.response.data.ocs.meta.message
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
operation() {
|
||||
return this.operationService.get(this.rule.class)
|
||||
},
|
||||
ruleStatus() {
|
||||
if (this.error) {
|
||||
return { title: 'Invalid', class: 'icon-close-white invalid', tooltip: { placement: 'bottom', show: true, content: escapeHTML(this.error) } }
|
||||
}
|
||||
if (!this.dirty || this.checking) {
|
||||
return { title: 'Active', class: 'icon icon-checkmark' }
|
||||
}
|
||||
return { title: 'Save', class: 'icon-confirm-white primary' }
|
||||
|
||||
|
||||
},
|
||||
lastCheckComplete() {
|
||||
const lastCheck = this.rule.checks[this.rule.checks.length-1]
|
||||
return typeof lastCheck === 'undefined' || lastCheck.class !== null
|
||||
async deleteRule() {
|
||||
try {
|
||||
await this.$store.dispatch('deleteRule', this.rule)
|
||||
} catch (e) {
|
||||
console.error('Failed to delete operation')
|
||||
this.error = e.response.data.ocs.meta.message
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateOperation(operation) {
|
||||
this.$set(this.rule, 'operation', operation)
|
||||
},
|
||||
async updateRule() {
|
||||
this.checking = true
|
||||
if (!this.dirty) {
|
||||
this.dirty = true
|
||||
}
|
||||
try {
|
||||
// TODO: add new verify endpoint
|
||||
//let result = await axios.post(OC.generateUrl(`/apps/workflowengine/operations/test`), this.rule)
|
||||
this.error = null
|
||||
this.checking = false
|
||||
} catch (e) {
|
||||
console.error('Failed to update operation', e)
|
||||
this.error = e.response.ocs.meta.message
|
||||
this.checking = false
|
||||
}
|
||||
},
|
||||
async saveRule() {
|
||||
try {
|
||||
await confirmPassword()
|
||||
let result
|
||||
if (this.rule.id === -1) {
|
||||
result = await axios.post(getApiUrl(''), {...this.rule, events: [this.rule.event]})
|
||||
this.rule.id = result.data.ocs.data.id
|
||||
} else {
|
||||
result = await axios.put(getApiUrl(`/${this.rule.id}`), {...this.rule, events: [this.rule.event]})
|
||||
}
|
||||
this.$emit('update', this.rule)
|
||||
this.dirty = false
|
||||
this.error = null
|
||||
} catch (e) {
|
||||
console.log(e.response.data.ocs.meta.message)
|
||||
console.error('Failed to update operation', e)
|
||||
this.error = e.response.data.ocs.meta.message
|
||||
}
|
||||
},
|
||||
async deleteRule() {
|
||||
try {
|
||||
await confirmPassword()
|
||||
await axios.delete(getApiUrl(`/${this.rule.id}`))
|
||||
this.$emit('delete')
|
||||
} catch (e) {
|
||||
console.error('Failed to delete operation')
|
||||
this.error = e.response
|
||||
}
|
||||
},
|
||||
removeCheck(check) {
|
||||
const index = this.rule.checks.findIndex(item => item === check)
|
||||
if (index !== -1) {
|
||||
this.rule.checks.splice(index, 1)
|
||||
}
|
||||
cancelRule() {
|
||||
this.$store.dispatch('removeRule', this.rule)
|
||||
},
|
||||
removeCheck(check) {
|
||||
const index = this.rule.checks.findIndex(item => item === check)
|
||||
if (index < 0) {
|
||||
this.rule.checks.splice(index, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
@ -162,6 +163,7 @@
|
|||
.status-button.invalid {
|
||||
background-color: var(--color-warning);
|
||||
color: #fff;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.rule {
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
<template>
|
||||
<input type="text" />
|
||||
<input type="text">
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Multiselect } from 'nextcloud-vue'
|
||||
import { Multiselect } from 'nextcloud-vue'
|
||||
|
||||
export default {
|
||||
name: 'SizeValue',
|
||||
components: {
|
||||
Multiselect
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
predefinedTypes: [
|
||||
{
|
||||
icon: 'icon-picture',
|
||||
label: 'Images',
|
||||
pattern: '/image\\/.*/'
|
||||
},
|
||||
{
|
||||
icon: 'icon-category-office',
|
||||
label: 'Office documents',
|
||||
pattern: '/(vnd\\.(ms-|openxmlformats-).*))$/'
|
||||
},
|
||||
{
|
||||
icon: 'icon-filetype-file',
|
||||
label: 'PDF documents',
|
||||
pattern: 'application/pdf'
|
||||
}
|
||||
]
|
||||
}
|
||||
export default {
|
||||
name: 'SizeValue',
|
||||
components: {
|
||||
Multiselect
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
predefinedTypes: [
|
||||
{
|
||||
icon: 'icon-picture',
|
||||
label: 'Images',
|
||||
pattern: '/image\\/.*/'
|
||||
},
|
||||
{
|
||||
icon: 'icon-category-office',
|
||||
label: 'Office documents',
|
||||
pattern: '/(vnd\\.(ms-|openxmlformats-).*))$/'
|
||||
},
|
||||
{
|
||||
icon: 'icon-filetype-file',
|
||||
label: 'PDF documents',
|
||||
pattern: 'application/pdf'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
@ -1,28 +1,29 @@
|
|||
<template>
|
||||
<input type="text" placeholder="1 MB" @input="$emit('input', newValue)" v-model="newValue">
|
||||
<input v-model="newValue" type="text" placeholder="1 MB"
|
||||
@input="$emit('input', newValue)">
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "SizeValue",
|
||||
props: {
|
||||
value: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
newValue: this.value
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value() {
|
||||
this.newValue = this.value
|
||||
}
|
||||
export default {
|
||||
name: 'SizeValue',
|
||||
props: {
|
||||
value: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
newValue: this.value
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value() {
|
||||
this.newValue = this.value
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
@ -4,93 +4,68 @@
|
|||
<h2>{{ t('workflowengine', 'Workflows') }}</h2>
|
||||
|
||||
<transition-group name="slide" tag="div" class="actions">
|
||||
<Operation v-for="operation in getMainOperations" :key="operation.class"
|
||||
:icon="operation.icon" :title="operation.title" :description="operation.description" :color="operation.color"
|
||||
@click.native="createNewRule(operation)"></Operation>
|
||||
<Operation v-for="operation in getMainOperations" :key="operation.id" :operation="operation"
|
||||
@click.native="createNewRule(operation)" />
|
||||
</transition-group>
|
||||
|
||||
<div class="actions__more" v-if="hasMoreOperations">
|
||||
<div v-if="hasMoreOperations" class="actions__more">
|
||||
<button class="icon" :class="showMoreOperations ? 'icon-triangle-n' : 'icon-triangle-s'"
|
||||
@click="showMoreOperations=!showMoreOperations">
|
||||
@click="showMoreOperations=!showMoreOperations">
|
||||
{{ showMoreOperations ? t('workflowengine', 'Show less') : t('workflowengine', 'Show more') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<transition-group name="slide" v-if="rules.length > 0">
|
||||
<Rule v-for="rule in rules" :key="rule.id" :rule="rule" @delete="removeRule(rule)" @cancel="removeRule(rule)" @update="updateRule"></Rule>
|
||||
<transition-group v-if="rules.length > 0" name="slide">
|
||||
<Rule v-for="rule in rules" :key="rule.id" :rule="rule" />
|
||||
</transition-group>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Rule from './Rule'
|
||||
import Operation from './Operation'
|
||||
import { operationService } from '../services/Operation'
|
||||
import axios from 'nextcloud-axios'
|
||||
import { getApiUrl } from '../helpers/api';
|
||||
import Rule from './Rule'
|
||||
import Operation from './Operation'
|
||||
import { mapGetters, mapState } from 'vuex'
|
||||
|
||||
const ACTION_LIMIT = 3
|
||||
const ACTION_LIMIT = 3
|
||||
|
||||
export default {
|
||||
name: 'Workflow',
|
||||
components: {
|
||||
Operation,
|
||||
Rule
|
||||
export default {
|
||||
name: 'Workflow',
|
||||
components: {
|
||||
Operation,
|
||||
Rule
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showMoreOperations: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
rules: 'getRules'
|
||||
}),
|
||||
...mapState({
|
||||
operations: 'operations'
|
||||
}),
|
||||
hasMoreOperations() {
|
||||
return Object.keys(this.operations).length > ACTION_LIMIT
|
||||
},
|
||||
async mounted() {
|
||||
const { data } = await axios.get(getApiUrl(''))
|
||||
this.rules = Object.values(data.ocs.data).flat()
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
scope: OCP.InitialState.loadState('workflowengine', 'scope'),
|
||||
operations: operationService,
|
||||
showMoreOperations: false,
|
||||
rules: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasMoreOperations() {
|
||||
return Object.keys(this.operations.getAll()).length > ACTION_LIMIT
|
||||
},
|
||||
getMainOperations() {
|
||||
if (this.showMoreOperations) {
|
||||
return Object.values(this.operations.getAll())
|
||||
}
|
||||
return Object.values(this.operations.getAll()).slice(0, ACTION_LIMIT)
|
||||
},
|
||||
getMoreOperations() {
|
||||
return Object.values(this.operations.getAll()).slice(ACTION_LIMIT)
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateRule(rule) {
|
||||
let index = this.rules.findIndex((item) => rule === item)
|
||||
this.$set(this.rules, index, rule)
|
||||
},
|
||||
removeRule(rule) {
|
||||
let index = this.rules.findIndex((item) => rule === item)
|
||||
this.rules.splice(index, 1)
|
||||
},
|
||||
showAllOperations() {
|
||||
|
||||
},
|
||||
createNewRule(operation) {
|
||||
this.rules.unshift({
|
||||
id: -1,
|
||||
class: operation.class,
|
||||
entity: undefined,
|
||||
event: undefined,
|
||||
name: '', // unused in the new ui, there for legacy reasons
|
||||
checks: [],
|
||||
operation: operation.operation || ''
|
||||
})
|
||||
getMainOperations() {
|
||||
if (this.showMoreOperations) {
|
||||
return Object.values(this.operations)
|
||||
}
|
||||
return Object.values(this.operations).slice(0, ACTION_LIMIT)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('fetchRules')
|
||||
},
|
||||
methods: {
|
||||
createNewRule(operation) {
|
||||
this.$store.dispatch('createNewRule', operation)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
@ -119,7 +94,6 @@
|
|||
background-position: 10px center;
|
||||
}
|
||||
|
||||
|
||||
.slide-enter-active {
|
||||
-moz-transition-duration: 0.3s;
|
||||
-webkit-transition-duration: 0.3s;
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
module.exports = function(classname) {
|
||||
var check = OCA.WorkflowEngine.getCheckByClass(classname);
|
||||
if (!_.isUndefined(check)) {
|
||||
return check['operators'];
|
||||
}
|
||||
return [];
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
module.exports = function(currentValue, itemValue) {
|
||||
if (currentValue === itemValue) {
|
||||
return 'selected="selected"';
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
|
@ -17,61 +17,61 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import FileMimeType from './components/Values/FileMimeType'
|
||||
import FileMimeType from './../components/Values/FileMimeType'
|
||||
|
||||
(function() {
|
||||
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {};
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {};
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {}
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {}
|
||||
|
||||
OCA.WorkflowEngine.Plugins.FileMimeTypePlugin = {
|
||||
getCheck: function() {
|
||||
return {
|
||||
'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')}
|
||||
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') }
|
||||
]
|
||||
};
|
||||
}
|
||||
},
|
||||
render: function(element, check) {
|
||||
if (check['class'] !== 'OCA\\WorkflowEngine\\Check\\FileMimeType') {
|
||||
return;
|
||||
if (check.class !== 'OCA\\WorkflowEngine\\Check\\FileMimeType') {
|
||||
return
|
||||
}
|
||||
|
||||
var placeholder = 'text/plain';
|
||||
if (check['operator'] === 'matches' || check['operator'] === '!matches') {
|
||||
placeholder = '/^text\\/(plain|html)$/i';
|
||||
var placeholder = 'text/plain'
|
||||
if (check.operator === 'matches' || check.operator === '!matches') {
|
||||
placeholder = '/^text\\/(plain|html)$/i'
|
||||
|
||||
if (this._validateRegex(check['value'])) {
|
||||
$(element).removeClass('invalid-input');
|
||||
if (this._validateRegex(check.value)) {
|
||||
$(element).removeClass('invalid-input')
|
||||
} else {
|
||||
$(element).addClass('invalid-input');
|
||||
$(element).addClass('invalid-input')
|
||||
}
|
||||
}
|
||||
|
||||
$(element).css('width', '250px')
|
||||
.attr('placeholder', placeholder)
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', {placeholder: placeholder}))
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', { placeholder: placeholder }))
|
||||
.addClass('has-tooltip')
|
||||
.tooltip({
|
||||
placement: 'bottom'
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
_validateRegex: function(string) {
|
||||
var regexRegex = /^\/(.*)\/([gui]{0,3})$/,
|
||||
result = regexRegex.exec(string);
|
||||
return result !== null;
|
||||
var regexRegex = /^\/(.*)\/([gui]{0,3})$/
|
||||
var result = regexRegex.exec(string)
|
||||
return result !== null
|
||||
},
|
||||
|
||||
component: function () {
|
||||
component: function() {
|
||||
return FileMimeType
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
})()
|
||||
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.FileMimeTypePlugin);
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.FileMimeTypePlugin)
|
|
@ -18,61 +18,61 @@
|
|||
*
|
||||
*/
|
||||
|
||||
(function () {
|
||||
(function() {
|
||||
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {};
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {};
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {}
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {}
|
||||
|
||||
OCA.WorkflowEngine.Plugins.FileNamePlugin = {
|
||||
getCheck: function () {
|
||||
getCheck: function() {
|
||||
return {
|
||||
'class': 'OCA\\WorkflowEngine\\Check\\FileName',
|
||||
'name': t('workflowengine', 'File name'),
|
||||
'operators': [
|
||||
{'operator': 'is', 'name': t('workflowengine', 'is')},
|
||||
{'operator': '!is', 'name': t('workflowengine', 'is not')},
|
||||
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', 'matches')
|
||||
},
|
||||
{
|
||||
'operator': '!matches',
|
||||
'name': t('workflowengine', 'does not match')
|
||||
operator: '!matches',
|
||||
name: t('workflowengine', 'does not match')
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
},
|
||||
render: function (element, check) {
|
||||
if (check['class'] !== 'OCA\\WorkflowEngine\\Check\\FileName') {
|
||||
return;
|
||||
render: function(element, check) {
|
||||
if (check.class !== 'OCA\\WorkflowEngine\\Check\\FileName') {
|
||||
return
|
||||
}
|
||||
|
||||
var placeholder = 'dummy.jpg';
|
||||
if (check['operator'] === 'matches' || check['operator'] === '!matches') {
|
||||
placeholder = '/^dummy-.+$/i';
|
||||
var placeholder = 'dummy.jpg'
|
||||
if (check.operator === 'matches' || check.operator === '!matches') {
|
||||
placeholder = '/^dummy-.+$/i'
|
||||
|
||||
if (this._validateRegex(check['value'])) {
|
||||
$(element).removeClass('invalid-input');
|
||||
if (this._validateRegex(check.value)) {
|
||||
$(element).removeClass('invalid-input')
|
||||
} else {
|
||||
$(element).addClass('invalid-input');
|
||||
$(element).addClass('invalid-input')
|
||||
}
|
||||
}
|
||||
|
||||
$(element).css('width', '250px')
|
||||
.attr('placeholder', placeholder)
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', {placeholder: placeholder}))
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', { placeholder: placeholder }))
|
||||
.addClass('has-tooltip')
|
||||
.tooltip({
|
||||
placement: 'bottom'
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
_validateRegex: function (string) {
|
||||
var regexRegex = /^\/(.*)\/([gui]{0,3})$/,
|
||||
result = regexRegex.exec(string);
|
||||
return result !== null;
|
||||
_validateRegex: function(string) {
|
||||
var regexRegex = /^\/(.*)\/([gui]{0,3})$/
|
||||
var result = regexRegex.exec(string)
|
||||
return result !== null
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
})()
|
||||
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.FileNamePlugin);
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.FileNamePlugin)
|
|
@ -17,43 +17,43 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import SizeValue from './components/Values/SizeValue'
|
||||
import SizeValue from './../components/Values/SizeValue'
|
||||
(function() {
|
||||
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {};
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {};
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {}
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {}
|
||||
|
||||
OCA.WorkflowEngine.Plugins.FileSizePlugin = {
|
||||
getCheck: function() {
|
||||
return {
|
||||
'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')}
|
||||
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') }
|
||||
]
|
||||
};
|
||||
}
|
||||
},
|
||||
render: function(element, check) {
|
||||
if (check['class'] !== 'OCA\\WorkflowEngine\\Check\\FileSize') {
|
||||
return;
|
||||
if (check.class !== 'OCA\\WorkflowEngine\\Check\\FileSize') {
|
||||
return
|
||||
}
|
||||
|
||||
var placeholder = '12 MB'; // Do not translate!!!
|
||||
var placeholder = '12 MB' // Do not translate!!!
|
||||
$(element).css('width', '250px')
|
||||
.attr('placeholder', placeholder)
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', {placeholder: placeholder}))
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', { placeholder: placeholder }))
|
||||
.addClass('has-tooltip')
|
||||
.tooltip({
|
||||
placement: 'bottom'
|
||||
});
|
||||
})
|
||||
},
|
||||
component: function () {
|
||||
component: function() {
|
||||
return SizeValue
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
})()
|
||||
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.FileSizePlugin);
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.FileSizePlugin)
|
|
@ -20,28 +20,28 @@
|
|||
|
||||
(function() {
|
||||
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {};
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {};
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {}
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {}
|
||||
|
||||
OCA.WorkflowEngine.Plugins.FileSystemTagsPlugin = {
|
||||
getCheck: function() {
|
||||
this.collection = OC.SystemTags.collection;
|
||||
this.collection = OC.SystemTags.collection
|
||||
|
||||
return {
|
||||
'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')}
|
||||
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') }
|
||||
]
|
||||
};
|
||||
}
|
||||
},
|
||||
render: function(element, check) {
|
||||
if (check['class'] !== 'OCA\\WorkflowEngine\\Check\\FileSystemTags') {
|
||||
return;
|
||||
if (check.class !== 'OCA\\WorkflowEngine\\Check\\FileSystemTags') {
|
||||
return
|
||||
}
|
||||
|
||||
$(element).css('width', '400px');
|
||||
$(element).css('width', '400px')
|
||||
|
||||
$(element).select2({
|
||||
allowClear: false,
|
||||
|
@ -50,29 +50,29 @@
|
|||
query: _.debounce(function(query) {
|
||||
query.callback({
|
||||
results: OC.SystemTags.collection.filterByName(query.term)
|
||||
});
|
||||
})
|
||||
}, 100, true),
|
||||
id: function(element) {
|
||||
return element.get('id');
|
||||
return element.get('id')
|
||||
},
|
||||
initSelection: function(element, callback) {
|
||||
callback($(element).val());
|
||||
callback($(element).val())
|
||||
},
|
||||
formatResult: function (tag) {
|
||||
return OC.SystemTags.getDescriptiveTag(tag);
|
||||
formatResult: function(tag) {
|
||||
return OC.SystemTags.getDescriptiveTag(tag)
|
||||
},
|
||||
formatSelection: function (tagId) {
|
||||
var tag = OC.SystemTags.collection.get(tagId);
|
||||
formatSelection: function(tagId) {
|
||||
var tag = OC.SystemTags.collection.get(tagId)
|
||||
if (!_.isUndefined(tag)) {
|
||||
return OC.SystemTags.getDescriptiveTag(tag);
|
||||
return OC.SystemTags.getDescriptiveTag(tag)
|
||||
}
|
||||
},
|
||||
escapeMarkup: function(m) {
|
||||
return m;
|
||||
return m
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
})()
|
||||
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.FileSystemTagsPlugin);
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.FileSystemTagsPlugin)
|
|
@ -20,64 +20,64 @@
|
|||
|
||||
(function() {
|
||||
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {};
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {};
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {}
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {}
|
||||
|
||||
OCA.WorkflowEngine.Plugins.RequestRemoteAddressPlugin = {
|
||||
getCheck: function() {
|
||||
return {
|
||||
'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')}
|
||||
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') }
|
||||
]
|
||||
};
|
||||
}
|
||||
},
|
||||
render: function(element, check) {
|
||||
if (check['class'] !== 'OCA\\WorkflowEngine\\Check\\RequestRemoteAddress') {
|
||||
return;
|
||||
if (check.class !== 'OCA\\WorkflowEngine\\Check\\RequestRemoteAddress') {
|
||||
return
|
||||
}
|
||||
|
||||
var placeholder = '127.0.0.1/32'; // Do not translate!!!
|
||||
if (check['operator'] === 'matchesIPv6' || check['operator'] === '!matchesIPv6') {
|
||||
placeholder = '::1/128'; // Do not translate!!!
|
||||
if (this._validateIPv6(check['value'])) {
|
||||
$(element).removeClass('invalid-input');
|
||||
var placeholder = '127.0.0.1/32' // Do not translate!!!
|
||||
if (check.operator === 'matchesIPv6' || check.operator === '!matchesIPv6') {
|
||||
placeholder = '::1/128' // Do not translate!!!
|
||||
if (this._validateIPv6(check.value)) {
|
||||
$(element).removeClass('invalid-input')
|
||||
} else {
|
||||
$(element).addClass('invalid-input');
|
||||
$(element).addClass('invalid-input')
|
||||
}
|
||||
} else {
|
||||
if (this._validateIPv4(check['value'])) {
|
||||
$(element).removeClass('invalid-input');
|
||||
if (this._validateIPv4(check.value)) {
|
||||
$(element).removeClass('invalid-input')
|
||||
} else {
|
||||
$(element).addClass('invalid-input');
|
||||
$(element).addClass('invalid-input')
|
||||
}
|
||||
}
|
||||
|
||||
$(element).css('width', '300px')
|
||||
.attr('placeholder', placeholder)
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', {placeholder: placeholder}))
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', { placeholder: placeholder }))
|
||||
.addClass('has-tooltip')
|
||||
.tooltip({
|
||||
placement: 'bottom'
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
_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])$/,
|
||||
result = regexRegex.exec(string);
|
||||
return result !== null;
|
||||
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
|
||||
},
|
||||
|
||||
_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])$/,
|
||||
result = regexRegex.exec(string);
|
||||
return result !== null;
|
||||
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
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
})()
|
||||
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.RequestRemoteAddressPlugin);
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.RequestRemoteAddressPlugin)
|
|
@ -20,81 +20,81 @@
|
|||
|
||||
(function() {
|
||||
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {};
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {};
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {}
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {}
|
||||
|
||||
OCA.WorkflowEngine.Plugins.RequestTimePlugin = {
|
||||
timezones: [
|
||||
"Europe/Berlin",
|
||||
"Europe/London"
|
||||
'Europe/Berlin',
|
||||
'Europe/London'
|
||||
],
|
||||
_$element: null,
|
||||
getCheck: function() {
|
||||
return {
|
||||
'class': 'OCA\\WorkflowEngine\\Check\\RequestTime',
|
||||
'name': t('workflowengine', 'Request time'),
|
||||
'operators': [
|
||||
{'operator': 'in', 'name': t('workflowengine', 'between')},
|
||||
{'operator': '!in', 'name': t('workflowengine', 'not between')}
|
||||
class: 'OCA\\WorkflowEngine\\Check\\RequestTime',
|
||||
name: t('workflowengine', 'Request time'),
|
||||
operators: [
|
||||
{ operator: 'in', name: t('workflowengine', 'between') },
|
||||
{ operator: '!in', name: t('workflowengine', 'not between') }
|
||||
]
|
||||
};
|
||||
}
|
||||
},
|
||||
render: function(element, check) {
|
||||
if (check['class'] !== 'OCA\\WorkflowEngine\\Check\\RequestTime') {
|
||||
return;
|
||||
if (check.class !== 'OCA\\WorkflowEngine\\Check\\RequestTime') {
|
||||
return
|
||||
}
|
||||
|
||||
var startTime = '09:00',
|
||||
endTime = '18:00',
|
||||
timezone = jstz.determine().name(),
|
||||
$element = $(element);
|
||||
var startTime = '09:00'
|
||||
var endTime = '18:00'
|
||||
var timezone = jstz.determine().name()
|
||||
var $element = $(element)
|
||||
|
||||
if (_.isString(check['value']) && check['value'] !== '') {
|
||||
var value = JSON.parse(check['value']),
|
||||
splittedStart = value[0].split(' ', 2),
|
||||
splittedEnd = value[1].split(' ', 2);
|
||||
if (_.isString(check.value) && check.value !== '') {
|
||||
var value = JSON.parse(check.value)
|
||||
var splittedStart = value[0].split(' ', 2)
|
||||
var splittedEnd = value[1].split(' ', 2)
|
||||
|
||||
startTime = splittedStart[0];
|
||||
endTime = splittedEnd[0];
|
||||
timezone = splittedStart[1];
|
||||
startTime = splittedStart[0]
|
||||
endTime = splittedEnd[0]
|
||||
timezone = splittedStart[1]
|
||||
}
|
||||
|
||||
var valueJSON = JSON.stringify([startTime + ' ' + timezone, endTime + ' ' + timezone]);
|
||||
if (check['value'] !== valueJSON) {
|
||||
check['value'] = valueJSON;
|
||||
$element.val(valueJSON);
|
||||
var valueJSON = JSON.stringify([startTime + ' ' + timezone, endTime + ' ' + timezone])
|
||||
if (check.value !== valueJSON) {
|
||||
check.value = valueJSON
|
||||
$element.val(valueJSON)
|
||||
}
|
||||
|
||||
$element.css('display', 'none');
|
||||
$element.css('display', 'none')
|
||||
|
||||
$('<input>')
|
||||
.attr('type', 'text')
|
||||
.attr('placeholder', t('workflowengine', 'Start'))
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', {placeholder: '16:00'}))
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', { placeholder: '16:00' }))
|
||||
.addClass('has-tooltip')
|
||||
.tooltip({
|
||||
placement: 'bottom'
|
||||
})
|
||||
.addClass('start')
|
||||
.val(startTime)
|
||||
.insertBefore($element);
|
||||
.insertBefore($element)
|
||||
$('<input>')
|
||||
.attr('type', 'text')
|
||||
.attr('placeholder', t('workflowengine', 'End'))
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', {placeholder: '16:00'}))
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', { placeholder: '16:00' }))
|
||||
.addClass('has-tooltip')
|
||||
.tooltip({
|
||||
placement: 'bottom'
|
||||
})
|
||||
.addClass('end')
|
||||
.val(endTime)
|
||||
.insertBefore($element);
|
||||
.insertBefore($element)
|
||||
|
||||
var timezoneInput = $('<input>')
|
||||
.attr('type', 'hidden')
|
||||
.css('width', '250px')
|
||||
.insertBefore($element)
|
||||
.val(timezone);
|
||||
.val(timezone)
|
||||
|
||||
timezoneInput.select2({
|
||||
allowClear: false,
|
||||
|
@ -104,93 +104,93 @@
|
|||
url: OC.generateUrl('apps/workflowengine/timezones'),
|
||||
dataType: 'json',
|
||||
quietMillis: 100,
|
||||
data: function (term) {
|
||||
data: function(term) {
|
||||
if (term === '') {
|
||||
// Default search in the same continent...
|
||||
term = jstz.determine().name().split('/');
|
||||
term = term[0];
|
||||
term = jstz.determine().name().split('/')
|
||||
term = term[0]
|
||||
}
|
||||
return {
|
||||
search: term
|
||||
};
|
||||
}
|
||||
},
|
||||
results: function (response) {
|
||||
var results = [];
|
||||
results: function(response) {
|
||||
var results = []
|
||||
$.each(response, function(timezone) {
|
||||
results.push({ id: timezone });
|
||||
});
|
||||
results.push({ id: timezone })
|
||||
})
|
||||
|
||||
return {
|
||||
results: results,
|
||||
more: false
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
initSelection: function (element, callback) {
|
||||
callback(element.val());
|
||||
initSelection: function(element, callback) {
|
||||
callback(element.val())
|
||||
},
|
||||
formatResult: function (element) {
|
||||
return '<span>' + element.id + '</span>';
|
||||
formatResult: function(element) {
|
||||
return '<span>' + element.id + '</span>'
|
||||
},
|
||||
formatSelection: function (element) {
|
||||
formatSelection: function(element) {
|
||||
if (!_.isUndefined(element.id)) {
|
||||
element = element.id;
|
||||
element = element.id
|
||||
}
|
||||
return '<span>' + element + '</span>';
|
||||
return '<span>' + element + '</span>'
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// Has to be added after select2 for `event.target.classList`
|
||||
timezoneInput.addClass('timezone');
|
||||
timezoneInput.addClass('timezone')
|
||||
|
||||
$element.parent()
|
||||
.on('change', '.start', _.bind(this.update, this))
|
||||
.on('change', '.end', _.bind(this.update, this))
|
||||
.on('change', '.timezone', _.bind(this.update, this));
|
||||
.on('change', '.timezone', _.bind(this.update, this))
|
||||
|
||||
this._$element = $element;
|
||||
this._$element = $element
|
||||
},
|
||||
update: function(event) {
|
||||
var value = event.target.value,
|
||||
key = null;
|
||||
var value = event.target.value
|
||||
var key = null
|
||||
|
||||
for (var i = 0; i < event.target.classList.length; i++) {
|
||||
key = event.target.classList[i];
|
||||
key = event.target.classList[i]
|
||||
}
|
||||
|
||||
if (key === null) {
|
||||
console.warn('update triggered but element doesn\'t have any class');
|
||||
return;
|
||||
console.warn('update triggered but element doesn\'t have any class')
|
||||
return
|
||||
}
|
||||
|
||||
var data = JSON.parse(this._$element.val()),
|
||||
startTime = moment(data[0].split(' ', 2)[0], 'H:m Z'),
|
||||
endTime = moment(data[1].split(' ', 2)[0], 'H:m Z'),
|
||||
timezone = data[0].split(' ', 2)[1];
|
||||
var data = JSON.parse(this._$element.val())
|
||||
var startTime = moment(data[0].split(' ', 2)[0], 'H:m Z')
|
||||
var endTime = moment(data[1].split(' ', 2)[0], 'H:m Z')
|
||||
var timezone = data[0].split(' ', 2)[1]
|
||||
|
||||
if (key === 'start' || key === 'end') {
|
||||
var parsedDate = moment(value, ['H:m', 'h:m a'], true).format('HH:mm');
|
||||
var parsedDate = moment(value, ['H:m', 'h:m a'], true).format('HH:mm')
|
||||
|
||||
if (parsedDate === 'Invalid date') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
var indexValue = 0;
|
||||
var indexValue = 0
|
||||
if (key === 'end') {
|
||||
indexValue = 1;
|
||||
indexValue = 1
|
||||
}
|
||||
data[indexValue] = parsedDate + ' ' + timezone;
|
||||
data[indexValue] = parsedDate + ' ' + timezone
|
||||
}
|
||||
|
||||
if (key === 'timezone') {
|
||||
data[0] = startTime.format('HH:mm') + ' ' + value;
|
||||
data[1] = endTime.format('HH:mm') + ' ' + value;
|
||||
data[0] = startTime.format('HH:mm') + ' ' + value
|
||||
data[1] = endTime.format('HH:mm') + ' ' + value
|
||||
}
|
||||
|
||||
this._$element.val(JSON.stringify(data));
|
||||
this._$element.trigger('change');
|
||||
this._$element.val(JSON.stringify(data))
|
||||
this._$element.trigger('change')
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
})()
|
||||
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.RequestTimePlugin);
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.RequestTimePlugin)
|
|
@ -20,98 +20,97 @@
|
|||
|
||||
(function() {
|
||||
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {};
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {};
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {}
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {}
|
||||
|
||||
OCA.WorkflowEngine.Plugins.RequestURLPlugin = {
|
||||
predefinedValues: ['webdav'],
|
||||
getCheck: function() {
|
||||
return {
|
||||
'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')}
|
||||
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') }
|
||||
]
|
||||
};
|
||||
}
|
||||
},
|
||||
render: function(element, check) {
|
||||
if (check['class'] !== 'OCA\\WorkflowEngine\\Check\\RequestURL') {
|
||||
return;
|
||||
if (check.class !== 'OCA\\WorkflowEngine\\Check\\RequestURL') {
|
||||
return
|
||||
}
|
||||
|
||||
var placeholder = 'https://localhost/index.php';
|
||||
var placeholder = 'https://localhost/index.php'
|
||||
|
||||
if (check['operator'] === 'matches' || check['operator'] === '!matches') {
|
||||
placeholder = '/^https\\:\\/\\/localhost\\/index\\.php$/i';
|
||||
if (check.operator === 'matches' || check.operator === '!matches') {
|
||||
placeholder = '/^https\\:\\/\\/localhost\\/index\\.php$/i'
|
||||
}
|
||||
|
||||
$(element).css('width', '250px')
|
||||
.attr('placeholder', placeholder)
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', {placeholder: placeholder}))
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', { placeholder: placeholder }))
|
||||
.addClass('has-tooltip')
|
||||
.tooltip({
|
||||
placement: 'bottom'
|
||||
});
|
||||
})
|
||||
|
||||
if (check['operator'] === 'matches' || check['operator'] === '!matches') {
|
||||
if (this._validateRegex(check['value'])) {
|
||||
$(element).removeClass('invalid-input');
|
||||
if (check.operator === 'matches' || check.operator === '!matches') {
|
||||
if (this._validateRegex(check.value)) {
|
||||
$(element).removeClass('invalid-input')
|
||||
} else {
|
||||
$(element).addClass('invalid-input');
|
||||
$(element).addClass('invalid-input')
|
||||
}
|
||||
} else {
|
||||
var self = this,
|
||||
data = [
|
||||
var self = this
|
||||
var data = [
|
||||
{
|
||||
text: t('workflowengine', 'Predefined URLs'),
|
||||
children: [
|
||||
{id: 'webdav', text: t('workflowengine', 'Files WebDAV')}
|
||||
{ id: 'webdav', text: t('workflowengine', 'Files WebDAV') }
|
||||
]
|
||||
}
|
||||
];
|
||||
if (this.predefinedValues.indexOf(check['value']) === -1) {
|
||||
]
|
||||
if (this.predefinedValues.indexOf(check.value) === -1) {
|
||||
data.unshift({
|
||||
id: check['value'],
|
||||
text: check['value']
|
||||
id: check.value,
|
||||
text: check.value
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
$(element).select2({
|
||||
data: data,
|
||||
createSearchChoice: function(term) {
|
||||
if (self.predefinedValues.indexOf(check['value']) === -1) {
|
||||
if (self.predefinedValues.indexOf(check.value) === -1) {
|
||||
return {
|
||||
id: term,
|
||||
text: term
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
id: function(element) {
|
||||
return element.id;
|
||||
return element.id
|
||||
},
|
||||
formatResult: function (tag) {
|
||||
return tag.text;
|
||||
formatResult: function(tag) {
|
||||
return tag.text
|
||||
},
|
||||
formatSelection: function (tag) {
|
||||
return tag.text;
|
||||
formatSelection: function(tag) {
|
||||
return tag.text
|
||||
},
|
||||
escapeMarkup: function(m) {
|
||||
return m;
|
||||
return m
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
_validateRegex: function(string) {
|
||||
var regexRegex = /^\/(.*)\/([gui]{0,3})$/,
|
||||
result = regexRegex.exec(string);
|
||||
return result !== null;
|
||||
var regexRegex = /^\/(.*)\/([gui]{0,3})$/
|
||||
var result = regexRegex.exec(string)
|
||||
return result !== null
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
})()
|
||||
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.RequestURLPlugin);
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.RequestURLPlugin)
|
|
@ -20,66 +20,66 @@
|
|||
|
||||
(function() {
|
||||
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {};
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {};
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {}
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {}
|
||||
|
||||
OCA.WorkflowEngine.Plugins.RequestUserAgentPlugin = {
|
||||
predefinedValues: ['android', 'ios', 'desktop'],
|
||||
getCheck: function() {
|
||||
return {
|
||||
'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')}
|
||||
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') }
|
||||
]
|
||||
};
|
||||
}
|
||||
},
|
||||
render: function(element, check) {
|
||||
if (check['class'] !== 'OCA\\WorkflowEngine\\Check\\RequestUserAgent') {
|
||||
return;
|
||||
if (check.class !== 'OCA\\WorkflowEngine\\Check\\RequestUserAgent') {
|
||||
return
|
||||
}
|
||||
|
||||
var placeholder = 'Mozilla/5.0 User Agent';
|
||||
var placeholder = 'Mozilla/5.0 User Agent'
|
||||
|
||||
if (check.operator === 'matches' || check.operator === '!matches') {
|
||||
placeholder = '/^Mozilla\\/5\\.0 (.*)$/i';
|
||||
placeholder = '/^Mozilla\\/5\\.0 (.*)$/i'
|
||||
}
|
||||
|
||||
$(element).css('width', '250px')
|
||||
.attr('placeholder', placeholder)
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', {placeholder: placeholder}))
|
||||
.attr('title', t('workflowengine', 'Example: {placeholder}', { placeholder: placeholder }))
|
||||
.addClass('has-tooltip')
|
||||
.tooltip({
|
||||
placement: 'bottom'
|
||||
});
|
||||
})
|
||||
|
||||
if (check.operator === 'matches' || check.operator === '!matches') {
|
||||
if (this._validateRegex(check.value)) {
|
||||
$(element).removeClass('invalid-input');
|
||||
$(element).removeClass('invalid-input')
|
||||
} else {
|
||||
$(element).addClass('invalid-input');
|
||||
$(element).addClass('invalid-input')
|
||||
}
|
||||
} else {
|
||||
var self = this,
|
||||
data = [
|
||||
var self = this
|
||||
var data = [
|
||||
{
|
||||
text: t('workflowengine', 'Sync clients'),
|
||||
children: [
|
||||
{id: 'android', text: t('workflowengine', 'Android client')},
|
||||
{id: 'ios', text: t('workflowengine', 'iOS client')},
|
||||
{id: 'desktop', text: t('workflowengine', 'Desktop client')},
|
||||
{id: 'mail', text: t('workflowengine', 'Thunderbird & Outlook addons')}
|
||||
{ id: 'android', text: t('workflowengine', 'Android client') },
|
||||
{ id: 'ios', text: t('workflowengine', 'iOS client') },
|
||||
{ id: 'desktop', text: t('workflowengine', 'Desktop client') },
|
||||
{ id: 'mail', text: t('workflowengine', 'Thunderbird & Outlook addons') }
|
||||
]
|
||||
}
|
||||
];
|
||||
]
|
||||
if (this.predefinedValues.indexOf(check.value) === -1) {
|
||||
data.unshift({
|
||||
id: check.value,
|
||||
text: check.value
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
$(element).select2({
|
||||
|
@ -89,31 +89,31 @@
|
|||
return {
|
||||
id: term,
|
||||
text: term
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
id: function(element) {
|
||||
return element.id;
|
||||
return element.id
|
||||
},
|
||||
formatResult: function (tag) {
|
||||
return tag.text;
|
||||
formatResult: function(tag) {
|
||||
return tag.text
|
||||
},
|
||||
formatSelection: function (tag) {
|
||||
return tag.text;
|
||||
formatSelection: function(tag) {
|
||||
return tag.text
|
||||
},
|
||||
escapeMarkup: function(m) {
|
||||
return m;
|
||||
return m
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
_validateRegex: function(string) {
|
||||
var regexRegex = /^\/(.*)\/([gui]{0,3})$/,
|
||||
result = regexRegex.exec(string);
|
||||
return result !== null;
|
||||
var regexRegex = /^\/(.*)\/([gui]{0,3})$/
|
||||
var result = regexRegex.exec(string)
|
||||
return result !== null
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
})()
|
||||
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.RequestUserAgentPlugin);
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.RequestUserAgentPlugin)
|
|
@ -20,56 +20,56 @@
|
|||
|
||||
(function() {
|
||||
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {};
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {};
|
||||
OCA.WorkflowEngine = OCA.WorkflowEngine || {}
|
||||
OCA.WorkflowEngine.Plugins = OCA.WorkflowEngine.Plugins || {}
|
||||
|
||||
OCA.WorkflowEngine.Plugins.UserGroupMembershipPlugin = {
|
||||
getCheck: function() {
|
||||
return {
|
||||
'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')}
|
||||
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') }
|
||||
]
|
||||
};
|
||||
}
|
||||
},
|
||||
render: function(element, check, groups) {
|
||||
if (check['class'] !== 'OCA\\WorkflowEngine\\Check\\UserGroupMembership') {
|
||||
return;
|
||||
if (check.class !== 'OCA\\WorkflowEngine\\Check\\UserGroupMembership') {
|
||||
return
|
||||
}
|
||||
|
||||
$(element).css('width', '400px');
|
||||
$(element).css('width', '400px')
|
||||
|
||||
$(element).select2({
|
||||
data: { results: groups, text: 'displayname' },
|
||||
initSelection: function (element, callback) {
|
||||
var groupId = element.val();
|
||||
initSelection: function(element, callback) {
|
||||
var groupId = element.val()
|
||||
if (groupId && groups.length > 0) {
|
||||
callback({
|
||||
id: groupId,
|
||||
displayname: groups.find(function (group) {
|
||||
return group.id === groupId;
|
||||
displayname: groups.find(function(group) {
|
||||
return group.id === groupId
|
||||
}).displayname
|
||||
});
|
||||
})
|
||||
} else if (groupId) {
|
||||
callback({
|
||||
id: groupId,
|
||||
displayname: groupId
|
||||
});
|
||||
})
|
||||
} else {
|
||||
callback();
|
||||
callback()
|
||||
}
|
||||
},
|
||||
formatResult: function (element) {
|
||||
return '<span>' + escapeHTML(element.displayname) + '</span>';
|
||||
formatResult: function(element) {
|
||||
return '<span>' + escapeHTML(element.displayname) + '</span>'
|
||||
},
|
||||
formatSelection: function (element) {
|
||||
return '<span title="'+escapeHTML(element.id)+'">'+escapeHTML(element.displayname)+'</span>';
|
||||
formatSelection: function(element) {
|
||||
return '<span title="' + escapeHTML(element.id) + '">' + escapeHTML(element.displayname) + '</span>'
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
})()
|
||||
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.UserGroupMembershipPlugin);
|
||||
OC.Plugins.register('OCA.WorkflowEngine.CheckPlugins', OCA.WorkflowEngine.Plugins.UserGroupMembershipPlugin)
|
|
@ -13,17 +13,9 @@ const ALL_CHECKS = [
|
|||
'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(), component: plugin.component }
|
||||
}
|
||||
return plugin.getCheck()
|
||||
}).reduce((obj, item) => {
|
||||
|
@ -31,113 +23,55 @@ const Checks = Object.values(OCA.WorkflowEngine.Plugins).map((plugin) => {
|
|||
return obj
|
||||
}, {})
|
||||
|
||||
const Operators = OCP.InitialState.loadState('workflowengine', 'operators')
|
||||
|
||||
/**
|
||||
* Register operations
|
||||
* TODO: should be provided by the backend
|
||||
* Extend operators for testing
|
||||
*/
|
||||
|
||||
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]
|
||||
}
|
||||
|
||||
}
|
||||
const operationService = new OperationService()
|
||||
|
||||
operationService.registerOperation({
|
||||
class: 'OCA\\FilesAccessControl\\Operation',
|
||||
title: 'Block access',
|
||||
description: 'Deny access to files when they are accessed',
|
||||
icon: 'icon-block',
|
||||
Operators['OCA\\FilesAccessControl\\Operation'] = {
|
||||
...Operators['OCA\\FilesAccessControl\\Operation'],
|
||||
color: 'var(--color-error)',
|
||||
entites: [
|
||||
entities: [
|
||||
'OCA\\WorkflowEngine\\Entity\\File'
|
||||
],
|
||||
events: [
|
||||
// TODO: this is probably handled differently since there is no regular event for files access control
|
||||
'OCA\\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: 'Assign a tag to a file',
|
||||
icon: 'icon-tag-white',
|
||||
events: [
|
||||
'WorkflowEngine_Entity_File::postWrite',
|
||||
//'WorkflowEngine_Entity_File::postTagged',
|
||||
],
|
||||
options: Tag
|
||||
|
||||
})
|
||||
|
||||
operationService.registerOperation({
|
||||
class: 'OCA\\WorkflowPDFConverter\\Operation',
|
||||
title: 'Convert to PDF',
|
||||
}
|
||||
Operators['OCA\\WorkflowPDFConverter\\Operation'] = {
|
||||
id: 'OCA\\WorkflowPDFConverter\\Operation',
|
||||
name: 'Convert to PDF',
|
||||
description: 'Generate a PDF file',
|
||||
color: '#dc5047',
|
||||
icon: 'icon-convert-pdf',
|
||||
events: [
|
||||
'WorkflowEngine_Entity_File::postWrite',
|
||||
//EVENT_FILE_TAGGED
|
||||
],
|
||||
iconClass: 'icon-convert-pdf',
|
||||
options: ConvertToPdf
|
||||
})
|
||||
|
||||
console.debug('[InitialState] Entities', Entities)
|
||||
console.debug('[WorkflowEngine] Checks', Checks)
|
||||
console.debug('[WorkflowEngine] Operations', operationService.operations)
|
||||
}
|
||||
|
||||
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'
|
||||
}
|
||||
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 {
|
||||
Entities,
|
||||
Checks,
|
||||
operationService
|
||||
Operators,
|
||||
ALL_CHECKS
|
||||
}
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
<div class="operation{{#if hasChanged}} modified{{/if}}">
|
||||
<div class="operation-header">
|
||||
<input type="text" class="operation-name" placeholder="{{shortRuleDescTXT}}" value="{{operation.name}}" />
|
||||
<input type="text" class="operation-operation" value="{{operation.operation}}" />
|
||||
{{! delete only makes sense if the operation is already saved }}
|
||||
{{#if operation.id}}
|
||||
<span class="button-delete icon-delete"></span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="checks">
|
||||
{{#each operation.checks}}
|
||||
<div class="check" data-id="{{@index}}">
|
||||
<select class="check-class">
|
||||
{{#each ../classes}}
|
||||
<option value="{{class}}" {{{selectItem class ../class}}}>{{name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
<select class="check-operator">
|
||||
{{#each (getOperators class)}}
|
||||
<option value="{{operator}}" {{{selectItem operator ../operator}}}>{{name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
<input type="text" class="check-value" value="{{value}}">
|
||||
<span class="button-delete-check icon-delete"></span>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
<button class="button-add">{{addRuleTXT}}</button>
|
||||
{{#if hasChanged}}
|
||||
{{! reset only makes sense if the operation is already saved }}
|
||||
{{#if operation.id}}
|
||||
<button class="button-reset pull-right">{{resetTXT}}</button>
|
||||
{{/if}}
|
||||
<button class="button-save pull-right">{{saveTXT}}</button>
|
||||
{{/if}}
|
||||
{{#if saving}}
|
||||
<span class="icon-loading-small pull-right"></span>
|
||||
<span class="pull-right">{{savingTXT}}</span>
|
||||
{{else}}{{#if message}}
|
||||
<span class="msg pull-right {{#if errorMessage}}error{{else}}success{{/if}}">
|
||||
{{message}}{{#if errorMessage}} {{errorMessage}}{{/if}}
|
||||
</span>
|
||||
{{/if}}{{/if}}
|
||||
</div>
|
|
@ -1,2 +0,0 @@
|
|||
<div class="operations"></div>
|
||||
<button class="button-add-operation">{{addRuleGroupTXT}}</button>
|
|
@ -1,19 +1,25 @@
|
|||
import './filemimetypeplugin'
|
||||
import './filenameplugin'
|
||||
import './filesizeplugin'
|
||||
import './filesystemtagsplugin'
|
||||
import './requestremoteaddressplugin'
|
||||
import './requesttimeplugin'
|
||||
import './requesturlplugin'
|
||||
import './requestuseragentplugin'
|
||||
import './usergroupmembershipplugin'
|
||||
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'
|
||||
|
||||
window.OCA.WorkflowEngine = OCA.WorkflowEngine
|
||||
Vue.use(Vuex)
|
||||
|
||||
import Vue from 'vue';
|
||||
|
||||
Vue.prototype.t = t;
|
||||
|
||||
import Settings from './components/Workflow';
|
||||
Vue.prototype.t = t
|
||||
const View = Vue.extend(Settings)
|
||||
new View({}).$mount('#workflowengine')
|
||||
new View({
|
||||
store
|
||||
}).$mount('#workflowengine')
|
||||
|
|
Loading…
Reference in New Issue