@kumologica/sdk 3.4.0 → 3.5.0-beta2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/cli/commands/create-commands/openapi.js +42 -0
  2. package/cli/commands/create.js +17 -8
  3. package/cli/commands/login.js +87 -0
  4. package/package.json +18 -7
  5. package/src/app/lib/ai/layout.js +75 -0
  6. package/src/app/lib/ai/openai.js +108 -0
  7. package/src/app/lib/ai/prompt.txt +583 -0
  8. package/src/app/lib/aws/ca-cloudwatch-api.js +2 -10
  9. package/src/app/lib/aws/ca-dynamodb-api.js +6 -10
  10. package/src/app/lib/aws/ca-elb-api.js +4 -24
  11. package/src/app/lib/aws/ca-events-api.js +5 -12
  12. package/src/app/lib/aws/ca-iot-api.js +3 -87
  13. package/src/app/lib/aws/ca-s3-api.js +17 -62
  14. package/src/app/lib/aws/ca-sns-api.js +6 -15
  15. package/src/app/lib/aws/ca-sqs-api.js +9 -6
  16. package/src/app/lib/aws/index.js +70 -86
  17. package/src/app/lib/aws/kl-apigw-api.js +40 -0
  18. package/src/app/lib/aws/kl-iam-api.js +5 -5
  19. package/src/app/lib/github/index.js +0 -17
  20. package/src/app/lib/serverless/index.js +1 -1
  21. package/src/app/lib/stores/settings-cloud-store.js +35 -2
  22. package/src/app/main.js +34 -32
  23. package/src/app/preload.js +36 -28
  24. package/src/app/ui/editor-client/public/red/red.js +924 -458
  25. package/src/app/ui/editor-client/public/red/red.min.js +2 -2
  26. package/src/app/ui/editor-client/public/red/style.min.css +1 -1
  27. package/src/app/ui/editor-client/src/js/nodes.js +19 -18
  28. package/src/app/ui/editor-client/src/js/red.js +6 -3
  29. package/src/app/ui/editor-client/src/js/ui/editor.js +70 -70
  30. package/src/app/ui/editor-client/src/js/ui/footer.js +143 -0
  31. package/src/app/ui/editor-client/src/js/ui/search.js +43 -34
  32. package/src/app/ui/editor-client/src/js/ui/sidebar.js +26 -24
  33. package/src/app/ui/editor-client/src/js/ui/signup.js +56 -0
  34. package/src/app/ui/editor-client/src/js/ui/tab-ai.js +210 -0
  35. package/src/app/ui/editor-client/src/js/ui/tab-awsDeploy.js +30 -5
  36. package/src/app/ui/editor-client/src/js/ui/tab-test.js +120 -99
  37. package/src/app/ui/editor-client/src/js/ui/update-panel.js +0 -1
  38. package/src/app/ui/editor-client/src/js/ui/view.js +201 -202
  39. package/src/app/ui/editor-client/src/sass/editor.scss +715 -645
  40. package/src/app/ui/editor-client/src/sass/sidebar.scss +21 -12
  41. package/src/app/ui/editor-client/src/sass/style.scss +101 -0
  42. package/src/app/ui/editor-client/src/sass/tab-ai.scss +68 -0
  43. package/src/app/ui/editor-client/src/sass/workspace.scss +12 -2
  44. package/src/app/ui/editor-client/templates/index.mst +41 -7
  45. package/src/server/DesignerServer.js +2 -1
  46. package/cli/.DS_Store +0 -0
  47. package/fixtures/.DS_Store +0 -0
  48. package/src/app/lib/aws/ca-apigw-api.js +0 -216
  49. package/src/app/lib/aws/ca-codecommit-api.js +0 -63
  50. package/src/app/lib/aws/kl-rekognition-api.js +0 -66
  51. package/src/app/lib/aws/kl-ssm-api.js +0 -24
@@ -145,9 +145,9 @@ RED.nodes = (function () {
145
145
 
146
146
  // TODO: too tightly coupled into palette UI
147
147
  }
148
-
148
+
149
149
  RED.events.emit('registry:node-type-added', nt);
150
-
150
+
151
151
  },
