@kumologica/sdk 3.3.0-beta8 → 3.4.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 (60) hide show
  1. package/cli/commands/open.js +6 -7
  2. package/cli/commands/test-commands/TestSuiteRunner.js +75 -0
  3. package/cli/commands/test-commands/lib/TestCaseRunner.js +105 -0
  4. package/cli/commands/test-commands/lib/index.js +12 -0
  5. package/cli/commands/test-commands/lib/reporters/index.js +120 -0
  6. package/cli/commands/test.js +92 -120
  7. package/package.json +4 -5
  8. package/src/app/lib/stores/store.js +15 -1
  9. package/src/app/lib/stores/user-preference-store.js +2 -0
  10. package/src/app/lib/stores/workspace-preference-store.js +42 -0
  11. package/src/app/main-process/editor-manager.js +11 -51
  12. package/src/app/main-process/main-window.js +10 -0
  13. package/src/app/main-process/menu.js +4 -2
  14. package/src/app/main-process/modal-home.js +5 -7
  15. package/src/app/main-process/modal-newproject.js +4 -6
  16. package/src/app/main-process/modal-newtab.js +4 -6
  17. package/src/app/main-process/modal-nodelibrary.js +4 -6
  18. package/src/app/main-process/modal-welcome.js +5 -8
  19. package/src/app/main.js +3 -1
  20. package/src/app/preload.js +28 -4
  21. package/src/app/ui/editor-api/lib/index.js +6 -9
  22. package/src/app/ui/editor-client/public/red/red.js +434 -176
  23. package/src/app/ui/editor-client/public/red/red.min.js +3 -3
  24. package/src/app/ui/editor-client/public/red/style.min.css +1 -1
  25. package/src/app/ui/editor-client/public/vendor/vendor.css +21 -1
  26. package/src/app/ui/editor-client/src/js/red.js +1 -1
  27. package/src/app/ui/editor-client/src/js/ui/clipboard.js +8 -0
  28. package/src/app/ui/editor-client/src/js/ui/header.js +2 -40
  29. package/src/app/ui/editor-client/src/js/ui/palette-explorer.js +328 -0
  30. package/src/app/ui/editor-client/src/js/ui/palette.js +10 -8
  31. package/src/app/ui/editor-client/src/js/ui/project-info.js +10 -8
  32. package/src/app/ui/editor-client/src/js/ui/search.js +147 -44
  33. package/src/app/ui/editor-client/src/js/ui/ui-settings.js +1 -1
  34. package/src/app/ui/editor-client/src/js/ui/view.js +2 -5
  35. package/src/app/ui/editor-client/src/js/validators.js +2 -2
  36. package/src/app/ui/editor-client/src/sass/dropdownMenu.scss +1 -1
  37. package/src/app/ui/editor-client/src/sass/editor.scss +1 -0
  38. package/src/app/ui/editor-client/src/sass/header.scss +16 -7
  39. package/src/app/ui/editor-client/src/sass/palette.scss +46 -5
  40. package/src/app/ui/editor-client/src/sass/project-info.scss +4 -3
  41. package/src/app/ui/editor-client/src/sass/search.scss +49 -21
  42. package/src/app/ui/editor-client/src/sass/style.scss +1 -0
  43. package/src/app/ui/editor-client/src/sass/ui/common/editableList.scss +3 -3
  44. package/src/app/ui/editor-client/src/sass/ui/common/searchBox.scss +1 -2
  45. package/src/app/ui/editor-client/src/sass/ui-settings.scss +5 -3
  46. package/src/app/ui/editor-client/src/vendor/jqtree/jqtree.css +21 -1
  47. package/src/app/ui/editor-client/templates/index.mst +89 -79
  48. package/src/server/DesignerServer.js +161 -0
  49. package/src/server/certificate.pem +23 -0
  50. package/src/server/private-key.pem +28 -0
  51. package/cli/commands/test-utils/TestSuiteController.js +0 -363
  52. package/cli/commands/test-utils/TestSuiteController.test.js +0 -171
  53. package/cli/commands/test-utils/util/output.js +0 -14
  54. package/cli/commands/test-utils/util/updates/index.js +0 -17
  55. package/cli/commands/test-utils/util/updates/pkg.js +0 -13
  56. package/cli/commands/test-utils/util/updates/templates/default-settings.js +0 -209
  57. package/src/app/ui/editor-client/src/js/ui/palette-navigator.js +0 -144
  58. /package/cli/commands/{test-utils → test-commands/lib}/fixtures/example3-flow.json +0 -0
  59. /package/cli/commands/{test-utils → test-commands/lib}/fixtures/package.json +0 -0
  60. /package/cli/commands/{test-utils → test-commands/lib}/fixtures/s3-event.js +0 -0
