Skip to content

Commit

Permalink
Added merge component.
Browse files Browse the repository at this point in the history
  • Loading branch information
petersirka committed Oct 4, 2023
1 parent e3dcb07 commit b4e11f8
Show file tree
Hide file tree
Showing 2 changed files with 259 additions and 157 deletions.
208 changes: 51 additions & 157 deletions components/merge.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,207 +2,101 @@

exports.id = 'merge';
exports.name = 'Merge';
exports.icon = 'ti ti-filter';
exports.icon = 'ti ti-cashregister';
exports.author = 'Total.js';
exports.version = '1';
exports.group = 'Common';
exports.config = { inputs: [] };
exports.inputs = [];
exports.config = { limit: 0, timeout: 2000 };
exports.inputs = [{ id: 'input', name: 'Input' }];
exports.outputs = [{ id: 'output', name: 'Output' }];

exports.make = function(instance, config) {

var compiled = null;
var checktimeout;
var values = {};
var value = {};
var queue = [];
var refs = {};
var timeout = null;
var status = { count: 0 }

var checkforce = function() {

checktimeout = null;

var skip = false;

for (var input of config.inputs) {

var val = values[input.id];
if (val === undefined) {
if (input.required) {
skip = true;
break;
}
}

if (input.assign)
U.set(value, input.assign, val);
else
U.extend(value, val);
var flush = function() {

if (timeout) {
clearTimeout(timeout);
timeout = null;
}

if (skip)
return;
var msg = instance.newmessage(queue);

for (var input of config.inputs) {
if (input.clear)
delete values[input.id];
}

instance.newmessage(value).send('output');
};
for (var key in refs)
msg.refs[key] = refs[key];

var check = function() {
checktimeout && clearTimeout(checktimeout);
checktimeout = setTimeout(checkforce, 100);
queue = [];
status.count = 0;
instance.status(status, 500);
msg.send('output');
};

instance.message = function($) {
var data = $.data;
var input = compiled[$.input];
if (input) {
values[$.input] = input.path ? U.get(data, input.path) : data;
check();
}
$.destroy();
};

instance.configure = function() {
var data = $.data;

var inputs = [];
for (var key in $.refs)
refs[key] = $.refs[key];

if (config.clear) {
values = {};
delete config.clear;
}
queue.push(data);

compiled = {};
if (config.limit && queue.length === config.limit)
flush();
else if (config.timeout && !timeout)
timeout = setTimeout(flush, config.timeout);

for (var item of config.inputs) {
if (item) {
compiled[item.id] = item;
inputs.push({ id: item.id, name: item.name });
}
}
$.destroy();

for (var key in values) {
if (!compiled[key])
delete values[key];
}
status.count = queue.length;
instance.status(status, 500);
};

var prev = JSON.stringify(instance.inputs);
var curr = JSON.stringify(inputs);
instance.close = function() {

if (prev !== curr) {
instance.inputs = inputs;
instance.save();
if (timeout) {
clearTimeout(timeout);
timeout = null;
}

queue = null;
};

instance.configure();

};

</script>

<readme>
This component merges multiple inputs into one object.
The component merges incoming data into an array.
</readme>

<settings>
<div class="CLASS-settings">
<div class="padding">
<ui-component name="input" path="?.clear" config="type:checkbox" class="m">Clear cache</ui-component>
<ui-component name="listform" path="?.inputs" config="autofocus:1;empty:You do not have defined any inputs;create:tmpmerge.add">

<script type="text/html">
<div class="item"><i class="ti ti-arrow-right"></i>{{ if required }}<b>{{fi}}{{ name }}{{ if required }}</b>{{fi}}{{ if assign }}<span class="fs11 gray ml5">{{ assign }}</span>{{ fi }}</div>
</script>

<script type="text/html">
<div class="padding">
<ui-component name="input" path="?.name" config="required:1;innerlabel:1;placeholder:Enter a name" default="''" class="m">Name</ui-component>
<div class="grid-2">
<div class="m">
<ui-component name="input" path="?.path" config="innerlabel:1;placeholder:path.to.property" default="''">Path</ui-component>
<div class="help">A value will be read according to this path</div>
</div>
<div class="m">
<ui-component name="input" path="?.assign" config="innerlabel:1;placeholder:path.to.property" default="''">Assign to the path</ui-component>
<div class="help">A value will be assigned according to this path. Otherwise, the message extends cached data.</div>
</div>
</div>
<hr class="nmt" />
<ui-component name="input" path="?.required" config="type:checkbox" default="false"><b>Required</b></ui-component>
<ui-component name="input" path="?.clear" config="type:checkbox" default="false" class="m">Clear value after use</ui-component>
<ui-component name="validate" path="?" class="toolbar">
<button name="submit"><i class="ti ti-file-code"></i>Save</button>
<button name="remove">Remove</button>
<button name="cancel">Cancel</button>
</ui-component>
</div>
</script>

<script type="text/html">
<div style="margin-top:10px"><button class="button button-inline" name="create"><i class="ti ti-plus-circle green"></i>Add input</button></div>
</script>

</ui-component>
<div class="padding">
<div class="grid-4">
<div class="m">
<ui-component name="input" path="?.limit" config="type:number">Limit</ui-component>
<div class="help"><code>0</code> means disabled</div>
</div>
<div class="m">
<ui-component name="input" path="?.timeout" config="type:number">Timeout</ui-component>
<div class="help">In milliseconds. <code>0</code> means disabled</div>
</div>
</div>
</div>
</settings>

<style>
.CLASS-settings .item { padding: 8px 10px; font-size: 12px; }
.CLASS-settings .item i { margin-right: 5px; }
.CLASS footer { height: 40px; line-height: 40px; padding: 0 10px; font-size: 12px; }
.CLASS header div { border-radius: var(--radius); padding: 3px; background-color: #777; color: #FFF; }
.CLASS header div i { background-color: rgba(0,0,0,0.2); }

.ui-dark .CLASS header div i { background-color: rgba(255,255,255,0.2); }
.CLASS footer { padding: 10px; font-size: 12px; }
</style>

<script>
TOUCH(function(exports, reinit) {

exports.settings = function(meta) {

var tmp = W.tmpmerge;

if (!tmp) {

tmp = {};
tmp.add = function(callback) {
var obj = {};
obj.id = 'i' + Math.random().toString(36).substring(6);
obj.name = 'Name';
obj.path = '';
obj.clear = false;
obj.required = false;
callback(obj);
};

W.tmpmerge = tmp;
}
};

exports.configure = function() {
var changes = exports.instance.changes;
if (changes && changes.newbie) {
var inputs = [];
for (var item of exports.config.inputs)
inputs.push({ id: item.id, name: item.name });
exports.instance.inputs = inputs;
UPD('flow.data');
}

};

});
</script>

<body>
<header>
<i class="ICON"></i>NAME
<i class="$ICON"></i>$NAME
</header>
<footer>
Pending: <ui-bind path="STATUS" config="text:value?value.count:0" class="b"></ui-bind>
</footer>
</body>
Loading

0 comments on commit b4e11f8

Please sign in to comment.