@backstage/core-components 0.18.11-next.1 → 0.18.11
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/CHANGELOG.md +19 -0
- package/dist/components/CodeSnippet/CodeSnippet.esm.js +6 -40
- package/dist/components/CodeSnippet/CodeSnippet.esm.js.map +1 -1
- package/dist/components/CodeSnippet/CodeSnippetContent.esm.js +46 -0
- package/dist/components/CodeSnippet/CodeSnippetContent.esm.js.map +1 -0
- package/dist/components/DependencyGraph/DependencyGraph.esm.js +8 -336
- package/dist/components/DependencyGraph/DependencyGraph.esm.js.map +1 -1
- package/dist/components/DependencyGraph/DependencyGraphContent.esm.js +342 -0
- package/dist/components/DependencyGraph/DependencyGraphContent.esm.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/layout/Sidebar/SidebarSubmenuItem.esm.js +1 -1
- package/dist/layout/Sidebar/SidebarSubmenuItem.esm.js.map +1 -1
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @backstage/core-components
|
|
2
2
|
|
|
3
|
+
## 0.18.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e0889a3: chore(deps): bump `qs` from 6.15.1 to 6.15.2
|
|
8
|
+
- a07e6a3: Added the correctly-spelled `'header'` literal to the `TableFiltersClassKey` union type and deprecated the previous typoed `'heder'` literal. The generated CSS class with the old key is preserved for backwards compatibility; switch to `'header'` to avoid future removal.
|
|
9
|
+
- c161e1c: Lazy-load `react-syntax-highlighter` and `@dagrejs/dagre` so they are no longer pulled in eagerly through the barrel export. This reduces the upfront module cost of importing from `@backstage/core-components` by roughly 10 MB. The public API is unchanged.
|
|
10
|
+
- dbe93a7: Fix autologout not working correctly when closing all tabs
|
|
11
|
+
- 8add9b9: Fixed the proxy-based sign-in page failing to read the session token when the proxy issues a token whose payload is encoded using the URL-safe base64 alphabet. Such tokens are now decoded correctly so sign-in no longer breaks.
|
|
12
|
+
- f35372d: Fixed text clipping in SidebarSubmenuItem by correcting line-height from 1 to 1.5
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
- @backstage/core-plugin-api@1.12.7
|
|
15
|
+
|
|
16
|
+
## 0.18.11-next.2
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- c161e1c: Lazy-load `react-syntax-highlighter` and `@dagrejs/dagre` so they are no longer pulled in eagerly through the barrel export. This reduces the upfront module cost of importing from `@backstage/core-components` by roughly 10 MB. The public API is unchanged.
|
|
21
|
+
|
|
3
22
|
## 0.18.11-next.1
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -1,45 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import { useTheme } from '@material-ui/core/styles';
|
|
4
|
-
import LightAsync from 'react-syntax-highlighter/dist/esm/light-async';
|
|
5
|
-
import dark from 'react-syntax-highlighter/dist/esm/styles/hljs/dark';
|
|
6
|
-
import docco from 'react-syntax-highlighter/dist/esm/styles/hljs/docco';
|
|
7
|
-
import { CopyTextButton } from '../CopyTextButton/CopyTextButton.esm.js';
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { lazy, Suspense } from 'react';
|
|
8
3
|
|
|
4
|
+
const LazyCodeSnippetContent = lazy(
|
|
5
|
+
() => import('./CodeSnippetContent.esm.js').then((m) => ({ default: m.CodeSnippet }))
|
|
6
|
+
);
|
|
9
7
|
function CodeSnippet(props) {
|
|
10
|
-
|
|
11
|
-
text,
|
|
12
|
-
language,
|
|
13
|
-
showLineNumbers = false,
|
|
14
|
-
highlightedNumbers,
|
|
15
|
-
wrapLongLines,
|
|
16
|
-
customStyle,
|
|
17
|
-
showCopyCodeButton = false
|
|
18
|
-
} = props;
|
|
19
|
-
const theme = useTheme();
|
|
20
|
-
const mode = theme.palette.type === "dark" ? dark : docco;
|
|
21
|
-
const highlightColor = theme.palette.type === "dark" ? "#256bf3" : "#e6ffed";
|
|
22
|
-
return /* @__PURE__ */ jsxs(Box, { position: "relative", children: [
|
|
23
|
-
/* @__PURE__ */ jsx(
|
|
24
|
-
LightAsync,
|
|
25
|
-
{
|
|
26
|
-
customStyle,
|
|
27
|
-
language,
|
|
28
|
-
style: mode,
|
|
29
|
-
showLineNumbers,
|
|
30
|
-
wrapLines: true,
|
|
31
|
-
wrapLongLines,
|
|
32
|
-
lineNumberStyle: { color: theme.palette.textVerySubtle },
|
|
33
|
-
lineProps: (lineNumber) => highlightedNumbers?.includes(lineNumber) ? {
|
|
34
|
-
style: {
|
|
35
|
-
backgroundColor: highlightColor
|
|
36
|
-
}
|
|
37
|
-
} : {},
|
|
38
|
-
children: text
|
|
39
|
-
}
|
|
40
|
-
),
|
|
41
|
-
showCopyCodeButton && /* @__PURE__ */ jsx(Box, { position: "absolute", top: 0, right: 0, children: /* @__PURE__ */ jsx(CopyTextButton, { text }) })
|
|
42
|
-
] });
|
|
8
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", {}), children: /* @__PURE__ */ jsx(LazyCodeSnippetContent, { ...props }) });
|
|
43
9
|
}
|
|
44
10
|
|
|
45
11
|
export { CodeSnippet };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeSnippet.esm.js","sources":["../../../src/components/CodeSnippet/CodeSnippet.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport
|
|
1
|
+
{"version":3,"file":"CodeSnippet.esm.js","sources":["../../../src/components/CodeSnippet/CodeSnippet.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Suspense, lazy } from 'react';\nimport type { CodeSnippetProps } from './CodeSnippetContent';\n\nexport type { CodeSnippetProps } from './CodeSnippetContent';\n\nconst LazyCodeSnippetContent = lazy(() =>\n import('./CodeSnippetContent').then(m => ({ default: m.CodeSnippet })),\n);\n\n/**\n * Thin wrapper on top of {@link https://react-syntax-highlighter.github.io/react-syntax-highlighter/ | react-syntax-highlighter}\n * providing consistent theming and copy code button\n *\n * @public\n */\nexport function CodeSnippet(props: CodeSnippetProps) {\n return (\n <Suspense fallback={<div />}>\n <LazyCodeSnippetContent {...props} />\n </Suspense>\n );\n}\n"],"names":[],"mappings":";;;AAqBA,MAAM,sBAAA,GAAyB,IAAA;AAAA,EAAK,MAClC,OAAO,6BAAsB,CAAA,CAAE,IAAA,CAAK,QAAM,EAAE,OAAA,EAAS,CAAA,CAAE,WAAA,EAAY,CAAE;AACvE,CAAA;AAQO,SAAS,YAAY,KAAA,EAAyB;AACnD,EAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAS,QAAA,kBAAU,GAAA,CAAC,KAAA,EAAA,EAAI,GACvB,QAAA,kBAAA,GAAA,CAAC,sBAAA,EAAA,EAAwB,GAAG,KAAA,EAAO,CAAA,EACrC,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import Box from '@material-ui/core/Box';
|
|
3
|
+
import { useTheme } from '@material-ui/core/styles';
|
|
4
|
+
import LightAsync from 'react-syntax-highlighter/dist/esm/light-async';
|
|
5
|
+
import dark from 'react-syntax-highlighter/dist/esm/styles/hljs/dark';
|
|
6
|
+
import docco from 'react-syntax-highlighter/dist/esm/styles/hljs/docco';
|
|
7
|
+
import { CopyTextButton } from '../CopyTextButton/CopyTextButton.esm.js';
|
|
8
|
+
|
|
9
|
+
function CodeSnippet(props) {
|
|
10
|
+
const {
|
|
11
|
+
text,
|
|
12
|
+
language,
|
|
13
|
+
showLineNumbers = false,
|
|
14
|
+
highlightedNumbers,
|
|
15
|
+
wrapLongLines,
|
|
16
|
+
customStyle,
|
|
17
|
+
showCopyCodeButton = false
|
|
18
|
+
} = props;
|
|
19
|
+
const theme = useTheme();
|
|
20
|
+
const mode = theme.palette.type === "dark" ? dark : docco;
|
|
21
|
+
const highlightColor = theme.palette.type === "dark" ? "#256bf3" : "#e6ffed";
|
|
22
|
+
return /* @__PURE__ */ jsxs(Box, { position: "relative", children: [
|
|
23
|
+
/* @__PURE__ */ jsx(
|
|
24
|
+
LightAsync,
|
|
25
|
+
{
|
|
26
|
+
customStyle,
|
|
27
|
+
language,
|
|
28
|
+
style: mode,
|
|
29
|
+
showLineNumbers,
|
|
30
|
+
wrapLines: true,
|
|
31
|
+
wrapLongLines,
|
|
32
|
+
lineNumberStyle: { color: theme.palette.textVerySubtle },
|
|
33
|
+
lineProps: (lineNumber) => highlightedNumbers?.includes(lineNumber) ? {
|
|
34
|
+
style: {
|
|
35
|
+
backgroundColor: highlightColor
|
|
36
|
+
}
|
|
37
|
+
} : {},
|
|
38
|
+
children: text
|
|
39
|
+
}
|
|
40
|
+
),
|
|
41
|
+
showCopyCodeButton && /* @__PURE__ */ jsx(Box, { position: "absolute", top: 0, right: 0, children: /* @__PURE__ */ jsx(CopyTextButton, { text }) })
|
|
42
|
+
] });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { CodeSnippet };
|
|
46
|
+
//# sourceMappingURL=CodeSnippetContent.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeSnippetContent.esm.js","sources":["../../../src/components/CodeSnippet/CodeSnippetContent.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Box from '@material-ui/core/Box';\nimport { useTheme } from '@material-ui/core/styles';\nimport type {} from 'react-syntax-highlighter';\nimport LightAsync from 'react-syntax-highlighter/dist/esm/light-async';\nimport dark from 'react-syntax-highlighter/dist/esm/styles/hljs/dark';\nimport docco from 'react-syntax-highlighter/dist/esm/styles/hljs/docco';\n\nimport { CopyTextButton } from '../CopyTextButton';\n\n/**\n * Properties for {@link CodeSnippet}\n *\n * @public\n */\nexport interface CodeSnippetProps {\n /**\n * Code Snippet text\n */\n text: string;\n /**\n * Language used by {@link CodeSnippetProps.text}\n */\n language: string;\n /**\n * Whether to show line number\n *\n * @remarks\n *\n * Default: false\n */\n showLineNumbers?: boolean;\n /**\n * Whether to show button to copy code snippet\n *\n * @remarks\n *\n * Default: false\n */\n showCopyCodeButton?: boolean;\n /**\n * Array of line numbers to highlight\n */\n highlightedNumbers?: number[];\n /**\n * Whether to style the `<code>` block with `white-space: pre-wrap` or `white-space: pre`\n *\n * @remarks\n *\n * Default: false (`white-space: pre`)\n */\n wrapLongLines?: boolean;\n /**\n * Custom styles applied to code\n *\n * @remarks\n *\n * Passed to {@link https://react-syntax-highlighter.github.io/react-syntax-highlighter/ | react-syntax-highlighter}\n */\n customStyle?: any;\n}\n\n/**\n * Thin wrapper on top of {@link https://react-syntax-highlighter.github.io/react-syntax-highlighter/ | react-syntax-highlighter}\n * providing consistent theming and copy code button\n *\n * @public\n */\nexport function CodeSnippet(props: CodeSnippetProps) {\n const {\n text,\n language,\n showLineNumbers = false,\n highlightedNumbers,\n wrapLongLines,\n customStyle,\n showCopyCodeButton = false,\n } = props;\n const theme = useTheme();\n const mode = theme.palette.type === 'dark' ? dark : docco;\n const highlightColor = theme.palette.type === 'dark' ? '#256bf3' : '#e6ffed';\n\n return (\n <Box position=\"relative\">\n <LightAsync\n customStyle={customStyle}\n language={language}\n style={mode}\n showLineNumbers={showLineNumbers}\n wrapLines\n wrapLongLines={wrapLongLines}\n lineNumberStyle={{ color: theme.palette.textVerySubtle }}\n lineProps={(lineNumber: number) =>\n highlightedNumbers?.includes(lineNumber)\n ? {\n style: {\n backgroundColor: highlightColor,\n },\n }\n : {}\n }\n >\n {text}\n </LightAsync>\n {showCopyCodeButton && (\n <Box position=\"absolute\" top={0} right={0}>\n <CopyTextButton text={text} />\n </Box>\n )}\n </Box>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AAmFO,SAAS,YAAY,KAAA,EAAyB;AACnD,EAAA,MAAM;AAAA,IACJ,IAAA;AAAA,IACA,QAAA;AAAA,IACA,eAAA,GAAkB,KAAA;AAAA,IAClB,kBAAA;AAAA,IACA,aAAA;AAAA,IACA,WAAA;AAAA,IACA,kBAAA,GAAqB;AAAA,GACvB,GAAI,KAAA;AACJ,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,KAAS,SAAS,IAAA,GAAO,KAAA;AACpD,EAAA,MAAM,cAAA,GAAiB,KAAA,CAAM,OAAA,CAAQ,IAAA,KAAS,SAAS,SAAA,GAAY,SAAA;AAEnE,EAAA,uBACE,IAAA,CAAC,GAAA,EAAA,EAAI,QAAA,EAAS,UAAA,EACZ,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,WAAA;AAAA,QACA,QAAA;AAAA,QACA,KAAA,EAAO,IAAA;AAAA,QACP,eAAA;AAAA,QACA,SAAA,EAAS,IAAA;AAAA,QACT,aAAA;AAAA,QACA,eAAA,EAAiB,EAAE,KAAA,EAAO,KAAA,CAAM,QAAQ,cAAA,EAAe;AAAA,QACvD,WAAW,CAAC,UAAA,KACV,kBAAA,EAAoB,QAAA,CAAS,UAAU,CAAA,GACnC;AAAA,UACE,KAAA,EAAO;AAAA,YACL,eAAA,EAAiB;AAAA;AACnB,YAEF,EAAC;AAAA,QAGN,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,IACC,kBAAA,oBACC,GAAA,CAAC,GAAA,EAAA,EAAI,QAAA,EAAS,UAAA,EAAW,GAAA,EAAK,CAAA,EAAG,KAAA,EAAO,CAAA,EACtC,QAAA,kBAAA,GAAA,CAAC,cAAA,EAAA,EAAe,IAAA,EAAY,CAAA,EAC9B;AAAA,GAAA,EAEJ,CAAA;AAEJ;;;;"}
|
|
@@ -1,341 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import useMeasure from 'react-use/esm/useMeasure';
|
|
4
|
-
import classNames from 'classnames';
|
|
5
|
-
import { once } from 'lodash';
|
|
6
|
-
import * as d3Zoom from 'd3-zoom';
|
|
7
|
-
import * as d3Selection from 'd3-selection';
|
|
8
|
-
import useTheme from '@material-ui/core/styles/useTheme';
|
|
9
|
-
import dagre from '@dagrejs/dagre';
|
|
10
|
-
import debounce from 'lodash/debounce';
|
|
11
|
-
import { DependencyGraphTypes } from './types.esm.js';
|
|
12
|
-
import { Node } from './Node.esm.js';
|
|
13
|
-
import { Edge } from './Edge.esm.js';
|
|
14
|
-
import { ARROW_MARKER_ID } from './constants.esm.js';
|
|
15
|
-
import IconButton from '@material-ui/core/IconButton';
|
|
16
|
-
import FullscreenIcon from '@material-ui/icons/Fullscreen';
|
|
17
|
-
import FullscreenExitIcon from '@material-ui/icons/FullscreenExit';
|
|
18
|
-
import { useFullScreenHandle, FullScreen } from 'react-full-screen';
|
|
19
|
-
import { makeStyles } from '@material-ui/core/styles';
|
|
20
|
-
import Tooltip from '@material-ui/core/Tooltip';
|
|
21
|
-
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
22
|
-
import { coreComponentsTranslationRef } from '../../translation.esm.js';
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { lazy, Suspense } from 'react';
|
|
23
3
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
root: {
|
|
30
|
-
overflow: "hidden",
|
|
31
|
-
minHeight: "100%",
|
|
32
|
-
minWidth: "100%"
|
|
33
|
-
},
|
|
34
|
-
fixedHeight: {
|
|
35
|
-
maxHeight: "100%"
|
|
36
|
-
},
|
|
37
|
-
fullscreen: {
|
|
38
|
-
backgroundColor: theme.palette.background.paper
|
|
39
|
-
}
|
|
40
|
-
}));
|
|
41
|
-
const WORKSPACE_ID = "workspace";
|
|
42
|
-
const DEPENDENCY_GRAPH_SVG = "dependency-graph";
|
|
4
|
+
const LazyDependencyGraphContent = lazy(
|
|
5
|
+
() => import('./DependencyGraphContent.esm.js').then((m) => ({
|
|
6
|
+
default: m.DependencyGraph
|
|
7
|
+
}))
|
|
8
|
+
);
|
|
43
9
|
function DependencyGraph(props) {
|
|
44
|
-
|
|
45
|
-
edges,
|
|
46
|
-
nodes,
|
|
47
|
-
renderNode,
|
|
48
|
-
direction = DependencyGraphTypes.Direction.TOP_BOTTOM,
|
|
49
|
-
align,
|
|
50
|
-
nodeMargin = 50,
|
|
51
|
-
edgeMargin = 10,
|
|
52
|
-
rankMargin = 50,
|
|
53
|
-
paddingX = 0,
|
|
54
|
-
paddingY = 0,
|
|
55
|
-
acyclicer,
|
|
56
|
-
ranker = DependencyGraphTypes.Ranker.NETWORK_SIMPLEX,
|
|
57
|
-
labelPosition = DependencyGraphTypes.LabelPosition.RIGHT,
|
|
58
|
-
labelOffset = 10,
|
|
59
|
-
edgeRanks = 1,
|
|
60
|
-
edgeWeight = 1,
|
|
61
|
-
renderEdge,
|
|
62
|
-
renderLabel,
|
|
63
|
-
defs,
|
|
64
|
-
zoom = "enabled",
|
|
65
|
-
curve = "curveMonotoneX",
|
|
66
|
-
showArrowHeads = false,
|
|
67
|
-
fit = "grow",
|
|
68
|
-
allowFullscreen = true,
|
|
69
|
-
...svgProps
|
|
70
|
-
} = props;
|
|
71
|
-
const theme = useTheme();
|
|
72
|
-
const [containerWidth, setContainerWidth] = useState(100);
|
|
73
|
-
const [containerHeight, setContainerHeight] = useState(100);
|
|
74
|
-
const fullScreenHandle = useFullScreenHandle();
|
|
75
|
-
const styles = useStyles();
|
|
76
|
-
const { t } = useTranslationRef(coreComponentsTranslationRef);
|
|
77
|
-
const graph = useRef(
|
|
78
|
-
new dagre.graphlib.Graph()
|
|
79
|
-
);
|
|
80
|
-
const [graphWidth, setGraphWidth] = useState(
|
|
81
|
-
graph.current.graph()?.width || 0
|
|
82
|
-
);
|
|
83
|
-
const [graphHeight, setGraphHeight] = useState(
|
|
84
|
-
graph.current.graph()?.height || 0
|
|
85
|
-
);
|
|
86
|
-
const [graphNodes, setGraphNodes] = useState([]);
|
|
87
|
-
const [graphEdges, setGraphEdges] = useState([]);
|
|
88
|
-
const maxWidth = Math.max(graphWidth, containerWidth);
|
|
89
|
-
const maxHeight = Math.max(graphHeight, containerHeight);
|
|
90
|
-
const [_measureRef] = useMeasure();
|
|
91
|
-
const measureRef = once(_measureRef);
|
|
92
|
-
const scalableHeight = fit === "grow" && !fullScreenHandle.active ? maxHeight : "100%";
|
|
93
|
-
const containerRef = useMemo(
|
|
94
|
-
() => debounce((root) => {
|
|
95
|
-
if (!root) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
measureRef(root);
|
|
99
|
-
const node = root.querySelector(
|
|
100
|
-
`svg#${DEPENDENCY_GRAPH_SVG}`
|
|
101
|
-
);
|
|
102
|
-
if (!node) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
const container = d3Selection.select(node);
|
|
106
|
-
const workspace = d3Selection.select(node.getElementById(WORKSPACE_ID));
|
|
107
|
-
function enableZoom() {
|
|
108
|
-
container.call(
|
|
109
|
-
d3Zoom.zoom().scaleExtent([1, Infinity]).on("zoom", (event) => {
|
|
110
|
-
event.transform.x = Math.min(
|
|
111
|
-
0,
|
|
112
|
-
Math.max(
|
|
113
|
-
event.transform.x,
|
|
114
|
-
maxWidth - maxWidth * event.transform.k
|
|
115
|
-
)
|
|
116
|
-
);
|
|
117
|
-
event.transform.y = Math.min(
|
|
118
|
-
0,
|
|
119
|
-
Math.max(
|
|
120
|
-
event.transform.y,
|
|
121
|
-
maxHeight - maxHeight * event.transform.k
|
|
122
|
-
)
|
|
123
|
-
);
|
|
124
|
-
workspace.attr("transform", event.transform);
|
|
125
|
-
})
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
if (zoom === "enabled") {
|
|
129
|
-
enableZoom();
|
|
130
|
-
} else if (zoom === "enable-on-click") {
|
|
131
|
-
container.on("click", () => enableZoom());
|
|
132
|
-
}
|
|
133
|
-
const { width: newContainerWidth, height: newContainerHeight } = root.getBoundingClientRect();
|
|
134
|
-
if (containerWidth !== newContainerWidth && newContainerWidth <= maxWidth) {
|
|
135
|
-
setContainerWidth(newContainerWidth);
|
|
136
|
-
}
|
|
137
|
-
if (containerHeight !== newContainerHeight && newContainerHeight <= maxHeight) {
|
|
138
|
-
setContainerHeight(newContainerHeight);
|
|
139
|
-
}
|
|
140
|
-
}, 100),
|
|
141
|
-
[measureRef, containerHeight, containerWidth, maxWidth, maxHeight, zoom]
|
|
142
|
-
);
|
|
143
|
-
const setNodesAndEdges = useCallback(() => {
|
|
144
|
-
const currentGraphNodes = graph.current.nodes();
|
|
145
|
-
const currentGraphEdges = graph.current.edges();
|
|
146
|
-
currentGraphNodes.forEach((nodeId) => {
|
|
147
|
-
const remainingNode = nodes.some((node) => node.id === nodeId);
|
|
148
|
-
if (!remainingNode) {
|
|
149
|
-
graph.current.removeNode(nodeId);
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
currentGraphEdges.forEach((e) => {
|
|
153
|
-
const remainingEdge = edges.some(
|
|
154
|
-
(edge) => edge.from === e.v && edge.to === e.w
|
|
155
|
-
);
|
|
156
|
-
if (!remainingEdge) {
|
|
157
|
-
graph.current.removeEdge(e.v, e.w);
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
nodes.forEach((node) => {
|
|
161
|
-
const existingNode = graph.current.nodes().find((nodeId) => node.id === nodeId);
|
|
162
|
-
if (existingNode && graph.current.node(existingNode)) {
|
|
163
|
-
const { width, height, x, y } = graph.current.node(existingNode);
|
|
164
|
-
graph.current.setNode(existingNode, { ...node, width, height, x, y });
|
|
165
|
-
} else {
|
|
166
|
-
graph.current.setNode(node.id, { ...node, width: 0, height: 0 });
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
edges.forEach((e) => {
|
|
170
|
-
graph.current.setEdge(e.from, e.to, {
|
|
171
|
-
...e,
|
|
172
|
-
label: e.label,
|
|
173
|
-
width: 0,
|
|
174
|
-
height: 0,
|
|
175
|
-
labelpos: labelPosition,
|
|
176
|
-
labeloffset: labelOffset,
|
|
177
|
-
weight: edgeWeight,
|
|
178
|
-
minlen: edgeRanks
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
}, [edges, nodes, labelPosition, labelOffset, edgeWeight, edgeRanks]);
|
|
182
|
-
const updateGraph = useMemo(
|
|
183
|
-
() => debounce(
|
|
184
|
-
() => {
|
|
185
|
-
dagre.layout(graph.current);
|
|
186
|
-
const { height, width } = graph.current.graph();
|
|
187
|
-
const newHeight = Math.max(0, height || 0);
|
|
188
|
-
const newWidth = Math.max(0, width || 0);
|
|
189
|
-
setGraphWidth(newWidth);
|
|
190
|
-
setGraphHeight(newHeight);
|
|
191
|
-
setGraphNodes(graph.current.nodes());
|
|
192
|
-
setGraphEdges(graph.current.edges());
|
|
193
|
-
},
|
|
194
|
-
250,
|
|
195
|
-
{ leading: true }
|
|
196
|
-
),
|
|
197
|
-
[]
|
|
198
|
-
);
|
|
199
|
-
useEffect(() => {
|
|
200
|
-
graph.current.setGraph({
|
|
201
|
-
rankdir: direction,
|
|
202
|
-
align,
|
|
203
|
-
nodesep: nodeMargin,
|
|
204
|
-
edgesep: edgeMargin,
|
|
205
|
-
ranksep: rankMargin,
|
|
206
|
-
marginx: paddingX,
|
|
207
|
-
marginy: paddingY,
|
|
208
|
-
acyclicer,
|
|
209
|
-
ranker
|
|
210
|
-
});
|
|
211
|
-
setNodesAndEdges();
|
|
212
|
-
updateGraph();
|
|
213
|
-
return updateGraph.cancel;
|
|
214
|
-
}, [
|
|
215
|
-
acyclicer,
|
|
216
|
-
align,
|
|
217
|
-
direction,
|
|
218
|
-
edgeMargin,
|
|
219
|
-
paddingX,
|
|
220
|
-
paddingY,
|
|
221
|
-
nodeMargin,
|
|
222
|
-
rankMargin,
|
|
223
|
-
ranker,
|
|
224
|
-
setNodesAndEdges,
|
|
225
|
-
updateGraph
|
|
226
|
-
]);
|
|
227
|
-
const setNode = useCallback(
|
|
228
|
-
(id, node) => {
|
|
229
|
-
graph.current.setNode(id, node);
|
|
230
|
-
updateGraph();
|
|
231
|
-
return graph.current;
|
|
232
|
-
},
|
|
233
|
-
[updateGraph]
|
|
234
|
-
);
|
|
235
|
-
const setEdge = useCallback(
|
|
236
|
-
(id, edge) => {
|
|
237
|
-
graph.current.setEdge(id, edge);
|
|
238
|
-
updateGraph();
|
|
239
|
-
return graph.current;
|
|
240
|
-
},
|
|
241
|
-
[updateGraph]
|
|
242
|
-
);
|
|
243
|
-
return /* @__PURE__ */ jsxs(
|
|
244
|
-
FullScreen,
|
|
245
|
-
{
|
|
246
|
-
handle: fullScreenHandle,
|
|
247
|
-
className: classNames(
|
|
248
|
-
fullScreenHandle.active ? styles.fullscreen : styles.root
|
|
249
|
-
),
|
|
250
|
-
children: [
|
|
251
|
-
allowFullscreen && /* @__PURE__ */ jsx(Tooltip, { title: t("dependencyGraph.fullscreenTooltip"), children: /* @__PURE__ */ jsx(
|
|
252
|
-
IconButton,
|
|
253
|
-
{
|
|
254
|
-
className: styles.fullscreenButton,
|
|
255
|
-
onClick: fullScreenHandle.active ? fullScreenHandle.exit : fullScreenHandle.enter,
|
|
256
|
-
children: fullScreenHandle.active ? /* @__PURE__ */ jsx(FullscreenExitIcon, {}) : /* @__PURE__ */ jsx(FullscreenIcon, {})
|
|
257
|
-
}
|
|
258
|
-
) }),
|
|
259
|
-
/* @__PURE__ */ jsx("div", { ref: containerRef, style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxs(
|
|
260
|
-
"svg",
|
|
261
|
-
{
|
|
262
|
-
...svgProps,
|
|
263
|
-
width: "100%",
|
|
264
|
-
height: scalableHeight,
|
|
265
|
-
viewBox: `0 0 ${maxWidth} ${maxHeight}`,
|
|
266
|
-
id: DEPENDENCY_GRAPH_SVG,
|
|
267
|
-
children: [
|
|
268
|
-
/* @__PURE__ */ jsxs("defs", { children: [
|
|
269
|
-
/* @__PURE__ */ jsx(
|
|
270
|
-
"marker",
|
|
271
|
-
{
|
|
272
|
-
id: ARROW_MARKER_ID,
|
|
273
|
-
viewBox: "0 0 24 24",
|
|
274
|
-
markerWidth: "14",
|
|
275
|
-
markerHeight: "14",
|
|
276
|
-
refX: "16",
|
|
277
|
-
refY: "12",
|
|
278
|
-
orient: "auto",
|
|
279
|
-
markerUnits: "strokeWidth",
|
|
280
|
-
children: /* @__PURE__ */ jsx(
|
|
281
|
-
"path",
|
|
282
|
-
{
|
|
283
|
-
fill: theme.palette.textSubtle,
|
|
284
|
-
d: "M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"
|
|
285
|
-
}
|
|
286
|
-
)
|
|
287
|
-
}
|
|
288
|
-
),
|
|
289
|
-
defs
|
|
290
|
-
] }),
|
|
291
|
-
/* @__PURE__ */ jsx("g", { id: WORKSPACE_ID, children: /* @__PURE__ */ jsxs(
|
|
292
|
-
"svg",
|
|
293
|
-
{
|
|
294
|
-
width: graphWidth,
|
|
295
|
-
height: graphHeight,
|
|
296
|
-
y: maxHeight / 2 - graphHeight / 2,
|
|
297
|
-
x: maxWidth / 2 - graphWidth / 2,
|
|
298
|
-
viewBox: `0 0 ${graphWidth} ${graphHeight}`,
|
|
299
|
-
children: [
|
|
300
|
-
graphEdges.map((e) => {
|
|
301
|
-
const edge = graph.current.edge(e);
|
|
302
|
-
if (!edge) return null;
|
|
303
|
-
if (renderEdge) return renderEdge({ edge, id: e });
|
|
304
|
-
return /* @__PURE__ */ jsx(
|
|
305
|
-
Edge,
|
|
306
|
-
{
|
|
307
|
-
id: e,
|
|
308
|
-
setEdge,
|
|
309
|
-
render: renderLabel,
|
|
310
|
-
edge,
|
|
311
|
-
curve,
|
|
312
|
-
showArrowHeads
|
|
313
|
-
},
|
|
314
|
-
`${e.v}-${e.w}`
|
|
315
|
-
);
|
|
316
|
-
}),
|
|
317
|
-
graphNodes.map((id) => {
|
|
318
|
-
const node = graph.current.node(id);
|
|
319
|
-
if (!node) return null;
|
|
320
|
-
return /* @__PURE__ */ jsx(
|
|
321
|
-
Node,
|
|
322
|
-
{
|
|
323
|
-
setNode,
|
|
324
|
-
render: renderNode,
|
|
325
|
-
node
|
|
326
|
-
},
|
|
327
|
-
id
|
|
328
|
-
);
|
|
329
|
-
})
|
|
330
|
-
]
|
|
331
|
-
}
|
|
332
|
-
) })
|
|
333
|
-
]
|
|
334
|
-
}
|
|
335
|
-
) })
|
|
336
|
-
]
|
|
337
|
-
}
|
|
338
|
-
);
|
|
10
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", {}), children: /* @__PURE__ */ jsx(LazyDependencyGraphContent, { ...props }) });
|
|
339
11
|
}
|
|
340
12
|
|
|
341
13
|
export { DependencyGraph };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DependencyGraph.esm.js","sources":["../../../src/components/DependencyGraph/DependencyGraph.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n SVGProps,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport useMeasure from 'react-use/esm/useMeasure';\nimport classNames from 'classnames';\nimport { once } from 'lodash';\nimport * as d3Zoom from 'd3-zoom';\nimport * as d3Selection from 'd3-selection';\nimport useTheme from '@material-ui/core/styles/useTheme';\nimport dagre from '@dagrejs/dagre';\nimport debounce from 'lodash/debounce';\nimport { DependencyGraphTypes as Types } from './types';\nimport { Node } from './Node';\nimport { Edge, GraphEdge } from './Edge';\nimport { ARROW_MARKER_ID } from './constants';\nimport IconButton from '@material-ui/core/IconButton';\nimport FullscreenIcon from '@material-ui/icons/Fullscreen';\nimport FullscreenExitIcon from '@material-ui/icons/FullscreenExit';\nimport { FullScreen, useFullScreenHandle } from 'react-full-screen';\nimport { makeStyles, Theme } from '@material-ui/core/styles';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { coreComponentsTranslationRef } from '../../translation';\n\nconst useStyles = makeStyles((theme: Theme) => ({\n fullscreenButton: {\n position: 'absolute',\n right: 0,\n },\n root: {\n overflow: 'hidden',\n minHeight: '100%',\n minWidth: '100%',\n },\n fixedHeight: {\n maxHeight: '100%',\n },\n fullscreen: {\n backgroundColor: theme.palette.background.paper,\n },\n}));\n\n/**\n * Properties of {@link DependencyGraph}\n *\n * @public\n * @remarks\n * `<NodeData>` and `<EdgeData>` are useful when rendering custom or edge labels\n */\nexport interface DependencyGraphProps<NodeData, EdgeData>\n extends SVGProps<SVGSVGElement> {\n /**\n * Edges of graph\n */\n edges: Types.DependencyEdge<EdgeData>[];\n /**\n * Nodes of Graph\n */\n nodes: Types.DependencyNode<NodeData>[];\n /**\n * Graph {@link DependencyGraphTypes.(Direction:namespace) | direction}\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.Direction.TOP_BOTTOM`\n */\n direction?: Types.Direction;\n /**\n * Node {@link DependencyGraphTypes.(Alignment:namespace) | alignment}\n */\n align?: Types.Alignment;\n /**\n * Margin between nodes on each rank\n *\n * @remarks\n *\n * Default: 50\n */\n nodeMargin?: number;\n /**\n * Margin between edges\n *\n * @remarks\n *\n * Default: 10\n */\n edgeMargin?: number;\n /**\n * Margin between each rank\n *\n * @remarks\n *\n * Default: 50\n */\n rankMargin?: number;\n /**\n * Margin on left and right of whole graph\n *\n * @remarks\n *\n * Default: 0\n */\n paddingX?: number;\n /**\n * Margin on top and bottom of whole graph\n *\n * @remarks\n *\n * Default: 0\n */\n paddingY?: number;\n /**\n * Heuristic used to find set of edges that will make graph acyclic\n */\n acyclicer?: 'greedy';\n /**\n * {@link DependencyGraphTypes.(Ranker:namespace) | Algorithm} used to rank nodes\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.Ranker.NETWORK_SIMPLEX`\n */\n ranker?: Types.Ranker;\n /**\n * {@link DependencyGraphTypes.(LabelPosition:namespace) | Position} of label in relation to edge\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.LabelPosition.RIGHT`\n */\n labelPosition?: Types.LabelPosition;\n /**\n * How much to move label away from edge\n *\n * @remarks\n *\n * Applies only when {@link DependencyGraphProps.labelPosition} is `DependencyGraphTypes.LabelPosition.LEFT` or\n * `DependencyGraphTypes.LabelPosition.RIGHT`\n */\n labelOffset?: number;\n /**\n * Minimum number of ranks to keep between connected nodes\n */\n edgeRanks?: number;\n /**\n * Weight applied to edges in graph\n */\n edgeWeight?: number;\n /**\n * Custom edge rendering component\n */\n renderEdge?: Types.RenderEdgeFunction<EdgeData>;\n /**\n * Custom node rendering component\n */\n renderNode?: Types.RenderNodeFunction<NodeData>;\n /**\n * Custom label rendering component\n */\n renderLabel?: Types.RenderLabelFunction<EdgeData>;\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs | Defs} shared by rendered SVG to be used by\n * {@link DependencyGraphProps.renderNode} and/or {@link DependencyGraphProps.renderLabel}\n */\n defs?: JSX.Element | JSX.Element[];\n /**\n * Controls zoom behavior of graph\n *\n * @remarks\n *\n * Default: `enabled`\n */\n zoom?: 'enabled' | 'disabled' | 'enable-on-click';\n /**\n * A factory for curve generators addressing both lines and areas.\n *\n * @remarks\n *\n * Default: 'curveMonotoneX'\n */\n curve?: 'curveStepBefore' | 'curveMonotoneX';\n /**\n * Controls if the arrow heads should be rendered or not.\n *\n * Default: false\n */\n showArrowHeads?: boolean;\n /**\n * Controls if the graph should be contained or grow\n *\n * @remarks\n *\n * Default: 'grow'\n */\n fit?: 'grow' | 'contain';\n /**\n * Controls if user can toggle fullscreen mode\n *\n * @remarks\n *\n * Default: true\n */\n allowFullscreen?: boolean;\n}\n\nconst WORKSPACE_ID = 'workspace';\nconst DEPENDENCY_GRAPH_SVG = 'dependency-graph';\n\n/**\n * Graph component used to visualize relations between entities\n *\n * @public\n */\nexport function DependencyGraph<NodeData, EdgeData>(\n props: DependencyGraphProps<NodeData, EdgeData>,\n) {\n const {\n edges,\n nodes,\n renderNode,\n direction = Types.Direction.TOP_BOTTOM,\n align,\n nodeMargin = 50,\n edgeMargin = 10,\n rankMargin = 50,\n paddingX = 0,\n paddingY = 0,\n acyclicer,\n ranker = Types.Ranker.NETWORK_SIMPLEX,\n labelPosition = Types.LabelPosition.RIGHT,\n labelOffset = 10,\n edgeRanks = 1,\n edgeWeight = 1,\n renderEdge,\n renderLabel,\n defs,\n zoom = 'enabled',\n curve = 'curveMonotoneX',\n showArrowHeads = false,\n fit = 'grow',\n allowFullscreen = true,\n ...svgProps\n } = props;\n const theme = useTheme();\n const [containerWidth, setContainerWidth] = useState<number>(100);\n const [containerHeight, setContainerHeight] = useState<number>(100);\n const fullScreenHandle = useFullScreenHandle();\n const styles = useStyles();\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n\n const graph = useRef<dagre.graphlib.Graph<Types.DependencyNode<NodeData>>>(\n new dagre.graphlib.Graph(),\n );\n const [graphWidth, setGraphWidth] = useState<number>(\n graph.current.graph()?.width || 0,\n );\n const [graphHeight, setGraphHeight] = useState<number>(\n graph.current.graph()?.height || 0,\n );\n const [graphNodes, setGraphNodes] = useState<string[]>([]);\n const [graphEdges, setGraphEdges] = useState<dagre.Edge[]>([]);\n\n const maxWidth = Math.max(graphWidth, containerWidth);\n const maxHeight = Math.max(graphHeight, containerHeight);\n\n const [_measureRef] = useMeasure();\n const measureRef = once(_measureRef);\n\n const scalableHeight =\n fit === 'grow' && !fullScreenHandle.active ? maxHeight : '100%';\n\n const containerRef = useMemo(\n () =>\n debounce((root: HTMLDivElement) => {\n if (!root) {\n return;\n }\n measureRef(root);\n\n // Set up zooming + panning\n const node: SVGSVGElement = root.querySelector(\n `svg#${DEPENDENCY_GRAPH_SVG}`,\n ) as SVGSVGElement;\n if (!node) {\n return;\n }\n const container = d3Selection.select<SVGSVGElement, null>(node);\n const workspace = d3Selection.select(node.getElementById(WORKSPACE_ID));\n\n function enableZoom() {\n container.call(\n d3Zoom\n .zoom<SVGSVGElement, null>()\n .scaleExtent([1, Infinity])\n .on('zoom', event => {\n event.transform.x = Math.min(\n 0,\n Math.max(\n event.transform.x,\n maxWidth - maxWidth * event.transform.k,\n ),\n );\n event.transform.y = Math.min(\n 0,\n Math.max(\n event.transform.y,\n maxHeight - maxHeight * event.transform.k,\n ),\n );\n workspace.attr('transform', event.transform);\n }),\n );\n }\n\n if (zoom === 'enabled') {\n enableZoom();\n } else if (zoom === 'enable-on-click') {\n container.on('click', () => enableZoom());\n }\n\n const { width: newContainerWidth, height: newContainerHeight } =\n root.getBoundingClientRect();\n if (\n containerWidth !== newContainerWidth &&\n newContainerWidth <= maxWidth\n ) {\n setContainerWidth(newContainerWidth);\n }\n if (\n containerHeight !== newContainerHeight &&\n newContainerHeight <= maxHeight\n ) {\n setContainerHeight(newContainerHeight);\n }\n }, 100),\n [measureRef, containerHeight, containerWidth, maxWidth, maxHeight, zoom],\n );\n\n const setNodesAndEdges = useCallback(() => {\n // Cleaning up lingering nodes and edges\n const currentGraphNodes = graph.current.nodes();\n const currentGraphEdges = graph.current.edges();\n\n currentGraphNodes.forEach(nodeId => {\n const remainingNode = nodes.some(node => node.id === nodeId);\n if (!remainingNode) {\n graph.current.removeNode(nodeId);\n }\n });\n\n currentGraphEdges.forEach(e => {\n const remainingEdge = edges.some(\n edge => edge.from === e.v && edge.to === e.w,\n );\n if (!remainingEdge) {\n graph.current.removeEdge(e.v, e.w);\n }\n });\n\n // Adding/updating nodes and edges\n nodes.forEach(node => {\n const existingNode = graph.current\n .nodes()\n .find(nodeId => node.id === nodeId);\n\n if (existingNode && graph.current.node(existingNode)) {\n const { width, height, x, y } = graph.current.node(existingNode);\n graph.current.setNode(existingNode, { ...node, width, height, x, y });\n } else {\n graph.current.setNode(node.id, { ...node, width: 0, height: 0 });\n }\n });\n\n edges.forEach(e => {\n graph.current.setEdge(e.from, e.to, {\n ...e,\n label: e.label,\n width: 0,\n height: 0,\n labelpos: labelPosition,\n labeloffset: labelOffset,\n weight: edgeWeight,\n minlen: edgeRanks,\n });\n });\n }, [edges, nodes, labelPosition, labelOffset, edgeWeight, edgeRanks]);\n\n const updateGraph = useMemo(\n () =>\n debounce(\n () => {\n dagre.layout(graph.current);\n const { height, width } = graph.current.graph();\n const newHeight = Math.max(0, height || 0);\n const newWidth = Math.max(0, width || 0);\n setGraphWidth(newWidth);\n setGraphHeight(newHeight);\n\n setGraphNodes(graph.current.nodes());\n setGraphEdges(graph.current.edges());\n },\n 250,\n { leading: true },\n ),\n [],\n );\n\n useEffect(() => {\n graph.current.setGraph({\n rankdir: direction,\n align,\n nodesep: nodeMargin,\n edgesep: edgeMargin,\n ranksep: rankMargin,\n marginx: paddingX,\n marginy: paddingY,\n acyclicer,\n ranker,\n });\n\n setNodesAndEdges();\n updateGraph();\n\n return updateGraph.cancel;\n }, [\n acyclicer,\n align,\n direction,\n edgeMargin,\n paddingX,\n paddingY,\n nodeMargin,\n rankMargin,\n ranker,\n setNodesAndEdges,\n updateGraph,\n ]);\n\n const setNode = useCallback(\n (id: string, node: Types.DependencyNode<NodeData>) => {\n graph.current.setNode(id, node);\n updateGraph();\n return graph.current;\n },\n [updateGraph],\n );\n\n const setEdge = useCallback(\n (id: dagre.Edge, edge: Types.DependencyEdge<EdgeData>) => {\n graph.current.setEdge(id, edge);\n updateGraph();\n return graph.current;\n },\n [updateGraph],\n );\n\n return (\n <FullScreen\n handle={fullScreenHandle}\n className={classNames(\n fullScreenHandle.active ? styles.fullscreen : styles.root,\n )}\n >\n {allowFullscreen && (\n <Tooltip title={t('dependencyGraph.fullscreenTooltip')}>\n <IconButton\n className={styles.fullscreenButton}\n onClick={\n fullScreenHandle.active\n ? fullScreenHandle.exit\n : fullScreenHandle.enter\n }\n >\n {fullScreenHandle.active ? (\n <FullscreenExitIcon />\n ) : (\n <FullscreenIcon />\n )}\n </IconButton>\n </Tooltip>\n )}\n\n <div ref={containerRef} style={{ width: '100%', height: '100%' }}>\n <svg\n {...svgProps}\n width=\"100%\"\n height={scalableHeight}\n viewBox={`0 0 ${maxWidth} ${maxHeight}`}\n id={DEPENDENCY_GRAPH_SVG}\n >\n <defs>\n <marker\n id={ARROW_MARKER_ID}\n viewBox=\"0 0 24 24\"\n markerWidth=\"14\"\n markerHeight=\"14\"\n refX=\"16\"\n refY=\"12\"\n orient=\"auto\"\n markerUnits=\"strokeWidth\"\n >\n <path\n fill={theme.palette.textSubtle}\n d=\"M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z\"\n />\n </marker>\n {defs}\n </defs>\n <g id={WORKSPACE_ID}>\n <svg\n width={graphWidth}\n height={graphHeight}\n y={maxHeight / 2 - graphHeight / 2}\n x={maxWidth / 2 - graphWidth / 2}\n viewBox={`0 0 ${graphWidth} ${graphHeight}`}\n >\n {graphEdges.map(e => {\n const edge = graph.current.edge(e) as GraphEdge<EdgeData>;\n if (!edge) return null;\n if (renderEdge) return renderEdge({ edge, id: e });\n\n return (\n <Edge\n key={`${e.v}-${e.w}`}\n id={e}\n setEdge={setEdge}\n render={renderLabel}\n edge={edge}\n curve={curve}\n showArrowHeads={showArrowHeads}\n />\n );\n })}\n {graphNodes.map((id: string) => {\n const node = graph.current.node(id);\n if (!node) return null;\n return (\n <Node\n key={id}\n setNode={setNode}\n render={renderNode}\n node={node}\n />\n );\n })}\n </svg>\n </g>\n </svg>\n </div>\n </FullScreen>\n );\n}\n"],"names":["Types"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DependencyGraph.esm.js","sources":["../../../src/components/DependencyGraph/DependencyGraph.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { type ComponentType, Suspense, lazy } from 'react';\nimport type { DependencyGraphProps } from './DependencyGraphContent';\n\nexport type { DependencyGraphProps } from './DependencyGraphContent';\n\nconst LazyDependencyGraphContent = lazy(() =>\n import('./DependencyGraphContent').then(m => ({\n default: m.DependencyGraph as ComponentType<any>,\n })),\n);\n\n/**\n * Graph component used to visualize relations between entities\n *\n * @public\n */\nexport function DependencyGraph<NodeData, EdgeData>(\n props: DependencyGraphProps<NodeData, EdgeData>,\n) {\n return (\n <Suspense fallback={<div />}>\n <LazyDependencyGraphContent {...props} />\n </Suspense>\n );\n}\n"],"names":[],"mappings":";;;AAqBA,MAAM,0BAAA,GAA6B,IAAA;AAAA,EAAK,MACtC,OAAO,iCAA0B,CAAA,CAAE,KAAK,CAAA,CAAA,MAAM;AAAA,IAC5C,SAAS,CAAA,CAAE;AAAA,GACb,CAAE;AACJ,CAAA;AAOO,SAAS,gBACd,KAAA,EACA;AACA,EAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAS,QAAA,kBAAU,GAAA,CAAC,KAAA,EAAA,EAAI,GACvB,QAAA,kBAAA,GAAA,CAAC,0BAAA,EAAA,EAA4B,GAAG,KAAA,EAAO,CAAA,EACzC,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useRef, useMemo, useCallback, useEffect } from 'react';
|
|
3
|
+
import useMeasure from 'react-use/esm/useMeasure';
|
|
4
|
+
import classNames from 'classnames';
|
|
5
|
+
import { once } from 'lodash';
|
|
6
|
+
import * as d3Zoom from 'd3-zoom';
|
|
7
|
+
import * as d3Selection from 'd3-selection';
|
|
8
|
+
import useTheme from '@material-ui/core/styles/useTheme';
|
|
9
|
+
import dagre from '@dagrejs/dagre';
|
|
10
|
+
import debounce from 'lodash/debounce';
|
|
11
|
+
import { DependencyGraphTypes } from './types.esm.js';
|
|
12
|
+
import { Node } from './Node.esm.js';
|
|
13
|
+
import { Edge } from './Edge.esm.js';
|
|
14
|
+
import { ARROW_MARKER_ID } from './constants.esm.js';
|
|
15
|
+
import IconButton from '@material-ui/core/IconButton';
|
|
16
|
+
import FullscreenIcon from '@material-ui/icons/Fullscreen';
|
|
17
|
+
import FullscreenExitIcon from '@material-ui/icons/FullscreenExit';
|
|
18
|
+
import { useFullScreenHandle, FullScreen } from 'react-full-screen';
|
|
19
|
+
import { makeStyles } from '@material-ui/core/styles';
|
|
20
|
+
import Tooltip from '@material-ui/core/Tooltip';
|
|
21
|
+
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
22
|
+
import { coreComponentsTranslationRef } from '../../translation.esm.js';
|
|
23
|
+
|
|
24
|
+
const useStyles = makeStyles((theme) => ({
|
|
25
|
+
fullscreenButton: {
|
|
26
|
+
position: "absolute",
|
|
27
|
+
right: 0
|
|
28
|
+
},
|
|
29
|
+
root: {
|
|
30
|
+
overflow: "hidden",
|
|
31
|
+
minHeight: "100%",
|
|
32
|
+
minWidth: "100%"
|
|
33
|
+
},
|
|
34
|
+
fixedHeight: {
|
|
35
|
+
maxHeight: "100%"
|
|
36
|
+
},
|
|
37
|
+
fullscreen: {
|
|
38
|
+
backgroundColor: theme.palette.background.paper
|
|
39
|
+
}
|
|
40
|
+
}));
|
|
41
|
+
const WORKSPACE_ID = "workspace";
|
|
42
|
+
const DEPENDENCY_GRAPH_SVG = "dependency-graph";
|
|
43
|
+
function DependencyGraph(props) {
|
|
44
|
+
const {
|
|
45
|
+
edges,
|
|
46
|
+
nodes,
|
|
47
|
+
renderNode,
|
|
48
|
+
direction = DependencyGraphTypes.Direction.TOP_BOTTOM,
|
|
49
|
+
align,
|
|
50
|
+
nodeMargin = 50,
|
|
51
|
+
edgeMargin = 10,
|
|
52
|
+
rankMargin = 50,
|
|
53
|
+
paddingX = 0,
|
|
54
|
+
paddingY = 0,
|
|
55
|
+
acyclicer,
|
|
56
|
+
ranker = DependencyGraphTypes.Ranker.NETWORK_SIMPLEX,
|
|
57
|
+
labelPosition = DependencyGraphTypes.LabelPosition.RIGHT,
|
|
58
|
+
labelOffset = 10,
|
|
59
|
+
edgeRanks = 1,
|
|
60
|
+
edgeWeight = 1,
|
|
61
|
+
renderEdge,
|
|
62
|
+
renderLabel,
|
|
63
|
+
defs,
|
|
64
|
+
zoom = "enabled",
|
|
65
|
+
curve = "curveMonotoneX",
|
|
66
|
+
showArrowHeads = false,
|
|
67
|
+
fit = "grow",
|
|
68
|
+
allowFullscreen = true,
|
|
69
|
+
...svgProps
|
|
70
|
+
} = props;
|
|
71
|
+
const theme = useTheme();
|
|
72
|
+
const [containerWidth, setContainerWidth] = useState(100);
|
|
73
|
+
const [containerHeight, setContainerHeight] = useState(100);
|
|
74
|
+
const fullScreenHandle = useFullScreenHandle();
|
|
75
|
+
const styles = useStyles();
|
|
76
|
+
const { t } = useTranslationRef(coreComponentsTranslationRef);
|
|
77
|
+
const graph = useRef(
|
|
78
|
+
new dagre.graphlib.Graph()
|
|
79
|
+
);
|
|
80
|
+
const [graphWidth, setGraphWidth] = useState(
|
|
81
|
+
graph.current.graph()?.width || 0
|
|
82
|
+
);
|
|
83
|
+
const [graphHeight, setGraphHeight] = useState(
|
|
84
|
+
graph.current.graph()?.height || 0
|
|
85
|
+
);
|
|
86
|
+
const [graphNodes, setGraphNodes] = useState([]);
|
|
87
|
+
const [graphEdges, setGraphEdges] = useState([]);
|
|
88
|
+
const maxWidth = Math.max(graphWidth, containerWidth);
|
|
89
|
+
const maxHeight = Math.max(graphHeight, containerHeight);
|
|
90
|
+
const [_measureRef] = useMeasure();
|
|
91
|
+
const measureRef = once(_measureRef);
|
|
92
|
+
const scalableHeight = fit === "grow" && !fullScreenHandle.active ? maxHeight : "100%";
|
|
93
|
+
const containerRef = useMemo(
|
|
94
|
+
() => debounce((root) => {
|
|
95
|
+
if (!root) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
measureRef(root);
|
|
99
|
+
const node = root.querySelector(
|
|
100
|
+
`svg#${DEPENDENCY_GRAPH_SVG}`
|
|
101
|
+
);
|
|
102
|
+
if (!node) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const container = d3Selection.select(node);
|
|
106
|
+
const workspace = d3Selection.select(node.getElementById(WORKSPACE_ID));
|
|
107
|
+
function enableZoom() {
|
|
108
|
+
container.call(
|
|
109
|
+
d3Zoom.zoom().scaleExtent([1, Infinity]).on("zoom", (event) => {
|
|
110
|
+
event.transform.x = Math.min(
|
|
111
|
+
0,
|
|
112
|
+
Math.max(
|
|
113
|
+
event.transform.x,
|
|
114
|
+
maxWidth - maxWidth * event.transform.k
|
|
115
|
+
)
|
|
116
|
+
);
|
|
117
|
+
event.transform.y = Math.min(
|
|
118
|
+
0,
|
|
119
|
+
Math.max(
|
|
120
|
+
event.transform.y,
|
|
121
|
+
maxHeight - maxHeight * event.transform.k
|
|
122
|
+
)
|
|
123
|
+
);
|
|
124
|
+
workspace.attr("transform", event.transform);
|
|
125
|
+
})
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
if (zoom === "enabled") {
|
|
129
|
+
enableZoom();
|
|
130
|
+
} else if (zoom === "enable-on-click") {
|
|
131
|
+
container.on("click", () => enableZoom());
|
|
132
|
+
}
|
|
133
|
+
const { width: newContainerWidth, height: newContainerHeight } = root.getBoundingClientRect();
|
|
134
|
+
if (containerWidth !== newContainerWidth && newContainerWidth <= maxWidth) {
|
|
135
|
+
setContainerWidth(newContainerWidth);
|
|
136
|
+
}
|
|
137
|
+
if (containerHeight !== newContainerHeight && newContainerHeight <= maxHeight) {
|
|
138
|
+
setContainerHeight(newContainerHeight);
|
|
139
|
+
}
|
|
140
|
+
}, 100),
|
|
141
|
+
[measureRef, containerHeight, containerWidth, maxWidth, maxHeight, zoom]
|
|
142
|
+
);
|
|
143
|
+
const setNodesAndEdges = useCallback(() => {
|
|
144
|
+
const currentGraphNodes = graph.current.nodes();
|
|
145
|
+
const currentGraphEdges = graph.current.edges();
|
|
146
|
+
currentGraphNodes.forEach((nodeId) => {
|
|
147
|
+
const remainingNode = nodes.some((node) => node.id === nodeId);
|
|
148
|
+
if (!remainingNode) {
|
|
149
|
+
graph.current.removeNode(nodeId);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
currentGraphEdges.forEach((e) => {
|
|
153
|
+
const remainingEdge = edges.some(
|
|
154
|
+
(edge) => edge.from === e.v && edge.to === e.w
|
|
155
|
+
);
|
|
156
|
+
if (!remainingEdge) {
|
|
157
|
+
graph.current.removeEdge(e.v, e.w);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
nodes.forEach((node) => {
|
|
161
|
+
const existingNode = graph.current.nodes().find((nodeId) => node.id === nodeId);
|
|
162
|
+
if (existingNode && graph.current.node(existingNode)) {
|
|
163
|
+
const { width, height, x, y } = graph.current.node(existingNode);
|
|
164
|
+
graph.current.setNode(existingNode, { ...node, width, height, x, y });
|
|
165
|
+
} else {
|
|
166
|
+
graph.current.setNode(node.id, { ...node, width: 0, height: 0 });
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
edges.forEach((e) => {
|
|
170
|
+
graph.current.setEdge(e.from, e.to, {
|
|
171
|
+
...e,
|
|
172
|
+
label: e.label,
|
|
173
|
+
width: 0,
|
|
174
|
+
height: 0,
|
|
175
|
+
labelpos: labelPosition,
|
|
176
|
+
labeloffset: labelOffset,
|
|
177
|
+
weight: edgeWeight,
|
|
178
|
+
minlen: edgeRanks
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
}, [edges, nodes, labelPosition, labelOffset, edgeWeight, edgeRanks]);
|
|
182
|
+
const updateGraph = useMemo(
|
|
183
|
+
() => debounce(
|
|
184
|
+
() => {
|
|
185
|
+
dagre.layout(graph.current);
|
|
186
|
+
const { height, width } = graph.current.graph();
|
|
187
|
+
const newHeight = Math.max(0, height || 0);
|
|
188
|
+
const newWidth = Math.max(0, width || 0);
|
|
189
|
+
setGraphWidth(newWidth);
|
|
190
|
+
setGraphHeight(newHeight);
|
|
191
|
+
setGraphNodes(graph.current.nodes());
|
|
192
|
+
setGraphEdges(graph.current.edges());
|
|
193
|
+
},
|
|
194
|
+
250,
|
|
195
|
+
{ leading: true }
|
|
196
|
+
),
|
|
197
|
+
[]
|
|
198
|
+
);
|
|
199
|
+
useEffect(() => {
|
|
200
|
+
graph.current.setGraph({
|
|
201
|
+
rankdir: direction,
|
|
202
|
+
align,
|
|
203
|
+
nodesep: nodeMargin,
|
|
204
|
+
edgesep: edgeMargin,
|
|
205
|
+
ranksep: rankMargin,
|
|
206
|
+
marginx: paddingX,
|
|
207
|
+
marginy: paddingY,
|
|
208
|
+
acyclicer,
|
|
209
|
+
ranker
|
|
210
|
+
});
|
|
211
|
+
setNodesAndEdges();
|
|
212
|
+
updateGraph();
|
|
213
|
+
return updateGraph.cancel;
|
|
214
|
+
}, [
|
|
215
|
+
acyclicer,
|
|
216
|
+
align,
|
|
217
|
+
direction,
|
|
218
|
+
edgeMargin,
|
|
219
|
+
paddingX,
|
|
220
|
+
paddingY,
|
|
221
|
+
nodeMargin,
|
|
222
|
+
rankMargin,
|
|
223
|
+
ranker,
|
|
224
|
+
setNodesAndEdges,
|
|
225
|
+
updateGraph
|
|
226
|
+
]);
|
|
227
|
+
const setNode = useCallback(
|
|
228
|
+
(id, node) => {
|
|
229
|
+
graph.current.setNode(id, node);
|
|
230
|
+
updateGraph();
|
|
231
|
+
return graph.current;
|
|
232
|
+
},
|
|
233
|
+
[updateGraph]
|
|
234
|
+
);
|
|
235
|
+
const setEdge = useCallback(
|
|
236
|
+
(id, edge) => {
|
|
237
|
+
graph.current.setEdge(id, edge);
|
|
238
|
+
updateGraph();
|
|
239
|
+
return graph.current;
|
|
240
|
+
},
|
|
241
|
+
[updateGraph]
|
|
242
|
+
);
|
|
243
|
+
return /* @__PURE__ */ jsxs(
|
|
244
|
+
FullScreen,
|
|
245
|
+
{
|
|
246
|
+
handle: fullScreenHandle,
|
|
247
|
+
className: classNames(
|
|
248
|
+
fullScreenHandle.active ? styles.fullscreen : styles.root
|
|
249
|
+
),
|
|
250
|
+
children: [
|
|
251
|
+
allowFullscreen && /* @__PURE__ */ jsx(Tooltip, { title: t("dependencyGraph.fullscreenTooltip"), children: /* @__PURE__ */ jsx(
|
|
252
|
+
IconButton,
|
|
253
|
+
{
|
|
254
|
+
className: styles.fullscreenButton,
|
|
255
|
+
onClick: fullScreenHandle.active ? fullScreenHandle.exit : fullScreenHandle.enter,
|
|
256
|
+
children: fullScreenHandle.active ? /* @__PURE__ */ jsx(FullscreenExitIcon, {}) : /* @__PURE__ */ jsx(FullscreenIcon, {})
|
|
257
|
+
}
|
|
258
|
+
) }),
|
|
259
|
+
/* @__PURE__ */ jsx("div", { ref: containerRef, style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxs(
|
|
260
|
+
"svg",
|
|
261
|
+
{
|
|
262
|
+
...svgProps,
|
|
263
|
+
width: "100%",
|
|
264
|
+
height: scalableHeight,
|
|
265
|
+
viewBox: `0 0 ${maxWidth} ${maxHeight}`,
|
|
266
|
+
id: DEPENDENCY_GRAPH_SVG,
|
|
267
|
+
children: [
|
|
268
|
+
/* @__PURE__ */ jsxs("defs", { children: [
|
|
269
|
+
/* @__PURE__ */ jsx(
|
|
270
|
+
"marker",
|
|
271
|
+
{
|
|
272
|
+
id: ARROW_MARKER_ID,
|
|
273
|
+
viewBox: "0 0 24 24",
|
|
274
|
+
markerWidth: "14",
|
|
275
|
+
markerHeight: "14",
|
|
276
|
+
refX: "16",
|
|
277
|
+
refY: "12",
|
|
278
|
+
orient: "auto",
|
|
279
|
+
markerUnits: "strokeWidth",
|
|
280
|
+
children: /* @__PURE__ */ jsx(
|
|
281
|
+
"path",
|
|
282
|
+
{
|
|
283
|
+
fill: theme.palette.textSubtle,
|
|
284
|
+
d: "M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"
|
|
285
|
+
}
|
|
286
|
+
)
|
|
287
|
+
}
|
|
288
|
+
),
|
|
289
|
+
defs
|
|
290
|
+
] }),
|
|
291
|
+
/* @__PURE__ */ jsx("g", { id: WORKSPACE_ID, children: /* @__PURE__ */ jsxs(
|
|
292
|
+
"svg",
|
|
293
|
+
{
|
|
294
|
+
width: graphWidth,
|
|
295
|
+
height: graphHeight,
|
|
296
|
+
y: maxHeight / 2 - graphHeight / 2,
|
|
297
|
+
x: maxWidth / 2 - graphWidth / 2,
|
|
298
|
+
viewBox: `0 0 ${graphWidth} ${graphHeight}`,
|
|
299
|
+
children: [
|
|
300
|
+
graphEdges.map((e) => {
|
|
301
|
+
const edge = graph.current.edge(e);
|
|
302
|
+
if (!edge) return null;
|
|
303
|
+
if (renderEdge) return renderEdge({ edge, id: e });
|
|
304
|
+
return /* @__PURE__ */ jsx(
|
|
305
|
+
Edge,
|
|
306
|
+
{
|
|
307
|
+
id: e,
|
|
308
|
+
setEdge,
|
|
309
|
+
render: renderLabel,
|
|
310
|
+
edge,
|
|
311
|
+
curve,
|
|
312
|
+
showArrowHeads
|
|
313
|
+
},
|
|
314
|
+
`${e.v}-${e.w}`
|
|
315
|
+
);
|
|
316
|
+
}),
|
|
317
|
+
graphNodes.map((id) => {
|
|
318
|
+
const node = graph.current.node(id);
|
|
319
|
+
if (!node) return null;
|
|
320
|
+
return /* @__PURE__ */ jsx(
|
|
321
|
+
Node,
|
|
322
|
+
{
|
|
323
|
+
setNode,
|
|
324
|
+
render: renderNode,
|
|
325
|
+
node
|
|
326
|
+
},
|
|
327
|
+
id
|
|
328
|
+
);
|
|
329
|
+
})
|
|
330
|
+
]
|
|
331
|
+
}
|
|
332
|
+
) })
|
|
333
|
+
]
|
|
334
|
+
}
|
|
335
|
+
) })
|
|
336
|
+
]
|
|
337
|
+
}
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export { DependencyGraph };
|
|
342
|
+
//# sourceMappingURL=DependencyGraphContent.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DependencyGraphContent.esm.js","sources":["../../../src/components/DependencyGraph/DependencyGraphContent.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n SVGProps,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport useMeasure from 'react-use/esm/useMeasure';\nimport classNames from 'classnames';\nimport { once } from 'lodash';\nimport * as d3Zoom from 'd3-zoom';\nimport * as d3Selection from 'd3-selection';\nimport useTheme from '@material-ui/core/styles/useTheme';\nimport dagre from '@dagrejs/dagre';\nimport debounce from 'lodash/debounce';\nimport { DependencyGraphTypes as Types } from './types';\nimport { Node } from './Node';\nimport { Edge, GraphEdge } from './Edge';\nimport { ARROW_MARKER_ID } from './constants';\nimport IconButton from '@material-ui/core/IconButton';\nimport FullscreenIcon from '@material-ui/icons/Fullscreen';\nimport FullscreenExitIcon from '@material-ui/icons/FullscreenExit';\nimport { FullScreen, useFullScreenHandle } from 'react-full-screen';\nimport { makeStyles, Theme } from '@material-ui/core/styles';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { coreComponentsTranslationRef } from '../../translation';\n\nconst useStyles = makeStyles((theme: Theme) => ({\n fullscreenButton: {\n position: 'absolute',\n right: 0,\n },\n root: {\n overflow: 'hidden',\n minHeight: '100%',\n minWidth: '100%',\n },\n fixedHeight: {\n maxHeight: '100%',\n },\n fullscreen: {\n backgroundColor: theme.palette.background.paper,\n },\n}));\n\n/**\n * Properties of {@link DependencyGraph}\n *\n * @public\n * @remarks\n * `<NodeData>` and `<EdgeData>` are useful when rendering custom or edge labels\n */\nexport interface DependencyGraphProps<NodeData, EdgeData>\n extends SVGProps<SVGSVGElement> {\n /**\n * Edges of graph\n */\n edges: Types.DependencyEdge<EdgeData>[];\n /**\n * Nodes of Graph\n */\n nodes: Types.DependencyNode<NodeData>[];\n /**\n * Graph {@link DependencyGraphTypes.(Direction:namespace) | direction}\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.Direction.TOP_BOTTOM`\n */\n direction?: Types.Direction;\n /**\n * Node {@link DependencyGraphTypes.(Alignment:namespace) | alignment}\n */\n align?: Types.Alignment;\n /**\n * Margin between nodes on each rank\n *\n * @remarks\n *\n * Default: 50\n */\n nodeMargin?: number;\n /**\n * Margin between edges\n *\n * @remarks\n *\n * Default: 10\n */\n edgeMargin?: number;\n /**\n * Margin between each rank\n *\n * @remarks\n *\n * Default: 50\n */\n rankMargin?: number;\n /**\n * Margin on left and right of whole graph\n *\n * @remarks\n *\n * Default: 0\n */\n paddingX?: number;\n /**\n * Margin on top and bottom of whole graph\n *\n * @remarks\n *\n * Default: 0\n */\n paddingY?: number;\n /**\n * Heuristic used to find set of edges that will make graph acyclic\n */\n acyclicer?: 'greedy';\n /**\n * {@link DependencyGraphTypes.(Ranker:namespace) | Algorithm} used to rank nodes\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.Ranker.NETWORK_SIMPLEX`\n */\n ranker?: Types.Ranker;\n /**\n * {@link DependencyGraphTypes.(LabelPosition:namespace) | Position} of label in relation to edge\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.LabelPosition.RIGHT`\n */\n labelPosition?: Types.LabelPosition;\n /**\n * How much to move label away from edge\n *\n * @remarks\n *\n * Applies only when {@link DependencyGraphProps.labelPosition} is `DependencyGraphTypes.LabelPosition.LEFT` or\n * `DependencyGraphTypes.LabelPosition.RIGHT`\n */\n labelOffset?: number;\n /**\n * Minimum number of ranks to keep between connected nodes\n */\n edgeRanks?: number;\n /**\n * Weight applied to edges in graph\n */\n edgeWeight?: number;\n /**\n * Custom edge rendering component\n */\n renderEdge?: Types.RenderEdgeFunction<EdgeData>;\n /**\n * Custom node rendering component\n */\n renderNode?: Types.RenderNodeFunction<NodeData>;\n /**\n * Custom label rendering component\n */\n renderLabel?: Types.RenderLabelFunction<EdgeData>;\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs | Defs} shared by rendered SVG to be used by\n * {@link DependencyGraphProps.renderNode} and/or {@link DependencyGraphProps.renderLabel}\n */\n defs?: JSX.Element | JSX.Element[];\n /**\n * Controls zoom behavior of graph\n *\n * @remarks\n *\n * Default: `enabled`\n */\n zoom?: 'enabled' | 'disabled' | 'enable-on-click';\n /**\n * A factory for curve generators addressing both lines and areas.\n *\n * @remarks\n *\n * Default: 'curveMonotoneX'\n */\n curve?: 'curveStepBefore' | 'curveMonotoneX';\n /**\n * Controls if the arrow heads should be rendered or not.\n *\n * Default: false\n */\n showArrowHeads?: boolean;\n /**\n * Controls if the graph should be contained or grow\n *\n * @remarks\n *\n * Default: 'grow'\n */\n fit?: 'grow' | 'contain';\n /**\n * Controls if user can toggle fullscreen mode\n *\n * @remarks\n *\n * Default: true\n */\n allowFullscreen?: boolean;\n}\n\nconst WORKSPACE_ID = 'workspace';\nconst DEPENDENCY_GRAPH_SVG = 'dependency-graph';\n\n/**\n * Graph component used to visualize relations between entities\n *\n * @public\n */\nexport function DependencyGraph<NodeData, EdgeData>(\n props: DependencyGraphProps<NodeData, EdgeData>,\n) {\n const {\n edges,\n nodes,\n renderNode,\n direction = Types.Direction.TOP_BOTTOM,\n align,\n nodeMargin = 50,\n edgeMargin = 10,\n rankMargin = 50,\n paddingX = 0,\n paddingY = 0,\n acyclicer,\n ranker = Types.Ranker.NETWORK_SIMPLEX,\n labelPosition = Types.LabelPosition.RIGHT,\n labelOffset = 10,\n edgeRanks = 1,\n edgeWeight = 1,\n renderEdge,\n renderLabel,\n defs,\n zoom = 'enabled',\n curve = 'curveMonotoneX',\n showArrowHeads = false,\n fit = 'grow',\n allowFullscreen = true,\n ...svgProps\n } = props;\n const theme = useTheme();\n const [containerWidth, setContainerWidth] = useState<number>(100);\n const [containerHeight, setContainerHeight] = useState<number>(100);\n const fullScreenHandle = useFullScreenHandle();\n const styles = useStyles();\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n\n const graph = useRef<dagre.graphlib.Graph<Types.DependencyNode<NodeData>>>(\n new dagre.graphlib.Graph(),\n );\n const [graphWidth, setGraphWidth] = useState<number>(\n graph.current.graph()?.width || 0,\n );\n const [graphHeight, setGraphHeight] = useState<number>(\n graph.current.graph()?.height || 0,\n );\n const [graphNodes, setGraphNodes] = useState<string[]>([]);\n const [graphEdges, setGraphEdges] = useState<dagre.Edge[]>([]);\n\n const maxWidth = Math.max(graphWidth, containerWidth);\n const maxHeight = Math.max(graphHeight, containerHeight);\n\n const [_measureRef] = useMeasure();\n const measureRef = once(_measureRef);\n\n const scalableHeight =\n fit === 'grow' && !fullScreenHandle.active ? maxHeight : '100%';\n\n const containerRef = useMemo(\n () =>\n debounce((root: HTMLDivElement) => {\n if (!root) {\n return;\n }\n measureRef(root);\n\n // Set up zooming + panning\n const node: SVGSVGElement = root.querySelector(\n `svg#${DEPENDENCY_GRAPH_SVG}`,\n ) as SVGSVGElement;\n if (!node) {\n return;\n }\n const container = d3Selection.select<SVGSVGElement, null>(node);\n const workspace = d3Selection.select(node.getElementById(WORKSPACE_ID));\n\n function enableZoom() {\n container.call(\n d3Zoom\n .zoom<SVGSVGElement, null>()\n .scaleExtent([1, Infinity])\n .on('zoom', event => {\n event.transform.x = Math.min(\n 0,\n Math.max(\n event.transform.x,\n maxWidth - maxWidth * event.transform.k,\n ),\n );\n event.transform.y = Math.min(\n 0,\n Math.max(\n event.transform.y,\n maxHeight - maxHeight * event.transform.k,\n ),\n );\n workspace.attr('transform', event.transform);\n }),\n );\n }\n\n if (zoom === 'enabled') {\n enableZoom();\n } else if (zoom === 'enable-on-click') {\n container.on('click', () => enableZoom());\n }\n\n const { width: newContainerWidth, height: newContainerHeight } =\n root.getBoundingClientRect();\n if (\n containerWidth !== newContainerWidth &&\n newContainerWidth <= maxWidth\n ) {\n setContainerWidth(newContainerWidth);\n }\n if (\n containerHeight !== newContainerHeight &&\n newContainerHeight <= maxHeight\n ) {\n setContainerHeight(newContainerHeight);\n }\n }, 100),\n [measureRef, containerHeight, containerWidth, maxWidth, maxHeight, zoom],\n );\n\n const setNodesAndEdges = useCallback(() => {\n // Cleaning up lingering nodes and edges\n const currentGraphNodes = graph.current.nodes();\n const currentGraphEdges = graph.current.edges();\n\n currentGraphNodes.forEach(nodeId => {\n const remainingNode = nodes.some(node => node.id === nodeId);\n if (!remainingNode) {\n graph.current.removeNode(nodeId);\n }\n });\n\n currentGraphEdges.forEach(e => {\n const remainingEdge = edges.some(\n edge => edge.from === e.v && edge.to === e.w,\n );\n if (!remainingEdge) {\n graph.current.removeEdge(e.v, e.w);\n }\n });\n\n // Adding/updating nodes and edges\n nodes.forEach(node => {\n const existingNode = graph.current\n .nodes()\n .find(nodeId => node.id === nodeId);\n\n if (existingNode && graph.current.node(existingNode)) {\n const { width, height, x, y } = graph.current.node(existingNode);\n graph.current.setNode(existingNode, { ...node, width, height, x, y });\n } else {\n graph.current.setNode(node.id, { ...node, width: 0, height: 0 });\n }\n });\n\n edges.forEach(e => {\n graph.current.setEdge(e.from, e.to, {\n ...e,\n label: e.label,\n width: 0,\n height: 0,\n labelpos: labelPosition,\n labeloffset: labelOffset,\n weight: edgeWeight,\n minlen: edgeRanks,\n });\n });\n }, [edges, nodes, labelPosition, labelOffset, edgeWeight, edgeRanks]);\n\n const updateGraph = useMemo(\n () =>\n debounce(\n () => {\n dagre.layout(graph.current);\n const { height, width } = graph.current.graph();\n const newHeight = Math.max(0, height || 0);\n const newWidth = Math.max(0, width || 0);\n setGraphWidth(newWidth);\n setGraphHeight(newHeight);\n\n setGraphNodes(graph.current.nodes());\n setGraphEdges(graph.current.edges());\n },\n 250,\n { leading: true },\n ),\n [],\n );\n\n useEffect(() => {\n graph.current.setGraph({\n rankdir: direction,\n align,\n nodesep: nodeMargin,\n edgesep: edgeMargin,\n ranksep: rankMargin,\n marginx: paddingX,\n marginy: paddingY,\n acyclicer,\n ranker,\n });\n\n setNodesAndEdges();\n updateGraph();\n\n return updateGraph.cancel;\n }, [\n acyclicer,\n align,\n direction,\n edgeMargin,\n paddingX,\n paddingY,\n nodeMargin,\n rankMargin,\n ranker,\n setNodesAndEdges,\n updateGraph,\n ]);\n\n const setNode = useCallback(\n (id: string, node: Types.DependencyNode<NodeData>) => {\n graph.current.setNode(id, node);\n updateGraph();\n return graph.current;\n },\n [updateGraph],\n );\n\n const setEdge = useCallback(\n (id: dagre.Edge, edge: Types.DependencyEdge<EdgeData>) => {\n graph.current.setEdge(id, edge);\n updateGraph();\n return graph.current;\n },\n [updateGraph],\n );\n\n return (\n <FullScreen\n handle={fullScreenHandle}\n className={classNames(\n fullScreenHandle.active ? styles.fullscreen : styles.root,\n )}\n >\n {allowFullscreen && (\n <Tooltip title={t('dependencyGraph.fullscreenTooltip')}>\n <IconButton\n className={styles.fullscreenButton}\n onClick={\n fullScreenHandle.active\n ? fullScreenHandle.exit\n : fullScreenHandle.enter\n }\n >\n {fullScreenHandle.active ? (\n <FullscreenExitIcon />\n ) : (\n <FullscreenIcon />\n )}\n </IconButton>\n </Tooltip>\n )}\n\n <div ref={containerRef} style={{ width: '100%', height: '100%' }}>\n <svg\n {...svgProps}\n width=\"100%\"\n height={scalableHeight}\n viewBox={`0 0 ${maxWidth} ${maxHeight}`}\n id={DEPENDENCY_GRAPH_SVG}\n >\n <defs>\n <marker\n id={ARROW_MARKER_ID}\n viewBox=\"0 0 24 24\"\n markerWidth=\"14\"\n markerHeight=\"14\"\n refX=\"16\"\n refY=\"12\"\n orient=\"auto\"\n markerUnits=\"strokeWidth\"\n >\n <path\n fill={theme.palette.textSubtle}\n d=\"M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z\"\n />\n </marker>\n {defs}\n </defs>\n <g id={WORKSPACE_ID}>\n <svg\n width={graphWidth}\n height={graphHeight}\n y={maxHeight / 2 - graphHeight / 2}\n x={maxWidth / 2 - graphWidth / 2}\n viewBox={`0 0 ${graphWidth} ${graphHeight}`}\n >\n {graphEdges.map(e => {\n const edge = graph.current.edge(e) as GraphEdge<EdgeData>;\n if (!edge) return null;\n if (renderEdge) return renderEdge({ edge, id: e });\n\n return (\n <Edge\n key={`${e.v}-${e.w}`}\n id={e}\n setEdge={setEdge}\n render={renderLabel}\n edge={edge}\n curve={curve}\n showArrowHeads={showArrowHeads}\n />\n );\n })}\n {graphNodes.map((id: string) => {\n const node = graph.current.node(id);\n if (!node) return null;\n return (\n <Node\n key={id}\n setNode={setNode}\n render={renderNode}\n node={node}\n />\n );\n })}\n </svg>\n </g>\n </svg>\n </div>\n </FullScreen>\n );\n}\n"],"names":["Types"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -236,6 +236,7 @@ interface CodeSnippetProps {
|
|
|
236
236
|
*/
|
|
237
237
|
customStyle?: any;
|
|
238
238
|
}
|
|
239
|
+
|
|
239
240
|
/**
|
|
240
241
|
* Thin wrapper on top of {@link https://react-syntax-highlighter.github.io/react-syntax-highlighter/ | react-syntax-highlighter}
|
|
241
242
|
* providing consistent theming and copy code button
|
|
@@ -713,6 +714,7 @@ interface DependencyGraphProps<NodeData, EdgeData> extends SVGProps<SVGSVGElemen
|
|
|
713
714
|
*/
|
|
714
715
|
allowFullscreen?: boolean;
|
|
715
716
|
}
|
|
717
|
+
|
|
716
718
|
/**
|
|
717
719
|
* Graph component used to visualize relations between entities
|
|
718
720
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SidebarSubmenuItem.esm.js","sources":["../../../src/layout/Sidebar/SidebarSubmenuItem.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useContext, useState } from 'react';\nimport { resolvePath, useLocation, useResolvedPath } from 'react-router-dom';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport { Link } from '../../components/Link';\nimport { IconComponent } from '@backstage/core-plugin-api';\nimport classnames from 'classnames';\nimport ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown';\nimport ArrowDropUpIcon from '@material-ui/icons/ArrowDropUp';\nimport { SidebarItemWithSubmenuContext } from './config';\nimport { isLocationMatch } from './utils';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\n\n/** @public */\nexport type SidebarSubmenuItemClassKey =\n | 'item'\n | 'itemContainer'\n | 'selected'\n | 'label'\n | 'subtitle'\n | 'dropdownArrow'\n | 'dropdown'\n | 'dropdownItem'\n | 'textContent';\n\nconst useStyles = makeStyles(\n theme => ({\n item: {\n height: 48,\n width: '100%',\n '&:hover': {\n background:\n theme.palette.navigation.navItem?.hoverBackground || '#6f6f6f',\n color: theme.palette.navigation.selectedColor,\n },\n display: 'flex',\n alignItems: 'center',\n color: theme.palette.navigation.color,\n padding: theme.spacing(2.5),\n cursor: 'pointer',\n position: 'relative',\n background: 'none',\n border: 'none',\n },\n itemContainer: {\n width: '100%',\n },\n selected: {\n background: '#6f6f6f',\n color: theme.palette.common.white,\n },\n label: {\n margin: theme.spacing(1.75),\n marginLeft: theme.spacing(1),\n fontSize: theme.typography.body2.fontSize,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n 'text-overflow': 'ellipsis',\n lineHeight: 1,\n },\n subtitle: {\n fontSize: 10,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n 'text-overflow': 'ellipsis',\n },\n dropdownArrow: {\n position: 'absolute',\n right: 21,\n },\n dropdown: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'end',\n },\n dropdownItem: {\n width: '100%',\n padding: '10px 0 10px 0',\n '&:hover': {\n background:\n theme.palette.navigation.navItem?.hoverBackground || '#6f6f6f',\n color: theme.palette.navigation.selectedColor,\n },\n },\n dropdownButton: {\n textTransform: 'none',\n justifyContent: 'flex-start',\n },\n textContent: {\n color: theme.palette.navigation.color,\n paddingLeft: theme.spacing(4),\n paddingRight: theme.spacing(1),\n fontSize: theme.typography.body2.fontSize,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n 'text-overflow': 'ellipsis',\n },\n }),\n { name: 'BackstageSidebarSubmenuItem' },\n);\n\n/**\n * Clickable item displayed when submenu item is clicked.\n * title: Text content of item\n * to: Path to navigate to when item is clicked\n *\n * @public\n */\nexport type SidebarSubmenuItemDropdownItem = {\n title: string;\n to: string;\n};\n/**\n * Holds submenu item content.\n *\n * @remarks\n * title: Text content of submenu item\n * subtitle: A subtitle displayed under the main title\n * to: Path to navigate to when item is clicked\n * icon: Icon displayed on the left of text content\n * dropdownItems: Optional array of dropdown items displayed when submenu item is clicked.\n *\n * @public\n */\nexport type SidebarSubmenuItemProps = {\n title: string;\n subtitle?: string;\n to?: string;\n icon?: IconComponent;\n dropdownItems?: SidebarSubmenuItemDropdownItem[];\n exact?: boolean;\n initialShowDropdown?: boolean;\n};\n\n/**\n * Item used inside a submenu within the sidebar.\n *\n * @public\n */\nexport const SidebarSubmenuItem = (props: SidebarSubmenuItemProps) => {\n const { title, subtitle, to, icon: Icon, dropdownItems, exact } = props;\n const classes = useStyles();\n const { setIsHoveredOn } = useContext(SidebarItemWithSubmenuContext);\n const closeSubmenu = () => {\n setIsHoveredOn(false);\n };\n const toLocation = useResolvedPath(to ?? '');\n const currentLocation = useLocation();\n let isActive = isLocationMatch(currentLocation, toLocation, exact);\n\n const [showDropDown, setShowDropDown] = useState(\n props.initialShowDropdown ?? false,\n );\n const handleClickDropdown = () => {\n setShowDropDown(!showDropDown);\n };\n if (dropdownItems !== undefined) {\n dropdownItems.some(item => {\n const resolvedPath = resolvePath(item.to);\n isActive = isLocationMatch(currentLocation, resolvedPath, exact);\n return isActive;\n });\n return (\n <Box className={classes.itemContainer}>\n <Tooltip title={title} enterDelay={500} enterNextDelay={500}>\n <Button\n role=\"button\"\n onClick={handleClickDropdown}\n onTouchStart={e => e.stopPropagation()}\n className={classnames(\n classes.item,\n classes.dropdownButton,\n isActive ? classes.selected : undefined,\n )}\n >\n {Icon && <Icon fontSize=\"small\" />}\n <Typography\n variant=\"subtitle1\"\n component=\"span\"\n className={classes.label}\n >\n {title}\n <br />\n {subtitle && (\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.subtitle}\n >\n {subtitle}\n </Typography>\n )}\n </Typography>\n {showDropDown ? (\n <ArrowDropUpIcon className={classes.dropdownArrow} />\n ) : (\n <ArrowDropDownIcon className={classes.dropdownArrow} />\n )}\n </Button>\n </Tooltip>\n {dropdownItems && showDropDown && (\n <Box className={classes.dropdown}>\n {dropdownItems.map((object, key) => (\n <Tooltip\n key={key}\n title={object.title}\n enterDelay={500}\n enterNextDelay={500}\n >\n <Link\n to={object.to}\n underline=\"none\"\n className={classes.dropdownItem}\n onClick={closeSubmenu}\n onTouchStart={e => e.stopPropagation()}\n >\n <Typography component=\"span\" className={classes.textContent}>\n {object.title}\n </Typography>\n </Link>\n </Tooltip>\n ))}\n </Box>\n )}\n </Box>\n );\n }\n\n return (\n <Box className={classes.itemContainer}>\n <Tooltip title={title} enterDelay={500} enterNextDelay={500}>\n <Link\n to={to!}\n underline=\"none\"\n className={classnames(\n classes.item,\n isActive ? classes.selected : undefined,\n )}\n onClick={closeSubmenu}\n onTouchStart={e => e.stopPropagation()}\n >\n {Icon && <Icon fontSize=\"small\" />}\n <Typography\n variant=\"subtitle1\"\n component=\"span\"\n className={classes.label}\n >\n {title}\n <br />\n {subtitle && (\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.subtitle}\n >\n {subtitle}\n </Typography>\n )}\n </Typography>\n </Link>\n </Tooltip>\n </Box>\n );\n};\n"],"names":["classnames"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SidebarSubmenuItem.esm.js","sources":["../../../src/layout/Sidebar/SidebarSubmenuItem.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useContext, useState } from 'react';\nimport { resolvePath, useLocation, useResolvedPath } from 'react-router-dom';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport { Link } from '../../components/Link';\nimport { IconComponent } from '@backstage/core-plugin-api';\nimport classnames from 'classnames';\nimport ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown';\nimport ArrowDropUpIcon from '@material-ui/icons/ArrowDropUp';\nimport { SidebarItemWithSubmenuContext } from './config';\nimport { isLocationMatch } from './utils';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\n\n/** @public */\nexport type SidebarSubmenuItemClassKey =\n | 'item'\n | 'itemContainer'\n | 'selected'\n | 'label'\n | 'subtitle'\n | 'dropdownArrow'\n | 'dropdown'\n | 'dropdownItem'\n | 'textContent';\n\nconst useStyles = makeStyles(\n theme => ({\n item: {\n height: 48,\n width: '100%',\n '&:hover': {\n background:\n theme.palette.navigation.navItem?.hoverBackground || '#6f6f6f',\n color: theme.palette.navigation.selectedColor,\n },\n display: 'flex',\n alignItems: 'center',\n color: theme.palette.navigation.color,\n padding: theme.spacing(2.5),\n cursor: 'pointer',\n position: 'relative',\n background: 'none',\n border: 'none',\n },\n itemContainer: {\n width: '100%',\n },\n selected: {\n background: '#6f6f6f',\n color: theme.palette.common.white,\n },\n label: {\n margin: theme.spacing(1.75),\n marginLeft: theme.spacing(1),\n fontSize: theme.typography.body2.fontSize,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n 'text-overflow': 'ellipsis',\n lineHeight: 1.5,\n },\n subtitle: {\n fontSize: 10,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n 'text-overflow': 'ellipsis',\n },\n dropdownArrow: {\n position: 'absolute',\n right: 21,\n },\n dropdown: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'end',\n },\n dropdownItem: {\n width: '100%',\n padding: '10px 0 10px 0',\n '&:hover': {\n background:\n theme.palette.navigation.navItem?.hoverBackground || '#6f6f6f',\n color: theme.palette.navigation.selectedColor,\n },\n },\n dropdownButton: {\n textTransform: 'none',\n justifyContent: 'flex-start',\n },\n textContent: {\n color: theme.palette.navigation.color,\n paddingLeft: theme.spacing(4),\n paddingRight: theme.spacing(1),\n fontSize: theme.typography.body2.fontSize,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n 'text-overflow': 'ellipsis',\n },\n }),\n { name: 'BackstageSidebarSubmenuItem' },\n);\n\n/**\n * Clickable item displayed when submenu item is clicked.\n * title: Text content of item\n * to: Path to navigate to when item is clicked\n *\n * @public\n */\nexport type SidebarSubmenuItemDropdownItem = {\n title: string;\n to: string;\n};\n/**\n * Holds submenu item content.\n *\n * @remarks\n * title: Text content of submenu item\n * subtitle: A subtitle displayed under the main title\n * to: Path to navigate to when item is clicked\n * icon: Icon displayed on the left of text content\n * dropdownItems: Optional array of dropdown items displayed when submenu item is clicked.\n *\n * @public\n */\nexport type SidebarSubmenuItemProps = {\n title: string;\n subtitle?: string;\n to?: string;\n icon?: IconComponent;\n dropdownItems?: SidebarSubmenuItemDropdownItem[];\n exact?: boolean;\n initialShowDropdown?: boolean;\n};\n\n/**\n * Item used inside a submenu within the sidebar.\n *\n * @public\n */\nexport const SidebarSubmenuItem = (props: SidebarSubmenuItemProps) => {\n const { title, subtitle, to, icon: Icon, dropdownItems, exact } = props;\n const classes = useStyles();\n const { setIsHoveredOn } = useContext(SidebarItemWithSubmenuContext);\n const closeSubmenu = () => {\n setIsHoveredOn(false);\n };\n const toLocation = useResolvedPath(to ?? '');\n const currentLocation = useLocation();\n let isActive = isLocationMatch(currentLocation, toLocation, exact);\n\n const [showDropDown, setShowDropDown] = useState(\n props.initialShowDropdown ?? false,\n );\n const handleClickDropdown = () => {\n setShowDropDown(!showDropDown);\n };\n if (dropdownItems !== undefined) {\n dropdownItems.some(item => {\n const resolvedPath = resolvePath(item.to);\n isActive = isLocationMatch(currentLocation, resolvedPath, exact);\n return isActive;\n });\n return (\n <Box className={classes.itemContainer}>\n <Tooltip title={title} enterDelay={500} enterNextDelay={500}>\n <Button\n role=\"button\"\n onClick={handleClickDropdown}\n onTouchStart={e => e.stopPropagation()}\n className={classnames(\n classes.item,\n classes.dropdownButton,\n isActive ? classes.selected : undefined,\n )}\n >\n {Icon && <Icon fontSize=\"small\" />}\n <Typography\n variant=\"subtitle1\"\n component=\"span\"\n className={classes.label}\n >\n {title}\n <br />\n {subtitle && (\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.subtitle}\n >\n {subtitle}\n </Typography>\n )}\n </Typography>\n {showDropDown ? (\n <ArrowDropUpIcon className={classes.dropdownArrow} />\n ) : (\n <ArrowDropDownIcon className={classes.dropdownArrow} />\n )}\n </Button>\n </Tooltip>\n {dropdownItems && showDropDown && (\n <Box className={classes.dropdown}>\n {dropdownItems.map((object, key) => (\n <Tooltip\n key={key}\n title={object.title}\n enterDelay={500}\n enterNextDelay={500}\n >\n <Link\n to={object.to}\n underline=\"none\"\n className={classes.dropdownItem}\n onClick={closeSubmenu}\n onTouchStart={e => e.stopPropagation()}\n >\n <Typography component=\"span\" className={classes.textContent}>\n {object.title}\n </Typography>\n </Link>\n </Tooltip>\n ))}\n </Box>\n )}\n </Box>\n );\n }\n\n return (\n <Box className={classes.itemContainer}>\n <Tooltip title={title} enterDelay={500} enterNextDelay={500}>\n <Link\n to={to!}\n underline=\"none\"\n className={classnames(\n classes.item,\n isActive ? classes.selected : undefined,\n )}\n onClick={closeSubmenu}\n onTouchStart={e => e.stopPropagation()}\n >\n {Icon && <Icon fontSize=\"small\" />}\n <Typography\n variant=\"subtitle1\"\n component=\"span\"\n className={classes.label}\n >\n {title}\n <br />\n {subtitle && (\n <Typography\n variant=\"caption\"\n component=\"span\"\n className={classes.subtitle}\n >\n {subtitle}\n </Typography>\n )}\n </Typography>\n </Link>\n </Tooltip>\n </Box>\n );\n};\n"],"names":["classnames"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/core-components",
|
|
3
|
-
"version": "0.18.11
|
|
3
|
+
"version": "0.18.11",
|
|
4
4
|
"description": "Core components used by Backstage plugins and apps",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "web-library"
|
|
@@ -66,11 +66,11 @@
|
|
|
66
66
|
"test": "backstage-cli package test"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@backstage/config": "1.3.8",
|
|
70
|
-
"@backstage/core-plugin-api": "1.12.7
|
|
71
|
-
"@backstage/errors": "1.3.1",
|
|
72
|
-
"@backstage/theme": "0.7.3",
|
|
73
|
-
"@backstage/version-bridge": "1.0.12",
|
|
69
|
+
"@backstage/config": "^1.3.8",
|
|
70
|
+
"@backstage/core-plugin-api": "^1.12.7",
|
|
71
|
+
"@backstage/errors": "^1.3.1",
|
|
72
|
+
"@backstage/theme": "^0.7.3",
|
|
73
|
+
"@backstage/version-bridge": "^1.0.12",
|
|
74
74
|
"@dagrejs/dagre": "^1.1.4",
|
|
75
75
|
"@date-io/core": "^1.3.13",
|
|
76
76
|
"@material-table/core": "^3.1.0",
|
|
@@ -110,10 +110,10 @@
|
|
|
110
110
|
"zod": "^3.25.76 || ^4.0.0"
|
|
111
111
|
},
|
|
112
112
|
"devDependencies": {
|
|
113
|
-
"@backstage/app-defaults": "1.7.9
|
|
114
|
-
"@backstage/cli": "0.36.3
|
|
115
|
-
"@backstage/core-app-api": "1.20.2
|
|
116
|
-
"@backstage/test-utils": "1.7.19
|
|
113
|
+
"@backstage/app-defaults": "^1.7.9",
|
|
114
|
+
"@backstage/cli": "^0.36.3",
|
|
115
|
+
"@backstage/core-app-api": "^1.20.2",
|
|
116
|
+
"@backstage/test-utils": "^1.7.19",
|
|
117
117
|
"@testing-library/dom": "^10.0.0",
|
|
118
118
|
"@testing-library/jest-dom": "^6.0.0",
|
|
119
119
|
"@testing-library/user-event": "^14.0.0",
|