@5minds/node-red-dashboard-2-processcube-process-progress-bar
Version:
A ui component for showing progress bars tracking a process
237 lines (209 loc) • 10.6 kB
HTML
<script type="text/javascript">
(function () {
function hasProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
RED.nodes.registerType('ui-process-progress-bar', {
category: 'ProcessCube UI',
color: '#00aed7',
defaults: {
name: { value: '' },
group: { type: 'ui-group', required: true },
order: { value: 1 },
color: { value: '#8899C9' },
steps: {
value: [],
validate: function (v) {
const unique = new Set(
v.map(function (o) {
return o.label;
})
);
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: 0 },
},
inputs: 1,
outputs: 0,
icon: 'ui-progress-bar.svg',
paletteLabel: 'ui-process-progress-bar',
label: function () {
return this.name || 'ui-process-progress-bar';
},
oneditprepare: function () {
$('#node-input-size').elementSizer({
width: '#node-input-width',
height: '#node-input-height',
group: '#node-input-group',
});
function generateStep(i, step) {
const container = $('<li/>', {
style: 'background: var(--red-ui-secondary-background, #fff); margin:0; padding:8px 0px 0px;',
});
// Create input fields for flowNodeId, icon and label
const row = $('<div/>').appendTo(container);
$('<input/>', {
class: 'node-input-step-label',
type: 'text',
style: 'margin-left:7px; width:calc(50% - 32px);',
placeholder: 'Label',
value: step.label,
})
.appendTo(row)
.typedInput({
type: 'str',
types: ['str'],
});
$('<input/>', {
class: 'node-input-step-flowNodeId',
type: 'text',
style: 'margin-left:7px; width:calc(50% - 32px);',
placeholder: 'FlownodeId',
value: step.flowNodeId,
})
.appendTo(row)
.typedInput({
type: 'str',
types: ['str'],
});
$('<input/>', {
class: 'node-input-step-icon',
type: 'text',
style: 'margin-left:7px; width:calc(50% - 32px);',
placeholder: 'Icon',
value: step.icon,
})
.appendTo(row)
.typedInput({
type: 'str',
types: ['str'],
});
$('<input/>', {
class: 'node-input-step-iconFinished',
type: 'text',
style: 'margin-left:7px; width:calc(50% - 32px);',
placeholder: 'Icon (finished)',
value: step.iconFinished,
})
.appendTo(row)
.typedInput({
type: 'str',
types: ['str'],
});
// Create delete button for the step
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-step-container').append(container);
}
$('#node-input-add-step').click(function () {
generateStep($('#node-input-step-container').children().length + 1, {});
$('#node-input-step-container-div').scrollTop(
$('#node-input-step-container-div').get(0).scrollHeight
);
});
for (let i = 0; i < this.steps.length; i++) {
const step = this.steps[i];
generateStep(i + 1, step);
}
$('#node-input-step-container').sortable({
axis: 'y',
handle: '.node-input-step-handle',
cursor: 'move',
});
},
oneditsave: function () {
const steps = $('#node-input-step-container').children();
const node = this;
node.steps = [];
steps.each(function (i) {
const step = $(this);
const o = {
label: step.find('.node-input-step-label').val(),
flowNodeId: step.find('.node-input-step-flowNodeId').val(),
icon: step.find('.node-input-step-icon').val(),
iconFinished: step.find('.node-input-step-iconFinished').val(),
};
node.steps.push(o);
});
},
});
})();
</script>
<script type="text/html" data-template-name="ui-process-progress-bar">
<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-process-progress-bar.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 form-row-flex node-input-step-container-row" style="margin-bottom: 0px;width: 100%">
<label for="node-input-width" style="vertical-align:top"><i class="fa fa-list-alt"></i> Steps</label>
<div id="node-input-step-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-step-container" style="list-style-type:none; margin:0;"></ol>
</div>
</div>
<!-- Add Step Button -->
<div class="form-row">
<a href="#" class="editor-button editor-button-small" id="node-input-add-step" style="margin-top:4px; margin-left:103px;"><i class="fa fa-plus"></i> <span>action</span></a>
</div>
<div class="form-row">
<label for="node-input-color"><i class="fa fa-table"></i> Color</label>
<input type="color" id="node-input-color" style="max-width:200px;">
</div>
</script>
<script type="text/markdown" data-help-name="ui-process-progress-bar">
A UI-Node to display a step-by-step progress bar, tracking the progress of a process.
## Usage
After configuring the node, use a `usertask-event-listener` node and direct all `new` and `finished` events for the tracked process into the `ui-process-progress-bar` node.
It will automatically update, when UserTasks are started or finished.
The output of a `usertask-input` node can also be used as an input, when using the `Result` type `Send First Task`.
This node can display 0-1 active steps and all steps before the running step are always displayed as finished.
## Steps
This field is used for configuring the steps of the progress bar.
Each step is defined by:
- **Label**: The text displayed for the progress bar step
- **FlownodeId**: The Id of the Flownode, that needs to be active/finished to start/fullfill this step.
- **Icon (optional)**: An URL for an image, that should be displayed in addition to the label. 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.
- **Icon finished (optional)**: An URL for an image, that should be displayed in addition to the label, after the step has been finished. 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.
## Color
Will be used as the outline/fill/text color for the steps.
## Reference
[https://docs.processcube.io/docs/node-red](https://docs.processcube.io/docs/node-red)
</script>