chore(graph): add storybook to graph-client (#11870)

This commit is contained in:
Philip Fulcher 2022-09-15 12:54:15 -06:00 committed by GitHub
parent 40fa765282
commit fb25fdada5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 1130 additions and 74 deletions

11
.storybook/main.js Normal file
View File

@ -0,0 +1,11 @@
module.exports = {
stories: [],
addons: ['@storybook/addon-essentials'],
// uncomment the property below if you want to apply some webpack config globally
// webpackFinal: async (config, { configType }) => {
// // Make whatever fine-grained changes you need that should apply to all storybook configs
// // Return the altered config
// return config;
// },
};

14
.storybook/tsconfig.json Normal file
View File

@ -0,0 +1,14 @@
{
"extends": "../tsconfig.base.json",
"exclude": [
"../**/*.spec.js",
"../**/*.test.js",
"../**/*.spec.ts",
"../**/*.test.ts",
"../**/*.spec.tsx",
"../**/*.test.tsx",
"../**/*.spec.jsx",
"../**/*.test.jsx"
],
"include": ["../**/*"]
}

View File

@ -1,57 +0,0 @@
window.exclude = [];
window.watch = false;
window.environment = 'dev';
window.useXstateInspect = false;
window.appConfig = {
showDebugger: false,
showExperimentalFeatures: false,
projectGraphs: [
{
id: 'nx',
label: 'Nx',
url: 'assets/graphs/nx.json',
},
{
id: 'ocean',
label: 'Ocean',
url: 'assets/graphs/ocean.json',
},
{
id: 'nx-examples',
label: 'Nx Examples',
url: 'assets/graphs/nx-examples.json',
},
{
id: 'sub-apps',
label: 'Sub Apps',
url: 'assets/graphs/sub-apps.json',
},
{
id: 'storybook',
label: 'Storybook',
url: 'assets/graphs/storybook.json',
},
{
id: 'focus-testing',
label: 'Focus',
url: 'assets/graphs/focus-testing.json',
},
{
id: 'affected',
label: 'Affected',
url: 'assets/graphs/affected.json',
},
{
id: 'collapsing-edges-testing',
label: 'Collapsing Edges',
url: 'assets/graphs/collapsing-edges-testing.json',
},
{
id: 'nested-workspace-layout',
label: 'Nested Workspace Layout',
url: 'assets/graphs/nested-workspace-layout.json',
},
],
defaultProjectGraph: 'nx',
};

View File

@ -0,0 +1,24 @@
const rootMain = require('../../../.storybook/main');
module.exports = {
...rootMain,
core: { ...rootMain.core, builder: 'webpack5' },
stories: [
...rootMain.stories,
'../src/app/**/*.stories.mdx',
'../src/app/**/*.stories.@(js|jsx|ts|tsx)',
],
addons: [...rootMain.addons, '@nrwl/react/plugins/storybook'],
webpackFinal: async (config, { configType }) => {
// apply any global webpack configs that might have been specified in .storybook/main.js
if (rootMain.webpackFinal) {
config = await rootMain.webpackFinal(config, { configType });
}
// add your own webpack tweaks if needed
return config;
},
};

View File

@ -0,0 +1,19 @@
import '../src/styles.scss';
export const decorators = [
(Story, context) => {
return (
<div className="bg-white text-slate-500 dark:bg-slate-900 dark:text-slate-400">
{context.title.startsWith('Project Graph') ? (
<div className="flex justify-center">
<div className="relative flex h-full w-72 flex-col overflow-y-scroll pb-10 shadow-lg ring-1 ring-slate-900/10 ring-opacity-10 transition-all dark:ring-slate-300/10">
<Story />
</div>
</div>
) : (
<Story />
)}
</div>
);
},
];

View File

@ -0,0 +1,27 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"emitDecoratorMetadata": true,
"outDir": ""
},
"files": [
"../../../node_modules/@nrwl/react/typings/styled-jsx.d.ts",
"../../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": [
"../**/*.spec.ts",
"../**/*.spec.js",
"../**/*.spec.tsx",
"../**/*.spec.jsx"
],
"include": [
"../src/**/*.stories.ts",
"../src/**/*.stories.js",
"../src/**/*.stories.jsx",
"../src/**/*.stories.tsx",
"../src/**/*.stories.mdx",
"*.js"
]
}

View File