@@ -47,6 +47,9 @@ ul.jqtree-tree {
47
47
 
48
48
  ul.jqtree-tree .jqtree-toggler.jqtree-toggler-left {
49
49
  margin-right: 0.5em;
50
+ margin-left: 1em;
51
+ color: grey;
52
+ font-size: smaller;
50
53
  }
51
54
 
52
55
  ul.jqtree-tree .jqtree-toggler.jqtree-toggler-right {
@@ -68,10 +71,27 @@ ul.jqtree-tree {
68
71
  ul.jqtree-tree .jqtree-title-button-left {
69
72
  margin-left: 1.5em;
70
73
  }
71
-
74
+ .jqtree-title-emptyfolder {
75
+ width: 100%;
76
+ margin-left: 2.5em !important;
77
+ color: #605d5d !important;
78
+ text-transform: uppercase;
79
+ font-weight: bold;
80
+ letter-spacing: 0.02em;
81
+ font-size: smaller;
82
+ overflow: hidden;
83
+ user-select: none;
84
+ }
72
85
  ul.jqtree-tree .jqtree-title-button-left.jqtree-title-folder {
73
86
  width: 100%;
74
87
  margin-left: 0;
88
+ color: #605d5d;
89
+ text-transform: uppercase;
90
+ font-weight: bold;
91
+ letter-spacing: 0.02em;
92
+ font-size: smaller;
93
+ overflow: hidden;
94
+ user-select: none;
75
95
  }
76
96
 
77
97
  ul.jqtree-tree li.jqtree-folder {
@@ -625,7 +625,7 @@ var RED = (function () {
625
625
  RED.library.init();
626
626
  RED.keyboard.init();
627
627
  RED.palette.init();
628
- RED.palette.navigator.init();
628
+ RED.palette.explorer.init();
629
629
  RED.palette.nodes.init();
630
630
  RED.eventLog.init();
631
631
  if (RED.settings.theme('palette.editable') !== false) {
@@ -74,9 +74,15 @@
74
74
  },
75
75
  close: function(e) {
76
76
  if (popover) {
77
+ console.log(popover);
77
78
  popover.close(true);
78
79
  currentPopoverError = null;
79
80
  }
81
+ // Otherwise for some fucking reason the screen gets moved to the top...
82
+ $('#main-container').hide();
83
+ window.setTimeout(()=> {
84
+ $('#main-container').show()
85
+ }, 10);
80
86
  }
81
87
  });
82
88
 
@@ -218,6 +224,8 @@
218
224
  if (disabled) {
219
225
  return;
220
226
  }
227
+ RED.actions.invoke('core:search:close');
228
+
221
229
  dialogContainer.empty();
222
230
  dialogContainer.append($(importNodesDialog));
223
231
  dialogContainer.i18n();
@@ -125,65 +125,27 @@ RED.header = (function () {
125
125
  initImportExport();
126
126
  initShelvesFromHeader();
127
127
  initSettingsButtonFromHeader();
128
- initSearchBtn();
129
128
  initDeployBtn();
130
129
  initProjectIndicator();
131
130
  }
132
131
 
133
132
  function initProjectIndicator() {
134
133
  $('#projectIndicator').click((e) => {
135
- e.preventDefault();
136
- if ($('#red-ui-project-info').is(':visible')) {
137
- RED.actions.invoke('core:project-info:close');
138
- } else {
139
- RED.actions.invoke('core:project-info');
140
- }
141
- });
142
- $('#projectInfoExpand').click((e) => {
143
- e.preventDefault();
144
- if ($('#red-ui-project-info').is(':visible')) {
145
- RED.actions.invoke('core:project-info:close');
146
- } else {
147
- RED.actions.invoke('core:project-info');
148
- }
149
- });
150
- $('#projectIndicator').hover(
151
- () => {
152
- $('#projectInfoExpand').css('color', '#999');
153
- },
154
- () => {
155
- $('#projectInfoExpand').css('color', '#ecebeb');
156
- }
157
- );
158
- $('#projectInfoExpand').hover(
159
- () => {
160
- $('#projectInfoExpand').css('color', '#999');
161
- },
162
- () => {
163
- $('#projectInfoExpand').css('color', '#ecebeb');
164
- }
165
- );
166
- }
167
-
168
- function initSearchBtn() {
169
- $('#btn-search').click((e) => {
170
134
  e.preventDefault();
171
135
  if ($('#red-ui-search').is(':visible')) {
172
- console.log('[header] closing search panel')
173
136
  RED.actions.invoke('core:search:close');
174
137
  } else {
175
- console.log('[header] opening search panel')
176
138
  RED.actions.invoke('core:search');
177
139
  }
178
140
  });
179
141
  }
180
142
 
181
-
182
143
  function initDeployBtn() {
183
144
  RED.actions.add('core:deploy', deployFlow);
184
145
 
185
146
  $('#btn-deploy').click((e) => {
186
- RED.actions.invoke('core:deploy');
147
+ e.stopPropagation();
148
+ RED.actions.invoke('core:deploy');
187
149
  });
188
150
 
189
151
  // RED.popover.tooltip($('#btn-deploy'), 'Save & Deploy');
@@ -0,0 +1,328 @@
1
+ RED.palette.explorer = (function () {
2
+ let workspacePreferences = window.__kumologica.settings.workspacePreferenceStore;
3
+ let path = window.__kumologica.libs.path;
4
+
5
+ const openProject = (projectLocation) => {
6
+ window.__kumologica.main.dispatch('modal-home:open-project-in-editor', {
7
+ payload: {
8
+ projectLocation
9
+ }
10
+ });
11
+ }
12
+
13
+ const initCurrentProject = () => {
14
+ // Add Tab button
15
+ let addTabBtn = `<div id="createTab" class="header-btn2"><i class="icofont-plus"></i></div>`;
16
+ $(addTabBtn).appendTo($('#exp-open-project-createTab'));
17
+ RED.popover.tooltip($('#exp-open-project-createTab'), 'Create Tab...');
18
+
19
+ $('#createTab').on('click', event => {
20
+ event.stopPropagation();
21
+ window.__kumologica.main.dispatch('navigator:open-new-tab-dialog', null);
22
+ })
23
+
24
+ // Initialize the palette explorer with folder only
25
+ let data = [
26
+ { id: '__root__',
27
+ name: 'OPEN PROJECT',
28
+ children: []
29
+ }
30
+ ];
31
+
32
+ try{
33
+ $('#exp-open-project').tree({
34
+ data:data,
35
+ autoOpen: true,
36
+ selectable: true,
37
+ onCanSelectNode: function(node) {
38
+ if (node.id === '__root__'){
39
+ $('#exp-open-project').tree('toggle', node);
40
+ return false;
41
+ } else {
42
+ return true;
43
+ }
44
+
45
+ },
46
+ usecontextmenu: true,
47
+ closedIcon: $('<i class="icofont-rounded-right"></i>'),
48
+ openedIcon: $('<i class="icofont-rounded-down"></i>'),
49
+ onCreateLi: function(node, $li) { }
50
+ });
51
+
52
+ // Add the context menu
53
+ $('#exp-open-project').jqTreeContextMenu({
54
+ menu: '#palette-explorer-context-menu',
55
+ onContextMenuItem: function(e, node, $el){
56
+ let operation = $el.data("item");
57
+ switch(operation) {
58
+ case "open":
59
+ RED.workspaces.showSafe(node.id);
60
+ break;
61
+ case "delete": {
62
+ RED.actions.invoke('core:deploy');
63
+ RED.workspaces.remove(node.id);
64
+ RED.actions.invoke('core:deploy'); // save it so we can persist the tab straight away.
65
+ refresh();
66
+ break;
67
+ }
68
+ default: {}
69
+ }
70
+
71
+ }
72
+ });
73
+ }catch(err) {
74
+ // HACK: case where a modal is using this module, which it has no biz on tree
75
+ }
76
+
77
+ let ipcRenderer = window.__kumologica.electron.ipcRenderer;
78
+ ipcRenderer.on('create-new-tab', (event, payload)=> {
79
+ let tabName = payload.tabName;
80
+ if (tabName){
81
+ createTabFn(tabName.toLowerCase());
82
+ }
83
+
84
+ });
85
+
86
+ // On select tab option
87
+ $('#exp-open-project').on(
88
+ 'tree.select',
89
+ function(event) {
90
+ event.stopImmediatePropagation();
91
+ if (event.node) {
92
+ // console.log(`[palette-navigator] Select Tab=(${event.node.id})`);
93
+ // node was selected
94
+ var node = event.node;
95
+ if (node.id){
96
+ RED.workspaces.showSafe(node.id);
97
+ }
98
+ }
99
+ else {
100
+ var prevNode = event.previous_node
101
+ if (prevNode.id){
102
+ RED.workspaces.showSafe(prevNode.id);
103
+ selectTab(prevNode.id);
104
+ }
105
+ }
106
+ }
107
+ );
108
+
109
+ refresh();
110
+ }
111
+
112
+ const initWorkspaceProjects = () => {
113
+ // Add Tab button
114
+ let addProjectToWorkspaceBtn = `<div id="addProjectToWorkspace" class="header-btn2"><i class="icofont-plus"></i></div>`;
115
+ $(addProjectToWorkspaceBtn).appendTo($('#exp-workspace-addFolder'));
116
+ RED.popover.tooltip($('#exp-workspace-addFolder'), 'Add Project to Workspace...');
117
+
118
+ // Add action to the add button
119
+ $('#addProjectToWorkspace').click((event) => {
120
+ console.log('[palette-explorer] addProjectToWorkspaceBtn clicked');
121
+
122
+ let currentWindow = window.__kumologica.electron.remote.getCurrentWindow()
123
+ let dialog = window.__kumologica.electron.remote.dialog;
124
+ let options = {
125
+ title: 'Select Projects to add to Workspace...',
126
+ properties: ['openDirectory', 'multiSelections'],
127
+ };
128
+ dialog.showOpenDialog(currentWindow, options).then((result) => {
129
+ if (!result.canceled){
130
+ let projects = result.filePaths;
131
+ console.log('[palette-explorer] projects=', projects);
132
+ projects.forEach(project => {
133
+ let valid = window.__kumologica.libs.findKumologicaFlowInDir(project);
134
+ if (valid) {
135
+ workspacePreferences.addProjectToWorkspace(project);
136
+ } else {
137
+ RED.notifications.notify(`<b>Invalid Kumologica project directory:</b> ${project}`, 'error', undefined, 3000);
138
+ }
139
+ });
140
+ refreshWorkspaceProjects();
141
+ }
142
+ console.log('[palette-explorer] result=', result);
143
+ });
144
+ });
145
+
146
+ // Initialize the projects in workspace
147
+ let data = [
148
+ { id: '__root__',
149
+ name: 'WORKSPACE PROJECTS',
150
+ children: []
151
+ }
152
+ ];
153
+
154
+ try{
155
+ $('#exp-workspace').tree({
156
+ data:data,
157
+ autoOpen: true,
158
+ selectable: true,
159
+ onCanSelectNode: function(node) {
160
+ if (node.id === '__root__'){
161
+ $('#exp-workspace').tree('toggle', node);
162
+ return false;
163
+ } else {
164
+ const el = $(node.element);
165
+ const selectionRequired = !el.hasClass('jqtree-selected');
166
+ // Deselect all nodes
167
+ $('#exp-workspace').find('.jqtree-selected').removeClass('jqtree-selected');
168
+
169
+ if (selectionRequired) {
170
+ el.addClass('jqtree-selected');
171
+ }
172
+
173
+ return false;
174
+ }
175
+
176
+ },
177
+ usecontextmenu: true,
178
+ closedIcon: $('<i class="icofont-rounded-right"></i>'),
179
+ openedIcon: $('<i class="icofont-rounded-down"></i>'),
180
+ onCreateLi: function(node, $li) {
181
+ if (node.id !== '__root__'){
182
+ RED.popover.tooltip(
183
+ $li.find('.jqtree-title'),
184
+ node.path
185
+ );
186
+ $li.find('.jqtree-title').before('<span class="icon" style="position: relative; left: 14px; font-size: 13px; color: #8b3ff8"><i class="fa fa-folder"></i></span>');
187
+ }
188
+ }
189
+ });
190
+
191
+ // Add the context menu
192
+ $('#exp-workspace').jqTreeContextMenu({
193
+ menu: '#palette-workspace-context-menu',
194
+ onContextMenuItem: function(e, node, $el){
195
+
196
+ let operation = $el.data("item");
197
+ let projectLocation = node.path;
198
+
199
+ switch(operation) {
200
+ case "open":
201
+ openProject(projectLocation);
202
+ break;
203
+ case "openLocation":
204
+ window.__kumologica.libs.openFolder(projectLocation);
205
+ break;
206
+ case "removeFromWorkspace": {
207
+ workspacePreferences.removeProjectFromWorkspace(projectLocation);
208
+ refreshWorkspaceProjects();
209
+ break;
210
+ }
211
+ default: {}
212
+ }
213
+
214
+ }
215
+ });
216
+ }catch(err) {
217
+ // HACK: case where a modal is using this module, which it has no biz on tree
218
+ }
219
+
220
+ // On double click project ...
221
+ // On select tab option
222
+ $('#exp-workspace').on(
223
+ 'tree.dblclick',
224
+ function(event) {
225
+ event.stopImmediatePropagation();
226
+ if (event.node && event.node.path) {
227
+ openProject(event.node.path)
228
+ }
229
+ }
230
+ );
231
+
232
+ }
233
+
234
+
235
+
236
+ const init = () => {
237
+ initCurrentProject();
238
+ initWorkspaceProjects();
239
+ }
240
+
241
+ const createTabFn = (newTabName) => {
242
+ try{
243
+ // RED.actions.invoke('core:deploy');
244
+ RED.workspaces.add(undefined, undefined, undefined, newTabName);
245
+ RED.actions.invoke('core:deploy'); // save it so we can persist the tab straight away.
246
+ refresh();
247
+ } catch(err){
248
+ RED.notify(`<strong>Error</strong>: "${newTabName}" tab already exists.`, 'error');
249
+ }
250
+
251
+ }
252
+
253
+ const selectTab = (nodeId) => {
254
+ const tnode = $('#exp-open-project').tree('getNodeById', nodeId);
255
+ $('#exp-open-project').tree('selectNode', tnode);
256
+ // Hack to maintain the focus on the selected tab
257
+ $('#workspace-tabs').addClass('workspace-focussed');
258
+ }
259
+
260
+ const refreshTabs = () => {
261
+ if (!RED.workspaces.tabs() || RED.workspaces.tabs().length === 0) return;
262
+
263
+ const tabs = RED.nodes.listWorkspaces();
264
+ const currentProjectName = RED.projectInfo.getWorkspaceInfo()[0].name;
265
+ let data = [
266
+ {
267
+ id: '__root__',
268
+ name: currentProjectName,
269
+ children: []
270
+ }
271
+ ];
272
+
273
+ for (const key in tabs) {
274
+ data[0].children.push({ id: tabs[key].id, name: tabs[key].label })
275
+ }
276
+
277
+ $('#exp-open-project').tree('loadData', data);
278
+ }
279
+
280
+ const refreshWorkspaceProjects = () => {
281
+ let projects = workspacePreferences.getWorkspaceProjects();
282
+
283
+ // Initialize the tree with empty data
284
+ let data = [
285
+ {
286
+ id: '__root__',
287
+ name: 'WORKSPACE PROJECTS',
288
+ children: []
289
+ }
290
+ ];
291
+
292
+
293
+ // Update the data with info from workspace preferences
294
+ if (projects){
295
+ projects.forEach((project, index) => {
296
+ let projectName = path.basename(project);
297
+ data[0].children.push({ id: name, name: projectName, path: project });
298
+ })
299
+ }
300
+
301
+ // Render the tree
302
+ $('#exp-workspace').tree('loadData', data);
303
+
304
+ // Hack to add style to the title if no projects are added. As this element is not considered a folder
305
+ if (!projects || projects.length === 0){
306
+ const elements = $('.jqtree-title-button-left');
307
+ const maxElements = elements.length;
308
+ for(let i = 0; i < maxElements; i++){
309
+ if ($(elements[i]).text() === 'WORKSPACE PROJECTS'){
310
+ $(elements[i]).addClass('jqtree-title-emptyfolder');
311
+ break;
312
+ }
313
+ }
314
+ }
315
+ }
316
+
317
+ const refresh = () => {
318
+ refreshTabs();
319
+ refreshWorkspaceProjects();
320
+ }
321
+
322
+ return {
323
+ init,
324
+ refresh,
325
+ selectTab
326
+ };
327
+
328
+ })();
@@ -7,11 +7,11 @@ RED.palette = (function () {
7
7
  RED.palette.nodes.collapseAllPalette()
8
8
  }
9
9
  },
10
- navigator: {
11
- header: 'palette-option-projectnav-a',
12
- panel: 'palette-projectnav',
10
+ explorer: {
11
+ header: 'palette-option-explorer-a',
12
+ panel: 'palette-explorer',
13
13
  onSelect: () => {
14
- RED.palette.navigator.refresh()
14
+ RED.palette.explorer.refresh()
15
15
  }
16
16
  }
17
17
  }
@@ -21,15 +21,17 @@ RED.palette = (function () {
21
21
  deselectAll();
22
22
  select(options.nodes);
23
23
  });
24
- $(`#${options.navigator.header}`).click(e=> {
24
+
25
+ $(`#${options.explorer.header}`).click(e=> {
25
26
  deselectAll();
26
- select(options.navigator);
27
+ select(options.explorer);
27
28
  });
28
29
  }
29
30
 
30
31
  const deselectAll = () => {
31
32
  deselect(options.nodes);
32
- deselect(options.navigator);
33
+ deselect(options.explorer);
34
+
33
35
  }
34
36
 
35
37
  const deselect = (option) => {
@@ -48,7 +50,7 @@ RED.palette = (function () {
48
50
 
49
51
  const init = () => {
50
52
  // Preselection
51
- deselect(options.navigator);
53
+ deselect(options.explorer);
52
54
  select(options.nodes);
53
55
 
54
56
  // Handle the click events
@@ -132,11 +132,6 @@ RED.projectInfo = (function () {
132
132
  hide();
133
133
  });
134
134
 
135
- // Hint to how to close the search panel
136
- $(`
137
- <div style="text-align:center; padding: 11px 0 11px 0">Press <span class="escape-key">Esc</span> to close</div>
138
- `).appendTo(dialog);
139
-
140
135
  if (config) {
141
136
  setValues(config);
142
137
  }
@@ -178,6 +173,12 @@ RED.projectInfo = (function () {
178
173
  RED.view.reveal(node.id);
179
174
  }
180
175
 
176
+ function getWorkspaceInfo() {
177
+ return [
178
+ { name: projectName, path: projectDir }
179
+ ]
180
+ }
181
+
181
182
  function show(v) {
182
183
  // Disable the search dialog if opened
183
184
  RED.actions.invoke('core:search:close');
@@ -227,8 +228,9 @@ RED.projectInfo = (function () {
227
228
  }
228
229
 
229
230
  return {
230
- init: init,
231
- show: show,
232
- hide: hide,
231
+ init,
232
+ show,
233
+ hide,
234
+ getWorkspaceInfo
233
235
  };
234
236
  })();