@saltcorn/builder 0.5.6-beta.2 → 0.6.0-alpha.0

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.
@@ -7,9 +7,8 @@ import {
7
7
  MinRoleSettingRow,
8
8
  OrFormula,
9
9
  TextStyleSetting,
10
+ ButtonOrLinkSettingsRows,
10
11
  } from "./utils";
11
- import FontIconPicker from "@fonticonpicker/react-fonticonpicker";
12
- import faIcons from "./faicons";
13
12
 
14
13
  export const ViewLink = ({
15
14
  name,
@@ -21,6 +20,9 @@ export const ViewLink = ({
21
20
  inModal,
22
21
  label,
23
22
  textStyle,
23
+ link_bgcol,
24
+ link_bordercol,
25
+ link_textcol,
24
26
  }) => {
25
27
  const {
26
28
  selected,
@@ -35,6 +37,15 @@ export const ViewLink = ({
35
37
  } ${link_style} ${link_size}`}
36
38
  {...blockProps(block)}
37
39
  ref={(dom) => connect(drag(dom))}
40
+ style={
41
+ link_style === "btn btn-custom-color"
42
+ ? {
43
+ backgroundColor: link_bgcol || "#000000",
44
+ borderColor: link_bordercol || "#000000",
45
+ color: link_textcol || "#000000",
46
+ }
47
+ : {}
48
+ }
38
49
  >
39
50
  {link_icon ? <i className={`${link_icon} mr-1`}></i> : ""}
40
51
  {displabel}
@@ -54,6 +65,9 @@ export const ViewLinkSettings = () => {
54
65
  link_size: node.data.props.link_size,
55
66
  link_icon: node.data.props.link_icon,
56
67
  textStyle: node.data.props.textStyle,
68
+ link_bgcol: node.data.props.link_bgcol,
69
+ link_bordercol: node.data.props.link_bordercol,
70
+ link_textcol: node.data.props.link_textcol,
57
71
  }));
58
72
  const {
59
73
  actions: { setProp },
@@ -63,82 +77,55 @@ export const ViewLinkSettings = () => {
63
77
  label,
64
78
  isFormula,
65
79
  inModal,
66
- link_style,
67
- link_icon,
68
- link_size,
69
80
  textStyle,
70
81
  } = node;
71
82
  const options = useContext(optionsCtx);
72
83
  return (
73
84
  <div>
74
- <div>
75
- <label>View to link to</label>
76
- <select
77
- value={name}
78
- className="form-control"
79
- onChange={(e) => setProp((prop) => (prop.name = e.target.value))}
80
- >
81
- {options.link_view_opts.map((f, ix) => (
82
- <option key={ix} value={f.name}>
83
- {f.label}
84
- </option>
85
- ))}
86
- </select>
87
- </div>
88
- <div>
89
- <label>Label (leave blank for default)</label>
90
- <OrFormula nodekey="label" {...{ setProp, isFormula, node }}>
91
- <input
92
- type="text"
93
- className="viewlink-label form-control"
94
- value={label}
95
- onChange={(e) => setProp((prop) => (prop.label = e.target.value))}
85
+ <table className="w-100">
86
+ <tbody>
87
+ <tr>
88
+ <td colSpan="2">
89
+ <label>View to link to</label>
90
+ <select
91
+ value={name}
92
+ className="form-control"
93
+ onChange={(e) =>
94
+ setProp((prop) => (prop.name = e.target.value))
95
+ }
96
+ >
97
+ {options.link_view_opts.map((f, ix) => (
98
+ <option key={ix} value={f.name}>
99
+ {f.label}
100
+ </option>
101
+ ))}
102
+ </select>
103
+ </td>
104
+ </tr>
105
+ <tr>
106
+ <td colSpan="2">
107
+ <label>Label (leave blank for default)</label>
108
+ <OrFormula nodekey="label" {...{ setProp, isFormula, node }}>
109
+ <input
110
+ type="text"
111
+ className="viewlink-label form-control"
112
+ value={label}
113
+ onChange={(e) =>
114
+ setProp((prop) => (prop.label = e.target.value))
115
+ }
116
+ />
117
+ </OrFormula>
118
+ </td>
119
+ </tr>
120
+ <ButtonOrLinkSettingsRows
121
+ setProp={setProp}
122
+ keyPrefix="link_"
123
+ btnClass="btn"
124
+ values={node}
125
+ linkFirst={true}
96
126
  />
97
- </OrFormula>
98
- </div>
99
- <div>
100
- <label>Link style</label>
101
- <select
102
- className="form-control"
103
- value={link_style}
104
- onChange={(e) =>
105
- setProp((prop) => (prop.link_style = e.target.value))
106
- }
107
- >
108
- <option value="">Link</option>
109
- <option value="btn btn-primary">Primary button</option>
110
- <option value="btn btn-secondary">Secondary button</option>
111
- <option value="btn btn-success">Success button</option>
112
- <option value="btn btn-danger">Danger button</option>
113
- <option value="btn btn-outline-primary">
114
- Primary outline button
115
- </option>
116
- <option value="btn btn-outline-secondary">
117
- Secondary outline button
118
- </option>
119
- </select>
120
- </div>
121
- <div>
122
- <label>Link size</label>
123
- <select
124
- className="form-control"
125
- value={link_size}
126
- onChange={(e) => setProp((prop) => (prop.link_size = e.target.value))}
127
- >
128
- <option value="">Standard</option>
129
- <option value="btn-lg">Large</option>
130
- <option value="btn-sm">Small</option>
131
- <option value="btn-block">Block</option>
132
- <option value="btn-block btn-lg">Large block</option>
133
- </select>
134
- </div>
135
- <label className="mr-2">Icon</label>
136
- <FontIconPicker
137
- value={link_icon}
138
- icons={faIcons}
139
- onChange={(value) => setProp((prop) => (prop.link_icon = value))}
140
- isMulti={false}
141
- />
127
+ </tbody>
128
+ </table>
142
129
  <div className="form-check">
143
130
  <input
144
131
  className="form-check-input"
@@ -179,6 +166,9 @@ ViewLink.craft = {
179
166
  "link_style",
180
167
  "link_icon",
181
168
  "link_size",
169
+ "link_bgcol",
170
+ "link_bordercol",
171
+ "link_textcol",
182
172
  ],
183
173
  },
184
174
  };
@@ -6,6 +6,8 @@ import {
6
6
  faChevronRight,
7
7
  } from "@fortawesome/free-solid-svg-icons";
8
8
  import { useNode } from "@craftjs/core";
9
+ import FontIconPicker from "@fonticonpicker/react-fonticonpicker";
10
+ import faIcons from "./faicons";
9
11
 
10
12
  export const blockProps = (is_block) =>
11
13
  is_block ? { style: { display: "block" } } : {};
@@ -17,7 +19,12 @@ export const BlockSetting = ({ block, setProp }) => (
17
19
  name="block"
18
20
  type="checkbox"
19
21
  checked={block}
20
- onChange={(e) => setProp((prop) => (prop.block = e.target.checked))}
22
+ onChange={(e) => {
23
+ if (e.target) {
24
+ const target_value = e.target.checked;
25
+ setProp((prop) => (prop.block = target_value));
26
+ }
27
+ }}
21
28
  />
22
29
  <label className="form-check-label">Block display</label>
23
30
  </div>
@@ -36,9 +43,12 @@ export const OrFormula = ({ setProp, isFormula, node, nodekey, children }) => {
36
43
  type="text"
37
44
  className="form-control text-to-display"
38
45
  value={node[nodekey]}
39
- onChange={(e) =>
40
- setProp((prop) => (prop[nodekey] = e.target.value))
41
- }
46
+ onChange={(e) => {
47
+ if (e.target) {
48
+ const target_value = e.target.value;
49
+ setProp((prop) => (prop[nodekey] = target_value));
50
+ }
51
+ }}
42
52
  />
43
53
  ) : (
44
54
  children
@@ -50,7 +60,7 @@ export const OrFormula = ({ setProp, isFormula, node, nodekey, children }) => {
50
60
  }`}
51
61
  title="Calculated formula"
52
62
  type="button"
53
- onClick={(e) =>
63
+ onClick={() =>
54
64
  setProp((prop) => (prop.isFormula[nodekey] = !isFormula[nodekey]))
55
65
  }
56
66
  >
@@ -73,7 +83,12 @@ export const MinRoleSetting = ({ minRole, setProp }) => {
73
83
  <label>Minimum Role</label>
74
84
  <select
75
85
  value={minRole}
76
- onChange={(e) => setProp((prop) => (prop.minRole = e.target.value))}
86
+ onChange={(e) => (e) => {
87
+ if (e.target) {
88
+ const target_value = e.target.value;
89
+ setProp((prop) => (prop.minRole = target_value));
90
+ }
91
+ }}
77
92
  >
78
93
  {options.roles.map((r) => (
79
94
  <option key={r.id} value={r.id}>
@@ -95,7 +110,12 @@ export const MinRoleSettingRow = ({ minRole, setProp }) => {
95
110
  <select
96
111
  value={minRole}
97
112
  className="form-control"
98
- onChange={(e) => setProp((prop) => (prop.minRole = e.target.value))}
113
+ onChange={(e) => {
114
+ if (e.target) {
115
+ const target_value = e.target.value;
116
+ setProp((prop) => (prop.minRole = target_value));
117
+ }
118
+ }}
99
119
  >
100
120
  {options.roles.map((r) => (
101
121
  <option key={r.id} value={r.id}>
@@ -112,7 +132,12 @@ const TextStyleSelect = ({ textStyle, setProp }) => {
112
132
  <select
113
133
  value={textStyle}
114
134
  className="form-control"
115
- onChange={(e) => setProp((prop) => (prop.textStyle = e.target.value))}
135
+ onChange={(e) => {
136
+ if (e.target) {
137
+ const target_value = e.target.value;
138
+ setProp((prop) => (prop.textStyle = target_value));
139
+ }
140
+ }}
116
141
  >
117
142
  <option value="">Normal</option>
118
143
  <option value="h1">Heading 1</option>
@@ -322,7 +347,9 @@ export const ConfigForm = ({
322
347
  setProp={setProp}
323
348
  onChange={onChange}
324
349
  />
325
- {f.sublabel ? <i>{f.sublabel}</i> : null}
350
+ {f.sublabel ? (
351
+ <i dangerouslySetInnerHTML={{ __html: f.sublabel }}></i>
352
+ ) : null}
326
353
  </div>
327
354
  );
328
355
  })}
@@ -341,8 +368,10 @@ export const ConfigField = ({
341
368
  }) => {
342
369
  const myOnChange = (v) => {
343
370
  setProp((prop) => {
344
- if (configuration) prop.configuration[field.name] = v;
345
- else prop[field.name] = v;
371
+ if (configuration) {
372
+ if (!prop.configuration) prop.configuration = {};
373
+ prop.configuration[field.name] = v;
374
+ } else prop[field.name] = v;
346
375
  });
347
376
  onChange && onChange(field.name, v);
348
377
  };
@@ -350,13 +379,19 @@ export const ConfigField = ({
350
379
  configuration ? configuration[field.name] : props[field.name],
351
380
  field.default
352
381
  );
353
- return {
382
+ if (field.input_type === "fromtype") field.input_type = null;
383
+ if (field.type && field.type.name === "String" && field.attributes.options) {
384
+ field.input_type = "select";
385
+ field.options = field.attributes.options;
386
+ if (!field.required) field.options.unshift("");
387
+ }
388
+ const dispatch = {
354
389
  String: () => (
355
390
  <input
356
391
  type="text"
357
392
  className="form-control"
358
- value={value}
359
- onChange={(e) => myOnChange(e.target.value)}
393
+ value={value || ""}
394
+ onChange={(e) => e.target && myOnChange(e.target.value)}
360
395
  />
361
396
  ),
362
397
  Integer: () => (
@@ -364,17 +399,17 @@ export const ConfigField = ({
364
399
  type="number"
365
400
  className="form-control"
366
401
  step={1}
367
- value={value}
368
- onChange={(e) => myOnChange(e.target.value)}
402
+ value={value || ""}
403
+ onChange={(e) => e.target && myOnChange(e.target.value)}
369
404
  />
370
405
  ),
371
406
  Float: () => (
372
407
  <input
373
408
  type="number"
374
409
  className="form-control"
375
- value={value}
410
+ value={value || ""}
376
411
  step={0.01}
377
- onChange={(e) => myOnChange(e.target.value)}
412
+ onChange={(e) => e.target && myOnChange(e.target.value)}
378
413
  />
379
414
  ),
380
415
  Color: () => (
@@ -382,7 +417,7 @@ export const ConfigField = ({
382
417
  type="color"
383
418
  value={value}
384
419
  className="form-control"
385
- onChange={(e) => myOnChange(e.target.value)}
420
+ onChange={(e) => e.target && myOnChange(e.target.value)}
386
421
  />
387
422
  ),
388
423
  Bool: () => (
@@ -391,7 +426,7 @@ export const ConfigField = ({
391
426
  type="checkbox"
392
427
  className="form-check-input"
393
428
  checked={value}
394
- onChange={(e) => myOnChange(e.target.checked)}
429
+ onChange={(e) => e.target && myOnChange(e.target.checked)}
395
430
  />
396
431
  <label className="form-check-label">{field.label}</label>
397
432
  </div>
@@ -402,14 +437,23 @@ export const ConfigField = ({
402
437
  type="text"
403
438
  className="form-control"
404
439
  value={value}
405
- onChange={(e) => myOnChange(e.target.value)}
440
+ onChange={(e) => e.target && myOnChange(e.target.value)}
441
+ />
442
+ ),
443
+ code: () => (
444
+ <textarea
445
+ rows="6"
446
+ type="text"
447
+ className="form-control"
448
+ value={value}
449
+ onChange={(e) => e.target && myOnChange(e.target.value)}
406
450
  />
407
451
  ),
408
452
  select: () => (
409
453
  <select
410
454
  className="form-control"
411
- value={value}
412
- onChange={(e) => myOnChange(e.target.value)}
455
+ value={value || ""}
456
+ onChange={(e) => e.target && myOnChange(e.target.value)}
413
457
  >
414
458
  {field.options.map((o, ix) => (
415
459
  <option key={ix}>{o}</option>
@@ -417,13 +461,14 @@ export const ConfigField = ({
417
461
  </select>
418
462
  ),
419
463
  btn_select: () => (
420
- <div class="btn-group w-100" role="group">
464
+ <div className="btn-group w-100" role="group">
421
465
  {field.options.map((o, ix) => (
422
466
  <button
467
+ key={ix}
423
468
  title={o.title || o.value}
424
469
  type="button"
425
470
  style={{ width: `${Math.floor(100 / field.options.length)}%` }}
426
- class={`btn btn-sm btn-${
471
+ className={`btn btn-sm btn-${
427
472
  value !== o.value ? "outline-" : ""
428
473
  }secondary ${field.btnClass || ""}`}
429
474
  onClick={() => myOnChange(o.value)}
@@ -453,17 +498,21 @@ export const ConfigField = ({
453
498
  )}
454
499
  className="w-50 form-control-sm d-inline dimunit"
455
500
  vert={true}
456
- onChange={(e) =>
501
+ onChange={(e) => {
502
+ if (!e.target) return;
503
+ const target_value = e.target.value;
457
504
  setProp((prop) => {
458
505
  if (configuration)
459
- prop.configuration[field.name + "Unit"] = e.target.value;
460
- else prop[field.name + "Unit"] = e.target.value;
461
- })
462
- }
506
+ prop.configuration[field.name + "Unit"] = target_value;
507
+ else prop[field.name + "Unit"] = target_value;
508
+ });
509
+ }}
463
510
  />
464
511
  </Fragment>
465
512
  ),
466
- }[field.input_type || field.type.name || field.type]();
513
+ };
514
+ const f = dispatch[field.input_type || field.type.name || field.type];
515
+ return f ? f() : null;
467
516
  };
468
517
 
469
518
  export const SettingsFromFields = (fields) => () => {
@@ -562,3 +611,129 @@ export class ErrorBoundary extends React.Component {
562
611
  return this.props.children;
563
612
  }
564
613
  }
614
+
615
+ export const ButtonOrLinkSettingsRows = ({
616
+ setProp,
617
+ btnClass = null,
618
+ keyPrefix = "",
619
+ values,
620
+ linkFirst = false,
621
+ }) => {
622
+ const setAProp = (key) => (e) => {
623
+ if (e.target) {
624
+ const target_value = e.target.value;
625
+ setProp((prop) => (prop[key] = target_value));
626
+ }
627
+ };
628
+ const addBtnClass = (s) => (btnClass ? `${btnClass} ${s}` : s);
629
+ return [
630
+ <tr key="btnstyle">
631
+ <td>
632
+ <label>Style</label>
633
+ </td>
634
+ <td>
635
+ <select
636
+ className="form-control"
637
+ value={values[keyPrefix + "style"]}
638
+ onChange={setAProp(keyPrefix + "style")}
639
+ >
640
+ {linkFirst ? (
641
+ <option value={addBtnClass("btn-link")}>Link</option>
642
+ ) : null}
643
+ <option value={addBtnClass("btn-primary")}>Primary button</option>
644
+ <option value={addBtnClass("btn-secondary")}>Secondary button</option>
645
+ <option value={addBtnClass("btn-success")}>Success button</option>
646
+ <option value={addBtnClass("btn-danger")}>Danger button</option>
647
+ <option value={addBtnClass("btn-outline-primary")}>
648
+ Primary outline button
649
+ </option>
650
+ <option value={addBtnClass("btn-outline-secondary")}>
651
+ Secondary outline button
652
+ </option>
653
+ <option value={addBtnClass("btn-custom-color")}>
654
+ Button custom color
655
+ </option>
656
+ {!linkFirst ? (
657
+ <option value={addBtnClass("btn-link")}>Link</option>
658
+ ) : null}
659
+ </select>
660
+ </td>
661
+ </tr>,
662
+ <tr key="btnsz">
663
+ <td>
664
+ <label>Action size</label>
665
+ </td>
666
+ <td>
667
+ <select
668
+ className="form-control"
669
+ value={values[keyPrefix + "size"]}
670
+ onChange={setAProp(keyPrefix + "size")}
671
+ >
672
+ <option value="">Standard</option>
673
+ <option value="btn-lg">Large</option>
674
+ <option value="btn-sm">Small</option>
675
+ <option value="btn-block">Block</option>
676
+ <option value="btn-block btn-lg">Large block</option>
677
+ </select>
678
+ </td>
679
+ </tr>,
680
+ <tr key="btnicon">
681
+ <td>
682
+ <label>Icon</label>
683
+ </td>
684
+ <td>
685
+ <FontIconPicker
686
+ value={values[keyPrefix + "icon"]}
687
+ onChange={(value) =>
688
+ setProp((prop) => (prop[keyPrefix + "icon"] = value))
689
+ }
690
+ isMulti={false}
691
+ icons={faIcons}
692
+ />
693
+ </td>
694
+ </tr>,
695
+ ...(values[keyPrefix + "style"] === addBtnClass("btn-custom-color")
696
+ ? [
697
+ <tr key="btnbgcol">
698
+ <td>
699
+ <label>Background</label>
700
+ </td>
701
+ <td>
702
+ <input
703
+ type="color"
704
+ value={values[keyPrefix + "bgcol"]}
705
+ className="form-control-sm w-50"
706
+ onChange={setAProp(keyPrefix + "bgcol")}
707
+ />
708
+ </td>
709
+ </tr>,
710
+ <tr key="btnbdcol">
711
+ <td>
712
+ <label>Border</label>
713
+ </td>
714
+ <td>
715
+ <input
716
+ type="color"
717
+ value={values[keyPrefix + "bordercol"]}
718
+ className="form-control-sm w-50"
719
+ onChange={setAProp(keyPrefix + "bordercol")}
720
+ />
721
+ </td>
722
+ </tr>,
723
+ <tr key="btntxtcol">
724
+ <td>
725
+ <label>Text</label>
726
+ </td>
727
+ <td>
728
+ <input
729
+ type="color"
730
+ value={values[keyPrefix + "textcol"]}
731
+ className="form-control-sm w-50"
732
+ onChange={setAProp(keyPrefix + "textcol")}
733
+ />
734
+ </td>
735
+ </tr>,
736
+ ]
737
+ : []),
738
+ ];
739
+ };
@@ -56,7 +56,7 @@ const allElements = [
56
56
  ToggleFilter,
57
57
  ];
58
58
 
59
- export const layoutToNodes = (layout, query, actions) => {
59
+ export const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
60
60
  //console.log("layoutToNodes", JSON.stringify(layout));
61
61
  function toTag(segment, ix) {
62
62
  if (!segment) return <Empty key={ix} />;
@@ -98,6 +98,7 @@ export const layoutToNodes = (layout, query, actions) => {
98
98
  textStyle={segment.textStyle || ""}
99
99
  labelFor={segment.labelFor || ""}
100
100
  icon={segment.icon}
101
+ font={segment.font || ""}
101
102
  />
102
103
  );
103
104
  } else if (segment.type === "view") {
@@ -107,6 +108,7 @@ export const layoutToNodes = (layout, query, actions) => {
107
108
  view={segment.view}
108
109
  name={segment.name}
109
110
  state={segment.state}
111
+ configuration={segment.configuration || {}}
110
112
  />
111
113
  );
112
114
  } else if (segment.type === "action") {
@@ -119,6 +121,9 @@ export const layoutToNodes = (layout, query, actions) => {
119
121
  action_style={segment.action_style || "btn-primary"}
120
122
  action_size={segment.action_size || ""}
121
123
  action_icon={segment.action_icon || ""}
124
+ action_bgcol={segment.action_bgcol || ""}
125
+ action_bordercol={segment.action_bordercol || ""}
126
+ action_textcol={segment.action_textcol || ""}
122
127
  confirm={segment.confirm}
123
128
  configuration={segment.configuration || {}}
124
129
  block={segment.block || false}
@@ -140,6 +145,7 @@ export const layoutToNodes = (layout, query, actions) => {
140
145
  gradStartColor={segment.gradStartColor}
141
146
  gradEndColor={segment.gradEndColor}
142
147
  gradDirection={segment.gradDirection}
148
+ rotate={segment.rotate || 0}
143
149
  customClass={segment.customClass}
144
150
  customCSS={segment.customCSS}
145
151
  overflow={segment.overflow}
@@ -231,12 +237,12 @@ export const layoutToNodes = (layout, query, actions) => {
231
237
  }
232
238
  //const node1 = query.createNode(toTag(layout));
233
239
  //actions.add(node1, );
234
- go(layout, "ROOT");
240
+ go(layout, parent);
235
241
  };
236
242
 
237
243
  const rand_ident = () => Math.floor(Math.random() * 16777215).toString(16);
238
244
 
239
- export const craftToSaltcorn = (nodes) => {
245
+ export const craftToSaltcorn = (nodes, startFrom = "ROOT") => {
240
246
  //console.log(JSON.stringify(nodes, null, 2));
241
247
  var columns = [];
242
248
  const get_nodes = (node) => {
@@ -314,6 +320,7 @@ export const craftToSaltcorn = (nodes) => {
314
320
  gradStartColor: node.props.gradStartColor,
315
321
  gradEndColor: node.props.gradEndColor,
316
322
  gradDirection: node.props.gradDirection,
323
+ rotate: node.props.rotate,
317
324
  };
318
325
  else return get_nodes(node);
319
326
  }
@@ -327,6 +334,7 @@ export const craftToSaltcorn = (nodes) => {
327
334
  isFormula: node.props.isFormula,
328
335
  labelFor: node.props.labelFor,
329
336
  icon: node.props.icon,
337
+ font: node.props.font,
330
338
  };
331
339
  }
332
340
 
@@ -357,6 +365,7 @@ export const craftToSaltcorn = (nodes) => {
357
365
  name:
358
366
  node.props.name === "not_assigned" ? rand_ident() : node.props.name,
359
367
  state: node.props.state,
368
+ configuration: node.props.configuration,
360
369
  };
361
370
  }
362
371
 
@@ -369,6 +378,9 @@ export const craftToSaltcorn = (nodes) => {
369
378
  action_style: node.props.action_style,
370
379
  action_size: node.props.action_size,
371
380
  action_icon: node.props.action_icon,
381
+ action_bgcol: node.props.action_bgcol,
382
+ action_bordercol: node.props.action_bordercol,
383
+ action_textcol: node.props.action_textcol,
372
384
  minRole: node.props.minRole,
373
385
  confirm: node.props.confirm,
374
386
  configuration: node.props.configuration,
@@ -385,13 +397,16 @@ export const craftToSaltcorn = (nodes) => {
385
397
  action_style: node.props.action_style,
386
398
  action_size: node.props.action_size,
387
399
  action_icon: node.props.action_icon,
400
+ action_bgcol: node.props.action_bgcol,
401
+ action_bordercol: node.props.action_bordercol,
402
+ action_textcol: node.props.action_textcol,
388
403
  minRole: node.props.minRole,
389
404
  isFormula: node.props.isFormula,
390
405
  rndid: node.props.rndid === "not_assigned" ? newid : node.props.rndid,
391
406
  };
392
407
  }
393
408
  };
394
- const layout = go(nodes["ROOT"]) || { type: "blank", contents: "" };
409
+ const layout = go(nodes[startFrom]) || { type: "blank", contents: "" };
395
410
  /*console.log("nodes", JSON.stringify(nodes));
396
411
  console.log("cols", JSON.stringify(columns));
397
412
  console.log("layout", JSON.stringify(layout));*/