fix(graph): remove redux and useState and useContext hook (#23085)
<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> ## Current Behavior <!-- This is the behavior we have today --> ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
This commit is contained in:
parent
2e621f324c
commit
bacdc799b4
@ -1,6 +1,4 @@
|
|||||||
import { themeInit } from '@nx/graph/ui-theme';
|
import { themeInit } from '@nx/graph/ui-theme';
|
||||||
import { rootStore } from '@nx/graph/state';
|
|
||||||
import { Provider as StoreProvider } from 'react-redux';
|
|
||||||
import { rankDirInit } from './rankdir-resolver';
|
import { rankDirInit } from './rankdir-resolver';
|
||||||
import { RouterProvider } from 'react-router-dom';
|
import { RouterProvider } from 'react-router-dom';
|
||||||
import { getRouter } from './get-router';
|
import { getRouter } from './get-router';
|
||||||
@ -9,9 +7,5 @@ themeInit();
|
|||||||
rankDirInit();
|
rankDirInit();
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
return (
|
return <RouterProvider router={getRouter()} />;
|
||||||
<StoreProvider store={rootStore}>
|
|
||||||
<RouterProvider router={getRouter()} />
|
|
||||||
</StoreProvider>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,8 +10,9 @@ import {
|
|||||||
useParams,
|
useParams,
|
||||||
useRouteLoaderData,
|
useRouteLoaderData,
|
||||||
} from 'react-router-dom';
|
} from 'react-router-dom';
|
||||||
import ProjectDetailsWrapper from './project-details-wrapper';
|
import { ProjectDetailsWrapper } from './project-details-wrapper';
|
||||||
import {
|
import {
|
||||||
|
ExpandedTargetsProvider,
|
||||||
fetchProjectGraph,
|
fetchProjectGraph,
|
||||||
getProjectGraphDataService,
|
getProjectGraphDataService,
|
||||||
useEnvironmentConfig,
|
useEnvironmentConfig,
|
||||||
@ -50,20 +51,22 @@ export function ProjectDetailsPage() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex w-full flex-col justify-center text-slate-700 dark:text-slate-400">
|
<ExpandedTargetsProvider>
|
||||||
<ScrollRestoration />
|
<div className="flex w-full flex-col justify-center text-slate-700 dark:text-slate-400">
|
||||||
{environment !== 'nx-console' ? (
|
<ScrollRestoration />
|
||||||
<ProjectDetailsHeader />
|
{environment !== 'nx-console' ? (
|
||||||
) : (
|
<ProjectDetailsHeader />
|
||||||
<div className="py-2"></div>
|
) : (
|
||||||
)}
|
<div className="py-2"></div>
|
||||||
<div className="mx-auto mb-8 w-full max-w-6xl flex-grow px-8">
|
)}
|
||||||
<ProjectDetailsWrapper
|
<div className="mx-auto mb-8 w-full max-w-6xl flex-grow px-8">
|
||||||
project={project}
|
<ProjectDetailsWrapper
|
||||||
sourceMap={sourceMap}
|
project={project}
|
||||||
errors={errors}
|
sourceMap={sourceMap}
|
||||||
></ProjectDetailsWrapper>
|
errors={errors}
|
||||||
|
></ProjectDetailsWrapper>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</ExpandedTargetsProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,33 +0,0 @@
|
|||||||
import {
|
|
||||||
AppDispatch,
|
|
||||||
RootState,
|
|
||||||
expandTargetActions,
|
|
||||||
getExpandedTargets,
|
|
||||||
} from '@nx/graph/state';
|
|
||||||
|
|
||||||
const mapStateToProps = (state: RootState) => {
|
|
||||||
return {
|
|
||||||
expandTargets: getExpandedTargets(state),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch: AppDispatch) => {
|
|
||||||
return {
|
|
||||||
setExpandTargets(targets: string[]) {
|
|
||||||
dispatch(expandTargetActions.setExpandTargets(targets));
|
|
||||||
},
|
|
||||||
collapseAllTargets() {
|
|
||||||
dispatch(expandTargetActions.collapseAllTargets());
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
type mapStateToPropsType = ReturnType<typeof mapStateToProps>;
|
|
||||||
type mapDispatchToPropsType = ReturnType<typeof mapDispatchToProps>;
|
|
||||||
|
|
||||||
export {
|
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps,
|
|
||||||
mapStateToPropsType,
|
|
||||||
mapDispatchToPropsType,
|
|
||||||
};
|
|
||||||
@ -5,9 +5,9 @@ import type { ProjectGraphProjectNode } from '@nx/devkit';
|
|||||||
import { GraphError } from 'nx/src/command-line/graph/graph';
|
import { GraphError } from 'nx/src/command-line/graph/graph';
|
||||||
/* eslint-enable @nx/enforce-module-boundaries */
|
/* eslint-enable @nx/enforce-module-boundaries */
|
||||||
import { useNavigate, useNavigation, useSearchParams } from 'react-router-dom';
|
import { useNavigate, useNavigation, useSearchParams } from 'react-router-dom';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import {
|
import {
|
||||||
ErrorToast,
|
ErrorToast,
|
||||||
|
ExpandedTargetsContext,
|
||||||
getExternalApiService,
|
getExternalApiService,
|
||||||
useEnvironmentConfig,
|
useEnvironmentConfig,
|
||||||
useRouteConstructor,
|
useRouteConstructor,
|
||||||
@ -15,27 +15,17 @@ import {
|
|||||||
import { Spinner } from '@nx/graph/ui-components';
|
import { Spinner } from '@nx/graph/ui-components';
|
||||||
|
|
||||||
import { ProjectDetails } from '@nx/graph/ui-project-details';
|
import { ProjectDetails } from '@nx/graph/ui-project-details';
|
||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback, useContext, useEffect } from 'react';
|
||||||
import {
|
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps,
|
|
||||||
mapStateToPropsType,
|
|
||||||
mapDispatchToPropsType,
|
|
||||||
} from './project-details-wrapper.state';
|
|
||||||
|
|
||||||
type ProjectDetailsProps = mapStateToPropsType &
|
interface ProjectDetailsProps {
|
||||||
mapDispatchToPropsType & {
|
project: ProjectGraphProjectNode;
|
||||||
project: ProjectGraphProjectNode;
|
sourceMap: Record<string, string[]>;
|
||||||
sourceMap: Record<string, string[]>;
|
errors?: GraphError[];
|
||||||
errors?: GraphError[];
|
}
|
||||||
};
|
|
||||||
|
|
||||||
export function ProjectDetailsWrapperComponent({
|
export function ProjectDetailsWrapper({
|
||||||
project,
|
project,
|
||||||
sourceMap,
|
sourceMap,
|
||||||
setExpandTargets,
|
|
||||||
expandTargets,
|
|
||||||
collapseAllTargets,
|
|
||||||
errors,
|
errors,
|
||||||
}: ProjectDetailsProps) {
|
}: ProjectDetailsProps) {
|
||||||
const environment = useEnvironmentConfig()?.environment;
|
const environment = useEnvironmentConfig()?.environment;
|
||||||
@ -44,6 +34,8 @@ export function ProjectDetailsWrapperComponent({
|
|||||||
const { state: navigationState, location } = useNavigation();
|
const { state: navigationState, location } = useNavigation();
|
||||||
const routeConstructor = useRouteConstructor();
|
const routeConstructor = useRouteConstructor();
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
|
const { expandedTargets, setExpandedTargets, collapseAllTargets } =
|
||||||
|
useContext(ExpandedTargetsContext);
|
||||||
|
|
||||||
const handleViewInProjectGraph = useCallback(
|
const handleViewInProjectGraph = useCallback(
|
||||||
(data: { projectName: string }) => {
|
(data: { projectName: string }) => {
|
||||||
@ -113,44 +105,39 @@ export function ProjectDetailsWrapperComponent({
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!project.data.targets) return;
|
|
||||||
|
|
||||||
const expandedTargetsParams = searchParams.get('expanded')?.split(',');
|
const expandedTargetsParams = searchParams.get('expanded')?.split(',');
|
||||||
if (expandedTargetsParams && expandedTargetsParams.length > 0) {
|
if (expandedTargetsParams && expandedTargetsParams.length > 0) {
|
||||||
setExpandTargets(expandedTargetsParams);
|
setExpandedTargets(expandedTargetsParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
collapseAllTargets();
|
collapseAllTargets();
|
||||||
searchParams.delete('expanded');
|
setSearchParams(
|
||||||
setSearchParams(searchParams, { replace: true });
|
(currentSearchParams) => {
|
||||||
|
currentSearchParams.delete('expanded');
|
||||||
|
return currentSearchParams;
|
||||||
|
},
|
||||||
|
{ replace: true, preventScrollReset: true }
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}, []); // only run on mount
|
}, []); // only run on mount
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!project.data.targets) return;
|
|
||||||
|
|
||||||
const expandedTargetsParams =
|
const expandedTargetsParams =
|
||||||
searchParams.get('expanded')?.split(',') || [];
|
searchParams.get('expanded')?.split(',') || [];
|
||||||
|
|
||||||
if (expandedTargetsParams.join(',') === expandTargets.join(',')) {
|
if (expandedTargetsParams.join(',') === expandedTargets.join(',')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setSearchParams(
|
setSearchParams(
|
||||||
(currentSearchParams) => {
|
(currentSearchParams) => {
|
||||||
updateSearchParams(currentSearchParams, expandTargets);
|
updateSearchParams(currentSearchParams, expandedTargets);
|
||||||
return currentSearchParams;
|
return currentSearchParams;
|
||||||
},
|
},
|
||||||
{ replace: true, preventScrollReset: true }
|
{ replace: true, preventScrollReset: true }
|
||||||
);
|
);
|
||||||
}, [
|
}, [expandedTargets, searchParams, setSearchParams]);
|
||||||
expandTargets,
|
|
||||||
project.data.targets,
|
|
||||||
setExpandTargets,
|
|
||||||
searchParams,
|
|
||||||
setSearchParams,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
navigationState === 'loading' &&
|
navigationState === 'loading' &&
|
||||||
@ -179,9 +166,3 @@ export function ProjectDetailsWrapperComponent({
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ProjectDetailsWrapper = connect(
|
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(ProjectDetailsWrapperComponent);
|
|
||||||
export default ProjectDetailsWrapper;
|
|
||||||
|
|||||||
@ -7,3 +7,4 @@ export * from './lib/use-interval-when';
|
|||||||
export * from './lib/project-graph-data-service/get-project-graph-data-service';
|
export * from './lib/project-graph-data-service/get-project-graph-data-service';
|
||||||
export * from './lib/fetch-project-graph';
|
export * from './lib/fetch-project-graph';
|
||||||
export * from './lib/error-toast';
|
export * from './lib/error-toast';
|
||||||
|
export * from './lib/expanded-targets-provider';
|
||||||
|
|||||||
38
graph/shared/src/lib/expanded-targets-provider.tsx
Normal file
38
graph/shared/src/lib/expanded-targets-provider.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { createContext, useState } from 'react';
|
||||||
|
|
||||||
|
export const ExpandedTargetsContext = createContext<{
|
||||||
|
expandedTargets?: string[];
|
||||||
|
setExpandedTargets?: (expandedTargets: string[]) => void;
|
||||||
|
toggleTarget?: (targetName: string) => void;
|
||||||
|
collapseAllTargets?: () => void;
|
||||||
|
}>({});
|
||||||
|
|
||||||
|
export const ExpandedTargetsProvider = ({ children }) => {
|
||||||
|
const [expandedTargets, setExpandedTargets] = useState<string[]>([]);
|
||||||
|
|
||||||
|
const toggleTarget = (targetName: string) => {
|
||||||
|
setExpandedTargets((prevExpandedTargets) => {
|
||||||
|
if (prevExpandedTargets.includes(targetName)) {
|
||||||
|
return prevExpandedTargets.filter((name) => name !== targetName);
|
||||||
|
}
|
||||||
|
return [...prevExpandedTargets, targetName];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const collapseAllTargets = () => {
|
||||||
|
setExpandedTargets([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ExpandedTargetsContext.Provider
|
||||||
|
value={{
|
||||||
|
expandedTargets,
|
||||||
|
setExpandedTargets,
|
||||||
|
toggleTarget,
|
||||||
|
collapseAllTargets,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</ExpandedTargetsContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"presets": [
|
|
||||||
[
|
|
||||||
"@nx/react/babel",
|
|
||||||
{
|
|
||||||
"runtime": "automatic",
|
|
||||||
"useBuiltIns": "usage"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"plugins": []
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": ["plugin:@nx/react", "../../.eslintrc.json"],
|
|
||||||
"ignorePatterns": ["!**/*"],
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
|
||||||
"rules": {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files": ["*.ts", "*.tsx"],
|
|
||||||
"rules": {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files": ["*.js", "*.jsx"],
|
|
||||||
"rules": {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "graph-state",
|
|
||||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
||||||
"sourceRoot": "graph/state/src",
|
|
||||||
"projectType": "library",
|
|
||||||
"tags": [],
|
|
||||||
"// targets": "to see all targets run: nx show project ui-icons --web",
|
|
||||||
"targets": {
|
|
||||||
"lint": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
export * from './lib/expand-targets/expand-targets.slice';
|
|
||||||
export * from './lib/root/root-state.initial';
|
|
||||||
export * from './lib/root/root-state.interface';
|
|
||||||
export * from './lib/root/root.reducer';
|
|
||||||
export * from './lib/root/root.store';
|
|
||||||
export * from './lib/store.decorator';
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
import { PayloadAction, createSlice } from '@reduxjs/toolkit';
|
|
||||||
|
|
||||||
export const EXPAND_TARGETS_KEY = 'expandTargets';
|
|
||||||
|
|
||||||
export const initialExpandTargets: string[] = [];
|
|
||||||
|
|
||||||
export const expandTargetSlice = createSlice({
|
|
||||||
name: EXPAND_TARGETS_KEY,
|
|
||||||
initialState: initialExpandTargets,
|
|
||||||
reducers: {
|
|
||||||
expandTarget: (state: string[], action: PayloadAction<string>) => {
|
|
||||||
if (state.includes(action.payload)) {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
state.push(action.payload);
|
|
||||||
return state;
|
|
||||||
},
|
|
||||||
collapseTarget: (state: string[], action: PayloadAction<string>) => {
|
|
||||||
if (state.includes(action.payload)) {
|
|
||||||
state = state.filter((target) => target !== action.payload);
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
},
|
|
||||||
toggleExpandTarget: (state: string[], action: PayloadAction<string>) => {
|
|
||||||
if (state.includes(action.payload)) {
|
|
||||||
state = state.filter((target) => target !== action.payload);
|
|
||||||
} else {
|
|
||||||
state.push(action.payload);
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
},
|
|
||||||
setExpandTargets: (state: string[], action: PayloadAction<string[]>) => {
|
|
||||||
state = action.payload;
|
|
||||||
return state;
|
|
||||||
},
|
|
||||||
collapseAllTargets: (state: string[]) => {
|
|
||||||
state = [];
|
|
||||||
return state;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Export reducer for store configuration.
|
|
||||||
*/
|
|
||||||
export const expandTargetReducer = expandTargetSlice.reducer;
|
|
||||||
|
|
||||||
export const expandTargetActions = expandTargetSlice.actions;
|
|
||||||
|
|
||||||
export const getExpandedTargets = <
|
|
||||||
ROOT extends { [EXPAND_TARGETS_KEY]: string[] }
|
|
||||||
>(
|
|
||||||
rootState: ROOT
|
|
||||||
): string[] => rootState[EXPAND_TARGETS_KEY];
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import {
|
|
||||||
EXPAND_TARGETS_KEY,
|
|
||||||
initialExpandTargets,
|
|
||||||
} from '../expand-targets/expand-targets.slice';
|
|
||||||
import { RootState } from './root-state.interface';
|
|
||||||
|
|
||||||
export const initialRootState: RootState = {
|
|
||||||
[EXPAND_TARGETS_KEY]: initialExpandTargets,
|
|
||||||
};
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
import { EXPAND_TARGETS_KEY } from '../expand-targets/expand-targets.slice';
|
|
||||||
|
|
||||||
export interface RootState {
|
|
||||||
[EXPAND_TARGETS_KEY]: string[];
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
import { combineReducers } from '@reduxjs/toolkit';
|
|
||||||
import {
|
|
||||||
EXPAND_TARGETS_KEY,
|
|
||||||
expandTargetReducer,
|
|
||||||
} from '../expand-targets/expand-targets.slice';
|
|
||||||
import { RootState } from './root-state.interface';
|
|
||||||
|
|
||||||
export const rootReducer = combineReducers<RootState>({
|
|
||||||
[EXPAND_TARGETS_KEY]: expandTargetReducer,
|
|
||||||
});
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
import { configureStore } from '@reduxjs/toolkit';
|
|
||||||
import { initialRootState } from './root-state.initial';
|
|
||||||
import { rootReducer } from './root.reducer';
|
|
||||||
|
|
||||||
declare const process: any;
|
|
||||||
|
|
||||||
export const rootStore = configureStore({
|
|
||||||
reducer: rootReducer,
|
|
||||||
middleware: (getDefaultMiddleware) => {
|
|
||||||
const defaultMiddleware = getDefaultMiddleware({
|
|
||||||
serializableCheck: false,
|
|
||||||
});
|
|
||||||
return defaultMiddleware;
|
|
||||||
},
|
|
||||||
devTools: process.env.NODE_ENV === 'development',
|
|
||||||
preloadedState: initialRootState,
|
|
||||||
});
|
|
||||||
|
|
||||||
export type AppDispatch = typeof rootStore.dispatch;
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Provider } from 'react-redux';
|
|
||||||
import { rootStore } from './root/root.store';
|
|
||||||
|
|
||||||
export const StoreDecorator = (story: any) => {
|
|
||||||
return <Provider store={rootStore}>{story()}</Provider>;
|
|
||||||
};
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"jsx": "react-jsx",
|
|
||||||
"allowJs": false,
|
|
||||||
"esModuleInterop": false,
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"strict": true
|
|
||||||
},
|
|
||||||
"files": [],
|
|
||||||
"include": [],
|
|
||||||
"references": [
|
|
||||||
{
|
|
||||||
"path": "./tsconfig.lib.json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"extends": "../../tsconfig.base.json"
|
|
||||||
}
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "./tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "../../dist/out-tsc",
|
|
||||||
"types": [
|
|
||||||
"node",
|
|
||||||
"@nx/react/typings/cssmodule.d.ts",
|
|
||||||
"@nx/react/typings/image.d.ts"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"exclude": [
|
|
||||||
"jest.config.ts",
|
|
||||||
"src/**/*.spec.ts",
|
|
||||||
"src/**/*.test.ts",
|
|
||||||
"src/**/*.spec.tsx",
|
|
||||||
"src/**/*.test.tsx",
|
|
||||||
"src/**/*.spec.js",
|
|
||||||
"src/**/*.test.js",
|
|
||||||
"src/**/*.spec.jsx",
|
|
||||||
"src/**/*.test.jsx",
|
|
||||||
"**/*.stories.ts",
|
|
||||||
"**/*.stories.js",
|
|
||||||
"**/*.stories.jsx",
|
|
||||||
"**/*.stories.tsx"
|
|
||||||
],
|
|
||||||
"include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]
|
|
||||||
}
|
|
||||||
@ -1,11 +1,9 @@
|
|||||||
import type { Meta } from '@storybook/react';
|
import type { Meta } from '@storybook/react';
|
||||||
import { ProjectDetails } from './project-details';
|
import { ProjectDetails } from './project-details';
|
||||||
import { StoreDecorator } from '@nx/graph/state';
|
|
||||||
|
|
||||||
const meta: Meta<typeof ProjectDetails> = {
|
const meta: Meta<typeof ProjectDetails> = {
|
||||||
component: ProjectDetails,
|
component: ProjectDetails,
|
||||||
title: 'ProjectDetails',
|
title: 'ProjectDetails',
|
||||||
decorators: [StoreDecorator],
|
|
||||||
};
|
};
|
||||||
export default meta;
|
export default meta;
|
||||||
|
|
||||||
|
|||||||
@ -3,12 +3,10 @@ import {
|
|||||||
TargetConfigurationGroupList,
|
TargetConfigurationGroupList,
|
||||||
TargetConfigurationGroupListProps,
|
TargetConfigurationGroupListProps,
|
||||||
} from './target-configuration-details-group-list';
|
} from './target-configuration-details-group-list';
|
||||||
import { StoreDecorator } from '@nx/graph/state';
|
|
||||||
|
|
||||||
const meta: Meta<typeof TargetConfigurationGroupList> = {
|
const meta: Meta<typeof TargetConfigurationGroupList> = {
|
||||||
component: TargetConfigurationGroupList,
|
component: TargetConfigurationGroupList,
|
||||||
title: 'TargetConfigurationGroupList',
|
title: 'TargetConfigurationGroupList',
|
||||||
decorators: [StoreDecorator],
|
|
||||||
};
|
};
|
||||||
export default meta;
|
export default meta;
|
||||||
|
|
||||||
|
|||||||
@ -64,7 +64,7 @@ export const TargetConfigurationDetailsHeader = ({
|
|||||||
collapsable ? 'cursor-pointer' : '',
|
collapsable ? 'cursor-pointer' : '',
|
||||||
isCompact ? 'px-2 py-1' : 'p-2',
|
isCompact ? 'px-2 py-1' : 'p-2',
|
||||||
!isCollasped || !collapsable
|
!isCollasped || !collapsable
|
||||||
? 'border-b bg-slate-50 dark:border-slate-300/10 dark:border-slate-700/60 dark:bg-slate-800 '
|
? 'border-b bg-slate-50 dark:border-slate-700/60 dark:bg-slate-800'
|
||||||
: ''
|
: ''
|
||||||
)}
|
)}
|
||||||
onClick={collapsable ? toggleCollapse : undefined}
|
onClick={collapsable ? toggleCollapse : undefined}
|
||||||
@ -155,7 +155,7 @@ export const TargetConfigurationDetailsHeader = ({
|
|||||||
color="text-gray-500 dark:text-slate-400"
|
color="text-gray-500 dark:text-slate-400"
|
||||||
/>
|
/>
|
||||||
{targetName !== 'nx-release-publish' && (
|
{targetName !== 'nx-release-publish' && (
|
||||||
<div className="text-right">
|
<div className="mt-2 text-right">
|
||||||
<code className="ml-4 rounded bg-gray-100 px-2 py-1 font-mono text-gray-800 dark:bg-gray-700 dark:text-gray-300">
|
<code className="ml-4 rounded bg-gray-100 px-2 py-1 font-mono text-gray-800 dark:bg-gray-700 dark:text-gray-300">
|
||||||
nx run {projectName}:{targetName}
|
nx run {projectName}:{targetName}
|
||||||
</code>
|
</code>
|
||||||
|
|||||||
@ -3,12 +3,10 @@ import {
|
|||||||
TargetConfigurationDetailsListItem,
|
TargetConfigurationDetailsListItem,
|
||||||
TargetConfigurationDetailsListItemProps,
|
TargetConfigurationDetailsListItemProps,
|
||||||
} from './target-configuration-details-list-item';
|
} from './target-configuration-details-list-item';
|
||||||
import { StoreDecorator } from '@nx/graph/state';
|
|
||||||
|
|
||||||
const meta: Meta<typeof TargetConfigurationDetailsListItem> = {
|
const meta: Meta<typeof TargetConfigurationDetailsListItem> = {
|
||||||
component: TargetConfigurationDetailsListItem,
|
component: TargetConfigurationDetailsListItem,
|
||||||
title: 'TargetConfigurationDetailsListItem',
|
title: 'TargetConfigurationDetailsListItem',
|
||||||
decorators: [StoreDecorator],
|
|
||||||
};
|
};
|
||||||
export default meta;
|
export default meta;
|
||||||
|
|
||||||
|
|||||||
@ -1,28 +0,0 @@
|
|||||||
/* eslint-disable @nx/enforce-module-boundaries */
|
|
||||||
// nx-ignore-next-line
|
|
||||||
import { AppDispatch, RootState, expandTargetActions } from '@nx/graph/state';
|
|
||||||
|
|
||||||
const mapStateToProps = (state: RootState) => {
|
|
||||||
return {};
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch: AppDispatch) => {
|
|
||||||
return {
|
|
||||||
setExpandTargets(targets: string[]) {
|
|
||||||
dispatch(expandTargetActions.setExpandTargets(targets));
|
|
||||||
},
|
|
||||||
collapseAllTargets() {
|
|
||||||
dispatch(expandTargetActions.collapseAllTargets());
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
type mapStateToPropsType = ReturnType<typeof mapStateToProps>;
|
|
||||||
type mapDispatchToPropsType = ReturnType<typeof mapDispatchToProps>;
|
|
||||||
|
|
||||||
export {
|
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps,
|
|
||||||
mapStateToPropsType,
|
|
||||||
mapDispatchToPropsType,
|
|
||||||
};
|
|
||||||
@ -1,18 +1,16 @@
|
|||||||
import type { Meta, StoryObj } from '@storybook/react';
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
import {
|
import {
|
||||||
TargetConfigurationDetailsListComponent,
|
TargetConfigurationDetailsList,
|
||||||
TargetConfigurationDetailsListProps,
|
TargetConfigurationDetailsListProps,
|
||||||
} from './target-configuration-details-list';
|
} from './target-configuration-details-list';
|
||||||
import { StoreDecorator } from '@nx/graph/state';
|
|
||||||
|
|
||||||
const meta: Meta<typeof TargetConfigurationDetailsListComponent> = {
|
const meta: Meta<typeof TargetConfigurationDetailsList> = {
|
||||||
component: TargetConfigurationDetailsListComponent,
|
component: TargetConfigurationDetailsList,
|
||||||
title: 'TargetConfigurationDetailsListComponent',
|
title: 'TargetConfigurationDetailsList',
|
||||||
decorators: [StoreDecorator],
|
|
||||||
};
|
};
|
||||||
export default meta;
|
export default meta;
|
||||||
|
|
||||||
type Story = StoryObj<typeof TargetConfigurationDetailsListComponent>;
|
type Story = StoryObj<typeof TargetConfigurationDetailsList>;
|
||||||
|
|
||||||
export const OneTarget: Story = {
|
export const OneTarget: Story = {
|
||||||
args: {
|
args: {
|
||||||
|
|||||||
@ -1,29 +1,21 @@
|
|||||||
import { connect } from 'react-redux';
|
|
||||||
/* eslint-disable @nx/enforce-module-boundaries */
|
/* eslint-disable @nx/enforce-module-boundaries */
|
||||||
// nx-ignore-next-line
|
// nx-ignore-next-line
|
||||||
import type { ProjectGraphProjectNode } from '@nx/devkit';
|
import type { ProjectGraphProjectNode } from '@nx/devkit';
|
||||||
import {
|
|
||||||
mapDispatchToProps,
|
|
||||||
mapDispatchToPropsType,
|
|
||||||
mapStateToProps,
|
|
||||||
mapStateToPropsType,
|
|
||||||
} from './target-configuration-details-list.state';
|
|
||||||
import { TargetConfigurationGroupList } from '../target-configuration-details-group-list/target-configuration-details-group-list';
|
import { TargetConfigurationGroupList } from '../target-configuration-details-group-list/target-configuration-details-group-list';
|
||||||
|
|
||||||
export type TargetConfigurationDetailsListProps = mapStateToPropsType &
|
export interface TargetConfigurationDetailsListProps {
|
||||||
mapDispatchToPropsType & {
|
project: ProjectGraphProjectNode;
|
||||||
project: ProjectGraphProjectNode;
|
sourceMap: Record<string, string[]>;
|
||||||
sourceMap: Record<string, string[]>;
|
variant?: 'default' | 'compact';
|
||||||
variant?: 'default' | 'compact';
|
onRunTarget?: (data: { projectName: string; targetName: string }) => void;
|
||||||
onRunTarget?: (data: { projectName: string; targetName: string }) => void;
|
onViewInTaskGraph?: (data: {
|
||||||
onViewInTaskGraph?: (data: {
|
projectName: string;
|
||||||
projectName: string;
|
targetName: string;
|
||||||
targetName: string;
|
}) => void;
|
||||||
}) => void;
|
className?: string;
|
||||||
className?: string;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
export function TargetConfigurationDetailsListComponent({
|
export function TargetConfigurationDetailsList({
|
||||||
project,
|
project,
|
||||||
variant,
|
variant,
|
||||||
sourceMap,
|
sourceMap,
|
||||||
@ -42,9 +34,3 @@ export function TargetConfigurationDetailsListComponent({
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TargetConfigurationDetailsList = connect(
|
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(TargetConfigurationDetailsListComponent);
|
|
||||||
export default TargetConfigurationDetailsList;
|
|
||||||
|
|||||||
@ -1,36 +0,0 @@
|
|||||||
import {
|
|
||||||
AppDispatch,
|
|
||||||
RootState,
|
|
||||||
expandTargetActions,
|
|
||||||
getExpandedTargets,
|
|
||||||
} from '@nx/graph/state';
|
|
||||||
|
|
||||||
const mapStateToProps = (state: RootState) => {
|
|
||||||
return {
|
|
||||||
expandedTargets: getExpandedTargets(state),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch: AppDispatch) => {
|
|
||||||
return {
|
|
||||||
expandTarget(target: string) {
|
|
||||||
dispatch(expandTargetActions.expandTarget(target));
|
|
||||||
},
|
|
||||||
collapseTarget(target: string) {
|
|
||||||
dispatch(expandTargetActions.collapseTarget(target));
|
|
||||||
},
|
|
||||||
toggleExpandTarget(target: string) {
|
|
||||||
dispatch(expandTargetActions.toggleExpandTarget(target));
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
type mapStateToPropsType = ReturnType<typeof mapStateToProps>;
|
|
||||||
type mapDispatchToPropsType = ReturnType<typeof mapDispatchToProps>;
|
|
||||||
|
|
||||||
export {
|
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps,
|
|
||||||
mapStateToPropsType,
|
|
||||||
mapDispatchToPropsType,
|
|
||||||
};
|
|
||||||
@ -3,7 +3,7 @@
|
|||||||
import type { TargetConfiguration } from '@nx/devkit';
|
import type { TargetConfiguration } from '@nx/devkit';
|
||||||
|
|
||||||
import { JsonCodeBlock } from '@nx/graph/ui-code-block';
|
import { JsonCodeBlock } from '@nx/graph/ui-code-block';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
||||||
import { SourceInfo } from '../source-info/source-info';
|
import { SourceInfo } from '../source-info/source-info';
|
||||||
import { FadingCollapsible } from './fading-collapsible';
|
import { FadingCollapsible } from './fading-collapsible';
|
||||||
import { TargetConfigurationProperty } from './target-configuration-property';
|
import { TargetConfigurationProperty } from './target-configuration-property';
|
||||||
@ -16,33 +16,26 @@ import {
|
|||||||
} from '@nx/graph/ui-tooltips';
|
} from '@nx/graph/ui-tooltips';
|
||||||
import { TooltipTriggerText } from './tooltip-trigger-text';
|
import { TooltipTriggerText } from './tooltip-trigger-text';
|
||||||
import { Pill } from '../pill';
|
import { Pill } from '../pill';
|
||||||
import {
|
|
||||||
mapDispatchToProps,
|
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToPropsType,
|
|
||||||
mapStateToPropsType,
|
|
||||||
} from './target-configuration-details.state';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { TargetConfigurationDetailsHeader } from '../target-configuration-details-header/target-configuration-details-header';
|
import { TargetConfigurationDetailsHeader } from '../target-configuration-details-header/target-configuration-details-header';
|
||||||
|
import { ExpandedTargetsContext } from '@nx/graph/shared';
|
||||||
|
|
||||||
type TargetConfigurationDetailsProps = mapStateToPropsType &
|
interface TargetConfigurationDetailsProps {
|
||||||
mapDispatchToPropsType & {
|
projectName: string;
|
||||||
|
targetName: string;
|
||||||
|
targetConfiguration: TargetConfiguration;
|
||||||
|
sourceMap: Record<string, string[]>;
|
||||||
|
variant?: 'default' | 'compact';
|
||||||
|
onCollapse?: (targetName: string) => void;
|
||||||
|
onExpand?: (targetName: string) => void;
|
||||||
|
onRunTarget?: (data: { projectName: string; targetName: string }) => void;
|
||||||
|
onViewInTaskGraph?: (data: {
|
||||||
projectName: string;
|
projectName: string;
|
||||||
targetName: string;
|
targetName: string;
|
||||||
targetConfiguration: TargetConfiguration;
|
}) => void;
|
||||||
sourceMap: Record<string, string[]>;
|
collapsable: boolean;
|
||||||
variant?: 'default' | 'compact';
|
}
|
||||||
onCollapse?: (targetName: string) => void;
|
|
||||||
onExpand?: (targetName: string) => void;
|
|
||||||
onRunTarget?: (data: { projectName: string; targetName: string }) => void;
|
|
||||||
onViewInTaskGraph?: (data: {
|
|
||||||
projectName: string;
|
|
||||||
targetName: string;
|
|
||||||
}) => void;
|
|
||||||
collapsable: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const TargetConfigurationDetailsComponent = ({
|
export default function TargetConfigurationDetails({
|
||||||
variant,
|
variant,
|
||||||
projectName,
|
projectName,
|
||||||
targetName,
|
targetName,
|
||||||
@ -50,27 +43,28 @@ export const TargetConfigurationDetailsComponent = ({
|
|||||||
sourceMap,
|
sourceMap,
|
||||||
onViewInTaskGraph,
|
onViewInTaskGraph,
|
||||||
onRunTarget,
|
onRunTarget,
|
||||||
expandedTargets,
|
|
||||||
toggleExpandTarget,
|
|
||||||
collapsable,
|
collapsable,
|
||||||
}: TargetConfigurationDetailsProps) => {
|
}: TargetConfigurationDetailsProps) {
|
||||||
const isCompact = variant === 'compact';
|
const isCompact = variant === 'compact';
|
||||||
const [collapsed, setCollapsed] = useState(true);
|
const [collapsed, setCollapsed] = useState(true);
|
||||||
|
const { expandedTargets, toggleTarget } = useContext(ExpandedTargetsContext);
|
||||||
|
|
||||||
const handleCopyClick = async (copyText: string) => {
|
const handleCopyClick = async (copyText: string) => {
|
||||||
await window.navigator.clipboard.writeText(copyText);
|
await window.navigator.clipboard.writeText(copyText);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCollapseToggle = useCallback(() => {
|
const handleCollapseToggle = useCallback(() => {
|
||||||
toggleExpandTarget(targetName);
|
if (toggleTarget) {
|
||||||
}, [toggleExpandTarget, targetName]);
|
toggleTarget(targetName);
|
||||||
|
}
|
||||||
|
}, [toggleTarget, targetName]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!collapsable) {
|
if (!collapsable) {
|
||||||
setCollapsed(false);
|
setCollapsed(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (expandedTargets.includes(targetName)) {
|
if (expandedTargets?.includes(targetName)) {
|
||||||
setCollapsed(false);
|
setCollapsed(false);
|
||||||
} else {
|
} else {
|
||||||
setCollapsed(true);
|
setCollapsed(true);
|
||||||
@ -420,10 +414,4 @@ export const TargetConfigurationDetailsComponent = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
export const TargetConfigurationDetails = connect(
|
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(TargetConfigurationDetailsComponent);
|
|
||||||
export default TargetConfigurationDetails;
|
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
import { JSX, ReactElement, useEffect, useState } from 'react';
|
import { JSX, ReactElement, useEffect, useState } from 'react';
|
||||||
import { Provider as StoreProvider } from 'react-redux';
|
|
||||||
import { rootStore } from '@nx/graph/state';
|
|
||||||
import { ProjectDetails as ProjectDetailsUi } from '@nx/graph/ui-project-details';
|
import { ProjectDetails as ProjectDetailsUi } from '@nx/graph/ui-project-details';
|
||||||
|
|
||||||
export function Loading() {
|
export function Loading() {
|
||||||
@ -82,13 +80,11 @@ export function ProjectDetails({
|
|||||||
height ? `p-4 h-[${height}] overflow-y-auto` : 'p-4'
|
height ? `p-4 h-[${height}] overflow-y-auto` : 'p-4'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<StoreProvider store={rootStore}>
|
<ProjectDetailsUi
|
||||||
<ProjectDetailsUi
|
project={parsedProps.project}
|
||||||
project={parsedProps.project}
|
sourceMap={parsedProps.sourceMap}
|
||||||
sourceMap={parsedProps.sourceMap}
|
variant="compact"
|
||||||
variant="compact"
|
/>
|
||||||
/>
|
|
||||||
</StoreProvider>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -39,7 +39,6 @@
|
|||||||
"@nx/gradle/*": ["packages/gradle/*"],
|
"@nx/gradle/*": ["packages/gradle/*"],
|
||||||
"@nx/graph/project-details": ["graph/project-details/src/index.ts"],
|
"@nx/graph/project-details": ["graph/project-details/src/index.ts"],
|
||||||
"@nx/graph/shared": ["graph/shared/src/index.ts"],
|
"@nx/graph/shared": ["graph/shared/src/index.ts"],
|
||||||
"@nx/graph/state": ["graph/state/src/index.ts"],
|
|
||||||
"@nx/graph/ui-code-block": ["graph/ui-code-block/src/index.ts"],
|
"@nx/graph/ui-code-block": ["graph/ui-code-block/src/index.ts"],
|
||||||
"@nx/graph/ui-components": ["graph/ui-components/src/index.ts"],
|
"@nx/graph/ui-components": ["graph/ui-components/src/index.ts"],
|
||||||
"@nx/graph/ui-graph": ["graph/ui-graph/src/index.ts"],
|
"@nx/graph/ui-graph": ["graph/ui-graph/src/index.ts"],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user