-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #168 from flowforge/data-table
Widget: Data Table
- Loading branch information
Showing
11 changed files
with
371 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
--- | ||
props: | ||
Group: Defines which group of the UI Dashboard this widget will render in. | ||
Size: Controls the width of the button with respect to the parent group. Maximum value is the width of the group. | ||
Label: The text shown within the button. | ||
Max Rows: Defines the maximum number of data-rows to render in the table. Excess rows will be available through pagination control. | ||
Auto Columns: If checked, then the columns are calculated automatically based on the contents of received messages. | ||
Columns: If "Auto Columns" is false, then these columns are used when rendering the table instead. | ||
--- | ||
|
||
<script setup> | ||
</script> | ||
|
||
# Data Table `ui-table` | ||
|
||
Renders a set of data in a tabular format. Expects an input (`mag.payload`) in the format of: | ||
|
||
```json | ||
[{ | ||
"colA": "A", | ||
"colB": "Hello", | ||
"colC": 3 | ||
}, { | ||
"colA": "B", | ||
"colB": "World", | ||
"colC": 5 | ||
}] | ||
``` | ||
|
||
The table will be rendered with colums `colA`, `colB` and `colC`, unless "Columns" are explicitely defined on the node, with "Auto Columns" toggled off. | ||
|
||
## Properties | ||
|
||
<PropsTable/> | ||
|
||
## Examples | ||
|
||
![Example of a Data Table](../../assets/images/node-examples/ui-table.png "Example of a Data Table"){data-zoomable} | ||
*Example of a rendered data table in a Dashboard.* | ||
|
||
![Example of a Paginated Table](../../assets/images/node-examples/ui-table-pagination.png "Example of a Paginated Table"){data-zoomable} | ||
*Example of a paginated table which has 10 rows of data, but with "Max Rows" set to 5.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
<script type="text/javascript"> | ||
(function () { | ||
RED.nodes.registerType('ui-table', { | ||
category: RED._('@flowforge/node-red-dashboard/ui-base:ui-base.label.category'), | ||
color: 'rgb(119, 198, 204)', | ||
defaults: { | ||
group: { type: 'ui-group', required: true }, | ||
name: { value: '' }, | ||
label: { value: 'text' }, | ||
order: { value: 0 }, | ||
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 }, | ||
maxrows: { value: 0, validate: RED.validators.number() }, | ||
autocols: { value: true }, | ||
columns: { | ||
// value: [{ key: '', label: '' }] | ||
value: null | ||
} | ||
}, | ||
inputs: 1, | ||
outputs: 0, | ||
outputLabels: function () { return this.mode }, | ||
icon: 'font-awesome/fa-table', | ||
paletteLabel: 'table', | ||
label: function () { | ||
return this.name || 'table' | ||
}, | ||
oneditprepare: function () { | ||
$('#node-input-size').elementSizer({ | ||
width: '#node-input-width', | ||
height: '#node-input-height', | ||
group: '#node-input-group' | ||
}) | ||
const autocols = $('#node-input-autocols') | ||
|
||
$(autocols).change(() => { | ||
const val = autocols.is(':checked') | ||
const customColsDiv = $('#node-input-columns-container') | ||
if (val) { | ||
customColsDiv.hide() | ||
} else { | ||
customColsDiv.show() | ||
} | ||
}) | ||
|
||
// Columns Editor | ||
function generateColumn (i, col) { | ||
const container = $('<li/>', { style: 'background: var(--red-ui-secondary-background, #fff); margin:0; padding:8px 0px 0px; border-bottom: 1px solid var(--red-ui-form-input-border-color, #ccc);' }) | ||
const row = $('<div/>').appendTo(container) | ||
$('<div/>', { style: 'padding-top:5px; padding-left:175px;' }).appendTo(container) | ||
$('<div/>', { style: 'padding-top:5px; padding-left:120px;' }).appendTo(container) | ||
|
||
$('<i style="color: var(--red-ui-form-text-color, #eee); cursor:move; margin-left:3px;" class="node-input-column-handle fa fa-bars"></i>').appendTo(row) | ||
|
||
$('<input/>', { class: 'node-input-column-key', type: 'text', style: 'margin-left:7px; width:calc(50% - 32px);', placeholder: 'Key', value: col.key }).appendTo(row) | ||
$('<input/>', { class: 'node-input-column-label', type: 'text', style: 'margin-left:7px; width:calc(50% - 32px);', placeholder: 'Label', value: col.label }).appendTo(row) | ||
|
||
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-column-container').append(container) | ||
} | ||
|
||
$('#node-input-add-column').click(function () { | ||
generateColumn($('#node-input-column-container').children().length + 1, {}) | ||
$('#node-input-column-container-div').scrollTop($('#node-input-column-column-div').get(0).scrollHeight) | ||
}) | ||
|
||
for (let i = 0; i < this.columns?.length; i++) { | ||
const col = this.columns[i] | ||
generateColumn(i + 1, col) | ||
} | ||
|
||
$('#node-input-column-container').sortable({ | ||
axis: 'y', | ||
handle: '.node-input-column-handle', | ||
cursor: 'move' | ||
}) | ||
}, | ||
oneditsave: function () { | ||
const columns = $('#node-input-column-container').children() | ||
const node = this | ||
node.columns = [] | ||
columns.each(function (i) { | ||
const column = $(this) | ||
const o = { | ||
label: column.find('.node-input-column-label').val(), | ||
key: column.find('.node-input-column-key').val() | ||
} | ||
node.columns.push(o) | ||
}) | ||
} | ||
}) | ||
})() | ||
</script> | ||
|
||
<script type="text/html" data-template-name="ui-table"> | ||
<div class="form-row"> | ||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | ||
<input type="text" id="node-input-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> 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-maxrows"><i class="fa fa-tag"></i> Max Rows</label> | ||
<input type="number" id="node-input-maxrows"> | ||
</div> | ||
<div class="form-row" style="display:flex;"> | ||
<label for="node-input-width" style="vertical-align:top"><i class="fa fa-list-alt"></i> Columns</label> | ||
<div class="form-row node-input-column-container-row" style="margin-bottom: 0px; width:calc(70% + 15px);"> | ||
<div> | ||
<input type="checkbox" checked id="node-input-autocols" style="display: inline-block; width: auto; margin: 0px 0px 0px 4px;"> | ||
<label style="width:auto" for="node-input-autocols">Auto Calculate Columns</label> | ||
</div> | ||
<div id="node-input-columns-container"> | ||
<div id="node-input-column-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: 100%;"> | ||
<ol id="node-input-column-container" style="list-style-type:none; margin:0;"></ol> | ||
</div> | ||
<a href="#" class="editor-button editor-button-small" id="node-input-add-column" style="margin-top:4px;"><i class="fa fa-plus"></i> <span>column</span></a> | ||
</div> | ||
</div> | ||
</div> | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module.exports = function (RED) { | ||
function TableNode (config) { | ||
const node = this | ||
|
||
// create node in Node-RED | ||
RED.nodes.createNode(this, config) | ||
|
||
// which group are we rendering this widget | ||
const group = RED.nodes.getNode(config.group) | ||
|
||
// inform the dashboard UI that we are adding this node | ||
group.register(node, config) | ||
} | ||
|
||
RED.nodes.registerType('ui-table', TableNode) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.