Skip to content

Commit

Permalink
Merge pull request #53 from chromaui/tom/ap-3562-send-main-config-loc…
Browse files Browse the repository at this point in the history
…ation-on-successfailure

Send mainPath and configDir on update success/failure
  • Loading branch information
Matthew Weeks authored Aug 29, 2023
2 parents 7576b70 + 1f7b002 commit 792ed16
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 58 deletions.
7 changes: 5 additions & 2 deletions src/Panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,16 @@ export const Panel = ({ active, api }: PanelProps) => {
},
[api]
);
const [
const {
projectId,
projectToken,
configDir,
mainPath,
updateProject,
projectUpdatingFailed,
projectIdUpdated,
clearProjectIdUpdated,
] = useProjectId();
} = useProjectId();

// Render a hidden element when the addon panel is not active.
// Storybook's AddonPanel component does the same but it's not styleable so we don't use it.
Expand All @@ -109,6 +110,7 @@ export const Panel = ({ active, api }: PanelProps) => {
<LinkingProjectFailed
projectId={projectId}
projectToken={projectToken}
mainPath={mainPath}
configDir={configDir}
/>
);
Expand All @@ -119,6 +121,7 @@ export const Panel = ({ active, api }: PanelProps) => {
<Provider key={PANEL_ID} value={client}>
<LinkedProject
projectId={projectId}
mainPath={mainPath}
goToNext={clearProjectIdUpdated}
setAccessToken={setAccessToken}
/>
Expand Down
5 changes: 5 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ export type UpdateProjectPayload = {
};

export const PROJECT_UPDATED = `${ADDON_ID}/projectUpdated`;
export type ProjectUpdatedPayload = {
mainPath: string;
configDir: string;
};
export const PROJECT_UPDATING_FAILED = `${ADDON_ID}/projectUpdatingFailed`;
export type ProjectUpdatingFailedPayload = {
mainPath?: string;
configDir: string;
};
16 changes: 12 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import type { Channel } from "@storybook/channels";
// eslint-disable-next-line import/no-unresolved
import { getGitInfo, GitInfo, run } from "chromatic/node";
import { relative } from "path";
import { basename, relative } from "path";

import {
BUILD_ANNOUNCED,
Expand All @@ -12,11 +12,13 @@ import {
GitInfoPayload,
PROJECT_UPDATED,
PROJECT_UPDATING_FAILED,
ProjectUpdatedPayload,
ProjectUpdatingFailedPayload,
START_BUILD,
UPDATE_PROJECT,
UpdateProjectPayload,
} from "./constants";
import { findConfig } from "./utils/storybook.config.utils";
import { updateMain } from "./utils/updateMain";

/**
Expand Down Expand Up @@ -94,13 +96,19 @@ async function serverChannel(
async ({ projectId, projectToken: updatedProjectToken }: UpdateProjectPayload) => {
projectToken = updatedProjectToken;

const relativeConfigDir = relative(process.cwd(), configDir);
let mainPath: string;
try {
await updateMain({ configDir, projectId, projectToken });
channel.emit(PROJECT_UPDATED);
mainPath = await findConfig(configDir, "main");
await updateMain({ mainPath, projectId, projectToken });
channel.emit(PROJECT_UPDATED, {
mainPath: basename(mainPath),
configDir: relativeConfigDir,
} satisfies ProjectUpdatedPayload);
} catch (err) {
console.warn(`Failed to update your main configuration:\n\n ${err}`);
const relativeConfigDir = relative(process.cwd(), configDir);
channel.emit(PROJECT_UPDATING_FAILED, {
mainPath: mainPath && basename(mainPath),
configDir: relativeConfigDir,
} satisfies ProjectUpdatingFailedPayload);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ import { action } from "@storybook/addon-actions";
import type { Meta, StoryObj } from "@storybook/react";
import { findByTestId } from "@storybook/testing-library";
import { graphql } from "msw";
import React from "react";

import { ProjectQueryQuery, SelectProjectsQueryQuery } from "../../gql/graphql";
import { SelectProjectsQueryQuery } from "../../gql/graphql";
import { storyWrapper } from "../../utils/graphQLClient";
import { playAll } from "../../utils/playAll";
import { withFigmaDesign } from "../../utils/withFigmaDesign";
import { LinkedProject } from "./LinkedProject";
import { LinkProject } from "./LinkProject";

const meta = {
Expand Down Expand Up @@ -239,35 +237,6 @@ export const SelectProjectManyProjects: Story = {
await leftDiv.scroll({ top: leftDiv.scrollHeight });
}),
};
export const Linked: Story = {
render: () => (
<LinkedProject
projectId="789"
goToNext={action("goToNext")}
setAccessToken={action("setAccessToken")}
/>
),
parameters: {
...withGraphQLQuery("ProjectQuery", (req, res, ctx) =>
res(
ctx.data({
project: {
id: "789",
name: "acme",
webUrl: "https://www.chromatic.com/builds?appId=789",
lastBuild: {
branch: "main",
number: 123,
},
},
} satisfies ProjectQueryQuery)
)
),
...withFigmaDesign(
"https://www.figma.com/file/GFEbCgCVDtbZhngULbw2gP/Visual-testing-in-Storybook?type=design&node-id=508-317094&t=435fylbu7gUQNEgq-4"
),
},
};

export const EmptyNoAccounts: Story = {
parameters: {
Expand Down
50 changes: 50 additions & 0 deletions src/screens/LinkProject/LinkedProject.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { action } from "@storybook/addon-actions";
import type { Meta, StoryObj } from "@storybook/react";
import { graphql } from "msw";

import { ProjectQueryQuery } from "../../gql/graphql";
import { storyWrapper } from "../../utils/graphQLClient";
import { withFigmaDesign } from "../../utils/withFigmaDesign";
import { LinkedProject } from "./LinkedProject";

const withGraphQLQuery = (...args: Parameters<typeof graphql.query>) => ({
msw: {
handlers: [graphql.query(...args)],
},
});

const meta = {
component: LinkedProject,
args: {
projectId: "Project:abc123",
mainPath: "main.ts",
goToNext: action("goToNext"),
setAccessToken: action("setAccessToken"),
},
decorators: [storyWrapper],
parameters: {
...withGraphQLQuery("ProjectQuery", (req, res, ctx) =>
res(
ctx.data({
project: {
id: "789",
name: "acme",
webUrl: "https://www.chromatic.com/builds?appId=789",
lastBuild: {
branch: "main",
number: 123,
},
},
} satisfies ProjectQueryQuery)
)
),
...withFigmaDesign(
"https://www.figma.com/file/GFEbCgCVDtbZhngULbw2gP/Visual-testing-in-Storybook?type=design&node-id=508-317094&t=435fylbu7gUQNEgq-4"
),
},
} satisfies Meta<typeof LinkedProject>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {};
6 changes: 4 additions & 2 deletions src/screens/LinkProject/LinkedProject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ const ProjectQuery = graphql(/* GraphQL */ `

export const LinkedProject = ({
projectId,
mainPath,
goToNext,
setAccessToken,
}: {
projectId: string;
mainPath: string;
goToNext: () => void;
setAccessToken: (accessToken: string | null) => void;
}) => {
Expand All @@ -62,8 +64,8 @@ export const LinkedProject = ({
<Heading>Project linked!</Heading>
<Text style={{ maxWidth: 380 }}>
The <code>projectId</code> for {data.project.name} has been added to this
Storybook&apos;s <code>main.js</code>. This will be used to sync with Chromatic.
Please commit this change to continue using this addon.
Storybook&apos;s <code>{mainPath}</code>. This will be used to sync with
Chromatic. Please commit this change to continue using this addon.
</Text>
<Button secondary onClick={() => goToNext()}>
Catch a UI change
Expand Down
6 changes: 6 additions & 0 deletions src/screens/LinkProject/LinkingProjectFailed.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,9 @@ export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {};

export const WithMainPath: Story = {
args: {
mainPath: "main.ts",
},
};
4 changes: 3 additions & 1 deletion src/screens/LinkProject/LinkingProjectFailed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type LinkingProjectFailedProps = {
projectId: string;
projectToken: string;
configDir: string;
mainPath?: string;
};

const addonName = "@chromaui/addon-visual-tests";
Expand All @@ -20,6 +21,7 @@ export function LinkingProjectFailed({
projectId,
projectToken,
configDir,
mainPath,
}: LinkingProjectFailedProps) {
return (
<Sections>
Expand All @@ -32,7 +34,7 @@ export function LinkingProjectFailed({
</CenterText>
<Code>
{dedent`
// ${configDir}/main.js|ts|tsx
// ${configDir}/${mainPath ?? `main.js|ts|tsx`}
module.exports = {
// ...,
Expand Down
6 changes: 2 additions & 4 deletions src/utils/updateMain.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { readConfig, writeConfig } from "@storybook/csf-tools";

import { CHROMATIC_ADDON_NAME } from "../constants";
import { findConfig } from "./storybook.config.utils";

export async function updateMain({
projectId,
projectToken,
configDir,
mainPath,
}: {
projectId: string;
projectToken: string;
configDir: string;
mainPath: string;
}) {
const mainPath = await findConfig(configDir, "main");
const MainConfig = await readConfig(mainPath);

const addonsConfig = MainConfig.getFieldValue(["addons"]);
Expand Down
26 changes: 13 additions & 13 deletions src/utils/useProjectId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,31 @@ import React from "react";
import {
PROJECT_UPDATED,
PROJECT_UPDATING_FAILED,
ProjectUpdatedPayload,
ProjectUpdatingFailedPayload,
UPDATE_PROJECT,
UpdateProjectPayload,
} from "../constants";

const { CHROMATIC_PROJECT_ID } = process.env;

export const useProjectId = (): [
projectId: string,
projectToken: string,
configDir: string,
updateProject: (projectId: string, projectToken?: string) => void,
projectUpdatingFailed: boolean,
projectIdUpdated: boolean,
clearProjectIdUpdated: () => void
] => {
export const useProjectId = () => {
const [projectId, setProjectId] = React.useState<string | null>(CHROMATIC_PROJECT_ID);
const [projectToken, setProjectToken] = React.useState<string | null>();
const [projectIdUpdated, setProjectIdUpdated] = React.useState(false);
const [projectUpdatingFailed, setProjectUpdatingFailed] = React.useState(false);
const [mainPath, setMainPath] = React.useState<string | null>();
const [configDir, setConfigDir] = React.useState<string | null>();

const emit = useChannel({
[PROJECT_UPDATED]: () => setProjectIdUpdated(true),
[PROJECT_UPDATED]: (payload: ProjectUpdatedPayload) => {
setProjectIdUpdated(true);
setMainPath(payload.mainPath);
setConfigDir(payload.configDir);
},
[PROJECT_UPDATING_FAILED]: (payload: ProjectUpdatingFailedPayload) => {
setProjectUpdatingFailed(true);
setMainPath(payload.mainPath);
setConfigDir(payload.configDir);
},
});
Expand All @@ -42,13 +41,14 @@ export const useProjectId = (): [
setProjectId(newProjectId);
setProjectToken(newProjectToken);
};
return [
return {
projectId,
projectToken,
configDir,
mainPath,
updateProject,
projectUpdatingFailed,
projectIdUpdated,
() => setProjectIdUpdated(false),
];
clearProjectIdUpdated: () => setProjectIdUpdated(false),
};
};

0 comments on commit 792ed16

Please sign in to comment.