@teambit/graph 0.0.752 → 0.0.753
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/graph.compare.section.d.ts +13 -0
- package/dist/graph.compare.section.js +57 -0
- package/dist/graph.compare.section.js.map +1 -0
- package/dist/graph.ui.runtime.d.ts +2 -1
- package/dist/graph.ui.runtime.js +28 -2
- package/dist/graph.ui.runtime.js.map +1 -1
- package/dist/index.d.ts +12 -7
- package/dist/index.js +149 -9
- package/dist/index.js.map +1 -1
- package/dist/ui/component-node/component-node.js +27 -1
- package/dist/ui/component-node/component-node.js.map +1 -1
- package/dist/ui/component-node/component-node.module.scss +8 -0
- package/dist/ui/component-node/index.d.ts +12 -1
- package/dist/ui/component-node/index.js +56 -0
- package/dist/ui/component-node/index.js.map +1 -1
- package/dist/ui/component-node/variants.d.ts +2 -2
- package/dist/ui/component-node/variants.js +3 -1
- package/dist/ui/component-node/variants.js.map +1 -1
- package/dist/ui/dependencies-compare/compare-graph-model.d.ts +7 -0
- package/dist/ui/dependencies-compare/compare-graph-model.js +29 -0
- package/dist/ui/dependencies-compare/compare-graph-model.js.map +1 -0
- package/dist/ui/dependencies-compare/compare-node-model.d.ts +9 -0
- package/dist/ui/dependencies-compare/compare-node-model.js +45 -0
- package/dist/ui/dependencies-compare/compare-node-model.js.map +1 -0
- package/dist/ui/dependencies-compare/dependencies-compare.d.ts +2 -0
- package/dist/ui/dependencies-compare/dependencies-compare.js +205 -0
- package/dist/ui/dependencies-compare/dependencies-compare.js.map +1 -0
- package/dist/ui/dependencies-compare/dependencies-compare.module.scss +12 -0
- package/dist/ui/dependencies-compare/dependency-compare-node.d.ts +7 -0
- package/dist/ui/dependencies-compare/dependency-compare-node.js +271 -0
- package/dist/ui/dependencies-compare/dependency-compare-node.js.map +1 -0
- package/dist/ui/dependencies-compare/dependency-compare-node.module.scss +21 -0
- package/dist/ui/dependencies-compare/dependency-compare-variants.module.scss +21 -0
- package/dist/ui/dependencies-compare/diff-graph.d.ts +4 -0
- package/dist/ui/dependencies-compare/diff-graph.js +96 -0
- package/dist/ui/dependencies-compare/diff-graph.js.map +1 -0
- package/dist/ui/dependencies-compare/index.d.ts +1 -0
- package/dist/ui/dependencies-compare/index.js +23 -0
- package/dist/ui/dependencies-compare/index.js.map +1 -0
- package/dist/ui/dependencies-graph/calc-elements.d.ts +3 -3
- package/dist/ui/dependencies-graph/calc-elements.js.map +1 -1
- package/dist/ui/dependencies-graph/calc-layout.d.ts +2 -2
- package/dist/ui/dependencies-graph/calc-layout.js.map +1 -1
- package/dist/ui/dependencies-graph/dependencies-graph.d.ts +2 -2
- package/dist/ui/dependencies-graph/dependencies-graph.js.map +1 -1
- package/dist/ui/dependencies-graph/index.d.ts +9 -0
- package/dist/ui/dependencies-graph/index.js +96 -0
- package/dist/ui/dependencies-graph/index.js.map +1 -1
- package/dist/ui/graph-page/index.d.ts +5 -0
- package/dist/ui/graph-page/index.js +40 -0
- package/dist/ui/graph-page/index.js.map +1 -1
- package/dist/ui/query/graph-model.d.ts +5 -5
- package/dist/ui/query/graph-model.js.map +1 -1
- package/dist/ui/query/index.d.ts +1 -0
- package/dist/ui/query/index.js +16 -0
- package/dist/ui/query/index.js.map +1 -1
- package/dist/ui/query/use-graph-query.d.ts +2 -2
- package/dist/ui/query/use-graph-query.js +2 -1
- package/dist/ui/query/use-graph-query.js.map +1 -1
- package/dist/ui/query/use-graph.d.ts +1 -1
- package/graph.compare.section.tsx +16 -0
- package/graph.ui.runtime.tsx +14 -4
- package/package-tar/teambit-graph-0.0.753.tgz +0 -0
- package/package.json +15 -8
- package/{preview-1654399579544.js → preview-1654572446572.js} +2 -2
- package/ui/component-node/component-node.module.scss +8 -0
- package/ui/component-node/component-node.tsx +5 -1
- package/ui/component-node/index.ts +6 -1
- package/ui/component-node/variants.ts +2 -2
- package/ui/dependencies-compare/compare-graph-model.ts +8 -0
- package/ui/dependencies-compare/compare-node-model.ts +11 -0
- package/ui/dependencies-compare/dependencies-compare.module.scss +12 -0
- package/ui/dependencies-compare/dependencies-compare.tsx +109 -0
- package/ui/dependencies-compare/dependency-compare-node.module.scss +21 -0
- package/ui/dependencies-compare/dependency-compare-node.tsx +99 -0
- package/ui/dependencies-compare/dependency-compare-variants.module.scss +21 -0
- package/ui/dependencies-compare/diff-graph.ts +69 -0
- package/ui/dependencies-compare/index.ts +1 -0
- package/ui/dependencies-graph/calc-elements.tsx +3 -3
- package/ui/dependencies-graph/calc-layout.tsx +2 -2
- package/ui/dependencies-graph/dependencies-graph.tsx +8 -8
- package/ui/dependencies-graph/index.ts +9 -0
- package/ui/graph-page/index.ts +6 -0
- package/ui/query/graph-model.ts +3 -2
- package/ui/query/index.ts +1 -0
- package/ui/query/use-graph-query.ts +3 -2
- package/package-tar/teambit-graph-0.0.752.tgz +0 -0
package/graph.ui.runtime.tsx
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
import { ComponentType } from 'react';
|
2
2
|
import { UIRuntime } from '@teambit/ui';
|
3
3
|
import { Slot, SlotRegistry } from '@teambit/harmony';
|
4
|
-
|
4
|
+
import { ComponentCompareUI, ComponentCompareAspect } from '@teambit/component-compare';
|
5
5
|
import { ComponentAspect, ComponentUI, ComponentModel } from '@teambit/component';
|
6
6
|
import { GraphAspect } from './graph.aspect';
|
7
7
|
import { GraphSection } from './ui/graph.section';
|
8
|
+
import { GraphCompareSection } from './graph.compare.section';
|
8
9
|
|
9
10
|
export interface ComponentWidgetProps extends React.HTMLAttributes<HTMLDivElement> {
|
10
11
|
component: ComponentModel;
|
@@ -25,15 +26,24 @@ export class GraphUI {
|
|
25
26
|
}
|
26
27
|
|
27
28
|
constructor(private componentWidgetSlot: ComponentWidgetSlot) {}
|
28
|
-
static dependencies = [ComponentAspect];
|
29
|
+
static dependencies = [ComponentAspect, ComponentCompareAspect];
|
29
30
|
static runtime = UIRuntime;
|
30
31
|
static slots = [Slot.withType<ComponentWidget>()];
|
31
|
-
static async provider(
|
32
|
+
static async provider(
|
33
|
+
[componentUI, componentCompare]: [ComponentUI, ComponentCompareUI],
|
34
|
+
config,
|
35
|
+
[componentWidgetSlot]: [ComponentWidgetSlot]
|
36
|
+
) {
|
32
37
|
const graphUI = new GraphUI(componentWidgetSlot);
|
33
38
|
const section = new GraphSection(componentWidgetSlot);
|
39
|
+
const graphSection = new GraphCompareSection();
|
34
40
|
componentUI.registerNavigation(section.navigationLink, section.order);
|
35
41
|
componentUI.registerRoute(section.route);
|
36
|
-
|
42
|
+
componentCompare.registerNavigation({
|
43
|
+
props: graphSection.navigationLink,
|
44
|
+
order: graphSection.navigationLink.order,
|
45
|
+
});
|
46
|
+
componentCompare.registerRoutes([graphSection.route]);
|
37
47
|
return graphUI;
|
38
48
|
}
|
39
49
|
}
|
Binary file
|
package/package.json
CHANGED
@@ -1,35 +1,41 @@
|
|
1
1
|
{
|
2
2
|
"name": "@teambit/graph",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.753",
|
4
4
|
"homepage": "https://bit.dev/teambit/component/graph",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"componentId": {
|
7
7
|
"scope": "teambit.component",
|
8
8
|
"name": "graph",
|
9
|
-
"version": "0.0.
|
9
|
+
"version": "0.0.753"
|
10
10
|
},
|
11
11
|
"dependencies": {
|
12
12
|
"graphql-tag": "2.12.1",
|
13
13
|
"lodash": "4.17.21",
|
14
14
|
"classnames": "2.2.6",
|
15
15
|
"react-flow-renderer": "8.3.7",
|
16
|
+
"semver": "7.3.4",
|
16
17
|
"dagre": "0.8.5",
|
17
18
|
"@babel/runtime": "7.12.18",
|
18
19
|
"core-js": "^3.0.0",
|
19
20
|
"@teambit/graph.cleargraph": "0.0.1",
|
20
21
|
"@teambit/harmony": "0.3.3",
|
22
|
+
"@teambit/base-ui.routing.nav-link": "1.0.0",
|
21
23
|
"@teambit/base-ui.surfaces.card": "1.0.1",
|
22
24
|
"@teambit/base-ui.text.muted-text": "1.0.1",
|
23
25
|
"@teambit/evangelist.input.checkbox.label": "1.0.3",
|
24
26
|
"@teambit/documenter.ui.heading": "4.1.1",
|
25
|
-
"@teambit/component": "0.0.
|
26
|
-
"@teambit/graphql": "0.0.
|
27
|
-
"@teambit/cli": "0.0.
|
28
|
-
"@teambit/
|
27
|
+
"@teambit/component": "0.0.753",
|
28
|
+
"@teambit/graphql": "0.0.753",
|
29
|
+
"@teambit/cli": "0.0.497",
|
30
|
+
"@teambit/component-compare": "0.0.1",
|
31
|
+
"@teambit/ui": "0.0.753",
|
29
32
|
"@teambit/legacy-bit-id": "0.0.399",
|
33
|
+
"@teambit/component.modules.component-url": "0.0.124",
|
30
34
|
"@teambit/component.ui.deprecation-icon": "0.0.493",
|
31
35
|
"@teambit/design.ui.styles.ellipsis": "0.0.347",
|
32
36
|
"@teambit/envs.ui.env-icon": "0.0.486",
|
37
|
+
"@teambit/component.ui.compare": "0.0.1",
|
38
|
+
"@teambit/design.ui.round-loader": "0.0.346",
|
33
39
|
"@teambit/design.ui.pages.not-found": "0.0.355",
|
34
40
|
"@teambit/design.ui.pages.server-error": "0.0.355",
|
35
41
|
"@teambit/ui-foundation.ui.full-loader": "0.0.486",
|
@@ -40,6 +46,7 @@
|
|
40
46
|
"@types/react": "^17.0.8",
|
41
47
|
"@types/lodash": "4.14.165",
|
42
48
|
"@types/classnames": "2.2.11",
|
49
|
+
"@types/semver": "7.3.4",
|
43
50
|
"@types/dagre": "0.7.44",
|
44
51
|
"@types/mocha": "9.1.0",
|
45
52
|
"@types/testing-library__jest-dom": "5.9.5",
|
@@ -49,7 +56,7 @@
|
|
49
56
|
},
|
50
57
|
"peerDependencies": {
|
51
58
|
"@apollo/client": "^3.0.0",
|
52
|
-
"@teambit/legacy": "1.0.
|
59
|
+
"@teambit/legacy": "1.0.277",
|
53
60
|
"react-dom": "^16.8.0 || ^17.0.0",
|
54
61
|
"react": "^16.8.0 || ^17.0.0"
|
55
62
|
},
|
@@ -77,7 +84,7 @@
|
|
77
84
|
"react": "-"
|
78
85
|
},
|
79
86
|
"peerDependencies": {
|
80
|
-
"@teambit/legacy": "1.0.
|
87
|
+
"@teambit/legacy": "1.0.277",
|
81
88
|
"react-dom": "^16.8.0 || ^17.0.0",
|
82
89
|
"react": "^16.8.0 || ^17.0.0"
|
83
90
|
}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
export const compositions = [require('/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.component_graph@0.0.
|
2
|
-
export const overview = [require('/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.component_graph@0.0.
|
1
|
+
export const compositions = [require('/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.component_graph@0.0.753/dist/graph.composition.js')]
|
2
|
+
export const overview = [require('/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.component_graph@0.0.753/dist/graph.docs.md')]
|
@@ -6,6 +6,8 @@ import { DeprecationIcon } from '@teambit/component.ui.deprecation-icon';
|
|
6
6
|
import { EnvIcon } from '@teambit/envs.ui.env-icon';
|
7
7
|
import { ellipsis } from '@teambit/design.ui.styles.ellipsis';
|
8
8
|
import { Card, CardProps } from '@teambit/base-ui.surfaces.card';
|
9
|
+
import { NavLink } from '@teambit/base-ui.routing.nav-link';
|
10
|
+
import { ComponentUrl } from '@teambit/component.modules.component-url';
|
9
11
|
import { NodeModel } from '../query/node-model';
|
10
12
|
import { ComponentGraphContext } from '../dependencies-graph/';
|
11
13
|
|
@@ -30,7 +32,9 @@ export function ComponentNode({ node, type = 'defaultNode', ...rest }: Component
|
|
30
32
|
<Breadcrumbs componentId={id} className={mutedText} />
|
31
33
|
</div>
|
32
34
|
<div className={styles.nameLine}>
|
33
|
-
<
|
35
|
+
<NavLink className={styles.link} external={true} href={ComponentUrl.toUrl(id, { includeVersion: false })}>
|
36
|
+
<span className={classnames(styles.name, ellipsis)}>{id.name}</span>
|
37
|
+
</NavLink>
|
34
38
|
{id.version && <span className={classnames(styles.version, ellipsis)}>{id.version}</span>}
|
35
39
|
|
36
40
|
<div className={styles.buffs}>
|
@@ -1,3 +1,8 @@
|
|
1
|
+
import componentStyles from './component-node.module.scss';
|
2
|
+
|
1
3
|
export { ComponentNode } from './component-node';
|
2
4
|
|
3
|
-
export { defaultNodeColor, rootNodeColor, externalNodeColor } from './variants';
|
5
|
+
export { defaultNodeColor, rootNodeColor, externalNodeColor, root, defaultNode, external } from './variants';
|
6
|
+
|
7
|
+
const { compNode, firstRow, envIcon, breadcrumbs, nameLine, name, version, buffs, link } = componentStyles;
|
8
|
+
export const styles = { compNode, firstRow, envIcon, breadcrumbs, nameLine, name, version, buffs, link };
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import variants from './variants.module.scss';
|
2
2
|
|
3
|
-
const { root, defaultNode, rootNodeColor, defaultNodeColor, externalNodeColor } = variants;
|
3
|
+
const { root, defaultNode, external, rootNodeColor, defaultNodeColor, externalNodeColor } = variants;
|
4
4
|
|
5
|
-
export { root, defaultNode, rootNodeColor, defaultNodeColor, externalNodeColor };
|
5
|
+
export { root, defaultNode, external, rootNodeColor, defaultNodeColor, externalNodeColor };
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { EdgeModel, GraphModel } from '@teambit/graph';
|
2
|
+
import { CompareNodeModel } from './compare-node-model';
|
3
|
+
|
4
|
+
export class CompareGraphModel extends GraphModel<CompareNodeModel, EdgeModel> {
|
5
|
+
constructor(public nodes: CompareNodeModel[], public edges: EdgeModel[]) {
|
6
|
+
super(nodes, edges);
|
7
|
+
}
|
8
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { ComponentModel } from '@teambit/component';
|
2
|
+
import { NodeModel } from '@teambit/graph';
|
3
|
+
|
4
|
+
export type CompareStatus = 'modified' | 'new' | 'deleted' | undefined;
|
5
|
+
|
6
|
+
export class CompareNodeModel extends NodeModel {
|
7
|
+
id: string;
|
8
|
+
component: ComponentModel;
|
9
|
+
compareVersion: string;
|
10
|
+
status: CompareStatus;
|
11
|
+
}
|
@@ -0,0 +1,109 @@
|
|
1
|
+
import classNames from 'classnames';
|
2
|
+
import { useComponentCompare } from '@teambit/component.ui.compare';
|
3
|
+
import { RoundLoader } from '@teambit/design.ui.round-loader';
|
4
|
+
import {
|
5
|
+
calcElements,
|
6
|
+
calcMinimapColors,
|
7
|
+
dependenciesGraphStyles,
|
8
|
+
GraphFilter,
|
9
|
+
GraphFilters,
|
10
|
+
graphPageStyles,
|
11
|
+
useGraphQuery,
|
12
|
+
} from '@teambit/graph';
|
13
|
+
import React, { useEffect, useRef, useState } from 'react';
|
14
|
+
import ReactFlow, {
|
15
|
+
Background,
|
16
|
+
Controls,
|
17
|
+
Handle,
|
18
|
+
MiniMap,
|
19
|
+
NodeProps,
|
20
|
+
NodeTypesType,
|
21
|
+
OnLoadParams,
|
22
|
+
Position,
|
23
|
+
ReactFlowProvider,
|
24
|
+
} from 'react-flow-renderer';
|
25
|
+
import styles from './dependencies-compare.module.scss';
|
26
|
+
import { DependencyCompareNode } from './dependency-compare-node';
|
27
|
+
import { diffGraph } from './diff-graph';
|
28
|
+
|
29
|
+
function ComponentNodeContainer(props: NodeProps) {
|
30
|
+
const { sourcePosition = Position.Top, targetPosition = Position.Bottom, data, id } = props;
|
31
|
+
|
32
|
+
return (
|
33
|
+
<div key={id}>
|
34
|
+
<Handle type="target" position={targetPosition} isConnectable={false} />
|
35
|
+
<Handle type="source" position={sourcePosition} isConnectable={false} />
|
36
|
+
<DependencyCompareNode node={data.node} type={data.type} />
|
37
|
+
</div>
|
38
|
+
);
|
39
|
+
}
|
40
|
+
|
41
|
+
const NodeTypes: NodeTypesType = { ComponentNode: ComponentNodeContainer };
|
42
|
+
|
43
|
+
export function DependenciesCompare() {
|
44
|
+
const graphRef = useRef<OnLoadParams>();
|
45
|
+
const componentCompare = useComponentCompare();
|
46
|
+
|
47
|
+
const baseId = componentCompare?.base?.id;
|
48
|
+
const compareId = componentCompare?.compare?.id;
|
49
|
+
|
50
|
+
const [filter, setFilter] = useState<GraphFilter>('runtimeOnly');
|
51
|
+
const isFiltered = filter === 'runtimeOnly';
|
52
|
+
const { loading: baseLoading, graph: baseGraph } = useGraphQuery(baseId && [baseId.toString()], filter);
|
53
|
+
const { loading: compareLoading, graph: compareGraph } = useGraphQuery(compareId && [compareId.toString()], filter);
|
54
|
+
const loading = baseLoading || compareLoading;
|
55
|
+
const graph = diffGraph(baseGraph, compareGraph, baseId) ?? undefined;
|
56
|
+
const elements = calcElements(graph, { rootNode: baseId });
|
57
|
+
|
58
|
+
useEffect(() => {
|
59
|
+
graphRef.current?.fitView();
|
60
|
+
}, [elements]);
|
61
|
+
|
62
|
+
function handleLoad(instance: OnLoadParams) {
|
63
|
+
graphRef.current = instance;
|
64
|
+
graphRef.current?.fitView();
|
65
|
+
}
|
66
|
+
|
67
|
+
const onCheckFilter = (_isFiltered: boolean) => {
|
68
|
+
setFilter(_isFiltered ? 'runtimeOnly' : undefined);
|
69
|
+
};
|
70
|
+
|
71
|
+
if (!loading && (!baseGraph || !compareGraph)) {
|
72
|
+
return <></>;
|
73
|
+
}
|
74
|
+
|
75
|
+
return (
|
76
|
+
<div className={classNames([styles.page, graphPageStyles.graph])}>
|
77
|
+
{loading && (
|
78
|
+
<div className={styles.loader}>
|
79
|
+
<RoundLoader />
|
80
|
+
</div>
|
81
|
+
)}
|
82
|
+
<ReactFlowProvider>
|
83
|
+
<ReactFlow
|
84
|
+
draggable={false}
|
85
|
+
nodesDraggable={true}
|
86
|
+
selectNodesOnDrag={false}
|
87
|
+
nodesConnectable={false}
|
88
|
+
zoomOnDoubleClick={false}
|
89
|
+
elementsSelectable={false}
|
90
|
+
maxZoom={1}
|
91
|
+
className={dependenciesGraphStyles.graph}
|
92
|
+
elements={elements}
|
93
|
+
nodeTypes={NodeTypes}
|
94
|
+
onLoad={handleLoad}
|
95
|
+
>
|
96
|
+
<Background />
|
97
|
+
<Controls className={dependenciesGraphStyles.controls} />
|
98
|
+
<MiniMap nodeColor={calcMinimapColors} className={dependenciesGraphStyles.minimap} />
|
99
|
+
<GraphFilters
|
100
|
+
className={graphPageStyles.filters}
|
101
|
+
disable={loading}
|
102
|
+
isFiltered={isFiltered}
|
103
|
+
onChangeFilter={onCheckFilter}
|
104
|
+
/>
|
105
|
+
</ReactFlow>
|
106
|
+
</ReactFlowProvider>
|
107
|
+
</div>
|
108
|
+
);
|
109
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
.arrowIcon {
|
2
|
+
height: 16px;
|
3
|
+
padding-right: 8px;
|
4
|
+
}
|
5
|
+
|
6
|
+
.versionUp {
|
7
|
+
color: var(--positive-color, #37b26c);
|
8
|
+
}
|
9
|
+
|
10
|
+
.versionDown {
|
11
|
+
color: var(--negative-color, #e62e5c);
|
12
|
+
}
|
13
|
+
|
14
|
+
.link {
|
15
|
+
text-decoration: none;
|
16
|
+
color: var(--bit-text-color-heavyed);
|
17
|
+
|
18
|
+
&:hover {
|
19
|
+
text-decoration: underline;
|
20
|
+
}
|
21
|
+
}
|
@@ -0,0 +1,99 @@
|
|
1
|
+
import { NavLink } from '@teambit/base-ui.routing.nav-link';
|
2
|
+
import { Card } from '@teambit/base-ui.surfaces.card';
|
3
|
+
import { mutedText } from '@teambit/base-ui.text.muted-text';
|
4
|
+
import { ComponentID } from '@teambit/component';
|
5
|
+
import { ComponentUrl } from '@teambit/component.modules.component-url';
|
6
|
+
import { CompareStatusResolver } from '@teambit/component.ui.compare';
|
7
|
+
import { DeprecationIcon } from '@teambit/component.ui.deprecation-icon';
|
8
|
+
import { ellipsis } from '@teambit/design.ui.styles.ellipsis';
|
9
|
+
import { EnvIcon } from '@teambit/envs.ui.env-icon';
|
10
|
+
import { componentNodeStyles, defaultNode, external } from '@teambit/graph';
|
11
|
+
import classnames from 'classnames';
|
12
|
+
import React, { useMemo } from 'react';
|
13
|
+
import { compare, valid } from 'semver';
|
14
|
+
import { CompareNodeModel } from './compare-node-model';
|
15
|
+
import styles from './dependency-compare-node.module.scss';
|
16
|
+
import variants from './dependency-compare-variants.module.scss';
|
17
|
+
|
18
|
+
function getVariant(nodeType?: string) {
|
19
|
+
switch (nodeType) {
|
20
|
+
case 'defaultNode':
|
21
|
+
return defaultNode;
|
22
|
+
case 'root':
|
23
|
+
return variants[nodeType];
|
24
|
+
case 'external':
|
25
|
+
return external;
|
26
|
+
default:
|
27
|
+
return null;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
export type DependencyCompareNodeProps = {
|
32
|
+
node: CompareNodeModel;
|
33
|
+
type?: string;
|
34
|
+
};
|
35
|
+
|
36
|
+
export function DependencyCompareNode(props: DependencyCompareNodeProps) {
|
37
|
+
const { node, type = 'defaultNode' } = props;
|
38
|
+
const { id: baseIdStr, component: baseComponent, compareVersion, status } = node;
|
39
|
+
const { version: baseVersion } = baseComponent;
|
40
|
+
const baseId = ComponentID.fromString(baseIdStr);
|
41
|
+
const versionDiff = useMemo(
|
42
|
+
() => valid(baseVersion) && valid(compareVersion) && compare(baseVersion, compareVersion),
|
43
|
+
[baseVersion, compareVersion]
|
44
|
+
);
|
45
|
+
|
46
|
+
return (
|
47
|
+
<Card className={classnames(componentNodeStyles.compNode, getVariant(type))} elevation="none">
|
48
|
+
<div className={componentNodeStyles.firstRow}>
|
49
|
+
<EnvIcon component={baseComponent} className={componentNodeStyles.envIcon} />
|
50
|
+
<Breadcrumbs componentId={baseId} className={mutedText} />
|
51
|
+
</div>
|
52
|
+
<div className={componentNodeStyles.nameLine}>
|
53
|
+
<NavLink className={styles.link} external={true} href={ComponentUrl.toUrl(baseId, { includeVersion: false })}>
|
54
|
+
<span className={classnames(componentNodeStyles.name, ellipsis)}>{baseId.name}</span>
|
55
|
+
</NavLink>
|
56
|
+
{baseId.version && <span className={classnames(componentNodeStyles.version, ellipsis)}>{baseId.version}</span>}
|
57
|
+
{versionDiff !== 0 && (
|
58
|
+
<img
|
59
|
+
className={classnames([styles.arrowIcon, styles.versionUp])}
|
60
|
+
src="https://static.bit.dev/bit-icons/version-bump.svg"
|
61
|
+
/>
|
62
|
+
)}
|
63
|
+
{compareVersion && versionDiff !== 0 && (
|
64
|
+
<span
|
65
|
+
className={classnames(
|
66
|
+
styles.version,
|
67
|
+
componentNodeStyles.version,
|
68
|
+
ellipsis,
|
69
|
+
versionDiff === -1 && styles.versionUp,
|
70
|
+
versionDiff === 1 && styles.versionDown
|
71
|
+
)}
|
72
|
+
>
|
73
|
+
{compareVersion}
|
74
|
+
</span>
|
75
|
+
)}
|
76
|
+
|
77
|
+
<div className={styles.buffs}>
|
78
|
+
<DeprecationIcon component={baseComponent} />
|
79
|
+
{status !== undefined && <CompareStatusResolver status={status} />}
|
80
|
+
</div>
|
81
|
+
</div>
|
82
|
+
</Card>
|
83
|
+
);
|
84
|
+
}
|
85
|
+
|
86
|
+
type BreadcrumbsProps = { componentId: ComponentID } & React.HTMLAttributes<HTMLDivElement>;
|
87
|
+
|
88
|
+
function Breadcrumbs({ componentId, className, ...rest }: BreadcrumbsProps) {
|
89
|
+
const { scope, namespace } = componentId;
|
90
|
+
const showSep = !!scope && !!namespace;
|
91
|
+
|
92
|
+
return (
|
93
|
+
<div {...rest} className={classnames(styles.breadcrumbs, ellipsis, className)}>
|
94
|
+
{scope}
|
95
|
+
{showSep && '/'}
|
96
|
+
{namespace}
|
97
|
+
</div>
|
98
|
+
);
|
99
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$success: #37b26c;
|
2
|
+
$borderLabelHeight: 20px;
|
3
|
+
|
4
|
+
.root {
|
5
|
+
border-color: $success;
|
6
|
+
border-top-width: 20px;
|
7
|
+
|
8
|
+
border-radius: 10px;
|
9
|
+
box-shadow: 0px 0px 0px 2px #d0f1de, var(--bit-shadow-hover-medium);
|
10
|
+
|
11
|
+
&:before {
|
12
|
+
content: 'Current component';
|
13
|
+
position: absolute;
|
14
|
+
top: 1px;
|
15
|
+
left: 10px;
|
16
|
+
|
17
|
+
font-size: $borderLabelHeight * 0.5;
|
18
|
+
color: white;
|
19
|
+
line-height: $borderLabelHeight;
|
20
|
+
}
|
21
|
+
}
|
@@ -0,0 +1,69 @@
|
|
1
|
+
import { ComponentID } from '@teambit/component';
|
2
|
+
import { EdgeModel, GraphModel, NodeModel } from '@teambit/graph';
|
3
|
+
import { CompareGraphModel } from './compare-graph-model';
|
4
|
+
import { CompareNodeModel } from './compare-node-model';
|
5
|
+
|
6
|
+
const toShortId = (node: NodeModel) => node.component.id.toStringWithoutVersion();
|
7
|
+
|
8
|
+
// this is to get a key with versions ignored so that we'll have a unique set of component nodes
|
9
|
+
const toShortIdFromNodeId = (nodeId: string) => nodeId.split('@')[0];
|
10
|
+
|
11
|
+
const delim = '::';
|
12
|
+
|
13
|
+
const getEdgeId = (_e: EdgeModel) => {
|
14
|
+
return `${toShortIdFromNodeId(_e.sourceId)}${delim}${toShortIdFromNodeId(_e.targetId)}`;
|
15
|
+
};
|
16
|
+
|
17
|
+
export function diffGraph(
|
18
|
+
baseGraph?: GraphModel<NodeModel, EdgeModel>,
|
19
|
+
compareGraph?: GraphModel<NodeModel, EdgeModel>,
|
20
|
+
baseId?: ComponentID
|
21
|
+
) {
|
22
|
+
if (!baseGraph || !compareGraph || !baseId) return null;
|
23
|
+
|
24
|
+
const baseNodes = baseGraph.nodes;
|
25
|
+
const compareNodes = compareGraph.nodes;
|
26
|
+
|
27
|
+
const baseNodesMap = new Map<string, NodeModel>(baseNodes.map((n) => [toShortId(n), n]));
|
28
|
+
const compareNodesMap = new Map<string, NodeModel>(compareNodes.map((n) => [toShortId(n), n]));
|
29
|
+
|
30
|
+
const allNodes: Array<CompareNodeModel> = [];
|
31
|
+
for (const baseNode of baseNodes) {
|
32
|
+
const compareNode = compareNodesMap.get(toShortId(baseNode));
|
33
|
+
if (compareNode) {
|
34
|
+
allNodes.push({
|
35
|
+
...baseNode,
|
36
|
+
compareVersion: compareNode.component.version,
|
37
|
+
status: compareNode.component.id.isEqual(baseNode.component.id) ? undefined : 'modified',
|
38
|
+
});
|
39
|
+
} else {
|
40
|
+
allNodes.push({
|
41
|
+
...baseNode,
|
42
|
+
compareVersion: baseNode.component.version,
|
43
|
+
status: 'deleted',
|
44
|
+
});
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
const newNodes = compareNodes.filter((n) => !baseNodesMap.has(toShortId(n)));
|
49
|
+
|
50
|
+
for (const node of newNodes) {
|
51
|
+
allNodes.push({
|
52
|
+
...node,
|
53
|
+
compareVersion: '',
|
54
|
+
status: 'new',
|
55
|
+
});
|
56
|
+
}
|
57
|
+
const allNodesMap = new Map<string, CompareNodeModel>(allNodes.map((n) => [toShortId(n), n]));
|
58
|
+
|
59
|
+
const baseEdgesMap = new Map<string, EdgeModel>(baseGraph.edges.map((baseEdge) => [getEdgeId(baseEdge), baseEdge]));
|
60
|
+
const edgesOnlyInCompare = compareGraph.edges
|
61
|
+
.filter((compareEdge) => !baseEdgesMap.has(getEdgeId(compareEdge)))
|
62
|
+
.map((compareEdge) => ({
|
63
|
+
...compareEdge,
|
64
|
+
sourceId: allNodesMap.get(toShortIdFromNodeId(compareEdge.sourceId))?.id.toString() || baseId.toString(),
|
65
|
+
targetId: allNodesMap.get(toShortIdFromNodeId(compareEdge.targetId))?.id.toString() || baseId.toString(),
|
66
|
+
}));
|
67
|
+
const allEdges = [...baseGraph.edges, ...edgesOnlyInCompare];
|
68
|
+
return new CompareGraphModel(allNodes, allEdges);
|
69
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export { DependenciesCompare } from './dependencies-compare';
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { useMemo } from 'react';
|
2
|
-
import {
|
2
|
+
import { ArrowHeadType, Edge, Node } from 'react-flow-renderer';
|
3
3
|
import { ComponentID } from '@teambit/component';
|
4
4
|
import { calcLayout } from './calc-layout';
|
5
|
-
import { GraphModel } from '../query';
|
5
|
+
import { EdgeModel, GraphModel, NodeModel } from '../query';
|
6
6
|
|
7
7
|
import { depTypeToClass, depTypeToLabel } from './dep-edge';
|
8
8
|
|
@@ -13,7 +13,7 @@ type ElementsOptions = {
|
|
13
13
|
/**
|
14
14
|
* generate Nodes and Edges for the ReactFlowRenderer graph renderer
|
15
15
|
*/
|
16
|
-
export function calcElements(graph: GraphModel | undefined, { rootNode }: ElementsOptions) {
|
16
|
+
export function calcElements(graph: GraphModel<NodeModel, EdgeModel> | undefined, { rootNode }: ElementsOptions) {
|
17
17
|
return useMemo(() => {
|
18
18
|
if (!graph) return [];
|
19
19
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import dagre, { graphlib } from 'dagre';
|
2
|
-
import { GraphModel } from '../query';
|
2
|
+
import { EdgeModel, GraphModel, NodeModel } from '../query';
|
3
3
|
|
4
4
|
const NODE_WIDTH = 260;
|
5
5
|
const NODE_HEIGHT = 90;
|
@@ -9,7 +9,7 @@ const BOTTOM_TO_TOP = 'BT';
|
|
9
9
|
/**
|
10
10
|
* calculate the specific location of each node in the graph
|
11
11
|
*/
|
12
|
-
export function calcLayout(graph: GraphModel) {
|
12
|
+
export function calcLayout(graph: GraphModel<NodeModel, EdgeModel>) {
|
13
13
|
const g = new graphlib.Graph();
|
14
14
|
g.setGraph({ rankdir: BOTTOM_TO_TOP });
|
15
15
|
g.setDefaultEdgeLabel(() => ({}));
|
@@ -1,22 +1,22 @@
|
|
1
|
-
import React, {
|
1
|
+
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
2
2
|
import classnames from 'classnames';
|
3
3
|
import ReactFlow, {
|
4
|
-
ReactFlowProvider,
|
5
|
-
Controls,
|
6
4
|
Background,
|
5
|
+
Controls,
|
6
|
+
Handle,
|
7
7
|
MiniMap,
|
8
|
-
|
8
|
+
NodeProps,
|
9
9
|
NodeTypesType,
|
10
|
-
|
10
|
+
OnLoadParams,
|
11
11
|
Position,
|
12
|
-
NodeProps,
|
13
12
|
ReactFlowProps,
|
13
|
+
ReactFlowProvider,
|
14
14
|
} from 'react-flow-renderer';
|
15
15
|
import { ComponentID } from '@teambit/component';
|
16
16
|
|
17
17
|
import { ComponentWidgetSlot } from '../../graph.ui.runtime';
|
18
18
|
import { ComponentNode } from '../component-node';
|
19
|
-
import { GraphModel } from '../query';
|
19
|
+
import { EdgeModel, GraphModel, NodeModel } from '../query';
|
20
20
|
import { calcElements } from './calc-elements';
|
21
21
|
import { calcMinimapColors } from './minimap';
|
22
22
|
import { ComponentGraphContext } from './graph-context';
|
@@ -40,7 +40,7 @@ const NodeTypes: NodeTypesType = { ComponentNode: ComponentNodeContainer };
|
|
40
40
|
|
41
41
|
export type DependenciesGraphProps = {
|
42
42
|
rootNode: ComponentID;
|
43
|
-
graph: GraphModel
|
43
|
+
graph: GraphModel<NodeModel, EdgeModel>;
|
44
44
|
componentWidgets: ComponentWidgetSlot;
|
45
45
|
onLoad?: (instance: OnLoadParams) => void;
|
46
46
|
} & Omit<ReactFlowProps, 'elements'>;
|
@@ -1,3 +1,12 @@
|
|
1
|
+
import componentStyles from './dependencies-graph.module.scss';
|
2
|
+
|
1
3
|
export { DependenciesGraph } from './dependencies-graph';
|
2
4
|
export { ComponentGraphContext, ComponentGraph } from './graph-context';
|
3
5
|
export type { DependenciesGraphProps } from './dependencies-graph';
|
6
|
+
export { depTypeToClass, depTypeToLabel } from './dep-edge';
|
7
|
+
export { calcMinimapColors } from './minimap';
|
8
|
+
export { calcLayout } from './calc-layout';
|
9
|
+
export { calcElements } from './calc-elements';
|
10
|
+
|
11
|
+
const { graph, minimap, controls } = componentStyles;
|
12
|
+
export const styles = { graph, minimap, controls };
|
package/ui/graph-page/index.ts
CHANGED
package/ui/query/graph-model.ts
CHANGED
@@ -2,8 +2,9 @@ import { RawGraph } from './get-graph.query';
|
|
2
2
|
import { NodeModel } from './node-model';
|
3
3
|
import { EdgeModel } from './edge-model';
|
4
4
|
|
5
|
-
export class GraphModel {
|
6
|
-
constructor(public nodes:
|
5
|
+
export class GraphModel<N extends NodeModel, E extends EdgeModel> {
|
6
|
+
constructor(public nodes: N[], public edges: E[]) {}
|
7
|
+
|
7
8
|
static from(rawGraph: RawGraph) {
|
8
9
|
const nodes = rawGraph.nodes.map(NodeModel.from);
|
9
10
|
const edges = rawGraph.edges.map(EdgeModel.from);
|
package/ui/query/index.ts
CHANGED