@5minds/node-red-dashboard-2-processcube-dynamic-list
Version:
A ui component for showing progress bars tracking a process
228 lines (200 loc) • 10.2 kB
HTML
<script type="text/javascript">
(function () {
function hasProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
RED.nodes.registerType('ui-dynamic-list', {
category: 'ProcessCube UI',
color: '#00aed7',
defaults: {
name: { value: '' },
group: { type: 'ui-group', required: true },
order: { value: 1 },
itemHoverEffect: { value: true },
actions: {
value: [],
validate: function (v) {
const unique = new Set(
v.map(function (o) {
return o.id;
})
);
return v.length === unique.size;
},
},
width: {
value: 0,
validate: function (v) {
const width = v || 0;
const currentGroup = $('#node-input-group').val() || this.group;
const groupNode = RED.nodes.node(currentGroup);
const valid = !groupNode || +width <= +groupNode.width;
$('#node-input-size').toggleClass('input-error', !valid);
return valid;
},
},
height: { value: 0 },
outputs: { value: 1 },
},
inputs: 1,
outputs: 1,
outputLabels: function (index) {
return index !== 0 ? this.actions[index - 1].id : 'Entry clicked';
},
icon: 'ui_dynamic_list.svg',
paletteLabel: 'ui-dynamic-list',
label: function () {
return this.name || 'ui-dynamic-list';
},
oneditprepare: function () {
$('#node-input-size').elementSizer({
width: '#node-input-width',
height: '#node-input-height',
group: '#node-input-group',
});
function generateAction(i, action) {
const container = $('<li/>', {
style: 'background: var(--red-ui-secondary-background, #fff); margin:0; padding:8px 0px 0px;',
});
// Create input fields for icon and id
const row = $('<div/>').appendTo(container);
$('<input/>', {
class: 'node-input-action-id',
type: 'text',
style: 'margin-left:7px; width:calc(50% - 32px);',
placeholder: 'Id',
value: action.id,
})
.appendTo(row)
.typedInput({
type: 'str',
types: ['str'],
});
$('<input/>', {
class: 'node-input-action-icon',
type: 'text',
style: 'margin-left:7px; width:calc(50% - 32px);',
placeholder: 'Icon',
value: action.icon,
})
.appendTo(row)
.typedInput({
type: 'str',
types: ['str'],
});
// Create delete button for the action
const finalSpan = $('<span/>', {
style: 'float:right; margin-right:8px;',
}).appendTo(row);
const deleteButton = $('<a/>', {
href: '#',
class: 'editor-button editor-button-small',
style: 'margin-top:7px; margin-left:5px;',
}).appendTo(finalSpan);
$('<i/>', { class: 'fa fa-remove' }).appendTo(deleteButton);
deleteButton.click(function () {
container.css({
background: 'var(--red-ui-secondary-background-inactive, #fee)',
});
container.fadeOut(300, function () {
$(this).remove();
});
});
$('#node-input-action-container').append(container);
}
$('#node-input-add-action').click(function () {
generateAction($('#node-input-action-container').children().length + 1, {});
$('#node-input-action-container-div').scrollTop(
$('#node-input-action-container-div').get(0).scrollHeight
);
});
for (let i = 0; i < this.actions.length; i++) {
const action = this.actions[i];
generateAction(i + 1, action);
}
$('#node-input-action-container').sortable({
axis: 'y',
handle: '.node-input-action-handle',
cursor: 'move',
});
},
oneditsave: function () {
const actions = $('#node-input-action-container').children();
const node = this;
node.actions = [];
actions.each(function (i) {
const action = $(this);
const o = {
id: action.find('.node-input-action-id').val(),
icon: action.find('.node-input-action-icon').val(),
};
node.actions.push(o);
});
node.outputs = node.actions.length + 1;
},
});
})();
</script>
<script type="text/html" data-template-name="ui-dynamic-list">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-row">
<label for="node-input-group"><i class="fa fa-table"></i> Group</label>
<input type="text" id="node-input-group">
</div>
<div class="form-row">
<label><i class="fa fa-object-group"></i> <span data-i18n="ui-dynamic-list.label.size"></label>
<input type="hidden" id="node-input-width">
<input type="hidden" id="node-input-height">
<button class="editor-button" id="node-input-size"></button>
</div>
<div class="form-row">
<label for="node-input-itemHoverEffect"><i class="fa fa-hand"></i>Item hover effect</label>
<input type="checkbox" id="node-input-itemHoverEffect" title="Uncheck to remove all hover effects from the list entries.">
</div>
<div class="form-row form-row-flex node-input-action-container-row" style="margin-bottom: 0px;width: 100%">
<label for="node-input-width" style="vertical-align:top"><i class="fa fa-list-alt"></i> Actions</label>
<div id="node-input-action-container-div" style="box-sizing:border-box; border-radius:5px; height:257px; padding:5px; border:1px solid var(--red-ui-form-input-border-color, #ccc); overflow-y:scroll; display:inline-block; width: 70%;">
<span id="valWarning" style="color: var(--red-ui-text-color-error, #910000)"><b>All Values must be unique.</b></span>
<ol id="node-input-action-container" style="list-style-type:none; margin:0;"></ol>
</div>
</div>
<!-- Add Action Button -->
<div class="form-row">
<a href="#" class="editor-button editor-button-small" id="node-input-add-action" style="margin-top:4px; margin-left:103px;"><i class="fa fa-plus"></i> <span>action</span></a>
</div>
</script>
<script type="text/markdown" data-help-name="ui-dynamic-list">
A UI-Node to display a list of process instances or usertasks.
## Usage
Query ProcessInstance or UserTask data from the process engine.
Use a `function` node to transform the queried data into the required format for the `dynamic-list` node.
The `dyanmic-list` node expects an array of objects as its messages `payload`. The expected schema of these objects is:
- title: string;
- progress?:
- type: 'boolean' | 'percentage';
- value: number; (value between 0 and 100)
- details?: string;
- state?:
- text: string;
- backgroundColor: string;
- assignee?: string;
Pipe the `function` nodes result into the `dynamic-list` node.
The nodes default output will be triggered each time a list entry was clicked.
The `payload` property of the message that is ouput will be an object identifieng the clicked list entry.
This object will exactly equal one of the objects that where used as an input for the `dynamic-list` node.
Therefore, any amount of additional properties can be passed through this node, besides the ones used for displaying the list entry. I. e. a `processInstanceId`, `flowNodeInstanceId` or `userTask`.
Each additional output, generated by `actions`, will behave in the same manner, but is only triggered when clicking onto the corresponding button.
## Actions
This field is used for configuring additional actions for each list entry. Actions will be displayed as buttons at the end of each row.
Each action is defined by:
- **Id**: The Id of the action. This will be the name of the nodes output.
- **Icon**: An URL for an image, that should be displayed. This will be used as the `src`-Property of a HTML `img`-Element. Therefore DataURLs can be used to add images/svgs etc., that are not available online.
For each action configured, the node will gain a new output, that is named as the linked actions id.
## Item hover effect
When not checked, all hover effects for the list entries will not be shown. Clicking the card will still trigger a message from the nodes first output.
## Reference
[https://docs.processcube.io/docs/node-red](https://docs.processcube.io/docs/node-red)
</script>