@ -132,6 +132,37 @@
"jestConfig": "graph/client/jest.config.ts", "jestConfig": "graph/client/jest.config.ts",
"passWithNoTests": true "passWithNoTests": true
} }
},
"storybook": {
"executor": "@nrwl/storybook:storybook",
"options": {
"uiFramework": "@storybook/react",
"port": 4400,
"config": {
"configFolder": "graph/client/.storybook"
}
},
"configurations": {
"ci": {
"quiet": true
}
}
},
"build-storybook": {
"executor": "@nrwl/storybook:build",
"outputs": ["{options.outputPath}"],
"options": {
"uiFramework": "@storybook/react",
"outputPath": "dist/storybook/graph-client",
"config": {
"configFolder": "graph/client/.storybook"
}
},
"configurations": {
"ci": {
"quiet": true
}
}
} }
}, },
"tags": [] "tags": []

View File

@ -0,0 +1,36 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { DebuggerPanel, DebuggerPanelProps } from './debugger-panel';
export default {
component: DebuggerPanel,
title: 'Shell/DebuggerPanel',
argTypes: {
projectGraphChange: { action: 'projectGraphChange' },
},
} as ComponentMeta<typeof DebuggerPanel>;
const Template: ComponentStory<typeof DebuggerPanel> = (args) => (
<DebuggerPanel {...args} />
);
export const Primary = Template.bind({});
Primary.args = {
projectGraphs: [
{
url: 'some-graph.json',
label: 'Some graph',
id: 'some-graph',
},
{
url: 'another-graph.json',
label: 'Another graph',
id: 'another-graph',
},
],
selectedProjectGraph: 'another-graph',
lastPerfReport: {
numEdges: 20,
numNodes: 10,
renderTime: 500,
},
};

View File

@ -0,0 +1,30 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { EdgeNodeTooltip, EdgeNodeTooltipProps } from './edge-tooltip';
import ProjectNodeToolTip from './project-node-tooltip';
import { selectValueByThemeStatic } from './theme-resolver';
import Tippy from '@tippyjs/react';
export default {
component: EdgeNodeTooltip,
title: 'Tooltips/EdgeNodeTooltip',
} as ComponentMeta<typeof EdgeNodeTooltip>;
const Template: ComponentStory<typeof EdgeNodeTooltip> = (args) => (
<Tippy
content={<EdgeNodeTooltip {...args} />}
visible={true}
theme="nx"
interactive={true}
maxWidth="none"
>
<p></p>
</Tippy>
);
export const Primary = Template.bind({});
Primary.args = {
type: 'static',
target: 'lib1',
source: 'lib2',
fileDependencies: [{ fileName: 'some/file.ts' }],
} as EdgeNodeTooltipProps;

View File

