pict-section-flow 0.0.8 → 0.0.9
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.
package/package.json
CHANGED
package/source/PictFlowCard.js
CHANGED
|
@@ -137,6 +137,10 @@ class PictFlowCard extends libFableServiceProviderBase
|
|
|
137
137
|
{
|
|
138
138
|
tmpPort.PortType = tmpInput.PortType;
|
|
139
139
|
}
|
|
140
|
+
if (tmpInput.DataType)
|
|
141
|
+
{
|
|
142
|
+
tmpPort.DataType = tmpInput.DataType;
|
|
143
|
+
}
|
|
140
144
|
tmpPorts.push(tmpPort);
|
|
141
145
|
}
|
|
142
146
|
|
|
@@ -155,6 +159,10 @@ class PictFlowCard extends libFableServiceProviderBase
|
|
|
155
159
|
{
|
|
156
160
|
tmpOutPort.PortType = tmpOutput.PortType;
|
|
157
161
|
}
|
|
162
|
+
if (tmpOutput.DataType)
|
|
163
|
+
{
|
|
164
|
+
tmpOutPort.DataType = tmpOutput.DataType;
|
|
165
|
+
}
|
|
158
166
|
tmpPorts.push(tmpOutPort);
|
|
159
167
|
}
|
|
160
168
|
|
|
@@ -53,7 +53,7 @@ class FlowCardPropertiesPanelForm extends libPictFlowCardPropertiesPanel
|
|
|
53
53
|
// Bind the node data to AppData.Record so the form descriptors
|
|
54
54
|
// (which use addresses like Record.Data.SearchString) resolve against
|
|
55
55
|
// the actual node object.
|
|
56
|
-
this.
|
|
56
|
+
this.fable.AppData.Record = pNodeData;
|
|
57
57
|
|
|
58
58
|
try
|
|
59
59
|
{
|
|
@@ -60,6 +60,8 @@ class PictProviderFlowCSS extends libFableServiceProviderBase
|
|
|
60
60
|
--pf-port-output-fill: #2ecc71;
|
|
61
61
|
--pf-port-stroke: #ffffff;
|
|
62
62
|
--pf-port-stroke-width: 2;
|
|
63
|
+
--pf-port-label-bg: rgba(255, 253, 240, 0.5);
|
|
64
|
+
--pf-port-label-text: #2c3e50;
|
|
63
65
|
|
|
64
66
|
/* Port Type Colors */
|
|
65
67
|
--pf-port-event-in-fill: #3498db;
|
|
@@ -663,6 +665,18 @@ class PictProviderFlowCSS extends libFableServiceProviderBase
|
|
|
663
665
|
color: #8e99a4;
|
|
664
666
|
font-size: 10px;
|
|
665
667
|
}
|
|
668
|
+
/* Port summary section appended below form panels */
|
|
669
|
+
.pict-flow-port-summary {
|
|
670
|
+
margin-top: 12px;
|
|
671
|
+
padding-top: 8px;
|
|
672
|
+
border-top: 1px solid #e8eaed;
|
|
673
|
+
}
|
|
674
|
+
.pict-flow-info-panel-port.event {
|
|
675
|
+
border-left: 3px solid var(--pf-port-event-in-fill);
|
|
676
|
+
}
|
|
677
|
+
.pict-flow-info-panel-port.value {
|
|
678
|
+
border-left: 3px solid var(--pf-port-value-fill);
|
|
679
|
+
}
|
|
666
680
|
`;
|
|
667
681
|
}
|
|
668
682
|
|
|
@@ -436,7 +436,7 @@ class PictViewFlowNode extends libPictView
|
|
|
436
436
|
tmpBgRect.setAttribute('y', String(tmpBadgeY));
|
|
437
437
|
tmpBgRect.setAttribute('width', String(tmpBadgeWidth));
|
|
438
438
|
tmpBgRect.setAttribute('height', String(tmpBadgeHeight));
|
|
439
|
-
tmpBgRect.setAttribute('fill', 'rgba(255, 253, 240, 0.5)');
|
|
439
|
+
tmpBgRect.setAttribute('fill', 'var(--pf-port-label-bg, rgba(255, 253, 240, 0.5))');
|
|
440
440
|
pGroup.appendChild(tmpBgRect);
|
|
441
441
|
|
|
442
442
|
// 3-sided border path (open on the edge-facing side)
|
|
@@ -461,7 +461,7 @@ class PictViewFlowNode extends libPictView
|
|
|
461
461
|
// Text label — appended after circle for z-order
|
|
462
462
|
tmpLabelElement = this._FlowView._SVGHelperProvider.createSVGElement('text');
|
|
463
463
|
tmpLabelElement.setAttribute('class', 'pict-flow-port-label');
|
|
464
|
-
tmpLabelElement.setAttribute('fill', '#2c3e50');
|
|
464
|
+
tmpLabelElement.setAttribute('fill', 'var(--pf-port-label-text, #2c3e50)');
|
|
465
465
|
tmpLabelElement.textContent = tmpPort.Label;
|
|
466
466
|
tmpLabelElement.setAttribute('x', String(tmpTextX));
|
|
467
467
|
tmpLabelElement.setAttribute('y', String(tmpBadgeY + tmpBadgeHeight / 2));
|
|
@@ -56,6 +56,22 @@ const _DefaultConfiguration =
|
|
|
56
56
|
Hash: 'Flow-InfoPanel-Port-Constraint',
|
|
57
57
|
Template: ' <span class="pict-flow-info-panel-port-constraint">{~D:Record.ConstraintText~}</span>'
|
|
58
58
|
},
|
|
59
|
+
{
|
|
60
|
+
Hash: 'Flow-InfoPanel-Section-Generic',
|
|
61
|
+
Template: '<div class="pict-flow-info-panel-section"><div class="pict-flow-info-panel-section-title">{~D:Record.SectionTitle~}</div>{~D:Record.PortsContent~}</div>'
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
Hash: 'Flow-InfoPanel-Port-Event',
|
|
65
|
+
Template: '<div class="pict-flow-info-panel-port event">{~D:Record.Label~}</div>'
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
Hash: 'Flow-InfoPanel-Port-Value',
|
|
69
|
+
Template: '<div class="pict-flow-info-panel-port value">{~D:Record.Label~}{~D:Record.DataType~}</div>'
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
Hash: 'Flow-InfoPanel-Port-DataType',
|
|
73
|
+
Template: ' <span class="pict-flow-info-panel-port-constraint">{~D:Record.DataTypeText~}</span>'
|
|
74
|
+
},
|
|
59
75
|
{
|
|
60
76
|
Hash: 'Flow-NodeProps-Editor',
|
|
61
77
|
Template: '<div class="pict-flow-node-props-fields"><div class="pict-flow-node-props-field"><label class="pict-flow-node-props-label">Title</label><input type="text" class="pict-flow-node-props-input" data-prop="Title" value="{~D:Record.Title~}" /></div><div class="pict-flow-node-props-field"><label class="pict-flow-node-props-label">Width</label><input type="number" class="pict-flow-node-props-input" data-prop="Width" value="{~D:Record.Width~}" min="60" step="10" /></div><div class="pict-flow-node-props-field"><label class="pict-flow-node-props-label">Height</label><input type="number" class="pict-flow-node-props-input" data-prop="Height" value="{~D:Record.Height~}" min="40" step="10" /></div><div class="pict-flow-node-props-field"><label class="pict-flow-node-props-label">Body Fill</label><input type="color" class="pict-flow-node-props-input pict-flow-node-props-color" data-prop="Style.BodyFill" value="{~D:Record.BodyFillValue~}" /></div><div class="pict-flow-node-props-field"><label class="pict-flow-node-props-label">Body Stroke</label><input type="color" class="pict-flow-node-props-input pict-flow-node-props-color" data-prop="Style.BodyStroke" value="{~D:Record.BodyStrokeValue~}" /></div><div class="pict-flow-node-props-field"><label class="pict-flow-node-props-label">Stroke Width</label><input type="number" class="pict-flow-node-props-input" data-prop="Style.BodyStrokeWidth" value="{~D:Record.BodyStrokeWidthValue~}" min="0" max="10" step="0.5" /></div><div class="pict-flow-node-props-field"><label class="pict-flow-node-props-label">Title Bar</label><input type="color" class="pict-flow-node-props-input pict-flow-node-props-color" data-prop="Style.TitleBarColor" value="{~D:Record.TitleBarColorValue~}" /></div></div>'
|
|
@@ -262,6 +278,11 @@ class PictViewFlowPropertiesPanel extends libPictView
|
|
|
262
278
|
{
|
|
263
279
|
tmpInstance.render(pBodyContainer, tmpNodeData);
|
|
264
280
|
}
|
|
281
|
+
|
|
282
|
+
// After the form renders, append port summary sections showing
|
|
283
|
+
// event inputs, event outputs, and state outputs.
|
|
284
|
+
// SettingsInputs are already visible as form fields above.
|
|
285
|
+
this._renderPortSummary(pBodyContainer, tmpNodeTypeConfig);
|
|
265
286
|
}
|
|
266
287
|
|
|
267
288
|
/**
|
|
@@ -362,6 +383,107 @@ class PictViewFlowPropertiesPanel extends libPictView
|
|
|
362
383
|
pContainer.innerHTML = this.pict.parseTemplateByHash('Flow-InfoPanel-Wrapper', { PanelContent: tmpContentParts.join('') });
|
|
363
384
|
}
|
|
364
385
|
|
|
386
|
+
/**
|
|
387
|
+
* Render port summary sections below the form panel content.
|
|
388
|
+
* Shows event inputs, event outputs, and state outputs — the ports
|
|
389
|
+
* that the form does not cover (since the form only shows SettingsInputs).
|
|
390
|
+
*
|
|
391
|
+
* @param {HTMLDivElement} pContainer
|
|
392
|
+
* @param {Object} pNodeTypeConfig
|
|
393
|
+
*/
|
|
394
|
+
_renderPortSummary(pContainer, pNodeTypeConfig)
|
|
395
|
+
{
|
|
396
|
+
let tmpPorts = pNodeTypeConfig.DefaultPorts || [];
|
|
397
|
+
if (tmpPorts.length === 0) return;
|
|
398
|
+
|
|
399
|
+
// Categorize ports by type (settings are already shown as form fields)
|
|
400
|
+
let tmpEventInputs = [];
|
|
401
|
+
let tmpEventOutputs = [];
|
|
402
|
+
let tmpStateOutputs = [];
|
|
403
|
+
|
|
404
|
+
for (let i = 0; i < tmpPorts.length; i++)
|
|
405
|
+
{
|
|
406
|
+
let tmpPort = tmpPorts[i];
|
|
407
|
+
let tmpPortType = tmpPort.PortType || '';
|
|
408
|
+
|
|
409
|
+
if (tmpPortType === 'event-in')
|
|
410
|
+
{
|
|
411
|
+
tmpEventInputs.push(tmpPort);
|
|
412
|
+
}
|
|
413
|
+
else if (tmpPortType === 'event-out' || tmpPortType === 'error')
|
|
414
|
+
{
|
|
415
|
+
tmpEventOutputs.push(tmpPort);
|
|
416
|
+
}
|
|
417
|
+
else if (tmpPortType === 'value')
|
|
418
|
+
{
|
|
419
|
+
tmpStateOutputs.push(tmpPort);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Only render if there are non-settings ports to show
|
|
424
|
+
if (tmpEventInputs.length === 0 && tmpEventOutputs.length === 0 && tmpStateOutputs.length === 0)
|
|
425
|
+
{
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
let tmpSummaryParts = [];
|
|
430
|
+
|
|
431
|
+
// Event Inputs
|
|
432
|
+
if (tmpEventInputs.length > 0)
|
|
433
|
+
{
|
|
434
|
+
let tmpPortsContent = '';
|
|
435
|
+
for (let i = 0; i < tmpEventInputs.length; i++)
|
|
436
|
+
{
|
|
437
|
+
tmpPortsContent += this.pict.parseTemplateByHash('Flow-InfoPanel-Port-Event', { Label: tmpEventInputs[i].Label || tmpEventInputs[i].Name || 'Event In' });
|
|
438
|
+
}
|
|
439
|
+
tmpSummaryParts.push(this.pict.parseTemplateByHash('Flow-InfoPanel-Section-Generic', { SectionTitle: 'Event Inputs', PortsContent: tmpPortsContent }));
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// Event Outputs
|
|
443
|
+
if (tmpEventOutputs.length > 0)
|
|
444
|
+
{
|
|
445
|
+
let tmpPortsContent = '';
|
|
446
|
+
for (let i = 0; i < tmpEventOutputs.length; i++)
|
|
447
|
+
{
|
|
448
|
+
let tmpPort = tmpEventOutputs[i];
|
|
449
|
+
let tmpLabel = tmpPort.Label || tmpPort.Name || 'Event Out';
|
|
450
|
+
if (tmpPort.PortType === 'error')
|
|
451
|
+
{
|
|
452
|
+
tmpLabel += ' ⚠';
|
|
453
|
+
}
|
|
454
|
+
tmpPortsContent += this.pict.parseTemplateByHash('Flow-InfoPanel-Port-Event', { Label: tmpLabel });
|
|
455
|
+
}
|
|
456
|
+
tmpSummaryParts.push(this.pict.parseTemplateByHash('Flow-InfoPanel-Section-Generic', { SectionTitle: 'Event Outputs', PortsContent: tmpPortsContent }));
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// State Outputs
|
|
460
|
+
if (tmpStateOutputs.length > 0)
|
|
461
|
+
{
|
|
462
|
+
let tmpPortsContent = '';
|
|
463
|
+
for (let i = 0; i < tmpStateOutputs.length; i++)
|
|
464
|
+
{
|
|
465
|
+
let tmpPort = tmpStateOutputs[i];
|
|
466
|
+
let tmpLabel = tmpPort.Label || tmpPort.Name || 'Output';
|
|
467
|
+
let tmpDataType = '';
|
|
468
|
+
if (tmpPort.DataType)
|
|
469
|
+
{
|
|
470
|
+
tmpDataType = this.pict.parseTemplateByHash('Flow-InfoPanel-Port-DataType', { DataTypeText: tmpPort.DataType });
|
|
471
|
+
}
|
|
472
|
+
tmpPortsContent += this.pict.parseTemplateByHash('Flow-InfoPanel-Port-Value', { Label: tmpLabel, DataType: tmpDataType });
|
|
473
|
+
}
|
|
474
|
+
tmpSummaryParts.push(this.pict.parseTemplateByHash('Flow-InfoPanel-Section-Generic', { SectionTitle: 'State Outputs', PortsContent: tmpPortsContent }));
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if (tmpSummaryParts.length > 0)
|
|
478
|
+
{
|
|
479
|
+
// Create a wrapper div for the port summary and append it to the container
|
|
480
|
+
let tmpSummaryDiv = document.createElement('div');
|
|
481
|
+
tmpSummaryDiv.className = 'pict-flow-info-panel pict-flow-port-summary';
|
|
482
|
+
tmpSummaryDiv.innerHTML = tmpSummaryParts.join('');
|
|
483
|
+
pContainer.appendChild(tmpSummaryDiv);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
365
487
|
/**
|
|
366
488
|
* Build the constraint markup for a port using configuration templates.
|
|
367
489
|
*
|