camunda-dmn-js
Version:
Embeddable Camunda modeling distributions based on dmn-js
1,383 lines (1,328 loc) • 44.1 kB
JavaScript
'use strict';
var DmnModeler = require('dmn-js/lib/Modeler');
var diagramOriginModule = require('diagram-js-origin');
var gridModule = require('diagram-js-grid');
var alignToOriginModule = require('@bpmn-io/align-to-origin');
var dmnJsPropertiesPanel = require('dmn-js-properties-panel');
var minDash = require('min-dash');
var CamundaModdle = require('camunda-dmn-moddle/resources/camunda.json');
var inferno = require('inferno');
var zeebeModdle = require('zeebe-dmn-moddle/resources/zeebe.json');
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
return n;
}
function _arrayWithoutHoles(r) {
if (Array.isArray(r)) return _arrayLikeToArray(r);
}
function _assertThisInitialized(e) {
if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
return e;
}
function _callSuper(t, o, e) {
return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
}
function _classCallCheck(a, n) {
if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
}
function _defineProperties(e, r) {
for (var t = 0; t < r.length; t++) {
var o = r[t];
o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
}
}
function _createClass(e, r, t) {
return r && _defineProperties(e.prototype, r), Object.defineProperty(e, "prototype", {
writable: !1
}), e;
}
function _defineProperty(e, r, t) {
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
value: t,
enumerable: !0,
configurable: !0,
writable: !0
}) : e[r] = t, e;
}
function _getPrototypeOf(t) {
return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
return t.__proto__ || Object.getPrototypeOf(t);
}, _getPrototypeOf(t);
}
function _inherits(t, e) {
if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
t.prototype = Object.create(e && e.prototype, {
constructor: {
value: t,
writable: !0,
configurable: !0
}
}), Object.defineProperty(t, "prototype", {
writable: !1
}), e && _setPrototypeOf(t, e);
}
function _isNativeReflectConstruct() {
try {
var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
} catch (t) {}
return (_isNativeReflectConstruct = function () {
return !!t;
})();
}
function _iterableToArray(r) {
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function ownKeys(e, r) {
var t = Object.keys(e);
if (Object.getOwnPropertySymbols) {
var o = Object.getOwnPropertySymbols(e);
r && (o = o.filter(function (r) {
return Object.getOwnPropertyDescriptor(e, r).enumerable;
})), t.push.apply(t, o);
}
return t;
}
function _objectSpread2(e) {
for (var r = 1; r < arguments.length; r++) {
var t = null != arguments[r] ? arguments[r] : {};
r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
_defineProperty(e, r, t[r]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
});
}
return e;
}
function _objectWithoutProperties(e, t) {
if (null == e) return {};
var o,
r,
i = _objectWithoutPropertiesLoose(e, t);
if (Object.getOwnPropertySymbols) {
var s = Object.getOwnPropertySymbols(e);
for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
}
return i;
}
function _objectWithoutPropertiesLoose(r, e) {
if (null == r) return {};
var t = {};
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
if (e.includes(n)) continue;
t[n] = r[n];
}
return t;
}
function _possibleConstructorReturn(t, e) {
if (e && ("object" == typeof e || "function" == typeof e)) return e;
if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined");
return _assertThisInitialized(t);
}
function _setPrototypeOf(t, e) {
return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
return t.__proto__ = e, t;
}, _setPrototypeOf(t, e);
}
function _toConsumableArray(r) {
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
}
function _toPrimitive(t, r) {
if ("object" != typeof t || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r);
if ("object" != typeof i) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return (String )(t);
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == typeof i ? i : i + "";
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) return _arrayLikeToArray(r, a);
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
/**
* Is an element of the given DMN type?
*
* @param {tjs.model.Base|ModdleElement} element
* @param {string} type
*
* @return {boolean}
*/
function is(element, type) {
var bo = getBusinessObject(element);
return bo && typeof bo.$instanceOf === 'function' && bo.$instanceOf(type);
}
function isInput(element) {
return is(element, 'dmn:InputClause');
}
function isOutput(element) {
return is(element, 'dmn:OutputClause');
}
/**
* Return the business object for a given element.
*
* @param {tjs.model.Base|ModdleElement} element
*
* @return {ModdleElement}
*/
function getBusinessObject(element) {
return element && element.businessObject || element;
}
/**
* Camunda-specific variable provider. Replaces variable name with element's id.
*/
var CamundaVariableProvider = /*#__PURE__*/function () {
function CamundaVariableProvider(variableResolver) {
_classCallCheck(this, CamundaVariableProvider);
variableResolver.registerProvider(this);
}
return _createClass(CamundaVariableProvider, [{
key: "getVariables",
value: function getVariables(variables, element) {
return variables.map(function (variable) {
return _objectSpread2(_objectSpread2({}, variable), {}, {
name: getVariableName(variable)
});
});
}
}]);
}();
CamundaVariableProvider.$inject = ['variableResolver'];
function getVariableName(variable) {
var origin = variable.origin;
if (origin && is(origin, 'dmn:Decision')) {
return origin.get('id');
}
return variable.name;
}
/**
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership.
*
* Camunda licenses this file to you under the MIT; you may not use this file
* except in compliance with the MIT License.
*/
var CamundaVariableProviderModule = {
__init__: ['camundaVariableProvider'],
camundaVariableProvider: ['type', CamundaVariableProvider]
};
var _excluded = ["boxedExpression", "common", "decisionTable", "drd", "literalExpression"];
var CamundaDmnModeler$2 = /*#__PURE__*/function (_DmnModeler) {
function CamundaDmnModeler() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, CamundaDmnModeler);
var _options$boxedExpress = options.boxedExpression,
boxedExpression = _options$boxedExpress === void 0 ? {} : _options$boxedExpress,
_options$common = options.common,
common = _options$common === void 0 ? {} : _options$common,
_options$decisionTabl = options.decisionTable,
decisionTable = _options$decisionTabl === void 0 ? {} : _options$decisionTabl,
_options$drd = options.drd,
drd = _options$drd === void 0 ? {} : _options$drd,
_options$literalExpre = options.literalExpression,
literalExpression = _options$literalExpre === void 0 ? {} : _options$literalExpre,
otherOptions = _objectWithoutProperties(options, _excluded);
var disableAdjustOrigin = drd.disableAdjustOrigin || common.disableAdjustOrigin;
var disableGrid = drd.disableGrid || common.disableGrid;
return _callSuper(this, CamundaDmnModeler, [_objectSpread2(_objectSpread2({}, otherOptions), {}, {
common: _objectSpread2(_objectSpread2({}, common), {}, {
feelLanguageContext: _objectSpread2({
parserDialect: 'camunda'
}, common === null || common === void 0 ? void 0 : common.feelLanguageContext)
}),
boxedExpression: mergeModules$2(boxedExpression, [CamundaVariableProviderModule]),
decisionTable: mergeModules$2(decisionTable, [CamundaVariableProviderModule]),
drd: mergeModules$2(drd, [disableAdjustOrigin ? diagramOriginModule : alignToOriginModule, disableGrid ? {} : gridModule, dmnJsPropertiesPanel.DmnPropertiesPanelModule, dmnJsPropertiesPanel.DmnPropertiesProviderModule]),
literalExpression: mergeModules$2(literalExpression, [CamundaVariableProviderModule])
})]);
}
_inherits(CamundaDmnModeler, _DmnModeler);
return _createClass(CamundaDmnModeler);
}(DmnModeler); // helpers ///////////////////////
function mergeModules$2(config, editorModules) {
var additionalModules = config.additionalModules || [];
return _objectSpread2(_objectSpread2({}, config), {}, {
additionalModules: [].concat(_toConsumableArray(editorModules), _toConsumableArray(additionalModules))
});
}
class Input extends inferno.Component {
constructor(props, context) {
super(props, context);
this.state = {
value: props.value
};
}
onInput = event => {
const {
onInput
} = this.props;
const value = event.target.value;
this.setState({
value
}, () => {
if (typeof onInput !== 'function') {
return;
}
onInput(value);
});
};
onChange = event => {
const {
onChange
} = this.props;
if (typeof onChange !== 'function') {
return;
}
onChange(event.target.value);
};
onKeyDown = event => {
const {
onKeyDown
} = this.props;
if (typeof onKeyDown !== 'function') {
return;
}
onKeyDown(event);
};
onKeyUp = event => {
const {
onKeyUp
} = this.props;
if (typeof onKeyUp !== 'function') {
return;
}
onKeyUp(event);
};
componentDidUpdate(prevProps) {
const {
value
} = this.props;
if (value !== prevProps.value && value !== this.state.value) {
this.setState({
value
});
}
}
render() {
const {
className,
label,
id,
placeholder,
type
} = this.props;
const {
value
} = this.state;
return inferno.createVNode(64, "input", [className || '', 'dms-input'].join(' '), null, 1, {
"aria-label": label,
"placeholder": placeholder || '',
"onChange": this.onChange,
"onInput": this.onInput,
"onKeyDown": this.onKeyDown,
"onKeyUp": this.onKeyUp,
"spellCheck": "false",
"type": type || 'text',
"value": value,
"id": id
});
}
}
var InputEditor = /*#__PURE__*/function (_Component) {
function InputEditor(props, context) {
var _this;
_classCallCheck(this, InputEditor);
_this = _callSuper(this, InputEditor, [props, context]);
_this._translate = context.injector.get('translate');
_this._modeling = context.injector.get('modeling');
var debounceInput = context.injector.get('debounceInput');
_this.state = {
inputVariable: _this.props.context.input.get('camunda:inputVariable') || ''
};
_this.handleInputVariableChange = _this.handleInputVariableChange.bind(_this);
_this._setInputVariable = debounceInput(_this._setInputVariable);
return _this;
}
_inherits(InputEditor, _Component);
return _createClass(InputEditor, [{
key: "handleInputVariableChange",
value: function handleInputVariableChange(value) {
var _this2 = this;
this.setState({
inputVariable: value || undefined
}, function () {
return _this2._setInputVariable(value);
});
}
}, {
key: "_setInputVariable",
value: function _setInputVariable(inputVariable) {
return this._modeling.updateProperties(this.props.context.input, {
// set to <undefined> to remove the property
'camunda:inputVariable': inputVariable || undefined
});
}
}, {
key: "render",
value: function render() {
var inputVariable = this.state.inputVariable;
return inferno.createVNode(1, "div", "context-menu-container", inferno.createVNode(1, "div", "dms-form-control", [inferno.createVNode(1, "label", "dms-label", this._translate('Input Variable'), 0), inferno.createComponentVNode(2, Input, {
"className": "ref-input-variable",
"value": inputVariable || '',
"onInput": this.handleInputVariableChange,
"placeholder": this._translate('cellInput')
})], 4), 2);
}
}]);
}(inferno.Component);
var InputVariableProvider = /*#__PURE__*/_createClass(function InputVariableProvider(components) {
_classCallCheck(this, InputVariableProvider);
components.onGetComponent('context-menu', function () {
var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (context.contextMenuType === 'input-edit') {
return InputEditor;
}
});
});
InputVariableProvider.$inject = ['components'];
var InputVariableModule = {
__init__: ['camundaPlatformInputVariable'],
camundaPlatformInputVariable: ['type', InputVariableProvider]
};
/**
* Input with optional validation.
*/
class ValidatedInput extends inferno.Component {
constructor(props, context) {
super(props, context);
const {
validate,
value
} = props;
const validationWarning = validate ? validate(value || '') : undefined;
this.state = {
validationWarning,
value
};
this.onInput = this.onInput.bind(this);
this.onKeyDown = this.onKeyDown.bind(this);
this.onKeyUp = this.onKeyUp.bind(this);
}
componentWillReceiveProps(props) {
const {
validate,
value
} = props;
const validationWarning = validate ? validate(value || '') : undefined;
this.setState({
validationWarning,
value
});
}
onInput(value) {
const {
onInput,
validate
} = this.props;
const validationWarning = validate ? validate(value) : undefined;
this.setState({
validationWarning,
value
});
if (typeof onInput !== 'function') {
return;
}
onInput && onInput({
isValid: !validationWarning,
value
});
}
onKeyDown(event) {
const {
target
} = event,
{
value
} = target;
const {
onKeyDown,
validate
} = this.props;
const validationWarning = validate ? validate(value) : undefined;
if (typeof onKeyDown !== 'function') {
return;
}
onKeyDown({
isValid: !validationWarning,
value,
event
});
}
onKeyUp(event) {
const {
target
} = event,
{
value
} = target;
const {
onKeyUp,
validate
} = this.props;
const validationWarning = validate ? validate(value) : undefined;
if (typeof onKeyUp !== 'function') {
return;
}
onKeyUp({
isValid: !validationWarning,
value,
event
});
}
render() {
const {
placeholder,
type,
className,
label
} = this.props;
const {
validationWarning,
value
} = this.state;
const parentClasses = ['dms-validated-input', className].join(' ');
const inputClasses = [];
if (validationWarning) {
inputClasses.push('invalid');
}
return inferno.createVNode(1, "div", parentClasses, [inferno.createComponentVNode(2, Input, {
"className": inputClasses,
"label": label,
"onInput": this.onInput,
"onKeyDown": this.onKeyDown,
"onKeyUp": this.onKeyUp,
"placeholder": placeholder || '',
"type": type,
"value": value || ''
}), validationWarning && inferno.createVNode(1, "p", "dms-hint dms-validation-warning", validationWarning, 0)], 0);
}
}
function inject(component) {
const Type = component.constructor;
return injectType(Type, component);
}
function injectType(Type, component) {
const annotation = Type.$inject;
if (!annotation) {
return;
}
const {
injector
} = component.context;
const setupFn = [...annotation, function (...args) {
for (const idx in args) {
const name = annotation[idx];
const value = args[idx];
component[name] = value;
}
}];
injector.invoke(setupFn);
}
/**
* Expose `parse`.
*/
var domify = parse;
/**
* Tests for browser support.
*/
var innerHTMLBug = false;
var bugTestDiv;
if (typeof document !== 'undefined') {
bugTestDiv = document.createElement('div');
// Setup
bugTestDiv.innerHTML = ' <link/><table></table><a href="/a">a</a><input type="checkbox"/>';
// Make sure that link elements get serialized correctly by innerHTML
// This requires a wrapper element in IE
innerHTMLBug = !bugTestDiv.getElementsByTagName('link').length;
bugTestDiv = undefined;
}
/**
* Wrap map from jquery.
*/
var map = {
legend: [1, '<fieldset>', '</fieldset>'],
tr: [2, '<table><tbody>', '</tbody></table>'],
col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
// for script/link/style tags to work in IE6-8, you have to wrap
// in a div with a non-whitespace character in front, ha!
_default: innerHTMLBug ? [1, 'X<div>', '</div>'] : [0, '', '']
};
map.td = map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
map.option = map.optgroup = [1, '<select multiple="multiple">', '</select>'];
map.thead = map.tbody = map.colgroup = map.caption = map.tfoot = [1, '<table>', '</table>'];
map.polyline = map.ellipse = map.polygon = map.circle = map.text = map.line = map.path = map.rect = map.g = [1, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">', '</svg>'];
/**
* Parse `html` and return a DOM Node instance, which could be a TextNode,
* HTML DOM Node of some kind (<div> for example), or a DocumentFragment
* instance, depending on the contents of the `html` string.
*
* @param {String} html - HTML string to "domify"
* @param {Document} doc - The `document` instance to create the Node for
* @return {DOMNode} the TextNode, DOM Node, or DocumentFragment instance
* @api private
*/
function parse(html, doc) {
if ('string' != typeof html) throw new TypeError('String expected');
// default to the global `document` object
if (!doc) doc = document;
// tag name
var m = /<([\w:]+)/.exec(html);
if (!m) return doc.createTextNode(html);
html = html.replace(/^\s+|\s+$/g, ''); // Remove leading/trailing whitespace
var tag = m[1];
// body support
if (tag == 'body') {
var el = doc.createElement('html');
el.innerHTML = html;
return el.removeChild(el.lastChild);
}
// wrap map
var wrap = Object.prototype.hasOwnProperty.call(map, tag) ? map[tag] : map._default;
var depth = wrap[0];
var prefix = wrap[1];
var suffix = wrap[2];
var el = doc.createElement('div');
el.innerHTML = prefix + html + suffix;
while (depth--) el = el.lastChild;
// one element
if (el.firstChild == el.lastChild) {
return el.removeChild(el.firstChild);
}
// several elements
var fragment = doc.createDocumentFragment();
while (el.firstChild) {
fragment.appendChild(el.removeChild(el.firstChild));
}
return fragment;
}
var domify$1 = domify;
function remove(el) {
el.parentNode && el.parentNode.removeChild(el);
}
class InputSelect extends inferno.Component {
constructor(props, context) {
super(props, context);
inject(this);
const {
value
} = props;
this.state = {
value,
optionsVisible: false
};
this._portalEl = null;
}
componentDidMount() {
document.addEventListener('mousedown', this.onGlobalClick);
document.addEventListener('focusin', this.onFocusChanged);
this.keyboard.addListener(this.onKeyboard);
}
componentWillUnmount() {
document.removeEventListener('focusin', this.onFocusChanged);
document.removeEventListener('mousedown', this.onGlobalClick);
this.keyboard.removeListener(this.onKeyboard);
this.removePortalEl();
}
componentWillReceiveProps(props) {
const {
value
} = props;
this.setState({
value
});
}
componentWillUpdate(nextProps, nextState) {
const {
optionsVisible
} = nextState;
if (optionsVisible) {
if (!this._portalEl) {
this.addPortalEl();
}
} else {
if (this._portalEl) {
this.removePortalEl();
}
}
}
componentDidUpdate() {
const {
optionsVisible
} = this.state;
if (!optionsVisible || !this.inputNode) {
return;
}
const optionsBounds = this.getOptionsBounds();
minDash.assign(this._portalEl.style, optionsBounds);
}
getOptionsBounds() {
const container = this.renderer.getContainer();
const {
top: containerTop,
left: containerLeft,
bottom: containerBottom
} = container.getBoundingClientRect();
const {
top: inputTop,
left: inputLeft,
width,
height,
bottom: inputBottom
} = this.inputNode.getBoundingClientRect();
const top = inputTop + height - containerTop + container.scrollTop;
const left = inputLeft - containerLeft + container.scrollLeft;
const bounds = {
top: `${top}px`,
left: `${left}px`,
width: `${width}px`,
'max-height': `calc(100% - ${top}px)`
};
// open the options upwards when not even one option (=input height) fits
if (containerBottom - inputBottom < height) {
const bottom = containerBottom - inputTop;
bounds.bottom = `${bottom}px`;
bounds['max-height'] = `calc(100% - ${bottom})`;
delete bounds.top;
}
return bounds;
}
addPortalEl() {
this._portalEl = domify$1('<div class="dms-select-options"></div>');
const container = this.renderer.getContainer();
container.appendChild(this._portalEl);
// suppress mousedown event propagation to handle click events inside the component
this._portalEl.addEventListener('mousedown', stopPropagation);
}
removePortalEl() {
if (this._portalEl) {
this._portalEl.removeEventListener('mousedown', stopPropagation);
remove(this._portalEl);
this._portalEl = null;
}
}
onChange = value => {
this.setState({
value
});
const {
onChange
} = this.props;
if (typeof onChange !== 'function') {
return;
}
onChange(value);
};
onInputClick = event => {
event.preventDefault();
event.stopPropagation();
this.setOptionsVisible(!this.state.optionsVisible);
this.focusInput();
};
onInput = event => {
const {
value
} = event.target;
this.onChange(value);
};
onOptionClick = (value, event) => {
event.preventDefault();
event.stopPropagation();
this.setOptionsVisible(false);
this.onChange(value);
this.focusInput();
};
/**
* Focus input node
*/
focusInput() {
const node = this.inputNode;
node.focus();
// move cursor to end of input
if ('selectionStart' in node) {
node.selectionStart = 100000;
}
}
checkClose(focusTarget) {
if (this._portalEl && !this._portalEl.contains(focusTarget) && !this.parentNode.contains(focusTarget)) {
this.setOptionsVisible(false);
}
}
onFocusChanged = evt => {
this.checkClose(evt.target);
};
onGlobalClick = evt => {
this.checkClose(evt.target);
};
select(direction) {
const {
options
} = this.props;
const {
value
} = this.state;
if (!options) {
return;
}
const option = options.filter(o => o.value === value)[0];
const idx = option ? options.indexOf(option) : -1;
const nextIdx = idx === -1 ? direction === 1 ? 0 : options.length - 1 : (idx + direction) % options.length;
const nextOption = options[nextIdx < 0 ? options.length + nextIdx : nextIdx];
this.onChange(nextOption.value);
}
setOptionsVisible(optionsVisible) {
this.setState({
optionsVisible
});
}
onKeyDown = evt => {
const {
optionsVisible
} = this.state;
var code = evt.which;
// DOWN or UP
if (code === 40 || code === 38) {
evt.stopPropagation();
evt.preventDefault();
if (!optionsVisible) {
this.setOptionsVisible(true);
} else {
this.select(code === 40 ? 1 : -1);
}
}
if (optionsVisible) {
// ENTER
// ESC
if (code === 13 || code === 27) {
evt.stopPropagation();
evt.preventDefault();
this.setOptionsVisible(false);
}
}
};
onKeyboard = keycode => {
const {
optionsVisible
} = this.state;
if (!optionsVisible) {
return;
}
// close on ESC
if (keycode === 27) {
this.setOptionsVisible(false);
return true;
}
};
renderOptions(options, activeOption) {
return inferno.createVNode(1, "div", "options", options.map(option => {
return inferno.createVNode(1, "div", ['option', activeOption === option ? 'active' : ''].join(' '), option.label, 0, {
"data-value": option.value,
"onClick": e => this.onOptionClick(option.value, e)
});
}), 0);
}
render() {
const {
className,
label: inputLabel,
id,
options,
noInput,
title
} = this.props;
const {
optionsVisible,
value
} = this.state;
const option = options ? options.filter(o => o.value === value)[0] : false;
const label = option ? option.label : value;
return inferno.createVNode(1, "div", [className || '', 'dms-input-select'].join(' '), [noInput ? inferno.createVNode(1, "div", "dms-input", label, 0, {
"aria-label": inputLabel,
"tabIndex": "0",
"onKeyDown": this.onKeyDown
}, null, node => this.inputNode = node) : inferno.createVNode(64, "input", "dms-input", null, 1, {
"aria-label": inputLabel,
"onInput": this.onInput,
"onKeyDown": this.onKeyDown,
"spellCheck": "false",
"type": "text",
"value": value,
"id": id
}, null, node => this.inputNode = node), inferno.createVNode(1, "span", ['dms-input-select-icon', optionsVisible ? 'dmn-icon-up' : 'dmn-icon-down'].join(' ')), optionsVisible && inferno.createPortal(this.renderOptions(options, option), this._portalEl)], 0, {
"title": title,
"onClick": this.onInputClick
}, null, node => this.parentNode = node);
}
}
InputSelect.$inject = ['keyboard', 'renderer'];
// helper ////
function stopPropagation(event) {
event.stopPropagation();
}
var ISO_DATE_REGEX = /^\d{4}(?:-\d\d){2}T(?:\d\d:){2}\d\d$/;
var BETWEEN_DATE_REGEX = /^\[date and time\("(\d{4}(?:-\d\d){2}T(?:\d\d:){2}\d\d)"\)..date and time\("(\d{4}(?:-\d\d){2}T(?:\d\d:){2}\d\d)"/;
var BEFORE_AFTER_DATE_REGEX = /^(<|>)\s*date and time\("(\d{4}(?:-\d\d){2}T(?:\d\d:){2}\d\d)"\)/;
var EXACT_DATE_REGEX = /^date and time\("(\d{4}(?:-\d\d){2}T(?:\d\d:){2}\d\d)"\)$/;
var EXACT$1 = 'exact',
BEFORE$1 = 'before',
AFTER$1 = 'after',
BETWEEN$1 = 'between';
function validateISOString(string) {
if (!ISO_DATE_REGEX.test(string.trim())) {
return 'Date must match pattern yyyy-MM-ddTHH:mm:ss.';
}
}
function getDateString(type, dates) {
if (type === EXACT$1) {
return "date and time(\"".concat(dates[0], "\")");
} else if (type === BEFORE$1) {
return "< date and time(\"".concat(dates[0], "\")");
} else if (type === AFTER$1) {
return "> date and time(\"".concat(dates[0], "\")");
} else if (type === BETWEEN$1) {
return "[date and time(\"".concat(dates[0], "\")..date and time(\"").concat(dates[1], "\")]");
}
}
function getSampleDate() {
var date = new Date();
date.setUTCHours(0, 0, 0, 0);
return date.toISOString().slice(0, -5);
}
function parseString(string) {
// emtpy
if (!string || string.trim() === '') {
return {
type: 'exact',
date: ''
};
}
// between
var matches = string.match(BETWEEN_DATE_REGEX);
if (matches) {
return {
type: 'between',
dates: [matches[1], matches[2]]
};
}
// before or after
matches = string.match(BEFORE_AFTER_DATE_REGEX);
if (matches) {
return {
type: matches[1] === '<' ? 'before' : 'after',
date: matches[2]
};
}
// exact
matches = string.match(EXACT_DATE_REGEX);
if (matches) {
return {
type: 'exact',
date: matches[1]
};
}
}
var EXACT = 'exact',
BEFORE = 'before',
AFTER = 'after',
BETWEEN = 'between';
var InputDateEdit = /*#__PURE__*/function (_Component) {
function InputDateEdit(props, context) {
var _this;
_classCallCheck(this, InputDateEdit);
_this = _callSuper(this, InputDateEdit, [props, context]);
_this._modeling = context.injector.get('modeling');
var element = _this.props.context.element;
var parsedString = parseString(element.businessObject.text);
if (parsedString) {
var dates;
if (parsedString.date) {
dates = [parsedString.date, ''];
} else if (parsedString.dates) {
dates = parsedString.dates;
} else {
dates = ['', ''];
}
_this.state = {
type: parsedString.type,
dates: dates
};
} else {
_this.state = {
type: EXACT,
dates: ['', '']
};
}
var debounceInput = context.injector.get('debounceInput');
_this.debouncedEditCell = debounceInput(_this.editCell.bind(_this));
_this.editCell = _this.editCell.bind(_this);
_this.onTypeChange = _this.onTypeChange.bind(_this);
_this.onSetStartDateTodayClick = _this.onSetStartDateTodayClick.bind(_this);
_this.onSetEndDateTodayClick = _this.onSetEndDateTodayClick.bind(_this);
_this.onStartDateInput = _this.onStartDateInput.bind(_this);
_this.onEndDateInput = _this.onEndDateInput.bind(_this);
return _this;
}
_inherits(InputDateEdit, _Component);
return _createClass(InputDateEdit, [{
key: "editCell",
value: function editCell(cell, text) {
this._modeling.editCell(cell, text);
}
}, {
key: "onTypeChange",
value: function onTypeChange(value) {
var element = this.props.context.element;
var dates = this.state.dates;
this.setState({
type: value
});
if (parseString(getDateString(value, dates))) {
this.editCell(element.businessObject, getDateString(value, dates));
}
}
}, {
key: "onSetStartDateTodayClick",
value: function onSetStartDateTodayClick() {
var element = this.props.context.element;
var _this$state = this.state,
dates = _this$state.dates,
type = _this$state.type;
var date = getSampleDate();
this.setState({
dates: [date, dates[1]]
});
if (parseString(getDateString(type, [date, dates[1]]))) {
this.editCell(element.businessObject, getDateString(type, [date, dates[1]]));
}
}
}, {
key: "onSetEndDateTodayClick",
value: function onSetEndDateTodayClick() {
var element = this.props.context.element;
var _this$state2 = this.state,
dates = _this$state2.dates,
type = _this$state2.type;
var date = getSampleDate();
this.setState({
dates: [dates[0], date]
});
if (parseString(getDateString(type, [dates[0], date]))) {
this.editCell(element.businessObject, getDateString(type, [dates[0], date]));
}
}
}, {
key: "onStartDateInput",
value: function onStartDateInput(_ref) {
var isValid = _ref.isValid,
value = _ref.value;
if (isValid) {
var element = this.props.context.element;
var _this$state3 = this.state,
dates = _this$state3.dates,
type = _this$state3.type;
this.setState({
dates: [value, dates[1]]
});
this.debouncedEditCell(element.businessObject, getDateString(type, [value, dates[1]]));
}
}
}, {
key: "onEndDateInput",
value: function onEndDateInput(_ref2) {
var isValid = _ref2.isValid,
value = _ref2.value;
if (isValid) {
var element = this.props.context.element;
var _this$state4 = this.state,
dates = _this$state4.dates,
type = _this$state4.type;
this.setState({
dates: [dates[0], value]
});
this.debouncedEditCell(element.businessObject, getDateString(type, [dates[0], value]));
}
}
}, {
key: "render",
value: function render() {
var _this$state5 = this.state,
dates = _this$state5.dates,
type = _this$state5.type;
var options = [{
label: 'Exactly',
value: EXACT
}, {
label: 'Before',
value: BEFORE
}, {
label: 'After',
value: AFTER
}, {
label: 'Between',
value: BETWEEN
}];
return inferno.createVNode(1, "div", "context-menu-container simple-date-edit", [inferno.createVNode(1, "h3", "dms-heading", inferno.createTextVNode("Edit Date"), 2), inferno.createVNode(1, "div", "dms-fill-row", inferno.createComponentVNode(2, InputSelect, {
"noInput": true,
"onChange": this.onTypeChange,
"options": options,
"value": type
}), 2), inferno.createVNode(1, "h4", "dms-heading", type === BETWEEN ? 'Edit Start Date' : 'Set Date', 0), inferno.createVNode(1, "div", null, [inferno.createComponentVNode(2, ValidatedInput, {
"className": "start-date-input dms-block",
"onInput": this.onStartDateInput,
"placeholder": "e.g. ".concat(getSampleDate()),
"validate": validateISOString,
"value": dates[0]
}), inferno.createVNode(1, "p", "dms-hint", [inferno.createVNode(1, "button", "use-today", inferno.createTextVNode("Use today"), 2, {
"type": "button",
"onClick": this.onSetStartDateTodayClick
}), inferno.createTextVNode(".")], 4)], 4), type === BETWEEN && inferno.createVNode(1, "h4", "dms-heading", inferno.createTextVNode("Edit End Date"), 2), type === BETWEEN && inferno.createVNode(1, "div", null, [inferno.createComponentVNode(2, ValidatedInput, {
"className": "end-date-input dms-block",
"onInput": this.onEndDateInput,
"placeholder": "e.g. ".concat(getSampleDate()),
"validate": validateISOString,
"value": dates[1]
}), inferno.createVNode(1, "p", "dms-hint", [inferno.createVNode(1, "button", "use-today", inferno.createTextVNode("Use today"), 2, {
"type": "button",
"onClick": this.onSetEndDateTodayClick
}), inferno.createTextVNode(".")], 4)], 4)], 0);
}
}]);
}(inferno.Component);
var OutputDateEdit = /*#__PURE__*/function (_Component) {
function OutputDateEdit(props, context) {
var _this;
_classCallCheck(this, OutputDateEdit);
_this = _callSuper(this, OutputDateEdit, [props, context]);
_this._modeling = context.injector.get('modeling');
var element = _this.props.context.element;
var parsedString = parseString(element.businessObject.text);
_this.state = {
date: parsedString ? parsedString.date : ''
};
var debounceInput = context.injector.get('debounceInput');
_this.debouncedEditCell = debounceInput(_this.editCell.bind(_this));
_this.editCell = _this.editCell.bind(_this);
_this.onClick = _this.onClick.bind(_this);
_this.onInput = _this.onInput.bind(_this);
return _this;
}
_inherits(OutputDateEdit, _Component);
return _createClass(OutputDateEdit, [{
key: "editCell",
value: function editCell(cell, text) {
this._modeling.editCell(cell, text);
}
}, {
key: "onClick",
value: function onClick() {
var element = this.props.context.element;
var date = getSampleDate();
this.setState({
date: date
});
this.editCell(element.businessObject, "date and time(\"".concat(date, "\")"));
}
}, {
key: "onInput",
value: function onInput(_ref) {
var isValid = _ref.isValid,
value = _ref.value;
if (isValid) {
var element = this.props.context.element;
this.setState({
date: value
});
this.debouncedEditCell(element.businessObject, "date and time(\"".concat(value, "\")"));
}
}
}, {
key: "render",
value: function render() {
var date = this.state.date;
return inferno.createVNode(1, "div", "context-menu-container simple-date-edit", [inferno.createVNode(1, "h3", "dms-heading", inferno.createTextVNode("Edit Date"), 2), inferno.createVNode(1, "h4", "dms-heading", inferno.createTextVNode("Set Date"), 2), inferno.createVNode(1, "div", null, [inferno.createComponentVNode(2, ValidatedInput, {
"onInput": this.onInput,
"placeholder": "e.g. ".concat(getSampleDate()),
"validate": validateISOString,
"value": date,
"className": "dms-block"
}), inferno.createVNode(1, "p", "dms-hint", [inferno.createTextVNode("Set date "), inferno.createVNode(1, "button", "use-today", inferno.createTextVNode("to today"), 2, {
"type": "button",
"onClick": this.onClick
}), inferno.createTextVNode(".")], 4)], 4)], 4);
}
}]);
}(inferno.Component);
var SimpleDateEdit = /*#__PURE__*/_createClass(function SimpleDateEdit(components, simpleMode) {
_classCallCheck(this, SimpleDateEdit);
simpleMode.registerProvider(function (element) {
var typeRef = getTypeRef(element);
return (isInput(element.col) || isOutput(element.col)) && isDate(typeRef);
});
components.onGetComponent('context-menu', function () {
var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (context.contextMenuType && context.contextMenuType === 'simple-mode-edit') {
if (!context.element) {
return;
}
var typeRef = getTypeRef(context.element);
if (isDate(typeRef)) {
if (isInput(context.element.col)) {
return InputDateEdit;
} else if (isOutput(context.element.col)) {
return OutputDateEdit;
}
}
}
});
});
SimpleDateEdit.$inject = ['components', 'simpleMode'];
// helpers //////////////////////
function getTypeRef(element) {
if (isInput(element.col)) {
return element.col && element.col.businessObject.inputExpression.typeRef;
} else {
return element.col && element.col.businessObject.typeRef;
}
}
function isDate(typeRef) {
return typeRef === 'date';
}
var SimpleDateEditModule = {
__init__: ['simpleDateEdit'],
simpleDateEdit: ['type', SimpleDateEdit]
};
// disables simple edit mode for unsupported data types
var SimpleModeModule = {
simpleDurationEdit: ['type', noop],
simpleDateTimeEdit: ['type', noop],
simpleTimeEdit: ['type', noop]
};
function noop() {}
var EXPRESSION_LANGUAGE_OPTIONS = [{
label: 'FEEL',
value: 'feel'
}, {
label: 'JUEL',
value: 'juel'
}, {
label: 'JavaScript',
value: 'javascript'
}, {
label: 'Groovy',
value: 'groovy'
}, {
label: 'Python',
value: 'python'
}, {
label: 'JRuby',
value: 'jruby'
}];
var dataTypes = ['string', 'boolean', 'integer', 'long', 'double', 'date'];
var CamundaDmnModeler$1 = /*#__PURE__*/function (_BaseModeler) {
function CamundaDmnModeler() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, CamundaDmnModeler);
var expressionLanguages = mergeExpressionLanguagesConfig(options.common);
var decisionTable = options.decisionTable || {};
var drd = options.drd || {};
var boxedExpression = options.boxedExpression || {};
return _callSuper(this, CamundaDmnModeler, [_objectSpread2(_objectSpread2({}, options), {}, {
boxedExpression: boxedExpression,
common: _objectSpread2(_objectSpread2({
dataTypes: dataTypes
}, options.common), {}, {
expressionLanguages: expressionLanguages
}),
decisionTable: mergeModules$1(decisionTable, [InputVariableModule, SimpleDateEditModule, SimpleModeModule]),
drd: mergeModules$1(drd, [dmnJsPropertiesPanel.CamundaPropertiesProviderModule]),
moddleExtensions: _objectSpread2({
camunda: CamundaModdle
}, options.moddleExtensions)
})]);
}
_inherits(CamundaDmnModeler, _BaseModeler);
return _createClass(CamundaDmnModeler);
}(CamundaDmnModeler$2);
function mergeExpressionLanguagesConfig() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var expressionLanguagesConfig = options.expressionLanguages || {};
var effectiveConfig = {
options: expressionLanguagesConfig.options || EXPRESSION_LANGUAGE_OPTIONS,
"default": expressionLanguagesConfig["default"] || {
editor: 'feel'
}
};
return effectiveConfig;
}
// helpers ///////////////////////
function mergeModules$1(config, editorModules) {
var additionalModules = config.additionalModules || [];
return _objectSpread2(_objectSpread2({}, config), {}, {
additionalModules: [].concat(_toConsumableArray(editorModules), _toConsumableArray(additionalModules))
});
}
/**
* @type { {
* zeebe: any
* } }
*/
var commonModdleExtensions = {
zeebe: zeebeModdle
};
var CamundaDmnModeler = /*#__PURE__*/function (_BaseModeler) {
function CamundaDmnModeler() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, CamundaDmnModeler);
var _options$common = options.common,
common = _options$common === void 0 ? {} : _options$common,
_options$drd = options.drd,
drd = _options$drd === void 0 ? {} : _options$drd,
_options$moddleExtens = options.moddleExtensions,
moddleExtensions = _options$moddleExtens === void 0 ? {} : _options$moddleExtens;
var _common$propertiesPan = common.propertiesPanel,
propertiesPanel = _common$propertiesPan === void 0 ? {} : _common$propertiesPan;
return _callSuper(this, CamundaDmnModeler, [_objectSpread2(_objectSpread2({}, options), {}, {
common: _objectSpread2(_objectSpread2({}, common), {}, {
propertiesPanel: _objectSpread2(_objectSpread2({}, propertiesPanel), {}, {
tooltip: dmnJsPropertiesPanel.ZeebeTooltipProvider
})
}),
drd: mergeModules(drd, [dmnJsPropertiesPanel.ZeebePropertiesProviderModule]),
moddleExtensions: _objectSpread2(_objectSpread2({}, commonModdleExtensions), moddleExtensions)
})]);
}
_inherits(CamundaDmnModeler, _BaseModeler);
return _createClass(CamundaDmnModeler);
}(CamundaDmnModeler$2); // helpers ///////////////////////
function mergeModules(config, editorModules) {
var additionalModules = config.additionalModules || [];
return _objectSpread2(_objectSpread2({}, config), {}, {
additionalModules: [].concat(_toConsumableArray(editorModules), _toConsumableArray(additionalModules))
});
}
exports.BaseModeler = CamundaDmnModeler$2;
exports.CamundaCloudModeler = CamundaDmnModeler;
exports.CamundaPlatformModeler = CamundaDmnModeler$1;
//# sourceMappingURL=index.js.map