152
152
  removeNodeType: function (nt) {
153
153
  if (nt.substring(0, 8) != 'subflow:') {
@@ -502,7 +502,7 @@ RED.nodes = (function () {
502
502
  if (
503
503
  !n.credentials._ ||
504
504
  n.credentials['has_' + cred] !=
505
- n.credentials._['has_' + cred] ||
505
+ n.credentials._['has_' + cred] ||
506
506
  (n.credentials['has_' + cred] && n.credentials[cred])
507
507
  ) {
508
508
  credentialSet[cred] = n.credentials[cred];
@@ -587,7 +587,7 @@ RED.nodes = (function () {
587
587
  node.caname = '_error_unknown';
588
588
  node.category = '_error_unknown'
589
589
  }
590
-
590
+
591
591
  return node;
592
592
  }
593
593
 
@@ -727,7 +727,7 @@ RED.nodes = (function () {
727
727
  }
728
728
  var nns = [];
729
729
  var i;
730
-
730
+
731
731
  for (i = 0; i < workspacesOrder.length; i++) {
732
732
  if (workspaces[workspacesOrder[i]].type == 'tab') {
733
733
  nns.push(convertWorkspace(workspaces[workspacesOrder[i]]));
@@ -745,12 +745,12 @@ RED.nodes = (function () {
745
745
  }
746
746
  for (i = 0; i < nodes.length; i++) {
747
747
  var node = nodes[i];
748
- let n = convertNode(node, exportCredentials);
749
- // check if we need to report an error with node convertion
750
- if (n.caname === '_error_unknown' && n.category === '_error_unknown'){
751
- RED.notify(`<strong>Error</strong>: Invalid flow due to node type unknown [${n.type}]`, 'error');
752
- }
753
- nns.push(n);
748
+ let n = convertNode(node, exportCredentials);
749
+ // check if we need to report an error with node convertion
750
+ if (n.caname === '_error_unknown' && n.category === '_error_unknown') {
751
+ RED.notify(`<strong>Error</strong>: Invalid flow due to node type unknown [${n.type}]`, 'error');
752
+ }
753
+ nns.push(n);
754
754
  }
755
755
  return nns;
756
756
  }
@@ -895,9 +895,9 @@ RED.nodes = (function () {
895
895
  var typeList = '<ul><li>' + unknownTypes.join('</li><li>') + '</li></ul>';
896
896
  RED.notify(
897
897
  '<p>' +
898
- 'Imported unrecognised type:' +
899
- '</p>' +
900
- typeList,
898
+ 'Imported unrecognised type:' +
899
+ '</p>' +
900
+ typeList,
901
901
  'error',
902
902
  false,
903
903
  10000
@@ -905,6 +905,7 @@ RED.nodes = (function () {
905
905
  }
906
906
 
907
907
  var activeWorkspace = RED.workspaces.active();
908
+ console.log('[nodes] ImportNodes --> activeWorkspace=', activeWorkspace)
908
909
  //TODO: check the z of the subflow instance and check _that_ if it exists
909
910
  var activeSubflow = getSubflow(activeWorkspace);
910
911
  for (i = 0; i < newNodes.length; i++) {
@@ -922,7 +923,7 @@ RED.nodes = (function () {
922
923
  }
923
924
  if (err) {
924
925
  // TODO: standardise error codes
925
- err.code = 'NODE_RED';
926
+ err.code = 'KUMOLOGICA';
926
927
  throw err;
927
928
  }
928
929
  }
@@ -1442,9 +1443,9 @@ RED.nodes = (function () {
1442
1443
  ];
1443
1444
  }
1444
1445
 
1445
- function getTabLabel(id){
1446
+ function getTabLabel(id) {
1446
1447
  let tabs = listWorkspaces();
1447
- for (tab in tabs){
1448
+ for (tab in tabs) {
1448
1449
  if (tabs[tab].id === id) {
1449
1450
  return tabs[tab].label;
1450
1451
  }
@@ -1727,7 +1728,7 @@ RED.nodes = (function () {
1727
1728
  }
1728
1729
  },
1729
1730
  eachWorkspace: eachWorkspace,
1730
-
1731
+
1731
1732
  listWorkspaces: listWorkspaces,
1732
1733
 
1733
1734
  node: getNode,
@@ -2,7 +2,7 @@ var RED = (function () {
2
2
  let disableComms = false;
3
3
 
4
4
  function appendNodeConfig(nodeConfig, done) {
5
- done = done || function () {};
5
+ done = done || function () { };
6
6
  var m = /<!-- --- \[red-module:(\S+)\] --- -->/.exec(nodeConfig.trim());
7
7
  var moduleId;
8
8
  if (m) {
@@ -72,7 +72,7 @@ var RED = (function () {
72
72
  success: function (data) {
73
73
  RED.nodes.setNodeList(data);
74
74
  // RED.i18n.loadNodeCatalogs(function () {
75
- loadIconList(loadNodes);
75
+ loadIconList(loadNodes);
76
76
  // });
77
77
  },
78
78
  });
@@ -396,7 +396,7 @@ var RED = (function () {
396
396
  appendNodeConfig(data);
397
397
  typeList =
398
398
  '<ul><li>' + msg.types.join('</li><li>') + '</li></ul>';
399
- RED.notify(`Node added to palette: ${msg.types.length} `+ typeList,
399
+ RED.notify(`Node added to palette: ${msg.types.length} ` + typeList,
400
400
  'success'
401
401
  );
402
402
  });
@@ -641,6 +641,7 @@ var RED = (function () {
641
641
  RED.subflow.init();
642
642
  RED.workspaces.init();
643
643
  RED.clipboard.init();
644
+ RED.signup.init();
644
645
  RED.search.init();
645
646
  RED.projectInfo.init();
646
647
  RED.uiSettings.init();
@@ -699,6 +700,8 @@ var RED = (function () {
699
700
  RED.i18n.init(options, function () {
700
701
  RED.settings.init(options, loadEditor);
701
702
  });
703
+ RED.footer.init();
704
+
702
705
  }
703
706
 
704
707
  return {
@@ -21,7 +21,7 @@ RED.editor = (function () {
21
21
  return latestNodeSelected;
22
22
  }
23
23
 
24
- function setLatestNodeSelected(newLatestNodeSelected){
24
+ function setLatestNodeSelected(newLatestNodeSelected) {
25
25
  // console.log('[editor] setLatestNodeSelected=', newLatestNodeSelected);
26
26
  latestNodeSelected = newLatestNodeSelected;
27
27
  }
@@ -297,10 +297,10 @@ RED.editor = (function () {
297
297
  updateConfigNodeSelect(property, type, node[property], prefix);
298
298
  $(
299
299
  '<a id="' +
300
- prefix +
301
- '-lookup-' +
302
- property +
303
- '" class="editor-button"><i class="fa fa-pencil"></i></a>'
300
+ prefix +
301
+ '-lookup-' +
302
+ property +
303
+ '" class="editor-button"><i class="fa fa-pencil"></i></a>'
304
304
  )
305
305
  .css({ position: 'absolute', right: 0, top: 0 })
306
306
  .appendTo(outerWrap);
@@ -422,10 +422,10 @@ RED.editor = (function () {
422
422
  // Add the icon of dynamic expression
423
423
 
424
424
  //input
425
- //.parent()
426
- // .append(
427
- // '<span style="display:none;float:right;position:relative;top:-23px;right:5px;color:#9c27b0;font-size:14px" class="fa fa-bolt icon-templatable"></span>'
428
- // );
425
+ //.parent()
426
+ // .append(
427
+ // '<span style="display:none;float:right;position:relative;top:-23px;right:5px;color:#9c27b0;font-size:14px" class="fa fa-bolt icon-templatable"></span>'
428
+ // );
429
429
 
430
430
  RED.popover.tooltip(
431
431
  input.parent().find($('span.icon-templatable')),
@@ -877,8 +877,8 @@ RED.editor = (function () {
877
877
  function buildEditForm(container, formId, type, ns, node) {
878
878
  var dialogForm = $(
879
879
  '<form id="' +
880
- formId +
881
- '" class="form-horizontal" autocomplete="off"></form>'
880
+ formId +
881
+ '" class="form-horizontal" autocomplete="off"></form>'
882
882
  ).appendTo(container);
883
883
  dialogForm.html($("script[data-template-name='" + type + "']").html());
884
884
  ns = ns || 'kumologica-core';
@@ -1124,8 +1124,8 @@ RED.editor = (function () {
1124
1124
  var summary = $('<span>').appendTo(metaRow);
1125
1125
  var resetButton = $(
1126
1126
  '<button type="button" class="editor-button editor-button-small">' +
1127
- 'use default' +
1128
- '</button>'
1127
+ 'use default' +
1128
+ '</button>'
1129
1129
  )
1130
1130
  .appendTo(metaRow)
1131
1131
  .click(function (e) {
@@ -1188,10 +1188,10 @@ RED.editor = (function () {
1188
1188
 
1189
1189
  $(
1190
1190
  '<div class="form-row">' +
1191
- '<label for="node-input-show-label-btn" data-i18n="editor.label"></label>' +
1192
- '<button type="button" id="node-input-show-label-btn" class="editor-button" style="min-width: 80px; text-align: left;" type="button"><i id="node-input-show-label-btn-i" class="fa fa-toggle-on"></i> <span id="node-input-show-label-label"></span></button> ' +
1193
- '<input type="checkbox" id="node-input-show-label" style="display: none;"/>' +
1194
- '</div>'
1191
+ '<label for="node-input-show-label-btn" data-i18n="editor.label"></label>' +
1192
+ '<button type="button" id="node-input-show-label-btn" class="editor-button" style="min-width: 80px; text-align: left;" type="button"><i id="node-input-show-label-btn-i" class="fa fa-toggle-on"></i> <span id="node-input-show-label-label"></span></button> ' +
1193
+ '<input type="checkbox" id="node-input-show-label" style="display: none;"/>' +
1194
+ '</div>'
1195
1195
  ).appendTo(dialogForm);
1196
1196
 
1197
1197
  var setToggleState = function (state) {
@@ -1381,7 +1381,7 @@ RED.editor = (function () {
1381
1381
  value: node.info || '',
1382
1382
  lineNumbers: false,
1383
1383
  toolbar: false,
1384
- onChange: function(delta) {
1384
+ onChange: function (delta) {
1385
1385
  // console.log('[editor] InfoTab changed. Delta=', delta);
1386
1386
  notifyChanges(getLatestNodeSelected());
1387
1387
  }
@@ -1390,7 +1390,7 @@ RED.editor = (function () {
1390
1390
  return nodeInfoEditor;
1391
1391
  }
1392
1392
 
1393
- function resetEditor(){
1393
+ function resetEditor() {
1394
1394
  editStack.pop();
1395
1395
  RED.sidebar.nodeinfo.emptyTab();
1396
1396
  RED.actions.invoke('core:hide-sidebar');
@@ -1400,7 +1400,7 @@ RED.editor = (function () {
1400
1400
  notifyChanges(getLatestNodeSelected());
1401
1401
  }
1402
1402
 
1403
- function notifyChanges(nodeSelected){
1403
+ function notifyChanges(nodeSelected) {
1404
1404
  // console.log('[editor] notifyChanges with nodeSelected: ', nodeSelected);
1405
1405
  let editing_node = nodeSelected;
1406
1406
  let node = nodeSelected;
@@ -1564,11 +1564,11 @@ RED.editor = (function () {
1564
1564
  changed = changed || credsChanged;
1565
1565
  }
1566
1566
  if (editing_node.hasOwnProperty("_outputs")) {
1567
- outputMap = editing_node._outputs;
1568
- delete editing_node._outputs;
1569
- if (Object.keys(outputMap).length > 0) {
1570
- changed = true;
1571
- }
1567
+ outputMap = editing_node._outputs;
1568
+ delete editing_node._outputs;
1569
+ if (Object.keys(outputMap).length > 0) {
1570
+ changed = true;
1571
+ }
1572
1572
  }
1573
1573
  var removedLinks = updateNodeProperties(editing_node, outputMap);
1574
1574
 
@@ -1607,7 +1607,7 @@ RED.editor = (function () {
1607
1607
  }
1608
1608
  }
1609
1609
 
1610
-
1610
+
1611
1611
  if (changed) {
1612
1612
  // console.log('[editor] Editing node detected a change. Saving required.');
1613
1613
  var wasChanged = editing_node.changed;
@@ -1652,7 +1652,7 @@ RED.editor = (function () {
1652
1652
  setLatestNodeSelected(editing_node);
1653
1653
  // console.log('[editor] Node changed. Required to be saved', editing_node);
1654
1654
  RED.events.emit('editor:save', editing_node);
1655
- }else{
1655
+ } else {
1656
1656
  // console.log('[editor] Editing node is same as current node. No saving required');
1657
1657
  return;
1658
1658
  }
@@ -1663,7 +1663,7 @@ RED.editor = (function () {
1663
1663
  // console.log('[editor] Node properties changed. Event: keyup change');
1664
1664
  notifyChanges(getLatestNodeSelected());
1665
1665
  // Wait until the DOM has been modified as part of the click event, to set the new listener to the new elements
1666
- setTimeout(()=> {
1666
+ setTimeout(() => {
1667
1667
  listenEditorChanges();
1668
1668
  }, 300);
1669
1669
  }
@@ -1672,13 +1672,13 @@ RED.editor = (function () {
1672
1672
  // console.log('[editor] Node properties changed. Event: a click');
1673
1673
 
1674
1674
  // Wait until the DOM has been modified as part of the click event, to set the new listener to the new elements
1675
- setTimeout(()=> {
1675
+ setTimeout(() => {
1676
1676
  notifyChanges(getLatestNodeSelected());
1677
1677
  listenEditorChanges();
1678
1678
  }, 300);
1679
1679
  }
1680
1680
 
1681
- function listenEditorChanges(){
1681
+ function listenEditorChanges() {
1682
1682
  // console.log('[editor] Setting new listeners...')
1683
1683
  $('#editor-stack :input').off('keyup change', attachListenerToFieldsChange);
1684
1684
  $('#editor-stack :input').on('keyup change', attachListenerToFieldsChange);
@@ -1688,31 +1688,31 @@ RED.editor = (function () {
1688
1688
  }
1689
1689
 
1690
1690
  function showEditDialog(node) {
1691
- if (RED.sidebar.isDragging()){
1691
+ if (RED.sidebar.isDragging()) {
1692
1692
  return;
1693
1693
  }
1694
1694
 
1695
1695
  let editing_node;
1696
- if (Object.keys(node).length === 0 && node.constructor === Object){
1696
+ if (Object.keys(node).length === 0 && node.constructor === Object) {
1697
1697
  resetEditor();
1698
1698
  return;
1699
1699
  }
1700
1700
  // Case selection is about a `link`
1701
- if (node && node.hasOwnProperty('link')){
1701
+ if (node && node.hasOwnProperty('link')) {
1702
1702
  return;
1703
1703
  }
1704
1704
 
1705
1705
  // Case selection is about a `node`
1706
1706
  if (node && node.hasOwnProperty('nodes') && node.nodes.length === 1) { // Single node selection
1707
1707
  // Ignore if sidebar is not visible - only double click will pull initially the sidebar
1708
- if (RED.sidebar.isSidebarVisible()){
1708
+ if (RED.sidebar.isSidebarVisible()) {
1709
1709
  editing_node = node.nodes[0];
1710
1710
  } else {
1711
1711
  setLatestNodeSelected(node.nodes[0]);
1712
1712
  return;
1713
1713
  }
1714
-
1715
- } else if (node && node.hasOwnProperty('nodes') && Array.isArray(node.nodes)){ // Multinode selection
1714
+
1715
+ } else if (node && node.hasOwnProperty('nodes') && Array.isArray(node.nodes)) { // Multinode selection
1716
1716
  return;
1717
1717
  } else { // Double click on node
1718
1718
  editing_node = node;
@@ -1725,7 +1725,7 @@ RED.editor = (function () {
1725
1725
  // console.log('[editor] Before editStack.push() =', editStack);
1726
1726
  editStack.pop();
1727
1727
  editStack.push(node);
1728
-
1728
+
1729
1729
  //RED.view.state(RED.state.EDITING);
1730
1730
  var type = node.type;
1731
1731
 
@@ -1741,9 +1741,9 @@ RED.editor = (function () {
1741
1741
  ],
1742
1742
  resize: function (dimensions) {
1743
1743
  editTrayWidthCache[type] = dimensions.width;
1744
- $('.editor-tray-content').height(dimensions.height - 50);
1744
+ // $('.editor-tray-content').height(dimensions.height - 50);
1745
1745
  var form = $('.editor-tray-content form');
1746
-
1746
+
1747
1747
  // var form = $('.editor-tray-content form').height(
1748
1748
  // dimensions.height - 50 - 40
1749
1749
  // );
@@ -1838,10 +1838,10 @@ RED.editor = (function () {
1838
1838
  let editorTabContent = $('#help-tab');
1839
1839
 
1840
1840
  let helpText =
1841
- $("script[data-help-name='" + node.type + "']").html() ||
1842
- '<span class="node-info-none">' +
1843
- 'None' +
1844
- '</span>';
1841
+ $("script[data-help-name='" + node.type + "']").html() ||
1842
+ '<span class="node-info-none">' +
1843
+ 'None' +
1844
+ '</span>';
1845
1845
 
1846
1846
  $(`<div class="node-help">${helpText}</div>`).appendTo(editorTabContent);
1847
1847
 
@@ -1911,8 +1911,8 @@ RED.editor = (function () {
1911
1911
  if (editing_node) {
1912
1912
  // console.log('[editor] Showing editor ...')
1913
1913
  RED.sidebar.info.refresh(editing_node);
1914
- // activate the save button when node properties have changed
1915
- setTimeout( ()=> {
1914
+ // activate the save button when node properties have changed
1915
+ setTimeout(() => {
1916
1916
  listenEditorChanges();
1917
1917
  }, 300);
1918
1918
  }
@@ -1974,7 +1974,7 @@ RED.editor = (function () {
1974
1974
 
1975
1975
  RED.view.state(RED.state.EDITING);
1976
1976
  var trayOptions = {
1977
- title: getEditStackTitle(),
1977
+ title: getEditStackTitle(),
1978
1978
  nodeIconPath: getNodeIconPath(),
1979
1979
  resize: function (dimensions) {
1980
1980
  $('.editor-tray-content').height(dimensions.height - 50);
@@ -2087,8 +2087,8 @@ RED.editor = (function () {
2087
2087
  tabSelect.off('change');
2088
2088
  tabSelect.append(
2089
2089
  '<option value=""' +
2090
- (!editing_config_node.z ? ' selected' : '') +
2091
- ' data-i18n="sidebar.config.global"></option>'
2090
+ (!editing_config_node.z ? ' selected' : '') +
2091
+ ' data-i18n="sidebar.config.global"></option>'
2092
2092
  );
2093
2093
  tabSelect.append(
2094
2094
  '<option disabled data-i18n="sidebar.config.flows"></option>'
@@ -2100,10 +2100,10 @@ RED.editor = (function () {
2100
2100
  }
2101
2101
  $(
2102
2102
  '<option value="' +
2103
- ws.id +
2104
- '"' +
2105
- (ws.id == editing_config_node.z ? ' selected' : '') +
2106
- '></option>'
2103
+ ws.id +
2104
+ '"' +
2105
+ (ws.id == editing_config_node.z ? ' selected' : '') +
2106
+ '></option>'
2107
2107
  )
2108
2108
  .text(workspaceLabel)
2109
2109
  .appendTo(tabSelect);
@@ -2118,10 +2118,10 @@ RED.editor = (function () {
2118
2118
  }
2119
2119
  $(
2120
2120
  '<option value="' +
2121
- ws.id +
2122
- '"' +
2123
- (ws.id == editing_config_node.z ? ' selected' : '') +
2124
- '></option>'
2121
+ ws.id +
2122
+ '"' +
2123
+ (ws.id == editing_config_node.z ? ' selected' : '') +
2124
+ '></option>'
2125
2125
  )
2126
2126
  .text(workspaceLabel)
2127
2127
  .appendTo(tabSelect);
@@ -2489,10 +2489,10 @@ RED.editor = (function () {
2489
2489
  configNodes.forEach(function (cn) {
2490
2490
  $(
2491
2491
  '<option value="' +
2492
- cn.id +
2493
- '"' +
2494
- (value == cn.id ? ' selected' : '') +
2495
- '></option>'
2492
+ cn.id +
2493
+ '"' +
2494
+ (value == cn.id ? ' selected' : '') +
2495
+ '></option>'
2496
2496
  )
2497
2497
  .text(RED.text.bidi.enforceTextDirectionWithUCC(cn.__label__))
2498
2498
  .appendTo(select);
@@ -2501,9 +2501,9 @@ RED.editor = (function () {
2501
2501
 
2502
2502
  select.append(
2503
2503
  '<option value="_ADD_"' +
2504
- (value === '' ? ' selected' : '') +
2505
- '>' + `Add new ${type}...` +
2506
- '</option>'
2504
+ (value === '' ? ' selected' : '') +
2505
+ '>' + `Add new ${type}...` +
2506
+ '</option>'
2507
2507
  );
2508
2508
  window.setTimeout(function () {
2509
2509
  select.change();
@@ -2782,7 +2782,7 @@ RED.editor = (function () {
2782
2782
  editStack.pop();
2783
2783
  editing_node = null;
2784
2784
  },
2785
- show: function () {},
2785
+ show: function () { },
2786
2786
  };
2787
2787
  RED.tray.show(trayOptions);
2788
2788
  }
@@ -2873,7 +2873,7 @@ RED.editor = (function () {
2873
2873
  }
2874
2874
  if (options.mode === 'ace/mode/markdown') {
2875
2875
  $(el).addClass('node-text-editor-container-toolbar');
2876
- if (options.toolbar === false ){
2876
+ if (options.toolbar === false) {
2877
2877
  // do not show the toolbar
2878
2878
  } else {
2879
2879
  editor.toolbar = customEditTypes['_markdown'].buildToolbar(
@@ -2881,7 +2881,7 @@ RED.editor = (function () {
2881
2881
  editor
2882
2882
  );
2883
2883
  }
2884
-
2884
+
2885
2885
 
2886
2886
  if (options.expandable !== false) {
2887
2887
  // var previewButton = $(
@@ -2907,9 +2907,9 @@ RED.editor = (function () {
2907
2907
  // autoClose: 50,
2908
2908
  // });
2909
2909
  }
2910
- if (options.onChange){
2911
- session.on("change", function(delta){
2912
- options.onChange(delta);
2910
+ if (options.onChange) {
2911
+ session.on("change", function (delta) {
2912
+ options.onChange(delta);
2913
2913
  })
2914
2914
  }
2915
2915
  return editor;
@@ -2977,7 +2977,7 @@ RED.editor = (function () {
2977
2977
  editBuffer: function (options) {
2978
2978
  showTypeEditor('_buffer', options);
2979
2979
  },
2980
- editText: function(options){
2980
+ editText: function (options) {
2981
2981
  showTypeEditor('_string', options);
2982
2982
  },
2983
2983
  buildEditForm: buildEditForm,
@@ -0,0 +1,143 @@
1
+ RED.footer = (function () {
2
+ // AI Section
3
+ const askConfigureAI = () => {
4
+ console.log(`[footer] showing "askConfigureAi"`)
5
+
6
+ $('#generate-code-ai').hide();
7
+ $('#explain-code-ai').hide();
8
+ $('#fix-code-ai').hide();
9
+
10
+ $('#ask-configure-ai').show();
11
+ }
12
+
13
+ const showTasksAI = () => {
14
+ console.log(`[footer] showing all AI tasks`)
15
+
16
+ $('#generate-code-ai').show();
17
+ $('#explain-code-ai').show();
18
+ $('#fix-code-ai').show();
19
+
20
+ $('#ask-configure-ai').hide();
21
+ }
22
+
23
+ const isEnabledAI = () => {
24
+ return false;
25
+ }
26
+
27
+
28
+ const handleChangeTestCase = (tcSelected) => {
29
+ console.log('[footer] callback with tcSelected', tcSelected);
30
+ let testcaseName = tcSelected.name || 'No TestCase selected'; // 'getTestCaseName(tcSelected.id);
31
+ console.log('[footer] Resolved testcase name=', testcaseName);
32
+
33
+ if (testcaseName) {
34
+ $('#footer-test').show();
35
+ $('#footer-test-value').text(testcaseName);
36
+ } else {
37
+ $('#footer-test').hide();
38
+ }
39
+ }
40
+
41
+ const getTestCaseName = (testcaseId) => {
42
+ if (!testcaseId) return "No TestCase selected";
43
+
44
+ if (testcaseId === '__runAll') {
45
+ return "Run all TestCases";
46
+ } else {
47
+ let nodeSelected = RED.nodes.filterNodes({ id: testcaseId });
48
+ console.log('[footer] Node Selected: ', nodeSelected)
49
+ if (nodeSelected && Array.isArray(nodeSelected) && nodeSelected.length > 0) {
50
+ let name = nodeSelected[0].name;
51
+ return name;
52
+ }
53
+ }
54
+ }
55
+
56
+ const initNodeLibraryWidget = () => {
57
+ let $nodeLibrary = $('#launch-node-library');
58
+ RED.popover.tooltip($nodeLibrary, 'Open node library...');
59
+ }
60
+
61
+ const initRuntimeVerWidget = () => {
62
+ let $runtimeVer = $('#footer-runtime-ver');
63
+ RED.popover.create({
64
+ target: $runtimeVer,
65
+ trigger: 'hover',
66
+ size: 'small',
67
+ direction: 'top',
68
+ content: 'Kumologica runtime installed',
69
+ delay: { show: 750, hide: 50 },
70
+ })
71
+ }
72
+
73
+ const initServerWidget = () => {
74
+ let $footerServer = $('#footer-server');
75
+ RED.popover.tooltip($footerServer, 'Local server listening address')
76
+ }
77
+ const initTestWidget = () => {
78
+ window.__kumologica.settings.loadConfigs();
79
+ console.log('[footer] testConfig=', window.__kumologica.settings.testConfig);
80
+
81
+ let testcaseId = window.__kumologica.settings.testConfig.getLatestSelectedTestCase();
82
+ let tcSelectedName = getTestCaseName(testcaseId);
83
+
84
+ handleChangeTestCase({
85
+ id: testcaseId,
86
+ name: tcSelectedName
87
+ });
88
+
89
+ // Add action
90
+ let $footerTest = $('#footer-test');
91
+ $footerTest.click(e => {
92
+ if (!$('.sidebar-test').is(':visible')) {
93
+ $('#red-ui-tab-test-link-button').click();
94
+ }
95
+
96
+ $('#test-sidebar-run-btn').click();
97
+ });
98
+ // Add popover
99
+ RED.popover.tooltip($footerTest, "Run TestCase");
100
+
101
+ // Attach listener
102
+ RED.actions.add('test:change-testcase-selected', handleChangeTestCase);
103
+ }
104
+
105
+ const initAIWidget = () => {
106
+ // check whether AI settings are configured or not
107
+ let aiEnabled = isEnabledAI();
108
+ if (aiEnabled) {
109
+ showTasksAI();
110
+ } else {
111
+ askConfigureAI();
112
+ }
113
+ }
114
+
115
+ const initTerminalWidget = () => {
116
+ let $footerTerminal = $('#footer-terminal');
117
+
118
+ $footerTerminal.click(e => {
119
+ $('#workspace-terminal').toggle();
120
+ });
121
+ RED.popover.create({
122
+ target: $footerTerminal,
123
+ trigger: 'hover',
124
+ size: 'small',
125
+ direction: 'left',
126
+ content: "Log Viewer",
127
+ delay: { show: 750, hide: 50 }
128
+ });
129
+ }
130
+
131
+ const init = () => {
132
+ initNodeLibraryWidget();
133
+ initRuntimeVerWidget();
134
+ initServerWidget();
135
+ setTimeout(() => initTestWidget(), 2000);
136
+ initAIWidget();
137
+ initTerminalWidget();
138
+ }
139
+
140
+ return {
141
+ init: init
142
+ }
143
+ })();