feat(dep-graph): add experimental collapse edges option (#9004)
This commit is contained in:
parent
2f78f29483
commit
31d51c36fd
12
dep-graph/client-e2e/cypress-release.json
Normal file
12
dep-graph/client-e2e/cypress-release.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"fileServerFolder": ".",
|
||||
"fixturesFolder": "./src/fixtures",
|
||||
"integrationFolder": "./src/release-integration",
|
||||
"modifyObstructiveCode": false,
|
||||
"pluginsFile": "./src/plugins/index",
|
||||
"supportFile": "./src/support/index.ts",
|
||||
"video": true,
|
||||
"videosFolder": "../../dist/cypress/dep-graph/client-e2e/videos",
|
||||
"screenshotsFolder": "../../dist/cypress/dep-graph/client-e2e/screenshots",
|
||||
"chromeWebSecurity": false
|
||||
}
|
||||
@ -21,6 +21,15 @@
|
||||
"baseUrl": "http://localhost:4200"
|
||||
}
|
||||
},
|
||||
"e2e-release-disabled": {
|
||||
"executor": "@nrwl/cypress:cypress",
|
||||
"options": {
|
||||
"cypressConfig": "dep-graph/client-e2e/cypress-release.json",
|
||||
"tsConfig": "dep-graph/client-e2e/tsconfig.e2e.json",
|
||||
"devServerTarget": "dep-graph-client:serve-for-e2e:release",
|
||||
"baseUrl": "http://localhost:4200"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nrwl/linter:eslint",
|
||||
"outputs": ["{options.outputFile}"],
|
||||
|
||||
@ -68,7 +68,7 @@ describe('dep-graph-client', () => {
|
||||
|
||||
describe('selecting a different project', () => {
|
||||
it('should change the available projects', () => {
|
||||
getProjectItems().should('have.length', 55);
|
||||
getProjectItems().should('have.length', 53);
|
||||
cy.get('[data-cy=project-select]').select('Ocean', { force: true });
|
||||
getProjectItems().should('have.length', 124);
|
||||
});
|
||||
@ -77,14 +77,14 @@ describe('dep-graph-client', () => {
|
||||
describe('select all button', () => {
|
||||
it('should check all project items', () => {
|
||||
getSelectAllButton().scrollIntoView().click({ force: true });
|
||||
getCheckedProjectItems().should('have.length', 55);
|
||||
getCheckedProjectItems().should('have.length', 53);
|
||||
});
|
||||
});
|
||||
|
||||
describe('deselect all button', () => {
|
||||
it('should uncheck all project items', () => {
|
||||
getDeselectAllButton().click();
|
||||
getUncheckedProjectItems().should('have.length', 55);
|
||||
getUncheckedProjectItems().should('have.length', 53);
|
||||
getSelectProjectsMessage().should('be.visible');
|
||||
});
|
||||
});
|
||||
@ -156,7 +156,7 @@ describe('dep-graph-client', () => {
|
||||
cy.get('[data-project="nx-dev"]').prev('button').click({ force: true });
|
||||
getUnfocusProjectButton().click();
|
||||
|
||||
getUncheckedProjectItems().should('have.length', 55);
|
||||
getUncheckedProjectItems().should('have.length', 53);
|
||||
});
|
||||
});
|
||||
|
||||
@ -263,6 +263,6 @@ describe('loading dep-graph client with url params', () => {
|
||||
// wait for first graph to finish loading
|
||||
cy.wait('@getGraph');
|
||||
|
||||
getCheckedProjectItems().should('have.length', 55);
|
||||
getCheckedProjectItems().should('have.length', 53);
|
||||
});
|
||||
});
|
||||
|
||||
18
dep-graph/client-e2e/src/release-integration/release.spec.ts
Normal file
18
dep-graph/client-e2e/src/release-integration/release.spec.ts
Normal file
@ -0,0 +1,18 @@
|
||||
describe('dep-graph-client release', () => {
|
||||
beforeEach(() => {
|
||||
cy.intercept('/assets/graphs/*').as('getGraph');
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
// wait for first graph to finish loading
|
||||
cy.wait('@getGraph');
|
||||
});
|
||||
|
||||
it('should not display experimental features', () => {
|
||||
cy.get('experimental-features').should('not.exist');
|
||||
});
|
||||
|
||||
it('should not display the debugger', () => {
|
||||
cy.get('debugger-panel').should('not.exist');
|
||||
});
|
||||
});
|
||||
@ -97,6 +97,12 @@
|
||||
"npx ts-node -P ./scripts/tsconfig.scripts.json ./scripts/copy-dep-graph-environment.ts watch",
|
||||
"nx serve-base dep-graph-client"
|
||||
]
|
||||
},
|
||||
"release": {
|
||||
"commands": [
|
||||
"npx ts-node -P ./scripts/tsconfig.scripts.json ./scripts/copy-dep-graph-environment.ts release",
|
||||
"nx serve-base dep-graph-client"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -117,6 +123,13 @@
|
||||
"nx serve-base dep-graph-client"
|
||||
],
|
||||
"readyWhen": "No issues found."
|
||||
},
|
||||
"release": {
|
||||
"commands": [
|
||||
"npx ts-node -P ./scripts/tsconfig.scripts.json ./scripts/copy-dep-graph-environment.ts release",
|
||||
"nx serve-base dep-graph-client"
|
||||
],
|
||||
"readyWhen": "No issues found."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ export const DebuggerPanel = memo(function ({
|
||||
}: DebuggerPanelProps) {
|
||||
return (
|
||||
<div
|
||||
id="debugger-panel"
|
||||
data-cy="debugger-panel"
|
||||
className="
|
||||
flex-column
|
||||
flex
|
||||
|
||||
18
dep-graph/client/src/app/experimental-feature.tsx
Normal file
18
dep-graph/client/src/app/experimental-feature.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { useEnvironmentConfig } from './hooks/use-environment-config';
|
||||
|
||||
function ExperimentalFeature(props) {
|
||||
const environment = useEnvironmentConfig();
|
||||
const showExperimentalFeatures =
|
||||
environment.appConfig.showExperimentalFeatures;
|
||||
|
||||
return showExperimentalFeatures ? (
|
||||
<div data-cy="experimental-features" className="bg-purple-200 pb-2">
|
||||
<h3 className="mt-4 cursor-text px-4 py-2 text-sm font-semibold uppercase tracking-wide text-gray-900 lg:text-xs ">
|
||||
Experimental Features
|
||||
</h3>
|
||||
{props.children}
|
||||
</div>
|
||||
) : null;
|
||||
}
|
||||
|
||||
export default ExperimentalFeature;
|
||||
@ -22,6 +22,7 @@ export interface Environment {
|
||||
|
||||
export interface AppConfig {
|
||||
showDebugger: boolean;
|
||||
showExperimentalFeatures: boolean;
|
||||
projectGraphs: ProjectGraphList[];
|
||||
defaultProjectGraph: string;
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ export const initialContext: DepGraphContext = {
|
||||
searchDepth: 1,
|
||||
searchDepthEnabled: false,
|
||||
groupByFolder: false,
|
||||
collapseEdges: false,
|
||||
workspaceLayout: {
|
||||
libsDir: '',
|
||||
appsDir: '',
|
||||
@ -66,6 +67,7 @@ export const depGraphMachine = Machine<
|
||||
affectedProjects: ctx.affectedProjects,
|
||||
workspaceLayout: ctx.workspaceLayout,
|
||||
groupByFolder: ctx.groupByFolder,
|
||||
collapseEdges: ctx.collapseEdges,
|
||||
}),
|
||||
{
|
||||
to: (context) => context.graphActor,
|
||||
@ -112,6 +114,39 @@ export const depGraphMachine = Machine<
|
||||
focusProject: {
|
||||
target: 'focused',
|
||||
},
|
||||
setCollapseEdges: {
|
||||
actions: [
|
||||
'setCollapseEdges',
|
||||
send(
|
||||
(ctx, event) => ({
|
||||
type: 'notifyGraphUpdateGraph',
|
||||
projects: ctx.projects,
|
||||
dependencies: ctx.dependencies,
|
||||
affectedProjects: ctx.affectedProjects,
|
||||
workspaceLayout: ctx.workspaceLayout,
|
||||
groupByFolder: ctx.groupByFolder,
|
||||
collapseEdges: ctx.collapseEdges,
|
||||
selectedProjects: ctx.selectedProjects,
|
||||
}),
|
||||
{
|
||||
to: (context) => context.graphActor,
|
||||
}
|
||||
),
|
||||
send(
|
||||
(ctx, event) => {
|
||||
if (event.type !== 'setCollapseEdges') return;
|
||||
|
||||
return {
|
||||
type: 'notifyRouteCollapseEdges',
|
||||
collapseEdges: event.collapseEdges,
|
||||
};
|
||||
},
|
||||
{
|
||||
to: (context) => context.routeSetterActor,
|
||||
}
|
||||
),
|
||||
],
|
||||
},
|
||||
setGroupByFolder: {
|
||||
actions: [
|
||||
'setGroupByFolder',
|
||||
@ -123,6 +158,7 @@ export const depGraphMachine = Machine<
|
||||
affectedProjects: ctx.affectedProjects,
|
||||
workspaceLayout: ctx.workspaceLayout,
|
||||
groupByFolder: ctx.groupByFolder,
|
||||
collapseEdges: ctx.collapseEdges,
|
||||
selectedProjects: ctx.selectedProjects,
|
||||
}),
|
||||
{
|
||||
@ -183,6 +219,11 @@ export const depGraphMachine = Machine<
|
||||
|
||||
ctx.groupByFolder = event.groupByFolder;
|
||||
}),
|
||||
setCollapseEdges: assign((ctx, event) => {
|
||||
if (event.type !== 'setCollapseEdges') return;
|
||||
|
||||
ctx.collapseEdges = event.collapseEdges;
|
||||
}),
|
||||
incrementSearchDepth: assign((ctx) => {
|
||||
ctx.searchDepthEnabled = true;
|
||||
ctx.searchDepth = ctx.searchDepth + 1;
|
||||
|
||||
@ -24,6 +24,7 @@ export class GraphService {
|
||||
private renderGraph: cy.Core;
|
||||
|
||||
private openTooltip: Instance = null;
|
||||
private collapseEdges = false;
|
||||
|
||||
constructor(
|
||||
private tooltipService: GraphTooltipService,
|
||||
@ -52,7 +53,8 @@ export class GraphService {
|
||||
event.groupByFolder,
|
||||
event.workspaceLayout,
|
||||
event.dependencies,
|
||||
event.affectedProjects
|
||||
event.affectedProjects,
|
||||
event.collapseEdges
|
||||
);
|
||||
break;
|
||||
|
||||
@ -62,7 +64,8 @@ export class GraphService {
|
||||
event.groupByFolder,
|
||||
event.workspaceLayout,
|
||||
event.dependencies,
|
||||
event.affectedProjects
|
||||
event.affectedProjects,
|
||||
event.collapseEdges
|
||||
);
|
||||
this.setShownProjects(
|
||||
event.selectedProjects.length > 0
|
||||
@ -112,9 +115,11 @@ export class GraphService {
|
||||
};
|
||||
|
||||
if (this.renderGraph) {
|
||||
this.renderGraph
|
||||
.elements()
|
||||
.sort((a, b) => a.id().localeCompare(b.id()))
|
||||
const elements = this.renderGraph.elements().sort((a, b) => {
|
||||
return a.id().localeCompare(b.id());
|
||||
});
|
||||
|
||||
elements
|
||||
.layout({
|
||||
name: 'dagre',
|
||||
nodeDimensionsIncludeLabels: true,
|
||||
@ -125,6 +130,80 @@ export class GraphService {
|
||||
} as CytoscapeDagreConfig)
|
||||
.run();
|
||||
|
||||
if (this.collapseEdges) {
|
||||
this.renderGraph.remove(this.renderGraph.edges());
|
||||
|
||||
elements.edges().forEach((edge) => {
|
||||
const sourceNode = edge.source();
|
||||
const targetNode = edge.target();
|
||||
|
||||
if (
|
||||
sourceNode.parent().first().id() ===
|
||||
targetNode.parent().first().id()
|
||||
) {
|
||||
this.renderGraph.add(edge);
|
||||
} else {
|
||||
let sourceAncestors, targetAncestors;
|
||||
const commonAncestors = edge.connectedNodes().commonAncestors();
|
||||
|
||||
if (commonAncestors.length > 0) {
|
||||
sourceAncestors = sourceNode
|
||||
.ancestors()
|
||||
.filter((anc) => !commonAncestors.contains(anc));
|
||||
targetAncestors = targetNode
|
||||
.ancestors()
|
||||
.filter((anc) => !commonAncestors.contains(anc));
|
||||
} else {
|
||||
sourceAncestors = sourceNode.ancestors();
|
||||
targetAncestors = targetNode.ancestors();
|
||||
}
|
||||
|
||||
let sourceId, targetId;
|
||||
|
||||
if (sourceAncestors.length > 0 && targetAncestors.length === 0) {
|
||||
sourceId = sourceAncestors.last().id();
|
||||
targetId = targetNode.id();
|
||||
} else if (
|
||||
targetAncestors.length > 0 &&
|
||||
sourceAncestors.length === 0
|
||||
) {
|
||||
sourceId = sourceNode.id();
|
||||
targetId = targetAncestors.last().id();
|
||||
} else {
|
||||
sourceId = sourceAncestors.last().id();
|
||||
targetId = targetAncestors.last().id();
|
||||
}
|
||||
|
||||
if (sourceId !== undefined && targetId !== undefined) {
|
||||
const edgeId = `${sourceId}|${targetId}`;
|
||||
|
||||
if (this.renderGraph.$id(edgeId).length === 0) {
|
||||
const ancestorEdge: cy.EdgeDefinition = {
|
||||
group: 'edges',
|
||||
data: {
|
||||
id: edgeId,
|
||||
source: sourceId,
|
||||
target: targetId,
|
||||
},
|
||||
};
|
||||
|
||||
this.renderGraph.add(ancestorEdge);
|
||||
}
|
||||
} else {
|
||||
console.log(`Couldn't figure out how to draw edge ${edge.id()}`);
|
||||
console.log(
|
||||
'source ancestors',
|
||||
sourceAncestors.map((anc) => anc.id())
|
||||
);
|
||||
console.log(
|
||||
'target ancestors',
|
||||
targetAncestors.map((anc) => anc.id())
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.renderGraph.fit().center().resize();
|
||||
|
||||
selectedProjectNames = this.renderGraph
|
||||
@ -284,12 +363,14 @@ export class GraphService {
|
||||
if (!!currentFocusedProjectName) {
|
||||
this.renderGraph.$id(currentFocusedProjectName).addClass('focused');
|
||||
}
|
||||
|
||||
this.renderGraph.on('zoom', () => {
|
||||
if (this.openTooltip) {
|
||||
this.openTooltip.hide();
|
||||
this.openTooltip = null;
|
||||
}
|
||||
});
|
||||
|
||||
this.listenForProjectNodeClicks();
|
||||
this.listenForProjectNodeHovers();
|
||||
}
|
||||
@ -330,8 +411,10 @@ export class GraphService {
|
||||
groupByFolder: boolean,
|
||||
workspaceLayout,
|
||||
dependencies: Record<string, ProjectGraphDependency[]>,
|
||||
affectedProjectIds: string[]
|
||||
affectedProjectIds: string[],
|
||||
collapseEdges: boolean
|
||||
) {
|
||||
this.collapseEdges = collapseEdges;
|
||||
this.tooltipService.hideAll();
|
||||
|
||||
this.generateCytoscapeLayout(
|
||||
|
||||
@ -35,6 +35,7 @@ export type DepGraphUIEvents =
|
||||
| { type: 'deselectAll' }
|
||||
| { type: 'selectAffected' }
|
||||
| { type: 'setGroupByFolder'; groupByFolder: boolean }
|
||||
| { type: 'setCollapseEdges'; collapseEdges: boolean }
|
||||
| { type: 'setIncludeProjectsByPath'; includeProjectsByPath: boolean }
|
||||
| { type: 'incrementSearchDepth' }
|
||||
| { type: 'decrementSearchDepth' }
|
||||
@ -73,6 +74,7 @@ export type GraphRenderEvents =
|
||||
appsDir: string;
|
||||
};
|
||||
groupByFolder: boolean;
|
||||
collapseEdges: boolean;
|
||||
}
|
||||
| {
|
||||
type: 'notifyGraphUpdateGraph';
|
||||
@ -84,6 +86,7 @@ export type GraphRenderEvents =
|
||||
appsDir: string;
|
||||
};
|
||||
groupByFolder: boolean;
|
||||
collapseEdges: boolean;
|
||||
selectedProjects: string[];
|
||||
}
|
||||
| {
|
||||
@ -124,6 +127,10 @@ export type RouteEvents =
|
||||
type: 'notifyRouteGroupByFolder';
|
||||
groupByFolder: boolean;
|
||||
}
|
||||
| {
|
||||
type: 'notifyRouteCollapseEdges';
|
||||
collapseEdges: boolean;
|
||||
}
|
||||
| {
|
||||
type: 'notifyRouteSearchDepth';
|
||||
searchDepthEnabled: boolean;
|
||||
@ -154,6 +161,7 @@ export interface DepGraphContext {
|
||||
searchDepth: number;
|
||||
searchDepthEnabled: boolean;
|
||||
groupByFolder: boolean;
|
||||
collapseEdges: boolean;
|
||||
workspaceLayout: {
|
||||
libsDir: string;
|
||||
appsDir: string;
|
||||
|
||||
@ -21,11 +21,10 @@ function parseSearchParamsToEvents(searchParams: string): DepGraphUIEvents[] {
|
||||
case 'groupByFolder':
|
||||
events.push({ type: 'setGroupByFolder', groupByFolder: true });
|
||||
break;
|
||||
case 'collapseEdges':
|
||||
events.push({ type: 'setCollapseEdges', collapseEdges: true });
|
||||
break;
|
||||
case 'searchDepth':
|
||||
// events.push({
|
||||
// type: 'setSearchDepthEnabled',
|
||||
// searchDepthEnabled: true,
|
||||
// });
|
||||
events.push({
|
||||
type: 'setSearchDepth',
|
||||
searchDepth: parseInt(value),
|
||||
|
||||
@ -3,7 +3,12 @@ import { createBrowserHistory } from 'history';
|
||||
import { Machine } from 'xstate';
|
||||
import { RouteEvents } from './interfaces';
|
||||
|
||||
type ParamKeys = 'focus' | 'groupByFolder' | 'searchDepth' | 'select';
|
||||
type ParamKeys =
|
||||
| 'focus'
|
||||
| 'groupByFolder'
|
||||
| 'searchDepth'
|
||||
| 'select'
|
||||
| 'collapseEdges';
|
||||
type ParamRecord = Record<ParamKeys, string | null>;
|
||||
|
||||
function reduceParamRecordToQueryString(params: ParamRecord): string {
|
||||
@ -25,6 +30,7 @@ export const createRouteMachine = () => {
|
||||
const paramRecord: ParamRecord = {
|
||||
focus: params.get('focus'),
|
||||
groupByFolder: params.get('groupByFolder'),
|
||||
collapseEdges: params.get('collapseEdges'),
|
||||
searchDepth: params.get('searchDepth'),
|
||||
select: params.get('select'),
|
||||
};
|
||||
@ -48,6 +54,7 @@ export const createRouteMachine = () => {
|
||||
groupByFolder: null,
|
||||
searchDepth: null,
|
||||
select: null,
|
||||
collapseEdges: null,
|
||||
},
|
||||
},
|
||||
always: {
|
||||
@ -98,6 +105,11 @@ export const createRouteMachine = () => {
|
||||
ctx.params.groupByFolder = event.groupByFolder ? 'true' : null;
|
||||
}),
|
||||
},
|
||||
notifyRouteCollapseEdges: {
|
||||
actions: assign((ctx, event) => {
|
||||
ctx.params.collapseEdges = event.collapseEdges ? 'true' : null;
|
||||
}),
|
||||
},
|
||||
notifyRouteSearchDepth: {
|
||||
actions: assign((ctx, event) => {
|
||||
ctx.params.searchDepth = event.searchDepthEnabled
|
||||
|
||||
@ -39,6 +39,9 @@ export const includePathSelector: DepGraphSelector<boolean> = (state) =>
|
||||
export const groupByFolderSelector: DepGraphSelector<boolean> = (state) =>
|
||||
state.context.groupByFolder;
|
||||
|
||||
export const collapseEdgesSelector: DepGraphSelector<boolean> = (state) =>
|
||||
state.context.collapseEdges;
|
||||
|
||||
export const textFilterSelector: DepGraphSelector<string> = (state) =>
|
||||
state.context.textFilter;
|
||||
|
||||
|
||||
41
dep-graph/client/src/app/sidebar/collapse-edges-panel.tsx
Normal file
41
dep-graph/client/src/app/sidebar/collapse-edges-panel.tsx
Normal file
@ -0,0 +1,41 @@
|
||||
import { memo } from 'react';
|
||||
|
||||
export interface CollapseEdgesPanelProps {
|
||||
collapseEdges: boolean;
|
||||
collapseEdgesChanged: (checked: boolean) => void;
|
||||
}
|
||||
|
||||
export const CollapseEdgesPanel = memo(
|
||||
({ collapseEdges, collapseEdgesChanged }: CollapseEdgesPanelProps) => {
|
||||
return (
|
||||
<div className="px-4">
|
||||
<div className="flex items-start">
|
||||
<div className="flex h-5 items-center">
|
||||
<input
|
||||
id="collapseEdges"
|
||||
name="collapseEdges"
|
||||
value="collapseEdges"
|
||||
type="checkbox"
|
||||
className="h-4 w-4 rounded border-gray-300"
|
||||
onChange={(event) => collapseEdgesChanged(event.target.checked)}
|
||||
checked={collapseEdges}
|
||||
></input>
|
||||
</div>
|
||||
<div className="ml-3 text-sm">
|
||||
<label
|
||||
htmlFor="collapseEdges"
|
||||
className="cursor-pointer font-medium text-gray-700"
|
||||
>
|
||||
Collapse edges
|
||||
</label>
|
||||
<p className="text-gray-500">
|
||||
Display edges between groups rather than libraries
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default CollapseEdgesPanel;
|
||||
@ -1,7 +1,9 @@
|
||||
import { useCallback } from 'react';
|
||||
import ExperimentalFeature from '../experimental-feature';
|
||||
import { useDepGraphService } from '../hooks/use-dep-graph';
|
||||
import { useDepGraphSelector } from '../hooks/use-dep-graph-selector';
|
||||
import {
|
||||
collapseEdgesSelector,
|
||||
focusedProjectNameSelector,
|
||||
groupByFolderSelector,
|
||||
hasAffectedProjectsSelector,
|
||||
@ -9,6 +11,7 @@ import {
|
||||
searchDepthSelector,
|
||||
textFilterSelector,
|
||||
} from '../machines/selectors';
|
||||
import CollapseEdgesPanel from './collapse-edges-panel';
|
||||
import FocusedProjectPanel from './focused-project-panel';
|
||||
import GroupByFolderPanel from './group-by-folder-panel';
|
||||
import ProjectList from './project-list';
|
||||
@ -24,6 +27,7 @@ export function Sidebar() {
|
||||
const textFilter = useDepGraphSelector(textFilterSelector);
|
||||
const hasAffectedProjects = useDepGraphSelector(hasAffectedProjectsSelector);
|
||||
const groupByFolder = useDepGraphSelector(groupByFolderSelector);
|
||||
const collapseEdges = useDepGraphSelector(collapseEdgesSelector);
|
||||
|
||||
function resetFocus() {
|
||||
depGraphService.send({ type: 'unfocusProject' });
|
||||
@ -52,6 +56,10 @@ export function Sidebar() {
|
||||
depGraphService.send({ type: 'setGroupByFolder', groupByFolder: checked });
|
||||
}
|
||||
|
||||
function collapseEdgesChanged(checked: boolean) {
|
||||
depGraphService.send({ type: 'setCollapseEdges', collapseEdges: checked });
|
||||
}
|
||||
|
||||
function incrementDepthFilter() {
|
||||
depGraphService.send({ type: 'incrementSearchDepth' });
|
||||
}
|
||||
@ -174,6 +182,13 @@ export function Sidebar() {
|
||||
incrementDepthFilter={incrementDepthFilter}
|
||||
decrementDepthFilter={decrementDepthFilter}
|
||||
></SearchDepth>
|
||||
|
||||
<ExperimentalFeature>
|
||||
<CollapseEdgesPanel
|
||||
collapseEdges={collapseEdges}
|
||||
collapseEdgesChanged={collapseEdgesChanged}
|
||||
></CollapseEdgesPanel>
|
||||
</ExperimentalFeature>
|
||||
</div>
|
||||
|
||||
<ProjectList></ProjectList>
|
||||
|
||||
@ -5,6 +5,7 @@ window.useXstateInspect = false;
|
||||
|
||||
window.appConfig = {
|
||||
showDebugger: true,
|
||||
showExperimentalFeatures: true,
|
||||
projectGraphs: [
|
||||
{
|
||||
id: 'nx',
|
||||
@ -41,6 +42,11 @@ window.appConfig = {
|
||||
label: 'Affected',
|
||||
url: 'assets/graphs/affected.json',
|
||||
},
|
||||
{
|
||||
id: 'collapsing-edges-testing',
|
||||
label: 'Collapsing Edges',
|
||||
url: 'assets/graphs/collapsing-edges-testing.json',
|
||||
},
|
||||
],
|
||||
defaultProjectGraph: 'nx',
|
||||
};
|
||||
|
||||
17
dep-graph/client/src/assets/environment.release.js
Normal file
17
dep-graph/client/src/assets/environment.release.js
Normal file
@ -0,0 +1,17 @@
|
||||
window.exclude = [];
|
||||
window.watch = false;
|
||||
window.environment = 'release';
|
||||
window.useXstateInspect = false;
|
||||
|
||||
window.appConfig = {
|
||||
showDebugger: false,
|
||||
showExperimentalFeatures: false,
|
||||
projectGraphs: [
|
||||
{
|
||||
id: 'local',
|
||||
label: 'local',
|
||||
url: 'assets/graphs/nx-examples.json',
|
||||
},
|
||||
],
|
||||
defaultProjectGraph: 'local',
|
||||
};
|
||||
@ -5,6 +5,7 @@ window.useXstateInspect = false;
|
||||
|
||||
window.appConfig = {
|
||||
showDebugger: false,
|
||||
showExperimentalFeatures: true,
|
||||
projectGraphs: [
|
||||
{
|
||||
id: 'local',
|
||||
|
||||
222
dep-graph/client/src/assets/graphs/collapsing-edges-testing.json
Normal file
222
dep-graph/client/src/assets/graphs/collapsing-edges-testing.json
Normal file
@ -0,0 +1,222 @@
|
||||
{
|
||||
"hash": "1c2b69586aa096dc5e42eb252d0b5bfb94f20dc969a1e7b6f381a3b13add6928",
|
||||
"layout": {
|
||||
"appsDir": "apps",
|
||||
"libsDir": "libs"
|
||||
},
|
||||
"projects": [
|
||||
{
|
||||
"name": "web",
|
||||
"type": "app",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"root": "apps/app1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "admin",
|
||||
"type": "app",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"root": "apps/app2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "core-util-auth",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"root": "core/util-auth"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "web-feature-home-page",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"root": "web/feature-homepage"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "web-feature-search",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"root": "web/feature-search"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "web-data-access",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"root": "web/feature-search"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "admin-feature-users",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"root": "admin/feature-users"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "admin-feature-billing",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"root": "admin/feature-billing"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "admin-data-access",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"root": "admin/data-access"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "shared-components-ui-button",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"root": "shared/components/ui-button"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "shared-components-ui-form",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"root": "shared/components/ui-form"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "shared-util",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"root": "shared/util"
|
||||
}
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"web": [
|
||||
{
|
||||
"type": "dynamic",
|
||||
"source": "web",
|
||||
"target": "web-feature-home-page"
|
||||
},
|
||||
{
|
||||
"type": "dynamic",
|
||||
"source": "web",
|
||||
"target": "web-feature-search"
|
||||
},
|
||||
{
|
||||
"type": "static",
|
||||
"source": "web",
|
||||
"target": "core-util-auth"
|
||||
}
|
||||
],
|
||||
"admin": [
|
||||
{
|
||||
"type": "dynamic",
|
||||
"source": "admin",
|
||||
"target": "admin-feature-users"
|
||||
},
|
||||
{
|
||||
"type": "dynamic",
|
||||
"source": "admin",
|
||||
"target": "admin-feature-billing"
|
||||
},
|
||||
{
|
||||
"type": "static",
|
||||
"source": "admin",
|
||||
"target": "core-util-auth"
|
||||
}
|
||||
],
|
||||
"web-feature-home-page": [
|
||||
{
|
||||
"type": "static",
|
||||
"source": "web-feature-home-page",
|
||||
"target": "web-data-access"
|
||||
},
|
||||
{
|
||||
"type": "static",
|
||||
"source": "web-feature-home-page",
|
||||
"target": "shared-components-ui-button"
|
||||
}
|
||||
],
|
||||
"web-feature-search": [
|
||||
{
|
||||
"type": "static",
|
||||
"source": "web-feature-search",
|
||||
"target": "web-data-access"
|
||||
},
|
||||
{
|
||||
"type": "static",
|
||||
"source": "web-feature-search",
|
||||
"target": "shared-components-ui-button"
|
||||
},
|
||||
{
|
||||
"type": "static",
|
||||
"source": "web-feature-search",
|
||||
"target": "shared-components-ui-form"
|
||||
}
|
||||
],
|
||||
"web-data-access": [
|
||||
{
|
||||
"type": "static",
|
||||
"source": "web-data-access",
|
||||
"target": "core-util-auth"
|
||||
}
|
||||
],
|
||||
"admin-feature-users": [
|
||||
{
|
||||
"type": "static",
|
||||
"source": "admin-feature-users",
|
||||
"target": "admin-data-access"
|
||||
},
|
||||
{
|
||||
"type": "static",
|
||||
"source": "admin-feature-users",
|
||||
"target": "shared-components-ui-button"
|
||||
}
|
||||
],
|
||||
"admin-feature-billing": [
|
||||
{
|
||||
"type": "static",
|
||||
"source": "admin-feature-billing",
|
||||
"target": "admin-data-access"
|
||||
},
|
||||
{
|
||||
"type": "static",
|
||||
"source": "admin-feature-billing",
|
||||
"target": "shared-components-ui-button"
|
||||
}
|
||||
],
|
||||
"admin-data-access": [
|
||||
{
|
||||
"type": "static",
|
||||
"source": "admin-data-access",
|
||||
"target": "core-util-auth"
|
||||
}
|
||||
],
|
||||
"core-util-auth": [],
|
||||
"shared-components-ui-button": [],
|
||||
"shared-components-ui-form": [
|
||||
{
|
||||
"type": "static",
|
||||
"source": "shared-components-ui-form",
|
||||
"target": "shared-util"
|
||||
}
|
||||
],
|
||||
"shared-util": []
|
||||
},
|
||||
"affected": [],
|
||||
"changes": {
|
||||
"added": []
|
||||
}
|
||||
}
|
||||
2
dep-graph/client/src/globals.d.ts
vendored
2
dep-graph/client/src/globals.d.ts
vendored
@ -1,6 +1,6 @@
|
||||
// nx-ignore-next-line
|
||||
import type { DepGraphClientResponse } from '@nrwl/workspace/src/command-line/dep-graph';
|
||||
import { AppConfig } from './app/models';
|
||||
import { AppConfig } from './app/interfaces';
|
||||
|
||||
export declare global {
|
||||
export interface Window {
|
||||
|
||||
@ -132,7 +132,7 @@
|
||||
"css-minimizer-webpack-plugin": "^3.1.1",
|
||||
"cypress": "^9.1.0",
|
||||
"cytoscape": "^3.18.2",
|
||||
"cytoscape-dagre": "^2.3.2",
|
||||
"cytoscape-dagre": "^2.4.0",
|
||||
"cytoscape-popper": "^2.0.0",
|
||||
"cz-conventional-changelog": "^3.0.2",
|
||||
"cz-customizable": "^6.2.0",
|
||||
|
||||
@ -64,6 +64,7 @@ function buildEnvironmentJs(
|
||||
|
||||
window.appConfig = {
|
||||
showDebugger: false,
|
||||
showExperimentalFeatures: false,
|
||||
projectGraphs: [
|
||||
{
|
||||
id: 'local',
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { copyFileSync } from 'fs';
|
||||
import { argv } from 'yargs';
|
||||
|
||||
type Mode = 'dev' | 'watch';
|
||||
type Mode = 'dev' | 'watch' | 'release';
|
||||
const mode = argv._[0];
|
||||
|
||||
console.log(`Setting up graph for ${mode}`);
|
||||
|
||||
@ -10342,10 +10342,10 @@ cypress@^9.1.0:
|
||||
url "^0.11.0"
|
||||
yauzl "^2.10.0"
|
||||
|
||||
cytoscape-dagre@^2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.npmjs.org/cytoscape-dagre/-/cytoscape-dagre-2.3.2.tgz"
|
||||
integrity sha512-dL9+RvGkatSlIdOKXiFwHpnpTo8ydFMqIYzZFkImJXNbDci3feyYxR46wFoaG9GFiWimc6XD9Lm0x29b1wvWpw==
|
||||
cytoscape-dagre@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/cytoscape-dagre/-/cytoscape-dagre-2.4.0.tgz#abf145b1c675afe3b7d531166e6727dc39dc350d"
|
||||
integrity sha512-jfOtKzKduCnruBs3YMHS9kqWjZKqvp6loSJwlotPO5pcU4wLUhkx7ZBIyW3VWZXa8wfkGxv/zhWoBxWtYrUxKQ==
|
||||
dependencies:
|
||||
dagre "^0.8.5"
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user