'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, getExtensionElements = require('../../../helper/ExtensionElementsHelper').getExtensionElements, removeEntry = require('../../../helper/ExtensionElementsHelper').removeEntry, extensionElements = require('./implementation/ExtensionElements'), properties = require('./implementation/Properties'), entryFactory = require('../../../factory/EntryFactory'), elementHelper = require('../../../helper/ElementHelper'), cmdHelper = require('../../../helper/CmdHelper'), formHelper = require('../../../helper/FormHelper'), utils = require('../../../Utils'), is = require('bpmn-js/lib/util/ModelUtil').is, find = require('lodash/find'), each = require('lodash/forEach'); function generateValueId() { return utils.nextId('Value_'); } /** * Generate a form field specific textField using entryFactory. * * @param {string} options.id * @param {string} options.label * @param {string} options.modelProperty * @param {function} options.validate * * @return {Object} an entryFactory.textField object */ function formFieldTextField(options, getSelectedFormField) { var id = options.id, label = options.label, modelProperty = options.modelProperty, validate = options.validate; return entryFactory.textField({ id: id, label: label, modelProperty: modelProperty, get: function(element, node) { var selectedFormField = getSelectedFormField(element, node) || {}, values = {}; values[modelProperty] = selectedFormField[modelProperty]; return values; }, set: function(element, values, node) { var commands = []; if (typeof options.set === 'function') { var cmd = options.set(element, values, node); if (cmd) { commands.push(cmd); } } var formField = getSelectedFormField(element, node), properties = {}; properties[modelProperty] = values[modelProperty] || undefined; commands.push(cmdHelper.updateBusinessObject(element, formField, properties)); return commands; }, hidden: function(element, node) { return !getSelectedFormField(element, node); }, validate: validate }); } function ensureFormKeyAndDataSupported(element) { return ( is(element, 'bpmn:StartEvent') && !is(element.parent, 'bpmn:SubProcess') ) || is(element, 'bpmn:UserTask'); } module.exports = function(group, element, bpmnFactory, translate) { if (!ensureFormKeyAndDataSupported(element)) { return; } /** * Return the currently selected form field querying the form field select box * from the DOM. * * @param {djs.model.Base} element * @param {DOMElement} node - DOM element of any form field text input * * @return {ModdleElement} the currently selected form field */ function getSelectedFormField(element, node) { var selected = formFieldsEntry.getSelected(element, node.parentNode); if (selected.idx === -1) { return; } return formHelper.getFormField(element, selected.idx); } // [FormKey] form key text input field group.entries.push(entryFactory.textField({ id : 'form-key', label : translate('Form Key'), modelProperty: 'formKey', get: function(element, node) { var bo = getBusinessObject(element); return { formKey: bo.get('activiti:formKey') }; }, set: function(element, values, node) { var bo = getBusinessObject(element), formKey = values.formKey || undefined; return cmdHelper.updateBusinessObject(element, bo, { 'activiti:formKey': formKey }); } })); // [FormData] form field select box var formFieldsEntry = extensionElements(element, bpmnFactory, { id: 'form-fields', label: translate('Form Fields'), modelProperty: 'id', prefix: 'FormProperty', createExtensionElement: function(element, extensionElements, value) { var bo = getBusinessObject(element), commands = []; if (!extensionElements) { extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory); commands.push(cmdHelper.updateProperties(element, { extensionElements: extensionElements })); } /* var formData = formHelper.getFormData(element); if (!formData) { formData = elementHelper.createElement('activiti:FormData', { fields: [] }, extensionElements, bpmnFactory); commands.push(cmdHelper.addAndRemoveElementsFromList( element, extensionElements, 'values', 'extensionElements', [formData], [] )); }*/ /**activiti 是向 extensionElements 下追加元素,而不是 formData 下,*/ var field = elementHelper.createElement('activiti:FormProperty', { id: value }, extensionElements, bpmnFactory); if (typeof extensionElements.values !== 'undefined') { commands.push(cmdHelper.addElementsTolist(element, extensionElements, 'values', [ field ])); } else { commands.push(cmdHelper.updateBusinessObject(element, extensionElements, { values: [ field ] })); } return commands; }, removeExtensionElement: function(element, extensionElements, value, idx) { var fields = formHelper.getFormFields(element); var entry = fields[idx], commands = []; if (fields.length < 2) { commands.push(removeEntry(getBusinessObject(element), element, extensionElements)); } else { commands.push(cmdHelper.removeElementsFromList(element, extensionElements, 'values', null, [entry])); /* if (entry.id === formData.get('businessKey')) { commands.push(cmdHelper.updateBusinessObject(element, extensionElements, { 'businessKey': undefined })); }*/ } return commands; }, getExtensionElements: function(element) { return formHelper.getFormFields(element); }, hideExtensionElements: function(element, node) { return false; } }); group.entries.push(formFieldsEntry); // [FormData] Form Field label group.entries.push(entryFactory.label({ id: 'form-field-header', labelText: translate('Form Field'), showLabel: function(element, node) { return !!getSelectedFormField(element, node); } })); // [FormData] form field id text input field group.entries.push(entryFactory.validationAwareTextField({ id: 'form-field-id', label: translate('ID'), modelProperty: 'id', getProperty: function(element, node) { var selectedFormField = getSelectedFormField(element, node) || {}; return selectedFormField.id; }, setProperty: function(element, properties, node) { var formField = getSelectedFormField(element, node); return cmdHelper.updateBusinessObject(element, formField, properties); }, hidden: function(element, node) { return !getSelectedFormField(element, node); }, validate: function(element, values, node) { var formField = getSelectedFormField(element, node); if (formField) { var idValue = values.id; if (!idValue || idValue.trim() === '') { return { id: 'Form field id must not be empty' }; } var formFields = formHelper.getFormFields(element); var existingFormField = find(formFields, function(f) { return f !== formField && f.id === idValue; }); if (existingFormField) { return { id: 'Form field id already used in form data.' }; } } } })); // [FormData] form field type combo box group.entries.push(entryFactory.comboBox({ id: 'form-field-type', label: translate('Type'), selectOptions: [ { name: 'string', value: 'string' }, { name: 'long', value: 'long' }, { name: 'boolean', value: 'boolean' }, { name: 'date', value: 'date' }, { name: 'enum', value: 'enum' } ], modelProperty: 'type', emptyParameter: true, get: function(element, node) { var selectedFormField = getSelectedFormField(element, node); if (selectedFormField) { return { type: selectedFormField.type }; } else { return {}; } }, set: function(element, values, node) { var selectedFormField = getSelectedFormField(element, node), commands = []; if (selectedFormField.type === 'enum' && values.type !== 'enum') { // delete activiti:value objects from formField.values when switching from type enum commands.push(cmdHelper.updateBusinessObject(element, selectedFormField, { values: undefined })); } commands.push(cmdHelper.updateBusinessObject(element, selectedFormField, values)); return commands; }, hidden: function(element, node) { return !getSelectedFormField(element, node); } })); // [FormData] form field label text input field group.entries.push(formFieldTextField({ id: 'form-field-label', label: translate('Label'), modelProperty: 'label' }, getSelectedFormField)); // [FormData] form field defaultValue text input field group.entries.push(formFieldTextField({ id: 'form-field-defaultValue', label: translate('Default Value'), modelProperty: 'defaultValue' }, getSelectedFormField)); // [FormData] form field enum values label group.entries.push(entryFactory.label({ id: 'form-field-enum-values-header', labelText: translate('Values'), divider: true, showLabel: function(element, node) { var selectedFormField = getSelectedFormField(element, node); return selectedFormField && selectedFormField.type === 'enum'; } })); // [FormData] form field enum values table group.entries.push(entryFactory.table({ id: 'form-field-enum-values', labels: [ translate('Id'), translate('Name') ], modelProperties: [ 'id', 'name' ], addLabel:translate('Add Value'), show: function(element, node) { var selectedFormField = getSelectedFormField(element, node); return selectedFormField && selectedFormField.type === 'enum'; }, getElements: function(element, node) { var selectedFormField = getSelectedFormField(element, node); return formHelper.getEnumValues(selectedFormField); }, addElement: function(element, node) { var selectedFormField = getSelectedFormField(element, node), id = generateValueId(); var enumValue = elementHelper.createElement( 'activiti:Value', { id: id, name: undefined }, getBusinessObject(element), bpmnFactory ); return cmdHelper.addElementsTolist(element, selectedFormField, 'values', [enumValue]); }, removeElement: function(element, node, idx) { var selectedFormField = getSelectedFormField(element, node), enumValue = selectedFormField.values[idx]; return cmdHelper.removeElementsFromList(element, selectedFormField, 'values', null, [enumValue]); }, updateElement: function(element, value, node, idx) { var selectedFormField = getSelectedFormField(element, node), enumValue = selectedFormField.values[idx]; value.name = value.name || undefined; return cmdHelper.updateBusinessObject(element, enumValue, value); }, validate: function(element, value, node, idx) { var selectedFormField = getSelectedFormField(element, node), enumValue = selectedFormField.values[idx]; if (enumValue) { // check if id is valid var validationError = utils.isIdValid(enumValue, value.id, translate); if (validationError) { return { id: validationError }; } } } })); // [FormData] Validation label group.entries.push(entryFactory.label({ id: 'form-field-validation-header', labelText: translate('Validation'), divider: true, showLabel: function(element, node) { return !!getSelectedFormField(element, node); } })); // [FormData] form field constraints table group.entries.push(entryFactory.table({ id: 'constraints-list', modelProperties: [ 'name', 'config' ], labels: [ translate('Name'), translate('Config') ], addLabel: translate('Add Constraint'), getElements: function(element, node) { var formField = getSelectedFormField(element, node); return formHelper.getConstraints(formField); }, addElement: function(element, node) { var commands = [], formField = getSelectedFormField(element, node), validation = formField.validation; if (!validation) { // create validation business object and add it to form data, if it doesn't exist validation = elementHelper.createElement('activiti:Validation', {}, getBusinessObject(element), bpmnFactory); commands.push(cmdHelper.updateBusinessObject(element, formField, { 'validation': validation })); } var newConstraint = elementHelper.createElement( 'activiti:Constraint', { name: undefined, config: undefined }, validation, bpmnFactory ); commands.push(cmdHelper.addElementsTolist(element, validation, 'constraints', [ newConstraint ])); return commands; }, updateElement: function(element, value, node, idx) { var formField = getSelectedFormField(element, node), constraint = formHelper.getConstraints(formField)[idx]; value.name = value.name || undefined; value.config = value.config || undefined; return cmdHelper.updateBusinessObject(element, constraint, value); }, removeElement: function(element, node, idx) { var commands = [], formField = getSelectedFormField(element, node), constraints = formHelper.getConstraints(formField), currentConstraint = constraints[idx]; commands.push(cmdHelper.removeElementsFromList( element, formField.validation, 'constraints', null, [ currentConstraint ] )); if (constraints.length === 1) { // remove activiti:validation if the last existing constraint has been removed commands.push(cmdHelper.updateBusinessObject(element, formField, { validation: undefined })); } return commands; }, show: function(element, node) { return !!getSelectedFormField(element, node); } })); // [FormData] Properties label group.entries.push(entryFactory.label({ id: 'form-field-properties-header', labelText: translate('Properties'), divider: true, showLabel: function(element, node) { return !!getSelectedFormField(element, node); } })); // [FormData] activiti:properties table group.entries.push(properties(element, bpmnFactory, { id: 'form-field-properties', modelProperties: [ 'id', 'value' ], labels: [ translate('Id'), translate('Value') ], getParent: function(element, node) { return getSelectedFormField(element, node); }, show: function(element, node) { return !!getSelectedFormField(element, node); } }, translate)); };