@neo4j-ndl/react 3.8.7 → 3.8.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.
Files changed (126) hide show
  1. package/lib/cjs/graph-visualization/graph-viz-buttons.js +142 -0
  2. package/lib/cjs/graph-visualization/graph-viz-buttons.js.map +1 -0
  3. package/lib/cjs/graph-visualization/graph-viz-context.js +62 -0
  4. package/lib/cjs/graph-visualization/graph-viz-context.js.map +1 -0
  5. package/lib/cjs/graph-visualization/graph-viz-sidepanel.js +56 -0
  6. package/lib/cjs/graph-visualization/graph-viz-sidepanel.js.map +1 -0
  7. package/lib/cjs/graph-visualization/graph-viz.js +289 -0
  8. package/lib/cjs/graph-visualization/graph-viz.js.map +1 -0
  9. package/lib/cjs/graph-visualization/index.js +44 -0
  10. package/lib/cjs/graph-visualization/index.js.map +1 -0
  11. package/lib/cjs/graph-visualization/map-to-nvl-graph.js +167 -0
  12. package/lib/cjs/graph-visualization/map-to-nvl-graph.js.map +1 -0
  13. package/lib/cjs/graph-visualization/sidepanel-components/button-group.js +96 -0
  14. package/lib/cjs/graph-visualization/sidepanel-components/button-group.js.map +1 -0
  15. package/lib/cjs/graph-visualization/sidepanel-components/clickable-urls-test.js +214 -0
  16. package/lib/cjs/graph-visualization/sidepanel-components/clickable-urls-test.js.map +1 -0
  17. package/lib/cjs/graph-visualization/sidepanel-components/clickable-urls.js +46 -0
  18. package/lib/cjs/graph-visualization/sidepanel-components/clickable-urls.js.map +1 -0
  19. package/lib/cjs/graph-visualization/sidepanel-components/details-panel.js +87 -0
  20. package/lib/cjs/graph-visualization/sidepanel-components/details-panel.js.map +1 -0
  21. package/lib/cjs/graph-visualization/sidepanel-components/overview-panel.js +45 -0
  22. package/lib/cjs/graph-visualization/sidepanel-components/overview-panel.js.map +1 -0
  23. package/lib/cjs/graph-visualization/sidepanel-components/properties-table.js +49 -0
  24. package/lib/cjs/graph-visualization/sidepanel-components/properties-table.js.map +1 -0
  25. package/lib/cjs/graph-visualization/sidepanel-components/show-all.js +44 -0
  26. package/lib/cjs/graph-visualization/sidepanel-components/show-all.js.map +1 -0
  27. package/lib/cjs/graph-visualization/sidepanel-components/single-selection-sidepanel-contents.js +35 -0
  28. package/lib/cjs/graph-visualization/sidepanel-components/single-selection-sidepanel-contents.js.map +1 -0
  29. package/lib/cjs/graph-visualization/stories/graph-viz-barebones.story.js +93 -0
  30. package/lib/cjs/graph-visualization/stories/graph-viz-barebones.story.js.map +1 -0
  31. package/lib/cjs/graph-visualization/stories/graph-viz-custom.story.js +74 -0
  32. package/lib/cjs/graph-visualization/stories/graph-viz-custom.story.js.map +1 -0
  33. package/lib/cjs/graph-visualization/stories/graph-viz-default.story.js +93 -0
  34. package/lib/cjs/graph-visualization/stories/graph-viz-default.story.js.map +1 -0
  35. package/lib/cjs/graph-visualization/stories/graph-viz-maximalist.story.js +106 -0
  36. package/lib/cjs/graph-visualization/stories/graph-viz-maximalist.story.js.map +1 -0
  37. package/lib/cjs/graph-visualization/stories/graph-viz.stories.js +85 -0
  38. package/lib/cjs/graph-visualization/stories/graph-viz.stories.js.map +1 -0
  39. package/lib/cjs/graph-visualization/stories/index.js +44 -0
  40. package/lib/cjs/graph-visualization/stories/index.js.map +1 -0
  41. package/lib/cjs/graph-visualization/stories/story-data.js +89 -0
  42. package/lib/cjs/graph-visualization/stories/story-data.js.map +1 -0
  43. package/lib/cjs/graph-visualization/use-managed-selection-state.js +258 -0
  44. package/lib/cjs/graph-visualization/use-managed-selection-state.js.map +1 -0
  45. package/lib/cjs/graph-visualization/use-semi-controlled-state.js +38 -0
  46. package/lib/cjs/graph-visualization/use-semi-controlled-state.js.map +1 -0
  47. package/lib/cjs/graph-visualization/utils.js +30 -0
  48. package/lib/cjs/graph-visualization/utils.js.map +1 -0
  49. package/lib/cjs/index.js +1 -0
  50. package/lib/cjs/index.js.map +1 -1
  51. package/lib/esm/graph-visualization/graph-viz-buttons.js +127 -0
  52. package/lib/esm/graph-visualization/graph-viz-buttons.js.map +1 -0
  53. package/lib/esm/graph-visualization/graph-viz-context.js +58 -0
  54. package/lib/esm/graph-visualization/graph-viz-context.js.map +1 -0
  55. package/lib/esm/graph-visualization/graph-viz-sidepanel.js +52 -0
  56. package/lib/esm/graph-visualization/graph-viz-sidepanel.js.map +1 -0
  57. package/lib/esm/graph-visualization/graph-viz.js +259 -0
  58. package/lib/esm/graph-visualization/graph-viz.js.map +1 -0
  59. package/lib/esm/graph-visualization/index.js +25 -0
  60. package/lib/esm/graph-visualization/index.js.map +1 -0
  61. package/lib/esm/graph-visualization/map-to-nvl-graph.js +162 -0
  62. package/lib/esm/graph-visualization/map-to-nvl-graph.js.map +1 -0
  63. package/lib/esm/graph-visualization/sidepanel-components/button-group.js +69 -0
  64. package/lib/esm/graph-visualization/sidepanel-components/button-group.js.map +1 -0
  65. package/lib/esm/graph-visualization/sidepanel-components/clickable-urls-test.js +212 -0
  66. package/lib/esm/graph-visualization/sidepanel-components/clickable-urls-test.js.map +1 -0
  67. package/lib/esm/graph-visualization/sidepanel-components/clickable-urls.js +40 -0
  68. package/lib/esm/graph-visualization/sidepanel-components/clickable-urls.js.map +1 -0
  69. package/lib/esm/graph-visualization/sidepanel-components/details-panel.js +83 -0
  70. package/lib/esm/graph-visualization/sidepanel-components/details-panel.js.map +1 -0
  71. package/lib/esm/graph-visualization/sidepanel-components/overview-panel.js +41 -0
  72. package/lib/esm/graph-visualization/sidepanel-components/overview-panel.js.map +1 -0
  73. package/lib/esm/graph-visualization/sidepanel-components/properties-table.js +45 -0
  74. package/lib/esm/graph-visualization/sidepanel-components/properties-table.js.map +1 -0
  75. package/lib/esm/graph-visualization/sidepanel-components/show-all.js +41 -0
  76. package/lib/esm/graph-visualization/sidepanel-components/show-all.js.map +1 -0
  77. package/lib/esm/graph-visualization/sidepanel-components/single-selection-sidepanel-contents.js +31 -0
  78. package/lib/esm/graph-visualization/sidepanel-components/single-selection-sidepanel-contents.js.map +1 -0
  79. package/lib/esm/graph-visualization/stories/graph-viz-barebones.story.js +90 -0
  80. package/lib/esm/graph-visualization/stories/graph-viz-barebones.story.js.map +1 -0
  81. package/lib/esm/graph-visualization/stories/graph-viz-custom.story.js +71 -0
  82. package/lib/esm/graph-visualization/stories/graph-viz-custom.story.js.map +1 -0
  83. package/lib/esm/graph-visualization/stories/graph-viz-default.story.js +90 -0
  84. package/lib/esm/graph-visualization/stories/graph-viz-default.story.js.map +1 -0
  85. package/lib/esm/graph-visualization/stories/graph-viz-maximalist.story.js +103 -0
  86. package/lib/esm/graph-visualization/stories/graph-viz-maximalist.story.js.map +1 -0
  87. package/lib/esm/graph-visualization/stories/graph-viz.stories.js +82 -0
  88. package/lib/esm/graph-visualization/stories/graph-viz.stories.js.map +1 -0
  89. package/lib/esm/graph-visualization/stories/index.js +34 -0
  90. package/lib/esm/graph-visualization/stories/index.js.map +1 -0
  91. package/lib/esm/graph-visualization/stories/story-data.js +86 -0
  92. package/lib/esm/graph-visualization/stories/story-data.js.map +1 -0
  93. package/lib/esm/graph-visualization/use-managed-selection-state.js +255 -0
  94. package/lib/esm/graph-visualization/use-managed-selection-state.js.map +1 -0
  95. package/lib/esm/graph-visualization/use-semi-controlled-state.js +35 -0
  96. package/lib/esm/graph-visualization/use-semi-controlled-state.js.map +1 -0
  97. package/lib/esm/graph-visualization/utils.js +25 -0
  98. package/lib/esm/graph-visualization/utils.js.map +1 -0
  99. package/lib/esm/index.js +1 -0
  100. package/lib/esm/index.js.map +1 -1
  101. package/lib/types/graph-visualization/graph-viz-buttons.d.ts +49 -0
  102. package/lib/types/graph-visualization/graph-viz-context.d.ts +122 -0
  103. package/lib/types/graph-visualization/graph-viz-sidepanel.d.ts +32 -0
  104. package/lib/types/graph-visualization/graph-viz.d.ts +149 -0
  105. package/lib/types/graph-visualization/index.d.ts +24 -0
  106. package/lib/types/graph-visualization/map-to-nvl-graph.d.ts +37 -0
  107. package/lib/types/graph-visualization/sidepanel-components/button-group.d.ts +24 -0
  108. package/lib/types/graph-visualization/sidepanel-components/clickable-urls-test.d.ts +21 -0
  109. package/lib/types/graph-visualization/sidepanel-components/clickable-urls.d.ts +26 -0
  110. package/lib/types/graph-visualization/sidepanel-components/details-panel.d.ts +25 -0
  111. package/lib/types/graph-visualization/sidepanel-components/overview-panel.d.ts +21 -0
  112. package/lib/types/graph-visualization/sidepanel-components/properties-table.d.ts +31 -0
  113. package/lib/types/graph-visualization/sidepanel-components/show-all.d.ts +29 -0
  114. package/lib/types/graph-visualization/sidepanel-components/single-selection-sidepanel-contents.d.ts +21 -0
  115. package/lib/types/graph-visualization/stories/graph-viz-barebones.story.d.ts +23 -0
  116. package/lib/types/graph-visualization/stories/graph-viz-custom.story.d.ts +23 -0
  117. package/lib/types/graph-visualization/stories/graph-viz-default.story.d.ts +23 -0
  118. package/lib/types/graph-visualization/stories/graph-viz-maximalist.story.d.ts +23 -0
  119. package/lib/types/graph-visualization/stories/graph-viz.stories.d.ts +36 -0
  120. package/lib/types/graph-visualization/stories/index.d.ts +28 -0
  121. package/lib/types/graph-visualization/stories/story-data.d.ts +26 -0
  122. package/lib/types/graph-visualization/use-managed-selection-state.d.ts +114 -0
  123. package/lib/types/graph-visualization/use-semi-controlled-state.d.ts +21 -0
  124. package/lib/types/graph-visualization/utils.d.ts +23 -0
  125. package/lib/types/index.d.ts +1 -0
  126. package/package.json +7 -2
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ /**
3
+ *
4
+ * Copyright (c) "Neo4j"
5
+ * Neo4j Sweden AB [http://neo4j.com]
6
+ *
7
+ * This file is part of Neo4j.
8
+ *
9
+ * Neo4j is free software: you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation, either version 3 of the License, or
12
+ * (at your option) any later version.
13
+ *
14
+ * This program is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ * GNU General Public License for more details.
18
+ *
19
+ * You should have received a copy of the GNU General Public License
20
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.captionPriorityOrder = exports.NO_LABEL_FALLBACK_COLOR = exports.DEFAULT_REL_COLOR = void 0;
24
+ exports.getDefaultCaptionKey = getDefaultCaptionKey;
25
+ exports.mapToNvlGraph = mapToNvlGraph;
26
+ const word_color_1 = require("@neo4j-devtools/word-color");
27
+ const base_1 = require("@neo4j-ndl/base");
28
+ exports.DEFAULT_REL_COLOR = base_1.tokens.colors.neutral['40'];
29
+ exports.NO_LABEL_FALLBACK_COLOR = base_1.tokens.colors.neutral['40'];
30
+ const sortAlphabetically = (a = '', b = '') => a.toLowerCase().localeCompare(b.toLowerCase());
31
+ function getMostCommonColor(colors) {
32
+ var _a;
33
+ const [firstColor] = colors;
34
+ if (firstColor === undefined) {
35
+ return exports.NO_LABEL_FALLBACK_COLOR;
36
+ }
37
+ const colorCounts = {};
38
+ for (const color of colors) {
39
+ colorCounts[color] = ((_a = colorCounts[color]) !== null && _a !== void 0 ? _a : 0) + 1;
40
+ }
41
+ let maxCount = 0;
42
+ let mostCommonColor = firstColor;
43
+ for (const [color, colorCount] of Object.entries(colorCounts)) {
44
+ if (colorCount > maxCount) {
45
+ maxCount = colorCount;
46
+ mostCommonColor = color;
47
+ }
48
+ }
49
+ return mostCommonColor;
50
+ }
51
+ function transformToItemMetada(arg) {
52
+ return Object.entries(arg).reduce((acc, [label, colors]) => {
53
+ acc[label] = {
54
+ mostCommonColor: getMostCommonColor(colors),
55
+ totalCount: colors.length,
56
+ };
57
+ return acc;
58
+ }, {});
59
+ }
60
+ exports.captionPriorityOrder = [
61
+ /^name$/i,
62
+ /^title$/i,
63
+ /^label$/i,
64
+ /name$/i,
65
+ /description$/i,
66
+ /^.+/,
67
+ ];
68
+ function getDefaultCaptionKey(options) {
69
+ const captionKeys = options
70
+ .filter((option) => option.type === 'property')
71
+ .map((option) => option.captionKey);
72
+ for (const regex of exports.captionPriorityOrder) {
73
+ const matchingKey = captionKeys.find((key) => regex.test(key));
74
+ if (matchingKey !== undefined) {
75
+ return {
76
+ captionKey: matchingKey,
77
+ type: 'property',
78
+ };
79
+ }
80
+ }
81
+ const typeOption = options.find((option) => option.type === 'type');
82
+ if (typeOption) {
83
+ return typeOption;
84
+ }
85
+ return options.find((option) => option.type === 'id');
86
+ }
87
+ const getDefaultNodeCaption = (item) => {
88
+ const options = Object.keys(item.properties).map((property) => ({
89
+ captionKey: property,
90
+ type: 'property',
91
+ }));
92
+ options.push({ type: 'id' }, { type: 'type' });
93
+ const defaultCaptionKey = getDefaultCaptionKey(options);
94
+ if ((defaultCaptionKey === null || defaultCaptionKey === void 0 ? void 0 : defaultCaptionKey.type) === 'property') {
95
+ const caption = item.properties[defaultCaptionKey.captionKey];
96
+ if (caption !== undefined) {
97
+ // remove quotes from string
98
+ if (caption.type === 'string') {
99
+ return [{ value: caption.stringified.slice(1, -1) }];
100
+ }
101
+ return [{ value: caption.stringified }];
102
+ }
103
+ }
104
+ const [firstLabel] = item.labels;
105
+ if ((defaultCaptionKey === null || defaultCaptionKey === void 0 ? void 0 : defaultCaptionKey.type) === 'type' && firstLabel !== undefined) {
106
+ return [{ value: firstLabel }];
107
+ }
108
+ return [{ value: item.id }];
109
+ };
110
+ // Properties can be huge, so we split them out into a separate lookup table
111
+ // to prevent them from making the physics slow
112
+ // here we also apply default colors & captions to nodes and relationships
113
+ // and sample colors for the sidepanel
114
+ // in the future we'll apply styling here as well
115
+ function mapToNvlGraph(rawNodes, rawRels) {
116
+ const labelColorPairs = {};
117
+ const typeColorPairs = {};
118
+ const nodeData = {};
119
+ const relData = {};
120
+ const nodes = rawNodes.map((node) => {
121
+ var _a;
122
+ const [firstLabel] = node.labels;
123
+ const newNode = Object.assign(Object.assign({ captions: getDefaultNodeCaption(node), color: (_a = node.color) !== null && _a !== void 0 ? _a : (firstLabel === undefined
124
+ ? exports.NO_LABEL_FALLBACK_COLOR
125
+ : (0, word_color_1.calculateDefaultNodeColors)(firstLabel).backgroundColor) }, node), { labels: undefined, properties: undefined });
126
+ nodeData[node.id] = {
127
+ color: newNode.color,
128
+ id: node.id,
129
+ labelsSorted: [...node.labels].sort(sortAlphabetically),
130
+ properties: node.properties,
131
+ };
132
+ node.labels.forEach((label) => {
133
+ var _a;
134
+ labelColorPairs[label] = [
135
+ ...((_a = labelColorPairs[label]) !== null && _a !== void 0 ? _a : []),
136
+ newNode.color,
137
+ ];
138
+ });
139
+ return newNode;
140
+ });
141
+ const rels = rawRels.map((rel) => {
142
+ var _a, _b, _c;
143
+ relData[rel.id] = {
144
+ color: (_a = rel.color) !== null && _a !== void 0 ? _a : exports.DEFAULT_REL_COLOR,
145
+ id: rel.id,
146
+ properties: rel.properties,
147
+ type: rel.type,
148
+ };
149
+ typeColorPairs[rel.type] = [
150
+ ...((_b = typeColorPairs[rel.type]) !== null && _b !== void 0 ? _b : []),
151
+ (_c = rel.color) !== null && _c !== void 0 ? _c : exports.DEFAULT_REL_COLOR,
152
+ ];
153
+ return Object.assign(Object.assign({ captions: [{ value: rel.type }], color: exports.DEFAULT_REL_COLOR }, rel), { properties: undefined, type: undefined });
154
+ });
155
+ const labelMetaData = transformToItemMetada(labelColorPairs);
156
+ const typeMetaData = transformToItemMetada(typeColorPairs);
157
+ const dataLookupTable = {
158
+ labelMetaData,
159
+ labels: Object.keys(labelMetaData).sort((a, b) => sortAlphabetically(a, b)),
160
+ nodes: nodeData,
161
+ relationships: relData,
162
+ typeMetaData,
163
+ types: Object.keys(typeMetaData).sort((a, b) => sortAlphabetically(a, b)),
164
+ };
165
+ return { dataLookupTable, nodes, rels };
166
+ }
167
+ //# sourceMappingURL=map-to-nvl-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map-to-nvl-graph.js","sourceRoot":"","sources":["../../../src/graph-visualization/map-to-nvl-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.ButtonGroup = void 0;
27
+ const jsx_runtime_1 = require("react/jsx-runtime");
28
+ /**
29
+ *
30
+ * Copyright (c) "Neo4j"
31
+ * Neo4j Sweden AB [http://neo4j.com]
32
+ *
33
+ * This file is part of Neo4j.
34
+ *
35
+ * Neo4j is free software: you can redistribute it and/or modify
36
+ * it under the terms of the GNU General Public License as published by
37
+ * the Free Software Foundation, either version 3 of the License, or
38
+ * (at your option) any later version.
39
+ *
40
+ * This program is distributed in the hope that it will be useful,
41
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
42
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43
+ * GNU General Public License for more details.
44
+ *
45
+ * You should have received a copy of the GNU General Public License
46
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
47
+ */
48
+ const react_1 = __importStar(require("react"));
49
+ const ButtonGroup = ({ children }) => {
50
+ const [selectedIndex, setSelectedIndex] = (0, react_1.useState)(0);
51
+ const parentRef = (0, react_1.useRef)(null);
52
+ const focusElement = (index) => {
53
+ var _a, _b;
54
+ const child = (_b = (_a = parentRef.current) === null || _a === void 0 ? void 0 : _a.children[index]) === null || _b === void 0 ? void 0 : _b.children[0];
55
+ if (child instanceof HTMLElement) {
56
+ child.focus();
57
+ }
58
+ };
59
+ const childrenCount = (0, react_1.useMemo)(() => react_1.default.Children.count(children), [children]);
60
+ const safeSetSelectedIndex = (0, react_1.useCallback)((index) => {
61
+ if (index >= childrenCount) {
62
+ setSelectedIndex(childrenCount - 1);
63
+ }
64
+ else {
65
+ setSelectedIndex(Math.max(0, index));
66
+ }
67
+ }, [childrenCount, setSelectedIndex]);
68
+ const handleKeyDown = (event) => {
69
+ let newIndx = selectedIndex;
70
+ if (event.key === 'ArrowRight' || event.key === 'ArrowDown') {
71
+ newIndx = (selectedIndex + 1) % react_1.default.Children.count(children);
72
+ safeSetSelectedIndex(newIndx);
73
+ }
74
+ else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {
75
+ newIndx =
76
+ (selectedIndex - 1 + react_1.default.Children.count(children)) %
77
+ react_1.default.Children.count(children);
78
+ safeSetSelectedIndex(newIndx);
79
+ }
80
+ // set focus to new button
81
+ focusElement(newIndx);
82
+ };
83
+ return (
84
+ // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
85
+ (0, jsx_runtime_1.jsx)("ul", { onKeyDown: (e) => handleKeyDown(e), ref: parentRef, style: { all: 'inherit', listStyleType: 'none' }, children: react_1.default.Children.map(children, (child, index) => {
86
+ if (!react_1.default.isValidElement(child)) {
87
+ return null;
88
+ }
89
+ const clonedElement = (0, react_1.cloneElement)(child, {
90
+ tabIndex: selectedIndex === index ? 0 : -1,
91
+ });
92
+ return (0, jsx_runtime_1.jsx)("li", { children: clonedElement }, index);
93
+ }) }));
94
+ };
95
+ exports.ButtonGroup = ButtonGroup;
96
+ //# sourceMappingURL=button-group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button-group.js","sourceRoot":"","sources":["../../../../src/graph-visualization/sidepanel-components/button-group.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const jsx_runtime_1 = require("react/jsx-runtime");
4
+ /**
5
+ *
6
+ * Copyright (c) "Neo4j"
7
+ * Neo4j Sweden AB [http://neo4j.com]
8
+ *
9
+ * This file is part of Neo4j.
10
+ *
11
+ * Neo4j is free software: you can redistribute it and/or modify
12
+ * it under the terms of the GNU General Public License as published by
13
+ * the Free Software Foundation, either version 3 of the License, or
14
+ * (at your option) any later version.
15
+ *
16
+ * This program is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ * GNU General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU General Public License
22
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
23
+ */
24
+ /* eslint-disable no-irregular-whitespace */
25
+ const react_1 = require("@testing-library/react");
26
+ const vitest_1 = require("vitest");
27
+ const clickable_urls_1 = require("./clickable-urls");
28
+ (0, vitest_1.describe)('clickable-urls', () => {
29
+ (0, vitest_1.describe)('convertUrlsToHrefTags', () => {
30
+ (0, vitest_1.test)('handles most common URL formats', () => {
31
+ const urls = [
32
+ 'bolt://127.0.0.1:7687',
33
+ 'http://foo.com',
34
+ 'http://goo.gl',
35
+ 'https://foo.com',
36
+ 'https://www.foo.com',
37
+ 'https://www.foo.com/',
38
+ 'https://www.foo.com/bar',
39
+ 'http://goo.gl/1',
40
+ 'http://goo.gl/2',
41
+ 'http://firstround.com/review/thoughts-on-gender-and-radical-candor/?ct=t(How_Does_Your_Leadership_Team_Rate_12_3_2015)',
42
+ 'https://google.com',
43
+ 'http://www.cool.com.au',
44
+ 'http://www.cool.com.au/ersdfs',
45
+ 'http://www.cool.com.au/ersdfs?dfd=dfgd@s=1',
46
+ 'http://www.cool.com:81/index.html',
47
+ ];
48
+ const expected = urls.map((url) => `
49
+ <div>
50
+ <span>
51
+
52
+ <a
53
+ href="${url}"
54
+ rel="noreferrer"
55
+ target="_blank"
56
+ >
57
+ ${url}
58
+ </a>
59
+
60
+ </span>
61
+ </div>
62
+ `);
63
+ urls.forEach((url, index) => (0, vitest_1.expect)((0, react_1.render)((0, jsx_runtime_1.jsx)(clickable_urls_1.ClickableUrls, { text: url })).container).toMatchInlineSnapshot(expected[index]));
64
+ });
65
+ (0, vitest_1.test)('does not catch invalid or missing protocol urls', () => {
66
+ (0, vitest_1.expect)((0, react_1.render)((0, jsx_runtime_1.jsx)(clickable_urls_1.ClickableUrls, { text: "google.com" })).container)
67
+ .toMatchInlineSnapshot(`
68
+ <div>
69
+ <span>
70
+ google.com
71
+ </span>
72
+ </div>
73
+ `);
74
+ (0, vitest_1.expect)((0, react_1.render)((0, jsx_runtime_1.jsx)(clickable_urls_1.ClickableUrls, { text: "https:google.com" })).container)
75
+ .toMatchInlineSnapshot(`
76
+ <div>
77
+ <span>
78
+ https:google.com
79
+ </span>
80
+ </div>
81
+ `);
82
+ });
83
+ (0, vitest_1.test)('handles urls inside parentheses', () => {
84
+ (0, vitest_1.expect)((0, react_1.render)((0, jsx_runtime_1.jsx)(clickable_urls_1.ClickableUrls, { text: "(http://goo.gl/1)" })).container)
85
+ .toMatchInlineSnapshot(`
86
+ <div>
87
+ <span>
88
+ (
89
+ <a
90
+ href="http://goo.gl/1"
91
+ rel="noreferrer"
92
+ target="_blank"
93
+ >
94
+ http://goo.gl/1
95
+ </a>
96
+ )
97
+ </span>
98
+ </div>
99
+ `);
100
+ });
101
+ (0, vitest_1.test)('does not include punctuation, comma, exclamation', () => {
102
+ (0, vitest_1.expect)((0, react_1.render)((0, jsx_runtime_1.jsx)(clickable_urls_1.ClickableUrls, { text: "http://foo.com/." })).container)
103
+ .toMatchInlineSnapshot(`
104
+ <div>
105
+ <span>
106
+
107
+ <a
108
+ href="http://foo.com/"
109
+ rel="noreferrer"
110
+ target="_blank"
111
+ >
112
+ http://foo.com/
113
+ </a>
114
+ .
115
+ </span>
116
+ </div>
117
+ `);
118
+ (0, vitest_1.expect)((0, react_1.render)((0, jsx_runtime_1.jsx)(clickable_urls_1.ClickableUrls, { text: "http://foo.com/!" })).container)
119
+ .toMatchInlineSnapshot(`
120
+ <div>
121
+ <span>
122
+
123
+ <a
124
+ href="http://foo.com/"
125
+ rel="noreferrer"
126
+ target="_blank"
127
+ >
128
+ http://foo.com/
129
+ </a>
130
+ !
131
+ </span>
132
+ </div>
133
+ `);
134
+ (0, vitest_1.expect)((0, react_1.render)((0, jsx_runtime_1.jsx)(clickable_urls_1.ClickableUrls, { text: "http://foo.com/," })).container)
135
+ .toMatchInlineSnapshot(`
136
+ <div>
137
+ <span>
138
+
139
+ <a
140
+ href="http://foo.com/"
141
+ rel="noreferrer"
142
+ target="_blank"
143
+ >
144
+ http://foo.com/
145
+ </a>
146
+ ,
147
+ </span>
148
+ </div>
149
+ `);
150
+ });
151
+ (0, vitest_1.test)('Handles multiple URLs, even if in a text block', () => {
152
+ const URLs = 'sftp://foo.se is better than ftp://bar.dk';
153
+ const textBlock = `
154
+ Long black tulips, born in your blue tints
155
+ Lemongrass eyelids, smoke in your slick lips
156
+ (${URLs})
157
+ Chocolate chapstick, backbeat strat flips
158
+ Swimming pool spaceships, light through the wave tips
159
+ `;
160
+ const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(clickable_urls_1.ClickableUrls, { text: textBlock }));
161
+ (0, vitest_1.expect)(container).toMatchInlineSnapshot(`
162
+ <div>
163
+ <span>
164
+
165
+ Long black tulips, born in your blue tints
166
+ Lemongrass eyelids, smoke in your slick lips
167
+ (
168
+ <a
169
+ href="sftp://foo.se"
170
+ rel="noreferrer"
171
+ target="_blank"
172
+ >
173
+ sftp://foo.se
174
+ </a>
175
+ is better than
176
+ <a
177
+ href="ftp://bar.dk"
178
+ rel="noreferrer"
179
+ target="_blank"
180
+ >
181
+ ftp://bar.dk
182
+ </a>
183
+ )
184
+ Chocolate chapstick, backbeat strat flips
185
+ Swimming pool spaceships, light through the wave tips
186
+
187
+ </span>
188
+ </div>
189
+ `);
190
+ });
191
+ });
192
+ (0, vitest_1.describe)('ClickableUrls', () => {
193
+ (0, vitest_1.it)('renders escaped HTML except for generated tags', () => {
194
+ const text = `Hello, my <strong>name</strong> is <a href="http://twitter.com/neo4j" onClick="alert(1)">Neo4j</a>.`;
195
+ const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(clickable_urls_1.ClickableUrls, { text: text }));
196
+ (0, vitest_1.expect)(container).toMatchInlineSnapshot(`
197
+ <div>
198
+ <span>
199
+ Hello, my &lt;strong&gt;name&lt;/strong&gt; is &lt;a href="
200
+ <a
201
+ href="http://twitter.com/neo4j"
202
+ rel="noreferrer"
203
+ target="_blank"
204
+ >
205
+ http://twitter.com/neo4j
206
+ </a>
207
+ " onClick="alert(1)"&gt;Neo4j&lt;/a&gt;.
208
+ </span>
209
+ </div>
210
+ `);
211
+ });
212
+ });
213
+ });
214
+ //# sourceMappingURL=clickable-urls-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickable-urls-test.js","sourceRoot":"","sources":["../../../../src/graph-visualization/sidepanel-components/clickable-urls-test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ClickableUrls = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ /**
9
+ *
10
+ * Copyright (c) "Neo4j"
11
+ * Neo4j Sweden AB [http://neo4j.com]
12
+ *
13
+ * This file is part of Neo4j.
14
+ *
15
+ * Neo4j is free software: you can redistribute it and/or modify
16
+ * it under the terms of the GNU General Public License as published by
17
+ * the Free Software Foundation, either version 3 of the License, or
18
+ * (at your option) any later version.
19
+ *
20
+ * This program is distributed in the hope that it will be useful,
21
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ * GNU General Public License for more details.
24
+ *
25
+ * You should have received a copy of the GNU General Public License
26
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
27
+ */
28
+ const react_1 = __importDefault(require("react"));
29
+ // credits to https://www.regextester.com/96504, modified though
30
+ const URL_REGEX =
31
+ // eslint-disable-next-line
32
+ /(?:https?|s?ftp|bolt):\/\/(?:(?:[^\s()<>]+|\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))?\))+(?:\((?:[^\s()<>]+|(?:\(?:[^\s()<>]+\)))?\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))?/gi;
33
+ const ClickableUrlsComponent = ({ text }) => {
34
+ var _a;
35
+ const definedText = text !== null && text !== void 0 ? text : '';
36
+ const urls = (_a = definedText.match(URL_REGEX)) !== null && _a !== void 0 ? _a : [];
37
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: definedText.split(URL_REGEX).map((t, index) => {
38
+ /* since we never move these components this key should be fine */
39
+ return ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [t, urls[index] && (
40
+ // Should be safe from XSS.
41
+ // Ref: https://mathiasbynens.github.io/rel-noopener/
42
+ (0, jsx_runtime_1.jsx)("a", { href: urls[index], target: "_blank", rel: "noopener noreferrer", className: "hover:underline", children: urls[index] }))] }, `clickable-url-${index}`));
43
+ }) }));
44
+ };
45
+ exports.ClickableUrls = react_1.default.memo(ClickableUrlsComponent);
46
+ //# sourceMappingURL=clickable-urls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickable-urls.js","sourceRoot":"","sources":["../../../../src/graph-visualization/sidepanel-components/clickable-urls.tsx"],"names":[],"mappings":";;;;;;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,kDAA0B;AAE1B,gEAAgE;AAChE,MAAM,SAAS;AACb,2BAA2B;AAC3B,oKAAoK,CAAC;AAMvK,MAAM,sBAAsB,GAAG,CAAC,EAAE,IAAI,EAAsB,EAAE,EAAE;;IAC9D,MAAM,WAAW,GAAG,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,MAAA,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,mCAAI,EAAE,CAAC;IAEhD,OAAO,CACL,2DACG,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;YAC7C,kEAAkE;YAClE,OAAO,CACL,wBAAC,eAAK,CAAC,QAAQ,eACZ,CAAC,EACD,IAAI,CAAC,KAAK,CAAC,IAAI;oBACd,2BAA2B;oBAC3B,qDAAqD;oBACrD,8BACE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EACjB,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,qBAAqB,EACzB,SAAS,EAAC,iBAAiB,YAE1B,IAAI,CAAC,KAAK,CAAC,GACV,CACL,KAbkB,iBAAiB,KAAK,EAAE,CAc5B,CAClB,CAAC;QACJ,CAAC,CAAC,GACD,CACJ,CAAC;AACJ,CAAC,CAAC;AAEW,QAAA,aAAa,GAAG,eAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC"}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DetailsPanel = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ /**
6
+ *
7
+ * Copyright (c) "Neo4j"
8
+ * Neo4j Sweden AB [http://neo4j.com]
9
+ *
10
+ * This file is part of Neo4j.
11
+ *
12
+ * Neo4j is free software: you can redistribute it and/or modify
13
+ * it under the terms of the GNU General Public License as published by
14
+ * the Free Software Foundation, either version 3 of the License, or
15
+ * (at your option) any later version.
16
+ *
17
+ * This program is distributed in the hope that it will be useful,
18
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ * GNU General Public License for more details.
21
+ *
22
+ * You should have received a copy of the GNU General Public License
23
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
24
+ */
25
+ const clipboard_copier_1 = require("@neo4j-ndl/react/clipboard-copier");
26
+ const graph_label_1 = require("@neo4j-ndl/react/graph-label");
27
+ const react_1 = require("react");
28
+ const graph_viz_context_1 = require("../graph-viz-context");
29
+ const graph_viz_sidepanel_1 = require("../graph-viz-sidepanel");
30
+ const properties_table_1 = require("./properties-table");
31
+ const DetailsPanel = ({ paneWidth = 400 }) => {
32
+ const { selected, nvlGraph } = (0, graph_viz_context_1.useGraphVizContext)();
33
+ const nodeData = (0, react_1.useMemo)(() => {
34
+ const [nodeId] = selected.nodeIds;
35
+ if (nodeId !== undefined) {
36
+ return nvlGraph.dataLookupTable.nodes[nodeId];
37
+ }
38
+ return undefined;
39
+ }, [selected, nvlGraph]);
40
+ const relData = (0, react_1.useMemo)(() => {
41
+ const [relId] = selected.relationshipIds;
42
+ if (relId !== undefined) {
43
+ return nvlGraph.dataLookupTable.relationships[relId];
44
+ }
45
+ return undefined;
46
+ }, [selected, nvlGraph]);
47
+ const selectedItem = (0, react_1.useMemo)(() => {
48
+ if (nodeData) {
49
+ return { data: nodeData, dataType: 'node' };
50
+ }
51
+ if (relData) {
52
+ return { data: relData, dataType: 'relationship' };
53
+ }
54
+ return undefined;
55
+ }, [nodeData, relData]);
56
+ if (selectedItem === undefined) {
57
+ return null;
58
+ }
59
+ const properties = [
60
+ {
61
+ key: '<id>',
62
+ type: 'String',
63
+ value: `${selectedItem.data.id}`,
64
+ },
65
+ ...Object.keys(selectedItem.data.properties).map((key) => {
66
+ return {
67
+ key: key,
68
+ type: selectedItem.data.properties[key].type,
69
+ value: selectedItem.data.properties[key].stringified,
70
+ };
71
+ }),
72
+ ];
73
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(graph_viz_sidepanel_1.GraphVizSidepanel.Title, { children: [(0, jsx_runtime_1.jsx)("h6", { className: "ndl-details-title", children: selectedItem.dataType === 'node'
74
+ ? 'Node details'
75
+ : 'Relationship details' }), (0, jsx_runtime_1.jsx)(clipboard_copier_1.ClipboardButton, { textToCopy: properties
76
+ .map((prop) => `${prop.key}: ${prop.value}`)
77
+ .join('\n'), size: "small" })] }), (0, jsx_runtime_1.jsxs)(graph_viz_sidepanel_1.GraphVizSidepanel.Content, { children: [(0, jsx_runtime_1.jsx)("div", { className: "ndl-details-tags", children: selectedItem.dataType === 'node' ? (selectedItem.data.labelsSorted.map((label) => {
78
+ var _a, _b;
79
+ return ((0, jsx_runtime_1.jsx)(graph_label_1.GraphLabel, { type: "node", color: (_b = (_a = nvlGraph.dataLookupTable.labelMetaData[label]) === null || _a === void 0 ? void 0 : _a.mostCommonColor) !== null && _b !== void 0 ? _b : '', as: "span", htmlAttributes: {
80
+ tabIndex: 0,
81
+ }, children: label }, label));
82
+ })) : ((0, jsx_runtime_1.jsx)(graph_label_1.GraphLabel, { type: "relationship", color: selectedItem.data.color, as: "span", htmlAttributes: {
83
+ tabIndex: 0,
84
+ }, children: selectedItem.data.type }, selectedItem.data.type)) }), (0, jsx_runtime_1.jsx)("div", { className: "ndl-details-divider" }), (0, jsx_runtime_1.jsx)(properties_table_1.PropertiesTable, { properties: selectedItem.data.properties, paneWidth: paneWidth })] })] }));
85
+ };
86
+ exports.DetailsPanel = DetailsPanel;
87
+ //# sourceMappingURL=details-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"details-panel.js","sourceRoot":"","sources":["../../../../src/graph-visualization/sidepanel-components/details-panel.tsx"],"names":[],"mappings":"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"}