@principal-ai/principal-view-react 0.6.21 → 0.6.23
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/dist/components/NodeInfoPanel.d.ts.map +1 -1
- package/dist/components/NodeInfoPanel.js +29 -1
- package/dist/components/NodeInfoPanel.js.map +1 -1
- package/dist/components/NodeTooltip.d.ts +19 -0
- package/dist/components/NodeTooltip.d.ts.map +1 -0
- package/dist/components/NodeTooltip.js +112 -0
- package/dist/components/NodeTooltip.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/nodes/CustomNode.d.ts.map +1 -1
- package/dist/nodes/CustomNode.js +100 -53
- package/dist/nodes/CustomNode.js.map +1 -1
- package/package.json +2 -2
- package/src/components/NodeInfoPanel.tsx +67 -0
- package/src/components/NodeTooltip.tsx +163 -0
- package/src/index.ts +4 -0
- package/src/nodes/CustomNode.tsx +216 -132
- package/src/stories/GraphRenderer.stories.tsx +434 -0
- package/src/stories/OtelComponents.stories.tsx +286 -0
|
@@ -640,3 +640,437 @@ export const ServiceArchitectureEditable: Story = {
|
|
|
640
640
|
},
|
|
641
641
|
},
|
|
642
642
|
};
|
|
643
|
+
|
|
644
|
+
// ============================================================================
|
|
645
|
+
// OTEL Log Association Canvas
|
|
646
|
+
// ============================================================================
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* OTEL Log Association architecture canvas
|
|
650
|
+
* Demonstrates OTEL badges, tooltips, and info panel integration
|
|
651
|
+
*/
|
|
652
|
+
const otelLogAssociationCanvas: ExtendedCanvas = {
|
|
653
|
+
nodes: [
|
|
654
|
+
{
|
|
655
|
+
id: 'otel-log',
|
|
656
|
+
type: 'text',
|
|
657
|
+
text: 'OtelLog',
|
|
658
|
+
x: -304,
|
|
659
|
+
y: 147,
|
|
660
|
+
width: 120,
|
|
661
|
+
height: 118,
|
|
662
|
+
pv: {
|
|
663
|
+
nodeType: 'otel-type',
|
|
664
|
+
name: 'OtelLog',
|
|
665
|
+
description:
|
|
666
|
+
'OpenTelemetry log record with timestamp, severity, body, resource, and trace context',
|
|
667
|
+
otel: {
|
|
668
|
+
kind: 'type',
|
|
669
|
+
category: 'log',
|
|
670
|
+
isNew: true,
|
|
671
|
+
},
|
|
672
|
+
shape: 'rectangle',
|
|
673
|
+
icon: 'FileText',
|
|
674
|
+
fill: '#4A90E2',
|
|
675
|
+
},
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
id: 'otel-resource',
|
|
679
|
+
type: 'text',
|
|
680
|
+
text: 'OtelResource',
|
|
681
|
+
x: -305,
|
|
682
|
+
y: 316,
|
|
683
|
+
width: 120,
|
|
684
|
+
height: 117,
|
|
685
|
+
pv: {
|
|
686
|
+
nodeType: 'otel-type',
|
|
687
|
+
name: 'OtelResource',
|
|
688
|
+
description: 'OTEL resource attributes like service.name, k8s.*, deployment.*',
|
|
689
|
+
otel: {
|
|
690
|
+
kind: 'type',
|
|
691
|
+
category: 'resource',
|
|
692
|
+
},
|
|
693
|
+
shape: 'rectangle',
|
|
694
|
+
icon: 'Box',
|
|
695
|
+
fill: '#4A90E2',
|
|
696
|
+
},
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
id: 'canvas-scope',
|
|
700
|
+
type: 'text',
|
|
701
|
+
text: 'CanvasScope',
|
|
702
|
+
x: -77,
|
|
703
|
+
y: -48,
|
|
704
|
+
width: 130,
|
|
705
|
+
height: 118,
|
|
706
|
+
pv: {
|
|
707
|
+
nodeType: 'service',
|
|
708
|
+
name: 'CanvasScope',
|
|
709
|
+
description: 'Filters which logs are relevant to this canvas based on resource attributes',
|
|
710
|
+
shape: 'hexagon',
|
|
711
|
+
icon: 'Filter',
|
|
712
|
+
fill: '#9B59B6',
|
|
713
|
+
},
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
id: 'log-router',
|
|
717
|
+
type: 'text',
|
|
718
|
+
text: 'LogRouter',
|
|
719
|
+
x: -80,
|
|
720
|
+
y: 150,
|
|
721
|
+
width: 130,
|
|
722
|
+
height: 118,
|
|
723
|
+
pv: {
|
|
724
|
+
nodeType: 'otel-service',
|
|
725
|
+
name: 'LogRouter',
|
|
726
|
+
description: 'Routes incoming OTEL logs to canvas nodes based on scope and resourceMatch criteria',
|
|
727
|
+
otel: {
|
|
728
|
+
kind: 'service',
|
|
729
|
+
category: 'router',
|
|
730
|
+
isNew: true,
|
|
731
|
+
},
|
|
732
|
+
shape: 'hexagon',
|
|
733
|
+
icon: 'GitBranch',
|
|
734
|
+
fill: '#7ED321',
|
|
735
|
+
},
|
|
736
|
+
},
|
|
737
|
+
{
|
|
738
|
+
id: 'resource-matcher',
|
|
739
|
+
type: 'text',
|
|
740
|
+
text: 'ResourceMatcher',
|
|
741
|
+
x: -82,
|
|
742
|
+
y: 440,
|
|
743
|
+
width: 130,
|
|
744
|
+
height: 119,
|
|
745
|
+
pv: {
|
|
746
|
+
nodeType: 'service',
|
|
747
|
+
name: 'ResourceMatcher',
|
|
748
|
+
description: 'Matches log resources against node resourceMatch criteria',
|
|
749
|
+
otel: {
|
|
750
|
+
kind: 'service',
|
|
751
|
+
category: 'match',
|
|
752
|
+
},
|
|
753
|
+
shape: 'hexagon',
|
|
754
|
+
icon: 'Search',
|
|
755
|
+
fill: '#7ED321',
|
|
756
|
+
},
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
id: 'resource-match',
|
|
760
|
+
type: 'text',
|
|
761
|
+
text: 'ResourceMatch',
|
|
762
|
+
x: 179,
|
|
763
|
+
y: 445,
|
|
764
|
+
width: 120,
|
|
765
|
+
height: 117,
|
|
766
|
+
pv: {
|
|
767
|
+
nodeType: 'otel-type',
|
|
768
|
+
name: 'ResourceMatch',
|
|
769
|
+
description: 'Criteria for matching OTEL resources to canvas nodes',
|
|
770
|
+
otel: {
|
|
771
|
+
kind: 'type',
|
|
772
|
+
category: 'match',
|
|
773
|
+
},
|
|
774
|
+
shape: 'rectangle',
|
|
775
|
+
icon: 'Target',
|
|
776
|
+
fill: '#4A90E2',
|
|
777
|
+
},
|
|
778
|
+
},
|
|
779
|
+
{
|
|
780
|
+
id: 'match-operator',
|
|
781
|
+
type: 'text',
|
|
782
|
+
text: 'MatchOperator',
|
|
783
|
+
x: 178,
|
|
784
|
+
y: 632,
|
|
785
|
+
width: 120,
|
|
786
|
+
height: 117,
|
|
787
|
+
pv: {
|
|
788
|
+
nodeType: 'otel-type',
|
|
789
|
+
name: 'MatchOperator',
|
|
790
|
+
description: 'Matching operators: exact, glob, regex, exists, oneOf',
|
|
791
|
+
otel: {
|
|
792
|
+
kind: 'type',
|
|
793
|
+
category: 'match',
|
|
794
|
+
},
|
|
795
|
+
shape: 'diamond',
|
|
796
|
+
icon: 'Code',
|
|
797
|
+
fill: '#F5A623',
|
|
798
|
+
},
|
|
799
|
+
},
|
|
800
|
+
{
|
|
801
|
+
id: 'canvas-node',
|
|
802
|
+
type: 'text',
|
|
803
|
+
text: 'Canvas Node',
|
|
804
|
+
x: 172,
|
|
805
|
+
y: 277,
|
|
806
|
+
width: 132,
|
|
807
|
+
height: 121,
|
|
808
|
+
pv: {
|
|
809
|
+
nodeType: 'service',
|
|
810
|
+
name: 'Canvas Node',
|
|
811
|
+
description: 'A node in the canvas that can receive routed logs',
|
|
812
|
+
shape: 'rectangle',
|
|
813
|
+
icon: 'Square',
|
|
814
|
+
fill: '#00BCD4',
|
|
815
|
+
},
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
id: 'routing-result',
|
|
819
|
+
type: 'text',
|
|
820
|
+
text: 'LogRoutingResult',
|
|
821
|
+
x: 169,
|
|
822
|
+
y: 80,
|
|
823
|
+
width: 150,
|
|
824
|
+
height: 135,
|
|
825
|
+
pv: {
|
|
826
|
+
nodeType: 'otel-type',
|
|
827
|
+
name: 'LogRoutingResult',
|
|
828
|
+
description: 'Result of routing a log: routed, orphaned, or out-of-scope',
|
|
829
|
+
otel: {
|
|
830
|
+
kind: 'type',
|
|
831
|
+
category: 'audit',
|
|
832
|
+
},
|
|
833
|
+
shape: 'rectangle',
|
|
834
|
+
icon: 'CheckCircle',
|
|
835
|
+
fill: '#4A90E2',
|
|
836
|
+
},
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
id: 'audit-collector',
|
|
840
|
+
type: 'text',
|
|
841
|
+
text: 'AuditCollector',
|
|
842
|
+
x: 380,
|
|
843
|
+
y: 150,
|
|
844
|
+
width: 130,
|
|
845
|
+
height: 117,
|
|
846
|
+
pv: {
|
|
847
|
+
nodeType: 'otel-service',
|
|
848
|
+
name: 'AuditCollector',
|
|
849
|
+
description: 'Tracks routing metrics, orphaned logs, silent nodes, and generates coverage reports',
|
|
850
|
+
otel: {
|
|
851
|
+
kind: 'service',
|
|
852
|
+
category: 'collector',
|
|
853
|
+
isNew: true,
|
|
854
|
+
},
|
|
855
|
+
shape: 'hexagon',
|
|
856
|
+
icon: 'BarChart2',
|
|
857
|
+
fill: '#7ED321',
|
|
858
|
+
},
|
|
859
|
+
},
|
|
860
|
+
{
|
|
861
|
+
id: 'orphaned-log',
|
|
862
|
+
type: 'text',
|
|
863
|
+
text: 'OrphanedLog',
|
|
864
|
+
x: 618,
|
|
865
|
+
y: 150,
|
|
866
|
+
width: 127,
|
|
867
|
+
height: 118,
|
|
868
|
+
pv: {
|
|
869
|
+
nodeType: 'otel-type',
|
|
870
|
+
name: 'OrphanedLog',
|
|
871
|
+
description:
|
|
872
|
+
'Logs that matched canvas scope but no node resourceMatch - indicates missing nodes or misconfiguration',
|
|
873
|
+
otel: {
|
|
874
|
+
kind: 'type',
|
|
875
|
+
category: 'audit',
|
|
876
|
+
isNew: true,
|
|
877
|
+
},
|
|
878
|
+
shape: 'rectangle',
|
|
879
|
+
icon: 'AlertTriangle',
|
|
880
|
+
fill: '#D0021B',
|
|
881
|
+
},
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
id: 'audit-report',
|
|
885
|
+
type: 'text',
|
|
886
|
+
text: 'AuditReport',
|
|
887
|
+
x: 618,
|
|
888
|
+
y: 288,
|
|
889
|
+
width: 124,
|
|
890
|
+
height: 123,
|
|
891
|
+
pv: {
|
|
892
|
+
nodeType: 'otel-type',
|
|
893
|
+
name: 'AuditReport',
|
|
894
|
+
description: 'Coverage report with node activity, orphans, and recommendations',
|
|
895
|
+
otel: {
|
|
896
|
+
kind: 'type',
|
|
897
|
+
category: 'audit',
|
|
898
|
+
},
|
|
899
|
+
shape: 'rectangle',
|
|
900
|
+
icon: 'FileText',
|
|
901
|
+
fill: '#4A90E2',
|
|
902
|
+
},
|
|
903
|
+
},
|
|
904
|
+
],
|
|
905
|
+
edges: [
|
|
906
|
+
{
|
|
907
|
+
id: 'log-to-router',
|
|
908
|
+
fromNode: 'otel-log',
|
|
909
|
+
toNode: 'log-router',
|
|
910
|
+
fromSide: 'right',
|
|
911
|
+
toSide: 'left',
|
|
912
|
+
label: 'route()',
|
|
913
|
+
pv: { edgeType: 'http-request' },
|
|
914
|
+
},
|
|
915
|
+
{
|
|
916
|
+
id: 'router-checks-scope',
|
|
917
|
+
fromNode: 'log-router',
|
|
918
|
+
toNode: 'canvas-scope',
|
|
919
|
+
fromSide: 'top',
|
|
920
|
+
toSide: 'bottom',
|
|
921
|
+
label: 'isInScope()',
|
|
922
|
+
pv: { edgeType: 'http-request' },
|
|
923
|
+
},
|
|
924
|
+
{
|
|
925
|
+
id: 'router-uses-matcher',
|
|
926
|
+
fromNode: 'log-router',
|
|
927
|
+
toNode: 'resource-matcher',
|
|
928
|
+
fromSide: 'bottom',
|
|
929
|
+
toSide: 'top',
|
|
930
|
+
label: 'match()',
|
|
931
|
+
pv: { edgeType: 'http-request' },
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
id: 'matcher-uses-match',
|
|
935
|
+
fromNode: 'resource-matcher',
|
|
936
|
+
toNode: 'resource-match',
|
|
937
|
+
fromSide: 'right',
|
|
938
|
+
toSide: 'left',
|
|
939
|
+
label: 'criteria',
|
|
940
|
+
pv: { edgeType: 'db-query' },
|
|
941
|
+
},
|
|
942
|
+
{
|
|
943
|
+
id: 'match-has-operator',
|
|
944
|
+
fromNode: 'resource-match',
|
|
945
|
+
toNode: 'match-operator',
|
|
946
|
+
fromSide: 'bottom',
|
|
947
|
+
toSide: 'top',
|
|
948
|
+
label: 'operators',
|
|
949
|
+
pv: { edgeType: 'db-query' },
|
|
950
|
+
},
|
|
951
|
+
{
|
|
952
|
+
id: 'router-to-node',
|
|
953
|
+
fromNode: 'log-router',
|
|
954
|
+
toNode: 'canvas-node',
|
|
955
|
+
fromSide: 'right',
|
|
956
|
+
toSide: 'left',
|
|
957
|
+
label: 'routed',
|
|
958
|
+
pv: { edgeType: 'http-request' },
|
|
959
|
+
},
|
|
960
|
+
{
|
|
961
|
+
id: 'router-returns-result',
|
|
962
|
+
fromNode: 'log-router',
|
|
963
|
+
toNode: 'routing-result',
|
|
964
|
+
fromSide: 'right',
|
|
965
|
+
toSide: 'left',
|
|
966
|
+
label: 'returns',
|
|
967
|
+
pv: { edgeType: 'http-request' },
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
id: 'result-to-audit',
|
|
971
|
+
fromNode: 'routing-result',
|
|
972
|
+
toNode: 'audit-collector',
|
|
973
|
+
fromSide: 'right',
|
|
974
|
+
toSide: 'left',
|
|
975
|
+
label: 'track()',
|
|
976
|
+
pv: { edgeType: 'http-request' },
|
|
977
|
+
},
|
|
978
|
+
{
|
|
979
|
+
id: 'audit-tracks-orphans',
|
|
980
|
+
fromNode: 'audit-collector',
|
|
981
|
+
toNode: 'orphaned-log',
|
|
982
|
+
fromSide: 'right',
|
|
983
|
+
toSide: 'left',
|
|
984
|
+
label: 'unmatched',
|
|
985
|
+
pv: { edgeType: 'db-query' },
|
|
986
|
+
},
|
|
987
|
+
{
|
|
988
|
+
id: 'audit-generates-report',
|
|
989
|
+
fromNode: 'audit-collector',
|
|
990
|
+
toNode: 'audit-report',
|
|
991
|
+
fromSide: 'right',
|
|
992
|
+
toSide: 'left',
|
|
993
|
+
label: 'generate()',
|
|
994
|
+
pv: { edgeType: 'db-query' },
|
|
995
|
+
},
|
|
996
|
+
{
|
|
997
|
+
id: 'node-has-match',
|
|
998
|
+
fromNode: 'canvas-node',
|
|
999
|
+
toNode: 'resource-match',
|
|
1000
|
+
fromSide: 'bottom',
|
|
1001
|
+
toSide: 'top',
|
|
1002
|
+
label: 'resourceMatch',
|
|
1003
|
+
pv: { edgeType: 'db-query' },
|
|
1004
|
+
},
|
|
1005
|
+
{
|
|
1006
|
+
id: 'log-has-resource',
|
|
1007
|
+
fromNode: 'otel-log',
|
|
1008
|
+
toNode: 'otel-resource',
|
|
1009
|
+
fromSide: 'bottom',
|
|
1010
|
+
toSide: 'top',
|
|
1011
|
+
label: 'resource',
|
|
1012
|
+
pv: { edgeType: 'db-query' },
|
|
1013
|
+
},
|
|
1014
|
+
],
|
|
1015
|
+
pv: {
|
|
1016
|
+
version: '1.0.0',
|
|
1017
|
+
name: 'OTEL Log Association Architecture',
|
|
1018
|
+
description: 'Shows how OtelLog flows through LogRouter to Canvas Nodes, with audit tracking',
|
|
1019
|
+
nodeTypes: {
|
|
1020
|
+
service: {
|
|
1021
|
+
label: 'Component',
|
|
1022
|
+
description: 'System component',
|
|
1023
|
+
shape: 'hexagon',
|
|
1024
|
+
},
|
|
1025
|
+
'otel-type': {
|
|
1026
|
+
label: 'Type',
|
|
1027
|
+
description: 'TypeScript type or interface representing OTEL concepts',
|
|
1028
|
+
shape: 'rectangle',
|
|
1029
|
+
},
|
|
1030
|
+
'otel-service': {
|
|
1031
|
+
label: 'Service',
|
|
1032
|
+
description: 'Runtime service component for OTEL processing',
|
|
1033
|
+
shape: 'hexagon',
|
|
1034
|
+
},
|
|
1035
|
+
},
|
|
1036
|
+
edgeTypes: {
|
|
1037
|
+
'http-request': {
|
|
1038
|
+
label: 'Flow',
|
|
1039
|
+
style: 'solid',
|
|
1040
|
+
color: '#4A90E2',
|
|
1041
|
+
directed: true,
|
|
1042
|
+
},
|
|
1043
|
+
'db-query': {
|
|
1044
|
+
label: 'Reference',
|
|
1045
|
+
style: 'dashed',
|
|
1046
|
+
color: '#999',
|
|
1047
|
+
directed: true,
|
|
1048
|
+
},
|
|
1049
|
+
},
|
|
1050
|
+
},
|
|
1051
|
+
};
|
|
1052
|
+
|
|
1053
|
+
export const OtelLogAssociation: Story = {
|
|
1054
|
+
args: {
|
|
1055
|
+
canvas: otelLogAssociationCanvas,
|
|
1056
|
+
width: 1000,
|
|
1057
|
+
height: 800,
|
|
1058
|
+
},
|
|
1059
|
+
parameters: {
|
|
1060
|
+
docs: {
|
|
1061
|
+
description: {
|
|
1062
|
+
story: `
|
|
1063
|
+
**OTEL Log Association Architecture** - Demonstrates the new OTEL visualization features:
|
|
1064
|
+
- **OTEL Badges**: Circular badges (T/S/I) in the top-right corner of nodes indicating Type, Service, or Instance
|
|
1065
|
+
- **Hover Tooltips**: Hover over any node to see the OTEL kind, category, NEW indicator, and description
|
|
1066
|
+
- **Node Info Panel**: Click a node to see the OpenTelemetry section in the info panel
|
|
1067
|
+
|
|
1068
|
+
Color coding:
|
|
1069
|
+
- **Blue (T)**: Type nodes - TypeScript types/interfaces
|
|
1070
|
+
- **Green (S)**: Service nodes - Runtime services
|
|
1071
|
+
- **Purple (I)**: Instance nodes - Specific running instances
|
|
1072
|
+
`,
|
|
1073
|
+
},
|
|
1074
|
+
},
|
|
1075
|
+
},
|
|
1076
|
+
};
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import { ThemeProvider } from '@principal-ade/industry-theme';
|
|
4
|
+
import { GraphRenderer } from '../components/GraphRenderer';
|
|
5
|
+
import { NodeInfoPanel } from '../components/NodeInfoPanel';
|
|
6
|
+
import { NodeTooltip } from '../components/NodeTooltip';
|
|
7
|
+
import type { NodeState, NodeTypeDefinition } from '@principal-ai/principal-view-core';
|
|
8
|
+
|
|
9
|
+
// OTEL Log Association canvas data
|
|
10
|
+
const otelCanvas = {
|
|
11
|
+
nodes: [
|
|
12
|
+
{
|
|
13
|
+
id: 'otel-log',
|
|
14
|
+
type: 'text',
|
|
15
|
+
text: 'OtelLog',
|
|
16
|
+
x: -304,
|
|
17
|
+
y: 147,
|
|
18
|
+
width: 120,
|
|
19
|
+
height: 118,
|
|
20
|
+
pv: {
|
|
21
|
+
nodeType: 'otel-type',
|
|
22
|
+
name: 'OtelLog',
|
|
23
|
+
description:
|
|
24
|
+
'OpenTelemetry log record with timestamp, severity, body, resource, and trace context',
|
|
25
|
+
otel: {
|
|
26
|
+
kind: 'type',
|
|
27
|
+
category: 'log',
|
|
28
|
+
isNew: true,
|
|
29
|
+
},
|
|
30
|
+
shape: 'rectangle',
|
|
31
|
+
icon: 'FileText',
|
|
32
|
+
fill: '#4A90E2',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'log-router',
|
|
37
|
+
type: 'text',
|
|
38
|
+
text: 'LogRouter',
|
|
39
|
+
x: -80,
|
|
40
|
+
y: 150,
|
|
41
|
+
width: 130,
|
|
42
|
+
height: 118,
|
|
43
|
+
pv: {
|
|
44
|
+
nodeType: 'otel-service',
|
|
45
|
+
name: 'LogRouter',
|
|
46
|
+
description: 'Routes incoming OTEL logs to canvas nodes based on scope and resourceMatch criteria',
|
|
47
|
+
otel: {
|
|
48
|
+
kind: 'service',
|
|
49
|
+
category: 'router',
|
|
50
|
+
isNew: true,
|
|
51
|
+
},
|
|
52
|
+
shape: 'hexagon',
|
|
53
|
+
icon: 'GitBranch',
|
|
54
|
+
fill: '#7ED321',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 'orphaned-log',
|
|
59
|
+
type: 'text',
|
|
60
|
+
text: 'OrphanedLog',
|
|
61
|
+
x: 150,
|
|
62
|
+
y: 150,
|
|
63
|
+
width: 127,
|
|
64
|
+
height: 118,
|
|
65
|
+
pv: {
|
|
66
|
+
nodeType: 'otel-type',
|
|
67
|
+
name: 'OrphanedLog',
|
|
68
|
+
description:
|
|
69
|
+
'Logs that matched canvas scope but no node resourceMatch - indicates missing nodes or misconfiguration',
|
|
70
|
+
otel: {
|
|
71
|
+
kind: 'type',
|
|
72
|
+
category: 'audit',
|
|
73
|
+
isNew: true,
|
|
74
|
+
},
|
|
75
|
+
shape: 'rectangle',
|
|
76
|
+
icon: 'AlertTriangle',
|
|
77
|
+
fill: '#D0021B',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: 'match-operator',
|
|
82
|
+
type: 'text',
|
|
83
|
+
text: 'MatchOperator',
|
|
84
|
+
x: -80,
|
|
85
|
+
y: 300,
|
|
86
|
+
width: 120,
|
|
87
|
+
height: 117,
|
|
88
|
+
pv: {
|
|
89
|
+
nodeType: 'service',
|
|
90
|
+
name: 'MatchOperator',
|
|
91
|
+
description: 'Matching operators: exact, glob, regex, exists, oneOf',
|
|
92
|
+
shape: 'diamond',
|
|
93
|
+
icon: 'Code',
|
|
94
|
+
fill: '#F5A623',
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
edges: [
|
|
99
|
+
{
|
|
100
|
+
id: 'log-to-router',
|
|
101
|
+
fromNode: 'otel-log',
|
|
102
|
+
toNode: 'log-router',
|
|
103
|
+
fromSide: 'right',
|
|
104
|
+
toSide: 'left',
|
|
105
|
+
label: 'route()',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
id: 'router-to-orphan',
|
|
109
|
+
fromNode: 'log-router',
|
|
110
|
+
toNode: 'orphaned-log',
|
|
111
|
+
fromSide: 'right',
|
|
112
|
+
toSide: 'left',
|
|
113
|
+
label: 'unmatched',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
id: 'router-to-operator',
|
|
117
|
+
fromNode: 'log-router',
|
|
118
|
+
toNode: 'match-operator',
|
|
119
|
+
fromSide: 'bottom',
|
|
120
|
+
toSide: 'top',
|
|
121
|
+
label: 'uses',
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
pv: {
|
|
125
|
+
version: '1.0.0',
|
|
126
|
+
name: 'OTEL Components Demo',
|
|
127
|
+
description: 'Demonstrates OTEL badges, tooltips, and info panel',
|
|
128
|
+
nodeTypes: {
|
|
129
|
+
'otel-type': {
|
|
130
|
+
label: 'Type',
|
|
131
|
+
description: 'TypeScript type or interface representing OTEL concepts',
|
|
132
|
+
shape: 'rectangle',
|
|
133
|
+
},
|
|
134
|
+
'otel-service': {
|
|
135
|
+
label: 'Service',
|
|
136
|
+
description: 'Runtime service component for OTEL processing',
|
|
137
|
+
shape: 'hexagon',
|
|
138
|
+
},
|
|
139
|
+
service: {
|
|
140
|
+
label: 'Component',
|
|
141
|
+
description: 'System component',
|
|
142
|
+
shape: 'hexagon',
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const meta: Meta = {
|
|
149
|
+
title: 'OTEL/Components',
|
|
150
|
+
parameters: {
|
|
151
|
+
layout: 'fullscreen',
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export default meta;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Shows nodes with OTEL badges (T/S/I circles) and hover tooltips.
|
|
159
|
+
* Hover over any node to see the tooltip with OTEL kind, category, and description.
|
|
160
|
+
*/
|
|
161
|
+
export const OtelBadgesAndTooltips: StoryObj = {
|
|
162
|
+
render: () => (
|
|
163
|
+
<ThemeProvider theme="technology">
|
|
164
|
+
<div style={{ width: '100%', height: '600px' }}>
|
|
165
|
+
<GraphRenderer
|
|
166
|
+
canvas={otelCanvas}
|
|
167
|
+
initialViewport={{ x: 200, y: 50, zoom: 1 }}
|
|
168
|
+
/>
|
|
169
|
+
</div>
|
|
170
|
+
</ThemeProvider>
|
|
171
|
+
),
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Standalone NodeTooltip component demo showing all OTEL kinds.
|
|
176
|
+
*/
|
|
177
|
+
export const TooltipVariants: StoryObj = {
|
|
178
|
+
render: () => (
|
|
179
|
+
<ThemeProvider theme="technology">
|
|
180
|
+
<div style={{ padding: '40px', display: 'flex', gap: '80px', flexWrap: 'wrap' }}>
|
|
181
|
+
<div style={{ position: 'relative', width: '200px', height: '150px' }}>
|
|
182
|
+
<div
|
|
183
|
+
style={{
|
|
184
|
+
padding: '20px',
|
|
185
|
+
border: '2px solid #4A90E2',
|
|
186
|
+
borderRadius: '8px',
|
|
187
|
+
textAlign: 'center',
|
|
188
|
+
}}
|
|
189
|
+
>
|
|
190
|
+
Type Node (hover below)
|
|
191
|
+
</div>
|
|
192
|
+
<NodeTooltip
|
|
193
|
+
description="OpenTelemetry log record with timestamp, severity, body"
|
|
194
|
+
otel={{ kind: 'type', category: 'log', isNew: true }}
|
|
195
|
+
visible={true}
|
|
196
|
+
/>
|
|
197
|
+
</div>
|
|
198
|
+
|
|
199
|
+
<div style={{ position: 'relative', width: '200px', height: '150px' }}>
|
|
200
|
+
<div
|
|
201
|
+
style={{
|
|
202
|
+
padding: '20px',
|
|
203
|
+
border: '2px solid #7ED321',
|
|
204
|
+
borderRadius: '8px',
|
|
205
|
+
textAlign: 'center',
|
|
206
|
+
}}
|
|
207
|
+
>
|
|
208
|
+
Service Node (hover below)
|
|
209
|
+
</div>
|
|
210
|
+
<NodeTooltip
|
|
211
|
+
description="Routes logs to canvas nodes based on resourceMatch"
|
|
212
|
+
otel={{ kind: 'service', category: 'router' }}
|
|
213
|
+
visible={true}
|
|
214
|
+
/>
|
|
215
|
+
</div>
|
|
216
|
+
|
|
217
|
+
<div style={{ position: 'relative', width: '200px', height: '150px' }}>
|
|
218
|
+
<div
|
|
219
|
+
style={{
|
|
220
|
+
padding: '20px',
|
|
221
|
+
border: '2px solid #9B59B6',
|
|
222
|
+
borderRadius: '8px',
|
|
223
|
+
textAlign: 'center',
|
|
224
|
+
}}
|
|
225
|
+
>
|
|
226
|
+
Instance Node (hover below)
|
|
227
|
+
</div>
|
|
228
|
+
<NodeTooltip
|
|
229
|
+
description="A specific running instance of a service"
|
|
230
|
+
otel={{ kind: 'instance', category: 'runtime' }}
|
|
231
|
+
visible={true}
|
|
232
|
+
/>
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
235
|
+
</ThemeProvider>
|
|
236
|
+
),
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* NodeInfoPanel with OTEL information section.
|
|
241
|
+
*/
|
|
242
|
+
export const InfoPanelWithOtel: StoryObj = {
|
|
243
|
+
render: () => {
|
|
244
|
+
const [selectedNode] = useState<NodeState>({
|
|
245
|
+
id: 'log-router',
|
|
246
|
+
type: 'otel-service',
|
|
247
|
+
name: 'LogRouter',
|
|
248
|
+
data: {
|
|
249
|
+
description: 'Routes incoming OTEL logs to canvas nodes based on scope and resourceMatch criteria',
|
|
250
|
+
otel: {
|
|
251
|
+
kind: 'service',
|
|
252
|
+
category: 'router',
|
|
253
|
+
isNew: true,
|
|
254
|
+
},
|
|
255
|
+
icon: 'GitBranch',
|
|
256
|
+
color: '#7ED321',
|
|
257
|
+
sources: ['src/services/LogRouter.ts'],
|
|
258
|
+
},
|
|
259
|
+
position: { x: 0, y: 0 },
|
|
260
|
+
createdAt: Date.now(),
|
|
261
|
+
updatedAt: Date.now(),
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
const typeDefinition: NodeTypeDefinition = {
|
|
265
|
+
shape: 'hexagon',
|
|
266
|
+
color: '#7ED321',
|
|
267
|
+
icon: 'GitBranch',
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
return (
|
|
271
|
+
<ThemeProvider theme="technology">
|
|
272
|
+
<div style={{ padding: '20px', position: 'relative', minHeight: '400px' }}>
|
|
273
|
+
<h3 style={{ marginBottom: '20px' }}>NodeInfoPanel with OTEL Section</h3>
|
|
274
|
+
<p style={{ marginBottom: '20px', color: '#666' }}>
|
|
275
|
+
The panel shows the OpenTelemetry section with kind badge, category, and NEW indicator.
|
|
276
|
+
</p>
|
|
277
|
+
<NodeInfoPanel
|
|
278
|
+
node={selectedNode}
|
|
279
|
+
typeDefinition={typeDefinition}
|
|
280
|
+
onClose={() => {}}
|
|
281
|
+
/>
|
|
282
|
+
</div>
|
|
283
|
+
</ThemeProvider>
|
|
284
|
+
);
|
|
285
|
+
},
|
|
286
|
+
};
|