@gregoriusrippenstein/node-red-contrib-flowhub
Version:
FlowHub.org: flow management with GitHub.
254 lines (215 loc) • 15.3 kB
HTML
<script type="text/javascript">
(function(){
function flowHubPullUpdateFlows(e=null,o=null){let t=t=>{if("failed"==t.status)return RED.notify(t.msg,{type:"error",id:"FlowHubPull",timeout:4e3});let i=[],r={},l=[];Object.keys(t.data).forEach(function(e){var o=t.data[e].name.match(/^(\[.+\])/);o?r[o[0]]?r[o[0]].push(t.data[e]):r[o[0]]=[t.data[e]]:l.push(t.data[e])}),Object.keys(r).sort((e,o)=>e<o?-1:1).forEach(e=>{var o=r[e].map(e=>({label:e.name,icon:"fa "+(RED.nodes.workspace(e.id)?"fa-check-circle-o":""),flowid:e.id,sublabel:e.id,selected:$("#node-input-flowhubpull-flowid").val()==e.id,checkbox:!1,children:void 0}));i.push({label:e,icon:"",flowid:"",sublabel:"",selected:!1,checkbox:!1,children:o.sort((e,o)=>e.label<o.label?-1:1)})}),l.sort((e,o)=>e.name<o.name?-1:1).forEach(e=>{i.push({label:e.name,icon:"fa "+(RED.nodes.workspace(e.id)?"fa-check-circle-o":""),flowid:e.id,sublabel:e.id,selected:$("#node-input-flowhubpull-flowid").val()==e.id,checkbox:!1,children:void 0})}),e&&e(i)};$.get({url:"https://api.flowhub.org/v1/flows?cb="+(new Date).getTime(),headers:{"X-FHB-TOKEN":o}}).done(e=>{t(e)}).fail(e=>{var i="";"rejected"==e.state()?$.ajax({url:"FlowHubCatalogue",type:"POST",contentType:"application/json; charset=utf-8",data:JSON.stringify({token:o}),success:function(e){t(e)},error:function(e,o,t){i="<p>Failed to retrieve FlowHub catalogue, request blocked.</p><p>Request: <b>https://api.flowhub.org/v1/flows</b></p><p>AdBlocker or uBlock might have prevented request.</p><p>Please check browser console for more details.</p>",console.log("Error",o),RED.notify(i,{type:"error",id:"FlowHubPull",timeout:4e3})}}):(i="<p>Failed to retrieve FlowHub catalogue.</p><p>Check browser console for more details.</p>",console.warn("Error loading https://api.flowhub.org/v1/flows:",e),RED.notify(i,{type:"error",id:"FlowHubPull",timeout:4e3}))})}function obtainConfigNode(){let o=[];return RED.nodes.eachConfig(function(e){"FlowHubCfg"===e.type&&o.push(e)}),o[0]}function tokenToUrl(e){e=e.substring(4);var o="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_".split("");let t=Object.fromEntries(o.map((e,o)=>[e,o])),i=Object.fromEntries(o.map((e,o)=>[o,e]));return e.replaceAll(/./gi,(e,o)=>i[(t[e]+o+1)%64])}function obtainFhbToken(e,i){$.ajax({url:"FlowHubToken",type:"POST",contentType:"application/json; charset=utf-8",data:JSON.stringify({cfgnode:e}),success:function(e){i(e.token)},error:function(e,o,t){i("")}})}function doFlowImportForSidebar(i,e){RED.notify("Pull triggered",{type:"warning",timeout:3e3}),$.get({url:"https://api.flowhub.org/v3/flows/"+$("#node-input-flowhubpull-flowid").val().trim()+"?cb="+(new Date).getTime()+"&v="+$("#node-input-flowhubpull-flowrevision").val().trim(),headers:{"X-FHB-TOKEN":e,"User-Agent":"FlowHub.org Sidebar"}}).done((o,e)=>{try{if(!o||!o.flowdata||!Array.isArray(JSON.parse(o.flowdata)))return RED.notify("Access denied or revision not found.",{type:"error",timeout:3e3})}catch(e){return RED.notify("Access Denied, parse error.",{type:"error",timeout:3e3})}var t;RED.nodes.workspace(o.flowid)||((t=ensureYourConfigNodeExists()).flowrevisions||={},t.flowrevisions[o.flowid]!=o.revision&&(t.flowrevisions[o.flowid]=o.revision)),RED.clipboard.import(),setTimeout(()=>{var e=JSON.parse(o.flowdata);i&&(e=e.filter(function(e){return"tab"!=e.type})),$("#red-ui-clipboard-dialog-import-text").val(JSON.stringify(e)).trigger("paste")},300)}).fail(e=>{var o="<p>Failed to retrieve flow data from FlowHub, request blocked.</p><p>Request: https://api.flowhub.org/v3/flows/"+$("#node-input-flowhubpull-flowid").val().trim()+"</p><p>AdBlocker or uBlock might have prevented request.</p><p>Please check browser console for more details.</p>";RED.notify(o,{type:"error",id:"FlowHubPull",timeout:4e3})})}function doFlowImportForPullNode(e,o){RED.notify("Pull triggered",{type:"warning",timeout:3e3});$.get({url:"https://api.flowhub.org/v3/flows/"+$("#node-input-flowid").val().trim()+"?cb="+(new Date).getTime()+"&v="+$("#node-input-flowrevision").val().trim(),headers:{"X-FHB-TOKEN":o,"User-Agent":"FlowHub.org Pull Node"}}).done((o,e)=>{try{if(!o||!o.flowdata||!Array.isArray(JSON.parse(o.flowdata)))return RED.notify("Access denied or revision not found.",{type:"error",timeout:3e3})}catch(e){return RED.notify("Access Denied, parse error.",{type:"error",timeout:3e3})}var t;RED.nodes.workspace(o.flowid)||(t=(()=>{let o=void 0;return RED.nodes.eachConfig(function(e){"FlowHubCfg"===e.type&&(o=e)}),o})())&&(t.flowrevisions||={},t.flowrevisions[o.flowid]!=o.revision)&&(t.flowrevisions[o.flowid]=o.revision),RED.clipboard.import(),setTimeout(()=>{var e=JSON.parse(o.flowdata);$("#red-ui-clipboard-dialog-import-text").val(JSON.stringify(e)).trigger("paste")},300)}).fail(e=>{var o="<p>Failed to retrieve flow data from FlowHub, request blocked.</p><p>Request: https://api.flowhub.org/v3/flows/"+$("#node-input-flowhubpull-flowid").val().trim()+"</p><p>AdBlocker or uBlock might have prevented request.</p><p>Please check browser console for more details.</p>";RED.notify(o,{type:"error",id:"FlowHubPull",timeout:4e3})})}function checkForDuplication(e){$.get({url:"https://api.flowhub.org/v1/flows/"+$("#node-input-flowhubpull-flowid").val()+"?cb="+(new Date).getTime()+"&v="+$("#node-input-flowhubpull-flowrevision").val(),headers:{"X-FHB-TOKEN":e}},function(e,o){let t=[];if(!Array.isArray(e))return RED.notify("Access denied or revision not found.","error");if(e.forEach((e,o)=>{"tab"==e.type?RED.nodes.workspace(e.id)&&t.push(e):"junction"==e.type?RED.nodes.junction(e.id)&&t.push(e):"group"==e.type?RED.nodes.group(e.id)&&t.push(e):"subflow"==e.type?RED.nodes.subflow(e.id)&&t.push(e):RED.nodes.node(e.id)&&t.push(e)}),0==t.length){RED.notify("Found no duplication.","success");try{$("#node-input-flowhubpull-sb-duplication-container-div").treeList("empty")}catch(e){}}else{RED.notify("Found "+t.length+" items of duplication","warning");try{$("#node-input-flowhubpull-sb-duplication-container-div").treeList("empty")}catch(e){$("#node-input-flowhubpull-sb-duplication-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,o){}).on("treelistitemmouseout",function(e,o){}).on("treelistselect",function(e,o){o.node&&(RED.workspaces.show(o.node.z,!1,!1,!0),RED.view.reveal(o.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,o){var t;o.node&&(t=o.node.id,setTimeout(()=>{var e=RED.nodes.node(t);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e)),t==RED.workspaces.active()&&RED.workspaces.edit()},50))})}t=t.map(e=>({node:e,label:e.id,sublabel:e.type,selected:!1,checkbox:!1})),$("#node-input-flowhubpull-sb-duplication-container-div").treeList("data",t)}})}
RED.nodes.registerType('FlowHubPull',{
color: '#44eeff',
icon: "flowhubpull.svg",
category: 'flowhub',
defaults: {
name: { value: ""},
notab: { value: false },
flowid: { value: "" },
flowname: { value: "" },
flowrevision: { value: "" }
},
inputs: 1,
outputs: 2,
label: function() {
return (this.name || this.flowname || this.flowid || this._def.paletteLabel);
},
onpaletteadd: () => {
},
oneditresize: function(size) {
if ( this._resize ) { this._resize(); };
},
oneditprepare: function() {
var dirList = $("#node-input-flowhubpull-target-container-div").css({
width: "100%",
height: "100%"
}).treeList(
{
multi:false
}
).on('treelistselect', function(event, item) {
if ( item.flowid ) {
$('#node-input-flowid').val(item.flowid);
$('#node-input-flowname').val(item.label);
obtainFhbToken(obtainConfigNode(), (token) => {
if ( token !== "" && token ) {
token = "?t=" + tokenToUrl(token)
}
$('#flowhubpull-view-flow-link').attr(
'href', 'https://flowhub.org/f/' + item.flowid + token
).show();
})
$('#node-input-import-flow-but').prop('disabled',false)
}
}).on('treelistconfirm', function(event, item) {
if ( item.flowid ) {
$('#node-input-flowid').val(item.flowid);
$('#node-input-flowname').val(item.label);
obtainFhbToken(obtainConfigNode(), (token) => {
if ( token !== "" && token ) {
token = "?t=" + tokenToUrl(token)
}
$('#flowhubpull-view-flow-link').attr(
'href', 'https://flowhub.org/f/' + item.flowid + token
).show();
});
$('#node-input-import-flow-but').prop('disabled',false)
$("#node-input-import-flow-but").trigger('click');
}
});
if ( this.flowid ) {
setTimeout( () => {
obtainFhbToken(obtainConfigNode(), (token) => {
if ( token !== "" && token ) {
token = "?t=" + tokenToUrl(token)
}
$('#flowhubpull-view-flow-link').attr(
'href', 'https://flowhub.org/f/' + $('#node-input-flowid').val() + token
).show();
})
}, 200);
} else {
$('#node-input-import-flow-but').prop('disabled',true)
}
this._resize = function() {
var rows = $("#dialog-form>div:not(.node-input-target-list-row)");
var height = $("#dialog-form").height();
for (var i=0;i<rows.length;i++) {
height -= $(rows[i]).outerHeight(true);
}
var editorRow = $("#dialog-form>div.node-input-target-list-row");
editorRow.css("height",height+"px");
};
var search = $("#node-input-flowhubpull-target-filter").searchBox({
style: "compact",
delay: 300,
change: function() {
var val = $(this).val().trim().toLowerCase();
if (val === "") {
dirList.treeList("filter", null);
search.searchBox("count","");
} else {
var count = dirList.treeList("filter", function(item) {
return item.label.toLowerCase().indexOf(val) > -1 || item.sublabel.toLowerCase().indexOf(val) > -1
});
search.searchBox("count",count + " / " + dirList.treeList("data").length);
}
}
});
obtainFhbToken(obtainConfigNode(), (token) => {
flowHubPullUpdateFlows( (lst) => { dirList.treeList('data', lst) }, token);
})
$('#node-input-refresh-list-but').on('click', function(e) {
e.preventDefault();
setTimeout( () => {
obtainFhbToken(obtainConfigNode(), (token) => {
flowHubPullUpdateFlows( (lst) => {
dirList.treeList('empty')
$('#flowhubpull-view-flow-link').hide()
setTimeout( () => {
dirList.treeList('data', lst)
},300)
}, token);
})
}, 300);
});
$("#node-input-import-flow-but").on("click", function(e) {
if ( e ) { e.preventDefault(); }
if ( $('#node-input-flowid').val().trim() == "" ||
!$('#node-input-flowid').val() ) {
return RED.notify(RED._("notification.warning", {
message: "FlowID not provided, doing nothing."
}), "warning");
}
$('#node-dialog-ok').trigger('click')
let notab = $('#node-input-notab').prop('checked');
obtainFhbToken(obtainConfigNode(), (token) => {
doFlowImportForPullNode(notab, token)
})
});
if ( this.notab ) {
$('#flowhubpull-dialog-import-opt-current').addClass('selected')
$('#flowhubpull-dialog-import-opt-new').removeClass('selected')
} else {
$('#flowhubpull-dialog-import-opt-new').addClass('selected')
$('#flowhubpull-dialog-import-opt-current').removeClass('selected')
}
$('#flowhubpull-dialog-import-opt-current').on('click', (e) => {
e.preventDefault();
$('#node-input-notab').prop('checked', true)
$('#flowhubpull-dialog-import-opt-new').removeClass('selected')
$('#flowhubpull-dialog-import-opt-current').addClass('selected')
})
$('#flowhubpull-dialog-import-opt-new').on('click', (e) => {
e.preventDefault();
$('#node-input-notab').prop('checked', false)
$('#flowhubpull-dialog-import-opt-current').removeClass('selected')
$('#flowhubpull-dialog-import-opt-new').addClass('selected')
})
},
oneditcancel: function() {
},
oneditsave: function() {
},
labelStyle: function() {
return this.name?"node_label_italic":"";
},
});
})();
</script>
<script type="text/html" data-template-name="FlowHubPull">
<div class="form-row">
<input type="text" id="node-input-flowid" disabled="disabled"
style="display:inline-block; width:40%; vertical-align:baseline;"
placeholder="FlowId to Import">
<button id="node-input-import-flow-but"
class="red-ui-button">Import Flow</button>
<input type="text" id="node-input-flowname" style="display: none;">
<a id="flowhubpull-view-flow-link" style="color: blue; display: none; margin-left: 80px;"
target="_blank" href="">Webiliser <i class="fa fa-external-link"></i></a>
</div>
<!--
<div class="form-row">
<label>
<span>Import to:</span>
</label>
<input type="checkbox" id="node-input-notab" style="display:none;">
<span>
<a id="flowhubpull-dialog-import-opt-current" class="red-ui-button toggle" href="#" data-i18n="clipboard.export.current">current flow</a>
<a id="flowhubpull-dialog-import-opt-new" class="red-ui-button toggle" href="#" data-i18n="clipboard.import.newFlow">new flow</a>
</span>
</div>
-->
<div class="form-row node-input-target-row">
<button id="node-input-refresh-list-but"
class="red-ui-button"><i class="fa fa-refresh"></i> Refresh Flow List</button>
</div>
<div class="form-row node-input-target-row node-input-target-list-row"
style="position: relative; min-height: 100px">
<div style="position: absolute; top: -30px; right: 0px;">
<input type="text" id="node-input-flowhubpull-target-filter">
</div>
<div id="node-input-flowhubpull-target-container-div"></div>
</div>
<div class="form-row">
<label for="node-input-flowrevision"><i class="fa fa-tag"></i> Revision</label>
<input type="text" id="node-input-flowrevision" placeholder="Revision"/>
</div>
<div class="form-row">
<hr/>
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name">Name</span></label>
<input type="text" id="node-input-name" placeholder="Name"/>
</div>
</script>
<script type="text/html" data-help-name="FlowHubPull">
<p>
Import Flows from FlowHub.org. Opens the flow import dialog
with flow data. Flow can be imported into a new tab or the
existing tab.
</p>
</script>