@ -4,7 +4,8 @@ export interface EdgeNodeTooltipProps {
target: string; target: string;
fileDependencies: Array<{ fileName: string }>; fileDependencies: Array<{ fileName: string }>;
} }
function EdgeNodeTooltip({
export function EdgeNodeTooltip({
type, type,
source, source,
target, target,
@ -23,7 +24,10 @@ function EdgeNodeTooltip({
</div> </div>
<ul className="max-h-[300px] divide-y divide-slate-200 overflow-auto dark:divide-slate-800"> <ul className="max-h-[300px] divide-y divide-slate-200 overflow-auto dark:divide-slate-800">
{fileDependencies.map((fileDep) => ( {fileDependencies.map((fileDep) => (
<li className="whitespace-nowrap px-4 py-2 text-sm font-medium text-slate-800 dark:text-slate-300"> <li
key={fileDep.fileName}
className="whitespace-nowrap px-4 py-2 text-sm font-medium text-slate-800 dark:text-slate-300"
>
<span className="block truncate font-normal"> <span className="block truncate font-normal">
{fileDep.fileName} {fileDep.fileName}
</span> </span>

View File

@ -0,0 +1,31 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import {
ProjectNodeToolTip,
ProjectNodeToolTipProps,
} from './project-node-tooltip';
import Tippy from '@tippyjs/react';
export default {
component: ProjectNodeToolTip,
title: 'Tooltips/ProjectNodeToolTip',
} as ComponentMeta<typeof ProjectNodeToolTip>;
const Template: ComponentStory<typeof ProjectNodeToolTip> = (args) => (
<Tippy
content={<ProjectNodeToolTip {...args} />}
visible={true}
theme="nx"
interactive={true}
maxWidth="none"
>
<p></p>
</Tippy>
);
export const Primary = Template.bind({});
const args: ProjectNodeToolTipProps = {
type: 'app',
tags: ['type:app', 'scope:store'],
id: 'store',
};
Primary.args = args;

View File

@ -6,7 +6,11 @@ export interface ProjectNodeToolTipProps {
tags: string[]; tags: string[];
} }
function ProjectNodeToolTip({ type, id, tags }: ProjectNodeToolTipProps) { export function ProjectNodeToolTip({
type,
id,
tags,
}: ProjectNodeToolTipProps) {
const depGraphService = getDepGraphService(); const depGraphService = getDepGraphService();
function onFocus() { function onFocus() {

View File

@ -0,0 +1,23 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import {
CollapseEdgesPanel,
CollapseEdgesPanelProps,
} from './collapse-edges-panel';
export default {
component: CollapseEdgesPanel,
title: 'Project Graph/CollapseEdgesPanel',
argTypes: {
collapseEdges: Boolean,
collapseEdgesChanged: { action: 'collapseEdgesChanged' },
},
} as ComponentMeta<typeof CollapseEdgesPanel>;
const Template: ComponentStory<typeof CollapseEdgesPanel> = (args) => (
<CollapseEdgesPanel {...args} />
);
export const Primary = Template.bind({});
Primary.args = {
collapseEdges: false,
};

View File

@ -0,0 +1,20 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import {
FocusedProjectPanel,
FocusedProjectPanelProps,
} from './focused-project-panel';
export default {
component: FocusedProjectPanel,
title: 'Project Graph/FocusedProjectPanel',
argTypes: { resetFocus: { action: 'resetFocus' } },
} as ComponentMeta<typeof FocusedProjectPanel>;
const Template: ComponentStory<typeof FocusedProjectPanel> = (args) => (
<FocusedProjectPanel {...args} />
);
export const Primary = Template.bind({});
Primary.args = {
focusedProject: 'store',
};

View File

@ -0,0 +1,20 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import {
DisplayOptionsPanelProps,
GroupByFolderPanel,
} from './group-by-folder-panel';
export default {
component: GroupByFolderPanel,
title: 'Project Graph/GroupByFolderPanel',
argTypes: { groupByFolderChanged: { action: 'groupByFolderChanged' } },
} as ComponentMeta<typeof GroupByFolderPanel>;
const Template: ComponentStory<typeof GroupByFolderPanel> = (args) => (
<GroupByFolderPanel {...args} />
);
export const Primary = Template.bind({});
Primary.args = {
groupByFolder: false,
};

View File

@ -0,0 +1,24 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { SearchDepth, SearchDepthProps } from './search-depth';
export default {
component: SearchDepth,
title: 'Project Graph/SearchDepth',
argTypes: {
searchDepthFilterEnabledChange: {
action: 'searchDepthFilterEnabledChange',
},
decrementDepthFilter: { action: 'decrementDepthFilter' },
incrementDepthFilter: { action: 'incrementDepthFilter' },
},
} as ComponentMeta<typeof SearchDepth>;
const Template: ComponentStory<typeof SearchDepth> = (args) => (
<SearchDepth {...args} />
);
export const Primary = Template.bind({});
Primary.args = {
searchDepthEnabled: false,
searchDepth: 1,
};

View File

@ -0,0 +1,29 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import {
ShowHideAllProjects,
ShowHideAllProjectsProps,
} from './show-hide-projects';
export default {
component: ShowHideAllProjects,
title: 'Project Graph/ShowHideAllProjects',
argTypes: {
hideAllProjects: { action: 'hideAllProjects' },
showAffectedProjects: { action: 'showAffectedProjects' },
showAllProjects: { action: 'showAllProjects' },
},
} as ComponentMeta<typeof ShowHideAllProjects>;
const Template: ComponentStory<typeof ShowHideAllProjects> = (args) => (
<ShowHideAllProjects {...args} />
);
export const Primary = Template.bind({});
Primary.args = {
hasAffectedProjects: false,
};
export const Affected = Template.bind({});
Affected.args = {
hasAffectedProjects: true,
};

View File

@ -0,0 +1,26 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { TextFilterPanel, TextFilterPanelProps } from './text-filter-panel';
export default {
component: TextFilterPanel,
title: 'Project Graph/TextFilterPanel',
argTypes: {
resetTextFilter: { action: 'resetTextFilter' },
toggleIncludeLibsInPathChange: {
action: 'toggleIncludeLibsInPathChange',
},
updateTextFilter: {
action: 'updateTextFilter',
},
},
} as ComponentMeta<typeof TextFilterPanel>;
const Template: ComponentStory<typeof TextFilterPanel> = (args) => (
<TextFilterPanel {...args} />
);
export const Primary = Template.bind({});
Primary.args = {
includePath: false,
textFilter: 'some-lib',
};

View File

@ -0,0 +1,12 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import ThemePanel from './theme-panel';
export default {
component: ThemePanel,
title: 'Project Graph/ThemePanel',
} as ComponentMeta<typeof ThemePanel>;
const Template: ComponentStory<typeof ThemePanel> = () => <ThemePanel />;
export const Primary = Template.bind({});
Primary.args = {};

View File

@ -0,0 +1,23 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { TracingPanel, TracingPanelProps } from './tracing-panel';
export default {
component: TracingPanel,
title: 'Project Graph/TracingPanel',
argTypes: {
resetEnd: { action: 'resetEnd' },
resetStart: { action: 'resetStart' },
setAlgorithm: { action: 'setAlgorithm' },
},
} as ComponentMeta<typeof TracingPanel>;
const Template: ComponentStory<typeof TracingPanel> = (args) => (
<TracingPanel {...args} />
);
export const Primary = Template.bind({});
Primary.args = {
end: 'shared-ui',
start: 'store',
algorithm: 'shortest',
};

View File

@ -18,7 +18,11 @@
"**/*.test.js", "**/*.test.js",
"**/*.spec.jsx", "**/*.spec.jsx",
"**/*.test.jsx", "**/*.test.jsx",
"jest.config.ts" "jest.config.ts",
"**/*.stories.ts",
"**/*.stories.js",
"**/*.stories.jsx",
"**/*.stories.tsx"
], ],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
} }

View File

@ -12,6 +12,9 @@
}, },
{ {
"path": "./tsconfig.spec.json" "path": "./tsconfig.spec.json"
},
{
"path": "./.storybook/tsconfig.json"
} }
] ]
} }

View File

@ -16,7 +16,8 @@
"build-base", "build-base",
"test", "test",
"sitemap", "sitemap",
"e2e" "e2e",
"build-storybook"
], ],
"useDaemonProcess": true, "useDaemonProcess": true,
"cacheDirectory": "/tmp/nx-cache", "cacheDirectory": "/tmp/nx-cache",

View File

@ -44,7 +44,9 @@
"@angular/router": "~14.2.0", "@angular/router": "~14.2.0",
"@angular/service-worker": "~14.2.0", "@angular/service-worker": "~14.2.0",
"@angular/upgrade": "~14.2.0", "@angular/upgrade": "~14.2.0",
"@babel/core": "^7.15.0",
"@babel/helper-create-regexp-features-plugin": "^7.14.5", "@babel/helper-create-regexp-features-plugin": "^7.14.5",
"@babel/preset-typescript": "^7.15.0",
"@cypress/react": "^6.0.0", "@cypress/react": "^6.0.0",
"@cypress/webpack-preprocessor": "^5.12.0", "@cypress/webpack-preprocessor": "^5.12.0",
"@nestjs/common": "^9.0.0", "@nestjs/common": "^9.0.0",
@ -84,8 +86,10 @@
"@storybook/addon-essentials": "~6.5.9", "@storybook/addon-essentials": "~6.5.9",
"@storybook/addon-knobs": "~6.3.0", "@storybook/addon-knobs": "~6.3.0",
"@storybook/angular": "~6.5.9", "@storybook/angular": "~6.5.9",
"@storybook/builder-webpack5": "~6.5.9",
"@storybook/core": "~6.5.9", "@storybook/core": "~6.5.9",
"@storybook/core-server": "~6.5.9", "@storybook/core-server": "~6.5.9",
"@storybook/manager-webpack5": "~6.5.9",
"@storybook/react": "~6.5.9", "@storybook/react": "~6.5.9",
"@svgr/webpack": "^6.1.2", "@svgr/webpack": "^6.1.2",
"@swc-node/register": "^1.4.2", "@swc-node/register": "^1.4.2",
@ -125,6 +129,7 @@
"angular": "1.8.0", "angular": "1.8.0",
"autoprefixer": "^10.4.9", "autoprefixer": "^10.4.9",
"babel-jest": "28.1.3", "babel-jest": "28.1.3",
"babel-loader": "^8.2.2",
"chalk": "4.1.0", "chalk": "4.1.0",
"chokidar": "^3.5.1", "chokidar": "^3.5.1",
"commitizen": "^4.0.3", "commitizen": "^4.0.3",
@ -263,7 +268,8 @@
"xstate": "^4.25.0", "xstate": "^4.25.0",
"yargs": "^17.4.0", "yargs": "^17.4.0",
"yargs-parser": "21.0.1", "yargs-parser": "21.0.1",
"zone.js": "~0.11.4" "zone.js": "~0.11.4",
"@nrwl/storybook": "14.7.0-beta.1"
}, },
"author": "Victor Savkin", "author": "Victor Savkin",
"license": "MIT", "license": "MIT",

View File

@ -5,7 +5,7 @@ import { satisfies } from 'semver';
const IGNORE_MATCHES = { const IGNORE_MATCHES = {
'*': [], '*': [],
angular: ['webpack-merge', '@phenomnomnominal/tsquery'], angular: ['webpack-merge', '@phenomnomnominal/tsquery'],
cypress: ['webpack'], cypress: ['webpack', '@babel/core', 'babel-loader'],
}; };
export default function getDiscrepancies( export default function getDiscrepancies(

711
yarn.lock

File diff suppressed because it is too large Load Diff