Setup chromatic and cleanup storybook (#3588)

This commit is contained in:
Krzysztof Żuraw 2023-05-12 13:06:27 +02:00 committed by GitHub
parent b9bf19ddfb
commit 50c8e93534
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
139 changed files with 15566 additions and 18270 deletions

View file

@ -0,0 +1,35 @@
name: QA
on: [pull_request]
jobs:
chromatic-storybook:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version-file: ".nvmrc"
- name: Cache node modules
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-qa-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-qa-${{ env.cache-name }}-
${{ runner.os }}-qa-
${{ runner.os }}-
- name: Install deps
run: npm ci
- name: Publish to Chromatic
uses: chromaui/action@a89b674adf766dbde41ad9ea2b2b60b91188a0f0 # v6.17.4
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}

View file

@ -49,7 +49,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-node@v3 - uses: actions/setup-node@v3
with: with:
node-version-file: '.nvmrc' node-version-file: ".nvmrc"
- name: Cache node modules - name: Cache node modules
uses: actions/cache@v2 uses: actions/cache@v2
env: env:

1
.gitignore vendored
View file

@ -21,6 +21,7 @@
!.travis* !.travis*
!.tx !.tx
!.husky !.husky
!.storybook
*.log *.log
*.pyc *.pyc
*.mo *.mo

View file

@ -1,7 +1,8 @@
import { Card, CardContent } from "@material-ui/core"; import { Card, CardContent } from "@material-ui/core";
import { Decorator } from "@storybook/react";
import React from "react"; import React from "react";
const CardDecorator = storyFn => ( export const CardDecorator: Decorator = Story => (
<Card <Card
style={{ style={{
margin: "auto", margin: "auto",
@ -10,7 +11,8 @@ const CardDecorator = storyFn => (
width: 400, width: 400,
}} }}
> >
<CardContent>{storyFn()}</CardContent> <CardContent>
<Story />
</CardContent>
</Card> </Card>
); );
export default CardDecorator;

View file

@ -1,22 +1,23 @@
import "@saleor/macaw-ui/next/style"; import "@saleor/macaw-ui/next/style";
import { ExternalAppProvider } from "@dashboard/apps/components/ExternalAppContext";
import { Locale, RawLocaleProvider } from "@dashboard/components/Locale";
import { FlagsServiceProvider } from "@dashboard/hooks/useFlags/flagsService";
import { paletteOverrides, themeOverrides } from "@dashboard/themeOverrides";
import { ThemeProvider as LegacyThemeProvider } from "@saleor/macaw-ui"; import { ThemeProvider as LegacyThemeProvider } from "@saleor/macaw-ui";
import { ThemeProvider } from "@saleor/macaw-ui/next"; import { ThemeProvider } from "@saleor/macaw-ui/next";
import React from "react"; import React from "react";
import { IntlProvider } from "react-intl"; import { IntlProvider } from "react-intl";
import { BrowserRouter } from "react-router-dom"; import { BrowserRouter } from "react-router-dom";
import { ExternalAppProvider } from "../../src/apps/components/ExternalAppContext";
import { DevModeProvider } from "../../src/components/DevModePanel/DevModeProvider";
import { Locale, RawLocaleProvider } from "../../src/components/Locale";
import { FlagsServiceProvider } from "../../src/hooks/useFlags/flagsService";
import { paletteOverrides, themeOverrides } from "../../src/themeOverrides";
import { Provider as DateProvider } from "../../src/components/Date/DateContext";
import { TimezoneProvider } from "../../src/components/Timezone";
import MessageManagerProvider from "../../src/components/messages";
import { getAppMountUri } from "../../src/config";
import { ApolloMockedProvider } from "../../testUtils/ApolloMockedProvider"; import { ApolloMockedProvider } from "../../testUtils/ApolloMockedProvider";
import { Provider as DateProvider } from "../components/Date/DateContext";
import MessageManagerProvider from "../components/messages";
import { TimezoneProvider } from "../components/Timezone";
import { getAppMountUri } from "../config";
export const Decorator = storyFn => ( export const MockedProvidersDecorator: React.FC = ({ children }) => (
<ApolloMockedProvider> <ApolloMockedProvider>
<IntlProvider defaultLocale={Locale.EN} locale={Locale.EN}> <IntlProvider defaultLocale={Locale.EN} locale={Locale.EN}>
<RawLocaleProvider <RawLocaleProvider
@ -36,13 +37,15 @@ export const Decorator = storyFn => (
<ExternalAppProvider> <ExternalAppProvider>
<FlagsServiceProvider> <FlagsServiceProvider>
<MessageManagerProvider> <MessageManagerProvider>
<DevModeProvider>
<div <div
style={{ style={{
padding: 24, padding: 24,
}} }}
> >
{storyFn()} {children}
</div> </div>
</DevModeProvider>
</MessageManagerProvider> </MessageManagerProvider>
</FlagsServiceProvider> </FlagsServiceProvider>
</ExternalAppProvider> </ExternalAppProvider>
@ -55,4 +58,3 @@ export const Decorator = storyFn => (
</IntlProvider> </IntlProvider>
</ApolloMockedProvider> </ApolloMockedProvider>
); );
export default Decorator;

View file

@ -0,0 +1,10 @@
import { Decorator } from "@storybook/react";
import React from "react";
import { paginatorContextValues } from "../../src/fixtures";
import { PaginatorContext } from "../../src/hooks/usePaginator";
export const PaginatorContextDecorator: Decorator = Story => (
<PaginatorContext.Provider value={paginatorContextValues}>
<Story />
</PaginatorContext.Provider>
);

View file

@ -0,0 +1,3 @@
export * from "./CardDecorator";
export * from "./MockedProvidersDecorator";
export * from "./PaginatorContextDecorator";

View file

@ -1,7 +1,7 @@
import { UserContext } from "@dashboard/auth";
import { adminUserPermissions } from "@dashboard/fixtures";
import { UserFragment } from "@dashboard/graphql";
import * as React from "react"; import * as React from "react";
import { UserContext } from "../../src/auth";
import { adminUserPermissions } from "../../src/fixtures";
import { UserFragment } from "../../src/graphql";
export const MockedUserProvider: React.FC<{ export const MockedUserProvider: React.FC<{
customPermissions?: UserFragment["userPermissions"]; customPermissions?: UserFragment["userPermissions"];

View file

@ -0,0 +1,2 @@
export * from "./MockedUserProvider";
export * from "./formError";

42
.storybook/main.ts Normal file
View file

@ -0,0 +1,42 @@
import { withoutVitePlugins } from "@storybook/builder-vite";
import type { StorybookConfig } from "@storybook/react-vite";
import { resolve } from "path";
import { mergeConfig } from "vite";
const config: StorybookConfig = {
stories: ["../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
],
framework: {
name: "@storybook/react-vite",
options: {},
},
docs: {
autodocs: "tag",
},
features: {
storyStoreV7: true,
},
async viteFinal(config) {
config.plugins = await withoutVitePlugins(config.plugins, ["vite:html"]);
return mergeConfig(config, {
build: {
commonjsOptions: {
transformMixedEsModules: true,
},
},
resolve: {
alias: {
"@material-ui/lab": resolve("./node_modules/@material-ui/lab"),
},
},
});
},
};
export default config;

View file

@ -1,2 +1,3 @@
<div id="dashboard-app"></div>
<div id="portal"></div> <div id="portal"></div>
<div id="modal-root"></div> <div id="modal-root"></div>

View file

@ -2,6 +2,7 @@
window.__SALEOR_CONFIG__ = { window.__SALEOR_CONFIG__ = {
API_URL: "", API_URL: "",
APP_MOUNT_URI: "/", APP_MOUNT_URI: "/",
IS_CLOUD_INSTANCE: "", IS_CLOUD_INSTANCE: false,
}; };
window.process = { cwd: () => "" };
</script> </script>

25
.storybook/preview.tsx Normal file
View file

@ -0,0 +1,25 @@
import "@saleor/macaw-ui/next/style";
import type { Decorator, Preview } from "@storybook/react";
import React from "react";
import { MockedProvidersDecorator } from "./decorators";
export const preview: Preview = {
parameters: {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
},
};
export const decorators: Decorator[] = [
Story => (
<MockedProvidersDecorator>
<Story />
</MockedProvidersDecorator>
),
];

View file

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

28460
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -150,6 +150,7 @@
"babel-core": "^7.0.0-bridge.0", "babel-core": "^7.0.0-bridge.0",
"babel-jest": "^27.5.1", "babel-jest": "^27.5.1",
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
"babel-plugin-macros": "^3.1.0",
"ci-info": "^3.7.0", "ci-info": "^3.7.0",
"codecov": "^3.7.1", "codecov": "^3.7.1",
"core-js": "^3.7.0", "core-js": "^3.7.0",
@ -159,7 +160,6 @@
"dotenv": "^10.0.0", "dotenv": "^10.0.0",
"env-var": "^7.3.0", "env-var": "^7.3.0",
"esbuild-loader": "^2.18.0", "esbuild-loader": "^2.18.0",
"fork-ts-checker-webpack-plugin": "^3.1.1",
"graphql-request": "^3.7.0", "graphql-request": "^3.7.0",
"identity-obj-proxy": "^3.0.0", "identity-obj-proxy": "^3.0.0",
"is-ci": "^3.0.1", "is-ci": "^3.0.1",
@ -171,7 +171,6 @@
"rimraf": "^3.0.0", "rimraf": "^3.0.0",
"rollup-plugin-polyfill-node": "^0.11.0", "rollup-plugin-polyfill-node": "^0.11.0",
"start-server-and-test": "^1.11.0", "start-server-and-test": "^1.11.0",
"tsconfig-paths-webpack-plugin": "^3.2.0",
"typescript": "^5.0.2", "typescript": "^5.0.2",
"vite": "^3.2.4", "vite": "^3.2.4",
"vite-plugin-html": "^3.2.0", "vite-plugin-html": "^3.2.0",
@ -184,7 +183,11 @@
"workbox-strategies": "^6.1.2" "workbox-strategies": "^6.1.2"
}, },
"optionalDependencies": { "optionalDependencies": {
"@storybook/react": "^5.1.9", "@storybook/addon-essentials": "^7.0.8",
"@storybook/addon-interactions": "^7.0.8",
"@storybook/addon-links": "^7.0.8",
"@storybook/react": "^7.0.8",
"@storybook/react-vite": "^7.0.8",
"@swc/core-darwin-arm64": "1.3.40", "@swc/core-darwin-arm64": "1.3.40",
"@swc/core-darwin-x64": "1.3.40", "@swc/core-darwin-x64": "1.3.40",
"@swc/core-linux-arm-gnueabihf": "1.3.40", "@swc/core-linux-arm-gnueabihf": "1.3.40",
@ -201,7 +204,7 @@
"@testing-library/user-event": "^14.4.3", "@testing-library/user-event": "^14.4.3",
"@types/jest": "^26.0.14", "@types/jest": "^26.0.14",
"@types/setup-polly-jest": "^0.5.0", "@types/setup-polly-jest": "^0.5.0",
"@types/storybook__react": "^4.0.2", "chromatic": "^6.17.4",
"cypress": "^12.4.0", "cypress": "^12.4.0",
"cypress-file-upload": "^5.0.8", "cypress-file-upload": "^5.0.8",
"cypress-mailhog": "^1.3.0", "cypress-mailhog": "^1.3.0",
@ -234,6 +237,7 @@
"mochawesome-report-generator": "^6.0.1", "mochawesome-report-generator": "^6.0.1",
"prettier": "^2.8.4", "prettier": "^2.8.4",
"setup-polly-jest": "^0.9.1", "setup-polly-jest": "^0.9.1",
"storybook": "^7.0.8",
"ts-jest": "^27.1.5" "ts-jest": "^27.1.5"
}, },
"//@swc/*": "swc packages are required until https://github.com/npm/cli/issues/4828 is fixed", "//@swc/*": "swc packages are required until https://github.com/npm/cli/issues/4828 is fixed",
@ -294,7 +298,7 @@
"dev": "vite --host", "dev": "vite --host",
"build": "cross-env NODE_OPTIONS=--max_old_space_size=16384 vite build", "build": "cross-env NODE_OPTIONS=--max_old_space_size=16384 vite build",
"preview": "vite preview", "preview": "vite preview",
"build-storybook": "cross-env NODE_OPTIONS=--openssl-legacy-provider build-storybook -c src/storybook/ -o build/storybook", "build-storybook": "cross-env NODE_OPTIONS=--max_old_space_size=16384 storybook build -o build/storybook",
"build-types": "node scripts/build-types.js", "build-types": "node scripts/build-types.js",
"prebuild": "npm run build-types", "prebuild": "npm run build-types",
"check-strict-null-errors": "tsc --noEmit --strictNullChecks | node scripts/count-strict-null-check-errors.js", "check-strict-null-errors": "tsc --noEmit --strictNullChecks | node scripts/count-strict-null-check-errors.js",
@ -305,7 +309,7 @@
"heroku-postbuild": "npm run build", "heroku-postbuild": "npm run build",
"serve:lhci": "cross-env NODE_ENV=production npm run server", "serve:lhci": "cross-env NODE_ENV=production npm run server",
"prestart": "npm run build-types", "prestart": "npm run build-types",
"storybook": "cross-env NODE_OPTIONS=--openssl-legacy-provider start-storybook -p 3000 -c src/storybook/", "storybook": "storybook dev --port 3000",
"cy:run": "cypress run", "cy:run": "cypress run",
"cy:run:dashboard": "cypress run --record", "cy:run:dashboard": "cypress run --record",
"cy:open": "cypress open", "cy:open": "cypress open",
@ -324,7 +328,8 @@
"predev": "npm run build-types", "predev": "npm run build-types",
"release": "release-it", "release": "release-it",
"prepare": "is-ci || husky install", "prepare": "is-ci || husky install",
"dep-status": "depcruise --config .dependency-cruiser.js src" "dep-status": "depcruise --config .dependency-cruiser.js src",
"chromatic": "chromatic --exit-zero-on-changes"
}, },
"description": "![Saleor Dashboard](https://user-images.githubusercontent.com/44495184/185379472-2a204c0b-9b7a-4a3e-93c0-2cb85205ed5e.png)" "description": "![Saleor Dashboard](https://user-images.githubusercontent.com/44495184/185379472-2a204c0b-9b7a-4a3e-93c0-2cb85205ed5e.png)"
} }

View file

@ -1,20 +0,0 @@
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react";
import AppDeactivateDialog, {
AppDeactivateDialogProps,
} from "./AppDeactivateDialog";
const props: AppDeactivateDialogProps = {
confirmButtonState: "default",
name: "App",
onClose: () => undefined,
onConfirm: () => undefined,
open: true,
};
storiesOf("Views / Apps / Deactivate app", module)
.addDecorator(Decorator)
.add("default", () => <AppDeactivateDialog {...props} />)
.add("unnamed app", () => <AppDeactivateDialog {...props} name={null} />);

View file

@ -1,19 +0,0 @@
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react";
import AppDeleteDialog, { AppDeleteDialogProps } from "./AppDeleteDialog";
const props: AppDeleteDialogProps = {
confirmButtonState: "default",
name: "App",
onClose: () => undefined,
onConfirm: () => undefined,
open: true,
type: "EXTERNAL",
};
storiesOf("Views / Apps / Delete app", module)
.addDecorator(Decorator)
.add("default", () => <AppDeleteDialog {...props} />)
.add("unnamed app", () => <AppDeleteDialog {...props} name={null} />);

View file

@ -1,5 +1,3 @@
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { appDetails } from "../../fixtures"; import { appDetails } from "../../fixtures";
@ -14,7 +12,10 @@ const props: AppDetailsPageProps = {
onAppDeleteOpen: () => undefined, onAppDeleteOpen: () => undefined,
}; };
storiesOf("Apps / App details", module) export default {
.addDecorator(Decorator) title: "Apps / App details",
.add("default", () => <AppDetailsPage {...props} />) };
.add("loading", () => <AppDetailsPage {...props} loading={true} />);
export const Default = () => <AppDetailsPage {...props} />;
export const Loading = () => <AppDetailsPage {...props} loading={true} />;

View file

@ -1,20 +0,0 @@
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react";
import AppInProgressDeleteDialog, {
AppInProgressDeleteDialogProps,
} from "./AppInProgressDeleteDialog";
const props: AppInProgressDeleteDialogProps = {
confirmButtonState: "default",
name: "App",
onClose: () => undefined,
onConfirm: () => undefined,
open: true,
};
storiesOf("Views / Apps / Delete app failed installation", module)
.addDecorator(Decorator)
.add("default", () => <AppInProgressDeleteDialog {...props} />)
.add("unnamed app", () => <AppInProgressDeleteDialog {...props} name="" />);

View file

@ -1,5 +1,3 @@
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { installApp } from "../../fixtures"; import { installApp } from "../../fixtures";
@ -12,7 +10,10 @@ const props: AppInstallPageProps = {
onSubmit: () => Promise.resolve([]), onSubmit: () => Promise.resolve([]),
}; };
storiesOf("Apps / Install App", module) export default {
.addDecorator(Decorator) title: "Apps / Install App",
.add("default", () => <AppInstallPage {...props} />) };
.add("loading", () => <AppInstallPage {...props} loading={true} />);
export const Default = () => <AppInstallPage {...props} />;
export const Loading = () => <AppInstallPage {...props} loading={true} />;

View file

@ -1,6 +1,4 @@
import { installedAppsList } from "@dashboard/apps/fixtures"; import { installedAppsList } from "@dashboard/apps/fixtures";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import AppListPage, { AppListPageProps } from "./AppListPage"; import AppListPage, { AppListPageProps } from "./AppListPage";
@ -10,14 +8,17 @@ const props: AppListPageProps = {
installedApps: installedAppsList, installedApps: installedAppsList,
}; };
storiesOf("Apps / New Apps / App List", module) export default {
.addDecorator(Decorator) title: "Apps / New Apps / App List",
.add("default", () => <AppListPage {...props} />) };
.add("empty", () => (
export const Default = () => <AppListPage {...props} />;
export const Empty = () => (
<AppListPage <AppListPage
{...props} {...props}
installedApps={[]} installedApps={[]}
installableMarketplaceApps={[]} installableMarketplaceApps={[]}
comingSoonMarketplaceApps={[]} comingSoonMarketplaceApps={[]}
/> />
)); );

View file

@ -1,5 +1,3 @@
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { appDetails } from "../../fixtures"; import { appDetails } from "../../fixtures";
@ -11,9 +9,12 @@ const props: AppPageProps = {
onError: () => undefined, onError: () => undefined,
}; };
storiesOf("Apps / App", module) export default {
.addDecorator(Decorator) title: "Apps / App",
.add("default", () => <AppPage {...props} />) };
.add("settings", () => (
export const Default = () => <AppPage {...props} />;
export const Settings = () => (
<AppPage {...props} url={appDetails.configurationUrl!} /> <AppPage {...props} url={appDetails.configurationUrl!} />
)); );

View file

@ -20,7 +20,7 @@ import AttributeDetailsComponent from "./views/AttributeDetails";
import AttributeListComponent from "./views/AttributeList"; import AttributeListComponent from "./views/AttributeList";
const AttributeList: React.FC<RouteComponentProps<{}>> = ({ location }) => { const AttributeList: React.FC<RouteComponentProps<{}>> = ({ location }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: AttributeListUrlQueryParams = asSortParams( const params: AttributeListUrlQueryParams = asSortParams(
qs, qs,
AttributeListUrlSortField, AttributeListUrlSortField,

View file

@ -1,8 +1,6 @@
import CardDecorator from "@dashboard/storybook/CardDecorator";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { CardDecorator } from "../../../../.storybook/decorators";
import LoginPage, { LoginCardProps } from "./LoginPage"; import LoginPage, { LoginCardProps } from "./LoginPage";
const props: Omit<LoginCardProps, "classes"> = { const props: Omit<LoginCardProps, "classes"> = {
@ -20,13 +18,21 @@ const props: Omit<LoginCardProps, "classes"> = {
onSubmit: () => undefined, onSubmit: () => undefined,
}; };
storiesOf("Authentication / Log in", module) export default {
.addDecorator(CardDecorator) title: "Authentication / Log in",
.addDecorator(Decorator) decorators: [CardDecorator],
.add("default", () => <LoginPage {...props} />) };
.add("error login", () => <LoginPage {...props} errors={["loginError"]} />)
.add("error external login", () => ( export const Default = () => <LoginPage {...props} />;
export const ErrorLogin = () => (
<LoginPage {...props} errors={["loginError"]} />
);
export const ErrorExternalLogin = () => (
<LoginPage {...props} errors={["externalLoginError"]} /> <LoginPage {...props} errors={["externalLoginError"]} />
)) );
.add("disabled", () => <LoginPage {...props} disabled={true} />)
.add("loading", () => <LoginPage {...props} loading={true} />); export const Disabled = () => <LoginPage {...props} disabled={true} />;
export const Loading = () => <LoginPage {...props} loading={true} />;

View file

@ -1,21 +1,23 @@
import { AccountErrorCode } from "@dashboard/graphql"; import { AccountErrorCode } from "@dashboard/graphql";
import CardDecorator from "@dashboard/storybook//CardDecorator";
import Decorator from "@dashboard/storybook//Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { CardDecorator } from "../../../../.storybook/decorators";
import NewPasswordPage from "./NewPasswordPage"; import NewPasswordPage from "./NewPasswordPage";
storiesOf("Authentication / Set up a new password", module) export default {
.addDecorator(CardDecorator) title: "Authentication / Set up a new password",
.addDecorator(Decorator) decorators: [CardDecorator],
.add("default", () => ( };
export const Default = () => (
<NewPasswordPage errors={[]} loading={false} onSubmit={() => undefined} /> <NewPasswordPage errors={[]} loading={false} onSubmit={() => undefined} />
)) );
.add("loading", () => (
export const Loading = () => (
<NewPasswordPage errors={[]} loading={true} onSubmit={() => undefined} /> <NewPasswordPage errors={[]} loading={true} onSubmit={() => undefined} />
)) );
.add("too short error", () => (
export const TooShortError = () => (
<NewPasswordPage <NewPasswordPage
errors={["password"].map(field => ({ errors={["password"].map(field => ({
__typename: "AccountError", __typename: "AccountError",
@ -27,4 +29,4 @@ storiesOf("Authentication / Set up a new password", module)
loading={false} loading={false}
onSubmit={() => undefined} onSubmit={() => undefined}
/> />
)); );

View file

@ -1,9 +1,7 @@
import CardDecorator from "@dashboard/storybook/CardDecorator";
import Decorator from "@dashboard/storybook/Decorator";
import { formError } from "@dashboard/storybook/formError";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { CardDecorator } from "../../../../.storybook/decorators";
import { formError } from "../../../../.storybook/helpers";
import ResetPasswordPage, { ResetPasswordPageProps } from "./ResetPasswordPage"; import ResetPasswordPage, { ResetPasswordPageProps } from "./ResetPasswordPage";
const props: ResetPasswordPageProps = { const props: ResetPasswordPageProps = {
@ -11,11 +9,16 @@ const props: ResetPasswordPageProps = {
error: undefined, error: undefined,
onSubmit: () => undefined, onSubmit: () => undefined,
}; };
storiesOf("Authentication / Reset password", module)
.addDecorator(CardDecorator) export default {
.addDecorator(Decorator) title: "Authentication / Reset password",
.add("default", () => <ResetPasswordPage {...props} />) decorators: [CardDecorator],
.add("loading", () => <ResetPasswordPage {...props} disabled={true} />) };
.add("error", () => (
export const Default = () => <ResetPasswordPage {...props} />;
export const Loading = () => <ResetPasswordPage {...props} disabled={true} />;
export const Error = () => (
<ResetPasswordPage {...props} error={formError("").message} /> <ResetPasswordPage {...props} error={formError("").message} />
)); );

View file

@ -1,11 +1,13 @@
import CardDecorator from "@dashboard/storybook/CardDecorator";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { CardDecorator } from "../../../../.storybook/decorators";
import ResetPasswordSuccessPage from "./ResetPasswordSuccessPage"; import ResetPasswordSuccessPage from "./ResetPasswordSuccessPage";
storiesOf("Authentication / Reset password success", module) export default {
.addDecorator(CardDecorator) title: "Authentication / Reset password success",
.addDecorator(Decorator) decorators: [CardDecorator],
.add("default", () => <ResetPasswordSuccessPage onBack={() => undefined} />); };
export const Default = () => (
<ResetPasswordSuccessPage onBack={() => undefined} />
);

View file

@ -16,7 +16,7 @@ import ResetPassword from "./views/ResetPassword";
import ResetPasswordSuccess from "./views/ResetPasswordSuccess"; import ResetPasswordSuccess from "./views/ResetPasswordSuccess";
const LoginView: React.FC<RouteComponentProps<any>> = () => { const LoginView: React.FC<RouteComponentProps<any>> = () => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: LoginUrlQueryParams = qs; const params: LoginUrlQueryParams = qs;
return <LoginViewComponent params={params} />; return <LoginViewComponent params={params} />;

View file

@ -17,7 +17,9 @@ const NewPassword: React.FC<RouteComponentProps> = ({ location }) => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [errors, setErrors] = useState<SetPasswordData["errors"]>([]); const [errors, setErrors] = useState<SetPasswordData["errors"]>([]);
const params: NewPasswordUrlQueryParams = parseQs(location.search.substr(1)); const params: NewPasswordUrlQueryParams = parseQs(
location.search.substr(1),
) as any;
const handleSubmit = async (data: NewPasswordPageFormData) => { const handleSubmit = async (data: NewPasswordPageFormData) => {
setLoading(true); setLoading(true);

View file

@ -1,6 +1,4 @@
import { ProductErrorCode } from "@dashboard/graphql"; import { ProductErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import CategoryCreatePage, { import CategoryCreatePage, {
@ -15,13 +13,17 @@ const createProps: CategoryCreatePageProps = {
saveButtonBarState: "default", saveButtonBarState: "default",
}; };
storiesOf("Categories / Create category", module) export default {
.addDecorator(Decorator) title: "Categories / Create category",
.add("default", () => <CategoryCreatePage {...createProps} />) };
.add("When loading", () => (
export const Default = () => <CategoryCreatePage {...createProps} />;
export const WhenLoading = () => (
<CategoryCreatePage {...createProps} disabled={true} /> <CategoryCreatePage {...createProps} disabled={true} />
)) );
.add("form errors", () => (
export const FormErrors = () => (
<CategoryCreatePage <CategoryCreatePage
{...createProps} {...createProps}
errors={[ errors={[
@ -40,4 +42,4 @@ storiesOf("Categories / Create category", module)
...err, ...err,
}))} }))}
/> />
)); );

View file

@ -7,11 +7,9 @@ import {
sortPageProps, sortPageProps,
tabPageProps, tabPageProps,
} from "@dashboard/fixtures"; } from "@dashboard/fixtures";
import Decorator from "@dashboard/storybook/Decorator";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import CategoryListPage, { CategoryTableProps } from "./CategoryListPage"; import CategoryListPage, { CategoryTableProps } from "./CategoryListPage";
const categoryTableProps: CategoryTableProps = { const categoryTableProps: CategoryTableProps = {
@ -28,13 +26,17 @@ const categoryTableProps: CategoryTableProps = {
}, },
}; };
storiesOf("Categories / Category list", module) export default {
.addDecorator(Decorator) title: "Categories / Category list",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <CategoryListPage {...categoryTableProps} />) };
.add("loading", () => (
export const Default = () => <CategoryListPage {...categoryTableProps} />;
export const Loading = () => (
<CategoryListPage {...categoryTableProps} categories={undefined} /> <CategoryListPage {...categoryTableProps} categories={undefined} />
)) );
.add("empty", () => (
export const Empty = () => (
<CategoryListPage {...categoryTableProps} categories={[]} /> <CategoryListPage {...categoryTableProps} categories={[]} />
)); );

View file

@ -2,12 +2,10 @@ import placeholderImage from "@assets/images/placeholder255x255.png";
import { category as categoryFixture } from "@dashboard/categories/fixtures"; import { category as categoryFixture } from "@dashboard/categories/fixtures";
import { listActionsProps } from "@dashboard/fixtures"; import { listActionsProps } from "@dashboard/fixtures";
import { ProductErrorCode } from "@dashboard/graphql"; import { ProductErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { mapEdgesToItems } from "@dashboard/utils/maps"; import { mapEdgesToItems } from "@dashboard/utils/maps";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import CategoryUpdatePage, { import CategoryUpdatePage, {
CategoryPageTab, CategoryPageTab,
CategoryUpdatePageProps, CategoryUpdatePageProps,
@ -35,17 +33,18 @@ const updateProps: Omit<CategoryUpdatePageProps, "classes"> = {
...listActionsProps, ...listActionsProps,
}; };
storiesOf("Categories / Update category", module) export default {
.addDecorator(Decorator) title: "Categories / Update category",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <CategoryUpdatePage {...updateProps} />) };
.add("products", () => (
<CategoryUpdatePage export const Default = () => <CategoryUpdatePage {...updateProps} />;
{...updateProps}
currentTab={CategoryPageTab.products} export const Products = () => (
/> <CategoryUpdatePage {...updateProps} currentTab={CategoryPageTab.products} />
)) );
.add("no background", () => (
export const NoBackground = () => (
<CategoryUpdatePage <CategoryUpdatePage
{...updateProps} {...updateProps}
category={{ category={{
@ -53,18 +52,21 @@ storiesOf("Categories / Update category", module)
backgroundImage: null, backgroundImage: null,
}} }}
/> />
)) );
.add("no subcategories", () => (
export const NoSubcategories = () => (
<CategoryUpdatePage {...updateProps} subcategories={[]} /> <CategoryUpdatePage {...updateProps} subcategories={[]} />
)) );
.add("no products", () => (
export const NoProducts = () => (
<CategoryUpdatePage <CategoryUpdatePage
{...updateProps} {...updateProps}
products={[]} products={[]}
currentTab={CategoryPageTab.products} currentTab={CategoryPageTab.products}
/> />
)) );
.add("loading", () => (
export const Loading = () => (
<CategoryUpdatePage <CategoryUpdatePage
{...updateProps} {...updateProps}
subcategories={undefined} subcategories={undefined}
@ -72,8 +74,9 @@ storiesOf("Categories / Update category", module)
products={undefined} products={undefined}
category={undefined} category={undefined}
/> />
)) );
.add("form errors", () => (
export const FormErrors = () => (
<CategoryUpdatePage <CategoryUpdatePage
{...updateProps} {...updateProps}
errors={[ errors={[
@ -92,4 +95,4 @@ storiesOf("Categories / Update category", module)
...err, ...err,
}))} }))}
/> />
)); );

View file

@ -21,9 +21,9 @@ import CategoryListComponent from "./views/CategoryList";
interface CategoryDetailsRouteParams { interface CategoryDetailsRouteParams {
id: string; id: string;
} }
const CategoryDetails: React.FC<RouteComponentProps< const CategoryDetails: React.FC<
CategoryDetailsRouteParams RouteComponentProps<CategoryDetailsRouteParams>
>> = ({ location, match }) => { > = ({ location, match }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1));
const params: CategoryUrlQueryParams = qs; const params: CategoryUrlQueryParams = qs;
@ -38,16 +38,16 @@ const CategoryDetails: React.FC<RouteComponentProps<
interface CategoryCreateRouteParams { interface CategoryCreateRouteParams {
id: string; id: string;
} }
const CategoryCreate: React.FC<RouteComponentProps< const CategoryCreate: React.FC<
CategoryCreateRouteParams RouteComponentProps<CategoryCreateRouteParams>
>> = ({ match }) => ( > = ({ match }) => (
<CategoryCreateView <CategoryCreateView
parentId={match.params.id ? decodeURIComponent(match.params.id) : undefined} parentId={match.params.id ? decodeURIComponent(match.params.id) : undefined}
/> />
); );
const CategoryList: React.FC<RouteComponentProps<{}>> = ({ location }) => { const CategoryList: React.FC<RouteComponentProps<{}>> = ({ location }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: CategoryListUrlQueryParams = { const params: CategoryListUrlQueryParams = {
...asSortParams(qs, CategoryListUrlSortField), ...asSortParams(qs, CategoryListUrlSortField),
}; };

View file

@ -29,7 +29,7 @@ const ChannelDetails: React.FC<RouteComponentProps<any>> = ({ match }) => {
}; };
const ChannelsList: React.FC<RouteComponentProps> = ({ location }) => { const ChannelsList: React.FC<RouteComponentProps> = ({ location }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: ChannelsListUrlQueryParams = asSortParams( const params: ChannelsListUrlQueryParams = asSortParams(
qs, qs,
ChannelsListUrlSortField, ChannelsListUrlSortField,

View file

@ -1,8 +1,6 @@
import { channel, channelCreateErrors } from "@dashboard/channels/fixtures"; import { channel, channelCreateErrors } from "@dashboard/channels/fixtures";
import { countries } from "@dashboard/fixtures"; import { countries } from "@dashboard/fixtures";
import { ChannelErrorFragment } from "@dashboard/graphql"; import { ChannelErrorFragment } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import ChannelDetailsPage, { import ChannelDetailsPage, {
@ -69,21 +67,26 @@ const props: ChannelDetailsPageProps<ChannelErrorFragment[]> = {
}, },
}; };
storiesOf("Channels / Channel details", module) export default {
.addDecorator(Decorator) title: "Channels / Channel details",
.add("default", () => <ChannelDetailsPage {...props} />) };
.add("disabled", () => <ChannelDetailsPage {...props} disabled={true} />)
.add("loading", () => ( export const Default = () => <ChannelDetailsPage {...props} />;
export const Disabled = () => <ChannelDetailsPage {...props} disabled={true} />;
export const Loading = () => (
<ChannelDetailsPage {...props} saveButtonBarState={"loading"} /> <ChannelDetailsPage {...props} saveButtonBarState={"loading"} />
)) );
.add("with data", () => <ChannelDetailsPage {...props} channel={channel} />)
.add("without editable currency code", () => ( export const WithData = () => (
<ChannelDetailsPage <ChannelDetailsPage {...props} channel={channel} />
{...props} );
currencyCodes={undefined}
channel={channel} export const WithoutEditableCurrencyCode = () => (
/> <ChannelDetailsPage {...props} currencyCodes={undefined} channel={channel} />
)) );
.add("with errors", () => (
export const WithErrors = () => (
<ChannelDetailsPage {...props} errors={channelCreateErrors} /> <ChannelDetailsPage {...props} errors={channelCreateErrors} />
)); );

View file

@ -1,7 +1,5 @@
import { channelsList } from "@dashboard/channels/fixtures"; import { channelsList } from "@dashboard/channels/fixtures";
import { limits, limitsReached } from "@dashboard/fixtures"; import { limits, limitsReached } from "@dashboard/fixtures";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import ChannelsListPage, { ChannelsListPageProps } from "./ChannelsListPage"; import ChannelsListPage, { ChannelsListPageProps } from "./ChannelsListPage";
@ -12,11 +10,18 @@ const props: ChannelsListPageProps = {
onRemove: () => undefined, onRemove: () => undefined,
}; };
storiesOf("Channels / Channels list", module) export default {
.addDecorator(Decorator) title: "Channels / Channels list",
.add("default", () => <ChannelsListPage {...props} />) };
.add("empty", () => <ChannelsListPage {...props} channelsList={[]} />)
.add("no limits", () => <ChannelsListPage {...props} limits={undefined} />) export const Default = () => <ChannelsListPage {...props} />;
.add("limits reached", () => (
export const Empty = () => <ChannelsListPage {...props} channelsList={[]} />;
export const NoLimits = () => (
<ChannelsListPage {...props} limits={undefined} />
);
export const LimitsReached = () => (
<ChannelsListPage {...props} limits={limitsReached} /> <ChannelsListPage {...props} limits={limitsReached} />
)); );

View file

@ -1,8 +1,6 @@
import { channelsList } from "@dashboard/channels/fixtures"; import { channelsList } from "@dashboard/channels/fixtures";
import { createCollectionChannels } from "@dashboard/channels/utils"; import { createCollectionChannels } from "@dashboard/channels/utils";
import { CollectionErrorCode } from "@dashboard/graphql"; import { CollectionErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import CollectionCreatePage, { import CollectionCreatePage, {
@ -23,11 +21,17 @@ const props: Omit<CollectionCreatePageProps, "classes"> = {
saveButtonBarState: "default", saveButtonBarState: "default",
}; };
storiesOf("Collections / Create collection", module) export default {
.addDecorator(Decorator) title: "Collections / Create collection",
.add("default", () => <CollectionCreatePage {...props} />) };
.add("loading", () => <CollectionCreatePage {...props} disabled={true} />)
.add("form errors", () => ( export const Default = () => <CollectionCreatePage {...props} />;
export const Loading = () => (
<CollectionCreatePage {...props} disabled={true} />
);
export const FormErrors = () => (
<CollectionCreatePage <CollectionCreatePage
{...props} {...props}
errors={[ errors={[
@ -46,4 +50,4 @@ storiesOf("Collections / Create collection", module)
...err, ...err,
}))} }))}
/> />
)); );

View file

@ -4,11 +4,9 @@ import { createCollectionChannelsData } from "@dashboard/channels/utils";
import { collection as collectionFixture } from "@dashboard/collections/fixtures"; import { collection as collectionFixture } from "@dashboard/collections/fixtures";
import { listActionsProps, pageListProps } from "@dashboard/fixtures"; import { listActionsProps, pageListProps } from "@dashboard/fixtures";
import { CollectionErrorCode } from "@dashboard/graphql"; import { CollectionErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import CollectionDetailsPage, { import CollectionDetailsPage, {
CollectionDetailsPageProps, CollectionDetailsPageProps,
} from "./CollectionDetailsPage"; } from "./CollectionDetailsPage";
@ -39,14 +37,18 @@ const props: Omit<CollectionDetailsPageProps, "classes"> = {
selectedChannelId: "123", selectedChannelId: "123",
}; };
storiesOf("Collections / Collection detailsCollection details", module) export default {
.addDecorator(Decorator) title: "Collections / Collection detailsCollection details",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <CollectionDetailsPage {...props} />) };
.add("loading", () => (
export const Default = () => <CollectionDetailsPage {...props} />;
export const Loading = () => (
<CollectionDetailsPage {...props} collection={undefined} disabled={true} /> <CollectionDetailsPage {...props} collection={undefined} disabled={true} />
)) );
.add("form errors", () => (
export const FormErrors = () => (
<CollectionDetailsPage <CollectionDetailsPage
{...props} {...props}
errors={[ errors={[
@ -65,8 +67,9 @@ storiesOf("Collections / Collection detailsCollection details", module)
...err, ...err,
}))} }))}
/> />
)) );
.add("no products", () => (
export const NoProducts = () => (
<CollectionDetailsPage <CollectionDetailsPage
{...props} {...props}
collection={{ collection={{
@ -77,4 +80,4 @@ storiesOf("Collections / Collection detailsCollection details", module)
}, },
}} }}
/> />
)); );

View file

@ -1,9 +1,7 @@
import { CollectionListUrlSortField } from "@dashboard/collections/urls"; import { CollectionListUrlSortField } from "@dashboard/collections/urls";
import Decorator from "@dashboard/storybook/Decorator";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import CollectionListPage, { import CollectionListPage, {
CollectionListPageProps, CollectionListPageProps,
} from "../../../collections/components/CollectionListPage"; } from "../../../collections/components/CollectionListPage";
@ -34,11 +32,15 @@ const props: CollectionListPageProps = {
filterOpts: collectionListFilterOpts, filterOpts: collectionListFilterOpts,
}; };
storiesOf("Collections / Collection list", module) export default {
.addDecorator(Decorator) title: "Collections / Collection list",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <CollectionListPage {...props} />) };
.add("loading", () => (
export const Default = () => <CollectionListPage {...props} />;
export const Loading = () => (
<CollectionListPage {...props} collections={undefined} disabled={true} /> <CollectionListPage {...props} collections={undefined} disabled={true} />
)) );
.add("no data", () => <CollectionListPage {...props} collections={[]} />);
export const NoData = () => <CollectionListPage {...props} collections={[]} />;

View file

@ -20,7 +20,7 @@ import CollectionDetailsView from "./views/CollectionDetails";
import CollectionListView from "./views/CollectionList"; import CollectionListView from "./views/CollectionList";
const CollectionList: React.FC<RouteComponentProps<{}>> = ({ location }) => { const CollectionList: React.FC<RouteComponentProps<{}>> = ({ location }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: CollectionListUrlQueryParams = asSortParams( const params: CollectionListUrlQueryParams = asSortParams(
qs, qs,
CollectionListUrlSortField, CollectionListUrlSortField,
@ -31,9 +31,9 @@ const CollectionList: React.FC<RouteComponentProps<{}>> = ({ location }) => {
interface CollectionDetailsRouteProps { interface CollectionDetailsRouteProps {
id: string; id: string;
} }
const CollectionDetails: React.FC<RouteComponentProps< const CollectionDetails: React.FC<
CollectionDetailsRouteProps RouteComponentProps<CollectionDetailsRouteProps>
>> = ({ location, match }) => { > = ({ location, match }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1));
const params: CollectionUrlQueryParams = qs; const params: CollectionUrlQueryParams = qs;
return ( return (

View file

@ -3,8 +3,6 @@ import {
AppStateContextType, AppStateContextType,
} from "@dashboard/containers/AppState"; } from "@dashboard/containers/AppState";
import { initialAppState } from "@dashboard/containers/AppState/state"; import { initialAppState } from "@dashboard/containers/AppState/state";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import ErrorPage, { ErrorPageProps } from "./ErrorPage"; import ErrorPage, { ErrorPageProps } from "./ErrorPage";
@ -29,15 +27,18 @@ const props: Omit<ErrorPageProps, "classes"> = {
onRefresh: () => undefined, onRefresh: () => undefined,
}; };
storiesOf("Error / Error page", module) export default {
.addDecorator(Decorator) title: "Error / Error page",
.add("default", () => ( };
export const Default = () => (
<AppStateContext.Provider value={initialAppStateFixture}> <AppStateContext.Provider value={initialAppStateFixture}>
<ErrorPage {...props} /> <ErrorPage {...props} />
</AppStateContext.Provider> </AppStateContext.Provider>
)) );
.add("with error id", () => (
export const WithErrorId = () => (
<AppStateContext.Provider value={errorAppStateFixture}> <AppStateContext.Provider value={errorAppStateFixture}>
<ErrorPage {...props} /> <ErrorPage {...props} />
</AppStateContext.Provider> </AppStateContext.Provider>
)); );

View file

@ -1,9 +1,9 @@
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import NotFoundPage from "./NotFoundPage"; import NotFoundPage from "./NotFoundPage";
storiesOf("Error / Not found", module) export default {
.addDecorator(Decorator) title: "Error / Not found",
.add("default", () => <NotFoundPage onBack={() => undefined} />); };
export const Default = () => <NotFoundPage onBack={() => undefined} />;

View file

@ -1,13 +1,15 @@
import { createConfigurationMenu } from "@dashboard/configuration"; import { createConfigurationMenu } from "@dashboard/configuration";
import { UserFragment } from "@dashboard/graphql"; import { UserFragment } from "@dashboard/graphql";
import { staffMember } from "@dashboard/staff/fixtures"; import { staffMember } from "@dashboard/staff/fixtures";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { ConfigurationPage } from "./ConfigurationPage"; import { ConfigurationPage } from "./ConfigurationPage";
export default {
title: "Configuration / Configuration",
};
const user = { const user = {
__typename: staffMember.__typename, __typename: staffMember.__typename,
avatar: { avatar: {
@ -40,14 +42,13 @@ const Story: React.FC<{ user: UserFragment }> = ({ user }) => {
); );
}; };
storiesOf("Configuration", module) export const Default = () => <Story user={user} />;
.addDecorator(Decorator)
.add("default", () => <Story user={user} />) export const PartialAccess = () => (
.add("partial access", () => (
<Story <Story
user={{ user={{
...user, ...user,
userPermissions: user.userPermissions.slice(2, 6), userPermissions: user.userPermissions.slice(2, 6),
}} }}
/> />
)); );

View file

@ -1,6 +1,4 @@
import { WebhookErrorCode } from "@dashboard/graphql"; import { WebhookErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { webhook } from "../../fixtures"; import { webhook } from "../../fixtures";
@ -18,14 +16,22 @@ const props: WebhookDetailsPageProps = {
webhook, webhook,
availableEvents: [], availableEvents: [],
}; };
storiesOf("Apps / Webhooks / Webhook details", module)
.addDecorator(Decorator) export default {
.add("default", () => <WebhookDetailsPage {...props} />) title: "Apps / Webhooks / Webhook details",
.add("undefined", () => <WebhookDetailsPage {...props} webhook={undefined} />) };
.add("loading", () => (
export const Default = () => <WebhookDetailsPage {...props} />;
export const Undefined = () => (
<WebhookDetailsPage {...props} webhook={undefined} />
);
export const Loading = () => (
<WebhookDetailsPage {...props} webhook={undefined} disabled={true} /> <WebhookDetailsPage {...props} webhook={undefined} disabled={true} />
)) );
.add("form errors", () => (
export const FormErrors = () => (
<WebhookDetailsPage <WebhookDetailsPage
{...props} {...props}
errors={["name", "targetUrl", "secretKey", null].map(field => ({ errors={["name", "targetUrl", "secretKey", null].map(field => ({
@ -35,4 +41,4 @@ storiesOf("Apps / Webhooks / Webhook details", module)
message: "Webhook invalid", message: "Webhook invalid",
}))} }))}
/> />
)); );

View file

@ -1,5 +1,3 @@
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { customer } from "../../fixtures"; import { customer } from "../../fixtures";
@ -14,15 +12,19 @@ const props: CustomerAddressListPageProps = {
onSetAsDefault: () => undefined, onSetAsDefault: () => undefined,
}; };
storiesOf("Customers / Address Book", module) export default {
.addDecorator(Decorator) title: "Customers / Address Book",
.add("default", () => <CustomerAddressListPage {...props} />) };
.add("loading", () => (
export const Default = () => <CustomerAddressListPage {...props} />;
export const Loading = () => (
<CustomerAddressListPage {...props} customer={undefined} disabled={true} /> <CustomerAddressListPage {...props} customer={undefined} disabled={true} />
)) );
.add("no data", () => (
export const NoData = () => (
<CustomerAddressListPage <CustomerAddressListPage
{...props} {...props}
customer={{ ...customer, addresses: [] }} customer={{ ...customer, addresses: [] }}
/> />
)); );

View file

@ -1,6 +1,4 @@
import { AccountErrorCode } from "@dashboard/graphql"; import { AccountErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import CustomerCreatePage, { import CustomerCreatePage, {
@ -19,14 +17,19 @@ const props: Omit<CustomerCreatePageProps, "classes"> = {
saveButtonBar: "default", saveButtonBar: "default",
}; };
storiesOf("Customers / Create customer", module) export default {
.addDecorator(Decorator) title: "Customers / Create customer",
.add("default", () => <CustomerCreatePage {...props} />) };
.add("loading", () => <CustomerCreatePage {...props} disabled={true} />)
.add("form errors", () => ( export const Default = () => <CustomerCreatePage {...props} />;
export const Loading = () => <CustomerCreatePage {...props} disabled={true} />;
export const FormErrors = () => (
<CustomerCreatePage <CustomerCreatePage
{...props} {...props}
errors={([ errors={(
[
"city", "city",
"cityArea", "cityArea",
"companyName", "companyName",
@ -40,7 +43,8 @@ storiesOf("Customers / Create customer", module)
"postalCode", "postalCode",
"streetAddress1", "streetAddress1",
"streetAddress2", "streetAddress2",
] as Array<keyof CustomerCreatePageFormData>).map(field => ({ ] as Array<keyof CustomerCreatePageFormData>
).map(field => ({
__typename: "AccountError", __typename: "AccountError",
code: AccountErrorCode.INVALID, code: AccountErrorCode.INVALID,
field, field,
@ -48,4 +52,4 @@ storiesOf("Customers / Create customer", module)
message: "Account invalid error", message: "Account invalid error",
}))} }))}
/> />
)); );

View file

@ -1,9 +1,7 @@
import { AccountErrorCode } from "@dashboard/graphql"; import { AccountErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { MockedUserProvider } from "@dashboard/storybook/MockedUserProvider";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { MockedUserProvider } from "../../../../.storybook/helpers";
import { customer } from "../../fixtures"; import { customer } from "../../fixtures";
import CustomerDetailsPageComponent, { import CustomerDetailsPageComponent, {
CustomerDetailsPageProps, CustomerDetailsPageProps,
@ -32,18 +30,24 @@ const CustomerDetailsPage = props => (
</MockedUserProvider> </MockedUserProvider>
); );
storiesOf("Customers / Customer details", module) export default {
.addDecorator(Decorator) title: "Customers / Customer details",
.add("default", () => <CustomerDetailsPage {...props} />) };
.add("loading", () => (
export const Default = () => <CustomerDetailsPage {...props} />;
export const Loading = () => (
<CustomerDetailsPage {...props} customer={undefined} disabled={true} /> <CustomerDetailsPage {...props} customer={undefined} disabled={true} />
)) );
.add("form errors", () => (
export const FormErrors = () => (
<CustomerDetailsPage <CustomerDetailsPage
{...props} {...props}
errors={(["email", "firstName", "lastName"] as Array< errors={(
["email", "firstName", "lastName"] as Array<
keyof CustomerDetailsPageErrors keyof CustomerDetailsPageErrors
>).map(field => ({ >
).map(field => ({
__typename: "AccountError", __typename: "AccountError",
code: AccountErrorCode.INVALID, code: AccountErrorCode.INVALID,
field, field,
@ -51,8 +55,9 @@ storiesOf("Customers / Customer details", module)
message: "Account invalid", message: "Account invalid",
}))} }))}
/> />
)) );
.add("different addresses", () => (
export const DifferentAddresses = () => (
<CustomerDetailsPage <CustomerDetailsPage
{...props} {...props}
customer={{ customer={{
@ -63,8 +68,9 @@ storiesOf("Customers / Customer details", module)
}, },
}} }}
/> />
)) );
.add("never logged", () => (
export const NeverLogged = () => (
<CustomerDetailsPage <CustomerDetailsPage
{...props} {...props}
customer={{ customer={{
@ -72,8 +78,9 @@ storiesOf("Customers / Customer details", module)
lastLogin: null, lastLogin: null,
}} }}
/> />
)) );
.add("never placed order", () => (
export const NeverPlacedOrder = () => (
<CustomerDetailsPage <CustomerDetailsPage
{...props} {...props}
customer={{ customer={{
@ -84,8 +91,9 @@ storiesOf("Customers / Customer details", module)
}, },
}} }}
/> />
)) );
.add("no default billing address", () => (
export const NoDefaultBillingAddress = () => (
<CustomerDetailsPage <CustomerDetailsPage
{...props} {...props}
customer={{ customer={{
@ -93,8 +101,9 @@ storiesOf("Customers / Customer details", module)
defaultBillingAddress: null, defaultBillingAddress: null,
}} }}
/> />
)) );
.add("no default shipping address", () => (
export const NoDefaultShippingAddress = () => (
<CustomerDetailsPage <CustomerDetailsPage
{...props} {...props}
customer={{ customer={{
@ -102,8 +111,9 @@ storiesOf("Customers / Customer details", module)
defaultShippingAddress: null, defaultShippingAddress: null,
}} }}
/> />
)) );
.add("no address at all", () => (
export const NoAddressAtAll = () => (
<CustomerDetailsPage <CustomerDetailsPage
{...props} {...props}
customer={{ customer={{
@ -112,4 +122,4 @@ storiesOf("Customers / Customer details", module)
defaultShippingAddress: null, defaultShippingAddress: null,
}} }}
/> />
)); );

View file

@ -6,12 +6,10 @@ import {
sortPageProps, sortPageProps,
tabPageProps, tabPageProps,
} from "@dashboard/fixtures"; } from "@dashboard/fixtures";
import Decorator from "@dashboard/storybook/Decorator";
import { MockedUserProvider } from "@dashboard/storybook/MockedUserProvider";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import { MockedUserProvider } from "../../../../.storybook/helpers";
import { customerList } from "../../fixtures"; import { customerList } from "../../fixtures";
import { CustomerListUrlSortField } from "../../urls"; import { CustomerListUrlSortField } from "../../urls";
import CustomerListPageComponent, { import CustomerListPageComponent, {
@ -55,11 +53,15 @@ const CustomerListPage = props => (
</MockedUserProvider> </MockedUserProvider>
); );
storiesOf("Customers / Customer list", module) export default {
.addDecorator(Decorator) title: "Customers / Customer list",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <CustomerListPage {...props} />) };
.add("loading", () => (
export const Default = () => <CustomerListPage {...props} />;
export const Loading = () => (
<CustomerListPage {...props} disabled={true} customers={undefined} /> <CustomerListPage {...props} disabled={true} customers={undefined} />
)) );
.add("no data", () => <CustomerListPage {...props} customers={[]} />);
export const NoData = () => <CustomerListPage {...props} customers={[]} />;

View file

@ -22,7 +22,7 @@ import CustomerDetailsViewComponent from "./views/CustomerDetails";
import CustomerListViewComponent from "./views/CustomerList"; import CustomerListViewComponent from "./views/CustomerList";
const CustomerListView: React.FC<RouteComponentProps<{}>> = ({ location }) => { const CustomerListView: React.FC<RouteComponentProps<{}>> = ({ location }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: CustomerListUrlQueryParams = asSortParams( const params: CustomerListUrlQueryParams = asSortParams(
qs, qs,
CustomerListUrlSortField, CustomerListUrlSortField,
@ -34,9 +34,9 @@ const CustomerListView: React.FC<RouteComponentProps<{}>> = ({ location }) => {
interface CustomerDetailsRouteParams { interface CustomerDetailsRouteParams {
id: string; id: string;
} }
const CustomerDetailsView: React.FC<RouteComponentProps< const CustomerDetailsView: React.FC<
CustomerDetailsRouteParams RouteComponentProps<CustomerDetailsRouteParams>
>> = ({ location, match }) => { > = ({ location, match }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1));
const params: CustomerUrlQueryParams = qs; const params: CustomerUrlQueryParams = qs;
@ -51,9 +51,9 @@ const CustomerDetailsView: React.FC<RouteComponentProps<
interface CustomerAddressesRouteParams { interface CustomerAddressesRouteParams {
id: string; id: string;
} }
const CustomerAddressesView: React.FC<RouteComponentProps< const CustomerAddressesView: React.FC<
CustomerAddressesRouteParams RouteComponentProps<CustomerAddressesRouteParams>
>> = ({ match }) => { > = ({ match }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1));
const params: CustomerAddressesUrlQueryParams = qs; const params: CustomerAddressesUrlQueryParams = qs;

View file

@ -1,8 +1,6 @@
import { channelsList } from "@dashboard/channels/fixtures"; import { channelsList } from "@dashboard/channels/fixtures";
import { createSaleChannels } from "@dashboard/channels/utils"; import { createSaleChannels } from "@dashboard/channels/utils";
import { DiscountErrorCode } from "@dashboard/graphql"; import { DiscountErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import SaleCreatePage, { SaleCreatePageProps } from "./SaleCreatePage"; import SaleCreatePage, { SaleCreatePageProps } from "./SaleCreatePage";
@ -21,11 +19,15 @@ const props: SaleCreatePageProps = {
saveButtonBarState: "default", saveButtonBarState: "default",
}; };
storiesOf("Discounts / Sale create", module) export default {
.addDecorator(Decorator) title: "Discounts / Sale create",
.add("default", () => <SaleCreatePage {...props} />) };
.add("loading", () => <SaleCreatePage {...props} disabled={true} />)
.add("form errors", () => ( export const Default = () => <SaleCreatePage {...props} />;
export const Loading = () => <SaleCreatePage {...props} disabled={true} />;
export const FormErrors = () => (
<SaleCreatePage <SaleCreatePage
{...props} {...props}
errors={["name", "startDate", "endDate", "value"].map(field => ({ errors={["name", "startDate", "endDate", "value"].map(field => ({
@ -36,4 +38,4 @@ storiesOf("Discounts / Sale create", module)
message: "Discount invalid", message: "Discount invalid",
}))} }))}
/> />
)); );

View file

@ -3,11 +3,9 @@ import { createSaleChannels } from "@dashboard/channels/utils";
import { sale } from "@dashboard/discounts/fixtures"; import { sale } from "@dashboard/discounts/fixtures";
import { listActionsProps } from "@dashboard/fixtures"; import { listActionsProps } from "@dashboard/fixtures";
import { DiscountErrorCode } from "@dashboard/graphql"; import { DiscountErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import SaleDetailsPage, { import SaleDetailsPage, {
SaleDetailsPageProps, SaleDetailsPageProps,
SaleDetailsPageTab, SaleDetailsPageTab,
@ -50,14 +48,18 @@ const props: SaleDetailsPageProps = {
...listActionsProps, ...listActionsProps,
}; };
storiesOf(" Discounts / Sale details", module) export default {
.addDecorator(Decorator) title: " Discounts / Sale details",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <SaleDetailsPage {...props} />) };
.add("loading", () => (
export const Default = () => <SaleDetailsPage {...props} />;
export const Loading = () => (
<SaleDetailsPage {...props} sale={undefined} disabled={true} /> <SaleDetailsPage {...props} sale={undefined} disabled={true} />
)) );
.add("form errors", () => (
export const FormErrors = () => (
<SaleDetailsPage <SaleDetailsPage
{...props} {...props}
errors={["name", "startDate", "endDate", "value"].map(field => ({ errors={["name", "startDate", "endDate", "value"].map(field => ({
@ -68,10 +70,12 @@ storiesOf(" Discounts / Sale details", module)
message: "Discount invalid", message: "Discount invalid",
}))} }))}
/> />
)) );
.add("collections", () => (
export const Collections = () => (
<SaleDetailsPage {...props} activeTab={SaleDetailsPageTab.collections} /> <SaleDetailsPage {...props} activeTab={SaleDetailsPageTab.collections} />
)) );
.add("products", () => (
export const Products = () => (
<SaleDetailsPage {...props} activeTab={SaleDetailsPageTab.products} /> <SaleDetailsPage {...props} activeTab={SaleDetailsPageTab.products} />
)); );

View file

@ -8,11 +8,9 @@ import {
tabPageProps, tabPageProps,
} from "@dashboard/fixtures"; } from "@dashboard/fixtures";
import { DiscountStatusEnum, DiscountValueTypeEnum } from "@dashboard/graphql"; import { DiscountStatusEnum, DiscountValueTypeEnum } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import SaleListPage, { SaleListPageProps } from "./SaleListPage"; import SaleListPage, { SaleListPageProps } from "./SaleListPage";
const props: SaleListPageProps = { const props: SaleListPageProps = {
@ -56,16 +54,21 @@ const props: SaleListPageProps = {
}, },
}; };
storiesOf("Discounts / Sale list", module) export default {
.addDecorator(Decorator) title: "Discounts / Sale list",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <SaleListPage {...props} />) };
.add("loading", () => <SaleListPage {...props} sales={undefined} />)
.add("no data", () => <SaleListPage {...props} sales={[]} />) export const Default = () => <SaleListPage {...props} />;
.add("no channels", () => (
export const Loading = () => <SaleListPage {...props} sales={undefined} />;
export const NoData = () => <SaleListPage {...props} sales={[]} />;
export const NoChannels = () => (
<SaleListPage <SaleListPage
{...props} {...props}
sales={saleList.map(sale => ({ ...sale, channelListings: [] }))} sales={saleList.map(sale => ({ ...sale, channelListings: [] }))}
selectedChannelId="" selectedChannelId=""
/> />
)); );

View file

@ -1,8 +1,6 @@
import { channelsList } from "@dashboard/channels/fixtures"; import { channelsList } from "@dashboard/channels/fixtures";
import { createVoucherChannels } from "@dashboard/channels/utils"; import { createVoucherChannels } from "@dashboard/channels/utils";
import { DiscountErrorCode } from "@dashboard/graphql"; import { DiscountErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import VoucherCreatePage, { import VoucherCreatePage, {
@ -23,13 +21,17 @@ const props: VoucherCreatePageProps = {
saveButtonBarState: "default", saveButtonBarState: "default",
}; };
storiesOf("Discounts / Voucher create", module) export default {
.addDecorator(Decorator) title: "Discounts / Voucher create",
.add("default", () => <VoucherCreatePage {...props} />) };
.add("form errors", () => (
export const Default = () => <VoucherCreatePage {...props} />;
export const FormErrors = () => (
<VoucherCreatePage <VoucherCreatePage
{...props} {...props}
errors={([ errors={(
[
"applyOncePerOrder", "applyOncePerOrder",
"code", "code",
"discountType", "discountType",
@ -40,7 +42,8 @@ storiesOf("Discounts / Voucher create", module)
"type", "type",
"usageLimit", "usageLimit",
"value", "value",
] as Array<keyof FormData>).map(field => ({ ] as Array<keyof FormData>
).map(field => ({
__typename: "DiscountError", __typename: "DiscountError",
channels: [], channels: [],
code: DiscountErrorCode.INVALID, code: DiscountErrorCode.INVALID,
@ -48,4 +51,4 @@ storiesOf("Discounts / Voucher create", module)
message: "Discount invalid", message: "Discount invalid",
}))} }))}
/> />
)); );

View file

@ -2,11 +2,9 @@ import { channelsList } from "@dashboard/channels/fixtures";
import { createChannelsDataWithDiscountPrice } from "@dashboard/channels/utils"; import { createChannelsDataWithDiscountPrice } from "@dashboard/channels/utils";
import { listActionsProps, pageListProps } from "@dashboard/fixtures"; import { listActionsProps, pageListProps } from "@dashboard/fixtures";
import { DiscountErrorCode } from "@dashboard/graphql"; import { DiscountErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import { voucherDetails } from "../../fixtures"; import { voucherDetails } from "../../fixtures";
import VoucherDetailsPage, { import VoucherDetailsPage, {
VoucherDetailsPageFormData, VoucherDetailsPageFormData,
@ -54,17 +52,22 @@ const props: VoucherDetailsPageProps = {
voucher: voucherDetails, voucher: voucherDetails,
}; };
storiesOf("Discounts / Voucher details", module) export default {
.addDecorator(Decorator) title: "Discounts / Voucher details",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <VoucherDetailsPage {...props} />) };
.add("loading", () => (
export const Default = () => <VoucherDetailsPage {...props} />;
export const Loading = () => (
<VoucherDetailsPage {...props} disabled={true} voucher={undefined} /> <VoucherDetailsPage {...props} disabled={true} voucher={undefined} />
)) );
.add("form errors", () => (
export const Error = () => (
<VoucherDetailsPage <VoucherDetailsPage
{...props} {...props}
errors={([ errors={(
[
"applyOncePerOrder", "applyOncePerOrder",
"code", "code",
"discountType", "discountType",
@ -75,7 +78,8 @@ storiesOf("Discounts / Voucher details", module)
"type", "type",
"usageLimit", "usageLimit",
"discountValue", "discountValue",
] as Array<keyof VoucherDetailsPageFormData>).map(field => ({ ] as Array<keyof VoucherDetailsPageFormData>
).map(field => ({
__typename: "DiscountError", __typename: "DiscountError",
channels: [], channels: [],
code: DiscountErrorCode.INVALID, code: DiscountErrorCode.INVALID,
@ -83,4 +87,4 @@ storiesOf("Discounts / Voucher details", module)
message: "Discount invalid", message: "Discount invalid",
}))} }))}
/> />
)); );

View file

@ -9,11 +9,9 @@ import {
tabPageProps, tabPageProps,
} from "@dashboard/fixtures"; } from "@dashboard/fixtures";
import { DiscountStatusEnum, VoucherDiscountType } from "@dashboard/graphql"; import { DiscountStatusEnum, VoucherDiscountType } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import VoucherListPage, { VoucherListPageProps } from "./VoucherListPage"; import VoucherListPage, { VoucherListPageProps } from "./VoucherListPage";
const props: VoucherListPageProps = { const props: VoucherListPageProps = {
@ -65,13 +63,18 @@ const props: VoucherListPageProps = {
vouchers: voucherList, vouchers: voucherList,
}; };
storiesOf("Discounts / Voucher list", module) export default {
.addDecorator(Decorator) title: "Discounts / Voucher list",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <VoucherListPage {...props} />) };
.add("loading", () => <VoucherListPage {...props} vouchers={undefined} />)
.add("no data", () => <VoucherListPage {...props} vouchers={[]} />) export const Default = () => <VoucherListPage {...props} />;
.add("no channels", () => (
export const Loading = () => (
<VoucherListPage {...props} vouchers={undefined} />
);
export const NoChannels = () => (
<VoucherListPage <VoucherListPage
{...props} {...props}
selectedChannelId="" selectedChannelId=""
@ -80,4 +83,4 @@ storiesOf("Discounts / Voucher list", module)
channelListings: [], channelListings: [],
}))} }))}
/> />
)); );

View file

@ -30,7 +30,7 @@ import VoucherDetailsViewComponent from "./views/VoucherDetails";
import VoucherListViewComponent from "./views/VoucherList"; import VoucherListViewComponent from "./views/VoucherList";
const SaleListView: React.FC<RouteComponentProps<{}>> = ({ location }) => { const SaleListView: React.FC<RouteComponentProps<{}>> = ({ location }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: SaleListUrlQueryParams = asSortParams(qs, SaleListUrlSortField); const params: SaleListUrlQueryParams = asSortParams(qs, SaleListUrlSortField);
return <SaleListViewComponent params={params} />; return <SaleListViewComponent params={params} />;
}; };
@ -58,7 +58,7 @@ const SaleCreateView: React.FC<RouteComponentProps> = ({ location }) => {
}; };
const VoucherListView: React.FC<RouteComponentProps<{}>> = ({ location }) => { const VoucherListView: React.FC<RouteComponentProps<{}>> = ({ location }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: VoucherListUrlQueryParams = asSortParams( const params: VoucherListUrlQueryParams = asSortParams(
qs, qs,
VoucherListUrlSortField, VoucherListUrlSortField,

View file

@ -31,7 +31,7 @@ const GiftCardUpdatePage: React.FC<RouteComponentProps<{ id: string }>> = ({
}; };
const GiftCardList: React.FC<RouteComponentProps<any>> = () => { const GiftCardList: React.FC<RouteComponentProps<any>> = () => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: GiftCardListUrlQueryParams = asSortParams( const params: GiftCardListUrlQueryParams = asSortParams(
qs, qs,
GiftCardUrlSortField, GiftCardUrlSortField,

View file

@ -2,12 +2,10 @@ import placeholderImage from "@assets/images/placeholder60x60.png";
import { adminUserPermissions } from "@dashboard/fixtures"; import { adminUserPermissions } from "@dashboard/fixtures";
import { PermissionEnum } from "@dashboard/graphql"; import { PermissionEnum } from "@dashboard/graphql";
import { shop as shopFixture } from "@dashboard/home/fixtures"; import { shop as shopFixture } from "@dashboard/home/fixtures";
import Decorator from "@dashboard/storybook/Decorator";
import { MockedUserProvider } from "@dashboard/storybook/MockedUserProvider";
import { mapEdgesToItems } from "@dashboard/utils/maps"; import { mapEdgesToItems } from "@dashboard/utils/maps";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { MockedUserProvider } from "../../../../.storybook/helpers";
import HomePageComponent, { HomePageProps } from "./HomePage"; import HomePageComponent, { HomePageProps } from "./HomePage";
const shop = shopFixture(placeholderImage); const shop = shopFixture(placeholderImage);
@ -38,10 +36,13 @@ const HomePage = props => {
); );
}; };
storiesOf("Home", module) export default {
.addDecorator(Decorator) title: "Home / Home",
.add("default", () => <HomePage {...homePageProps} />) };
.add("loading", () => (
export const Default = () => <HomePage {...homePageProps} />;
export const Loading = () => (
<HomePage <HomePage
{...homePageProps} {...homePageProps}
activities={undefined} activities={undefined}
@ -53,26 +54,30 @@ storiesOf("Home", module)
topProducts={undefined} topProducts={undefined}
userName={undefined} userName={undefined}
/> />
)) );
.add("no data", () => (
export const NoData = () => (
<HomePage {...homePageProps} topProducts={[]} activities={[]} /> <HomePage {...homePageProps} topProducts={[]} activities={[]} />
)) );
.add("no permissions", () => (
export const NoPermissions = () => (
<HomePage {...homePageProps} customPermissions={[]} /> <HomePage {...homePageProps} customPermissions={[]} />
)) );
.add("product permissions", () => (
export const ProductPermissions = () => (
<HomePage <HomePage
{...homePageProps} {...homePageProps}
customPermissions={adminUserPermissions.filter( customPermissions={adminUserPermissions.filter(
perm => perm.code === PermissionEnum.MANAGE_PRODUCTS, perm => perm.code === PermissionEnum.MANAGE_PRODUCTS,
)} )}
/> />
)) );
.add("order permissions", () => (
export const OrderPermissions = () => (
<HomePage <HomePage
{...homePageProps} {...homePageProps}
customPermissions={adminUserPermissions.filter( customPermissions={adminUserPermissions.filter(
perm => perm.code === PermissionEnum.MANAGE_ORDERS, perm => perm.code === PermissionEnum.MANAGE_ORDERS,
)} )}
/> />
)); );

View file

@ -1,7 +1,5 @@
import { MenuErrorCode } from "@dashboard/graphql"; import { MenuErrorCode } from "@dashboard/graphql";
import { menu } from "@dashboard/navigation/fixtures"; import { menu } from "@dashboard/navigation/fixtures";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import MenuDetailsPage, { MenuDetailsPageProps } from "./MenuDetailsPage"; import MenuDetailsPage, { MenuDetailsPageProps } from "./MenuDetailsPage";
@ -18,22 +16,17 @@ const props: MenuDetailsPageProps = {
saveButtonState: "default", saveButtonState: "default",
}; };
storiesOf("Navigation / Menu details", module) export default {
.addDecorator(Decorator) title: "Navigation / Menu details",
.add("default", () => <MenuDetailsPage {...props} />) };
.add("loading", () => (
export const Default = () => <MenuDetailsPage {...props} />;
export const Loading = () => (
<MenuDetailsPage {...props} disabled={true} menu={undefined} /> <MenuDetailsPage {...props} disabled={true} menu={undefined} />
)) );
.add("no data", () => (
<MenuDetailsPage export const FormErrors = () => (
{...props}
menu={{
...props.menu,
items: [],
}}
/>
))
.add("form errors", () => (
<MenuDetailsPage <MenuDetailsPage
{...props} {...props}
errors={["name"].map(field => ({ errors={["name"].map(field => ({
@ -43,4 +36,4 @@ storiesOf("Navigation / Menu details", module)
message: "Invalid field", message: "Invalid field",
}))} }))}
/> />
)); );

View file

@ -5,11 +5,9 @@ import {
} from "@dashboard/fixtures"; } from "@dashboard/fixtures";
import { menuList } from "@dashboard/navigation/fixtures"; import { menuList } from "@dashboard/navigation/fixtures";
import { MenuListUrlSortField } from "@dashboard/navigation/urls"; import { MenuListUrlSortField } from "@dashboard/navigation/urls";
import Decorator from "@dashboard/storybook/Decorator";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import MenuListPage, { MenuListPageProps } from "./MenuListPage"; import MenuListPage, { MenuListPageProps } from "./MenuListPage";
const props: MenuListPageProps = { const props: MenuListPageProps = {
@ -24,11 +22,15 @@ const props: MenuListPageProps = {
}, },
}; };
storiesOf("Navigation / Menu list", module) export default {
.addDecorator(Decorator) title: "Navigation / Menu list",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <MenuListPage {...props} />) };
.add("loading", () => (
export const Default = () => <MenuListPage {...props} />;
export const Loading = () => (
<MenuListPage {...props} disabled={true} menus={undefined} /> <MenuListPage {...props} disabled={true} menus={undefined} />
)) );
.add("no data", () => <MenuListPage {...props} menus={[]} />);
export const NoData = () => <MenuListPage {...props} menus={[]} />;

View file

@ -13,7 +13,7 @@ import MenuDetailsComponent from "./views/MenuDetails";
import MenuListComponent from "./views/MenuList"; import MenuListComponent from "./views/MenuList";
const MenuList: React.FC<RouteComponentProps<{}>> = ({ location }) => { const MenuList: React.FC<RouteComponentProps<{}>> = ({ location }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: MenuListUrlQueryParams = asSortParams(qs, MenuListUrlSortField); const params: MenuListUrlQueryParams = asSortParams(qs, MenuListUrlSortField);
return <MenuListComponent params={params} />; return <MenuListComponent params={params} />;

View file

@ -46,13 +46,9 @@ export interface OrderChangeWarehouseDialogProps {
onClose(); onClose();
} }
export const OrderChangeWarehouseDialog: React.FC<OrderChangeWarehouseDialogProps> = ({ export const OrderChangeWarehouseDialog: React.FC<
open, OrderChangeWarehouseDialogProps
line, > = ({ open, line, currentWarehouseId, onConfirm, onClose }) => {
currentWarehouseId,
onConfirm,
onClose,
}) => {
const classes = useStyles(); const classes = useStyles();
const intl = useIntl(); const intl = useIntl();
@ -71,7 +67,11 @@ export const OrderChangeWarehouseDialog: React.FC<OrderChangeWarehouseDialogProp
} }
}, [currentWarehouseId]); }, [currentWarehouseId]);
const { result: warehousesOpts, loadMore, search } = useWarehouseSearch({ const {
result: warehousesOpts,
loadMore,
search,
} = useWarehouseSearch({
variables: { variables: {
after: null, after: null,
first: 20, first: 20,
@ -150,7 +150,7 @@ export const OrderChangeWarehouseDialog: React.FC<OrderChangeWarehouseDialogProp
</DialogContent> </DialogContent>
</ScrollShadow> </ScrollShadow>
<DialogTable ref={setAnchor}> <DialogTable ref={setAnchor} css>
{filteredWarehouses ? ( {filteredWarehouses ? (
<RadioGroup <RadioGroup
value={selectedWarehouseId} value={selectedWarehouseId}
@ -158,10 +158,8 @@ export const OrderChangeWarehouseDialog: React.FC<OrderChangeWarehouseDialogProp
className={classes.tableBody} className={classes.tableBody}
> >
{filteredWarehouses.map(warehouse => { {filteredWarehouses.map(warehouse => {
const lineQuantityInWarehouse = getLineAvailableQuantityInWarehouse( const lineQuantityInWarehouse =
line, getLineAvailableQuantityInWarehouse(line, warehouse);
warehouse,
);
return ( return (
<TableRowLink key={warehouse.id}> <TableRowLink key={warehouse.id}>
<TableCell className={classes.tableCell}> <TableCell className={classes.tableCell}>

View file

@ -1,21 +1,14 @@
import { import {
FulfillmentStatus, FulfillmentStatus,
GiftCardEventsEnum,
OrderDetailsFragment,
OrderStatus, OrderStatus,
PaymentChargeStatusEnum, PaymentChargeStatusEnum,
} from "@dashboard/graphql"; } from "@dashboard/graphql";
import { import {
grantedRefunds,
order, order,
ORDER_AMOUNT,
payments, payments,
prepareMoney, prepareMoney,
shop, shop,
transactions,
} from "@dashboard/orders/fixtures"; } from "@dashboard/orders/fixtures";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import OrderDetailsPage, { OrderDetailsPageProps } from "./OrderDetailsPage"; import OrderDetailsPage, { OrderDetailsPageProps } from "./OrderDetailsPage";
@ -49,9 +42,11 @@ const props: Omit<OrderDetailsPageProps, "classes"> = {
saveButtonBarState: "default", saveButtonBarState: "default",
}; };
storiesOf("Orders / Order details", module) export default {
.addDecorator(Decorator) title: "Orders / Order details",
.add("pending", () => ( };
export const Pending = () => (
<OrderDetailsPage <OrderDetailsPage
{...props} {...props}
order={{ order={{
@ -61,8 +56,9 @@ storiesOf("Orders / Order details", module)
payments: [payments.pending], payments: [payments.pending],
}} }}
/> />
)) );
.add("authorized", () => (
export const Authorized = () => (
<OrderDetailsPage <OrderDetailsPage
{...props} {...props}
order={{ order={{
@ -72,8 +68,9 @@ storiesOf("Orders / Order details", module)
payments: [payments.authorized], payments: [payments.authorized],
}} }}
/> />
)) );
.add("completed", () => (
export const Completed = () => (
<OrderDetailsPage <OrderDetailsPage
{...props} {...props}
order={{ order={{
@ -83,8 +80,9 @@ storiesOf("Orders / Order details", module)
payments: [payments.completed], payments: [payments.completed],
}} }}
/> />
)) );
.add("no payment", () => (
export const NoPayment = () => (
<OrderDetailsPage <OrderDetailsPage
{...props} {...props}
order={{ order={{
@ -95,8 +93,9 @@ storiesOf("Orders / Order details", module)
totalAuthorized: prepareMoney(0), totalAuthorized: prepareMoney(0),
}} }}
/> />
)) );
.add("refunded", () => (
export const Refunded = () => (
<OrderDetailsPage <OrderDetailsPage
{...props} {...props}
order={{ order={{
@ -106,8 +105,9 @@ storiesOf("Orders / Order details", module)
payments: [payments.refunded], payments: [payments.refunded],
}} }}
/> />
)) );
.add("partial refund", () => (
export const PartialRefund = () => (
<OrderDetailsPage <OrderDetailsPage
{...props} {...props}
order={{ order={{
@ -117,8 +117,9 @@ storiesOf("Orders / Order details", module)
payments: [payments.partialRefund], payments: [payments.partialRefund],
}} }}
/> />
)) );
.add("rejected", () => (
export const Rejected = () => (
<OrderDetailsPage <OrderDetailsPage
{...props} {...props}
order={{ order={{
@ -128,192 +129,13 @@ storiesOf("Orders / Order details", module)
payments: [payments.rejected], payments: [payments.rejected],
}} }}
/> />
)); );
storiesOf("Views / Orders / Order details / transactions", module) export const Default = () => <OrderDetailsPage {...props} />;
.addDecorator(Decorator)
.add("preauthorized", () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: false,
totalAuthorized: prepareMoney(),
totalCharged: prepareMoney(0),
paymentStatus: PaymentChargeStatusEnum.NOT_CHARGED,
transactions: transactions.preauthorized,
}}
/>
))
.add("pending", () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: false,
paymentStatus: PaymentChargeStatusEnum.PENDING,
transactions: transactions.pendingCharge,
}}
/>
))
.add("success", () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: true,
totalAuthorized: prepareMoney(0),
totalCharged: prepareMoney(),
paymentStatus: PaymentChargeStatusEnum.FULLY_CHARGED,
transactions: transactions.chargeSuccess,
}}
/>
))
.add("partial capture", () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: true,
totalAuthorized: prepareMoney(ORDER_AMOUNT - 10),
totalCharged: prepareMoney(10),
paymentStatus: PaymentChargeStatusEnum.PARTIALLY_CHARGED,
transactions: transactions.chargePartial,
}}
/>
))
.add("failed", () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: false,
paymentStatus: PaymentChargeStatusEnum.REFUSED,
transactions: transactions.chargeFail,
}}
/>
))
.add("refund requested", () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: true,
totalAuthorized: prepareMoney(0),
totalCharged: prepareMoney(),
paymentStatus: PaymentChargeStatusEnum.FULLY_CHARGED,
transactions: transactions.refundRequested,
}}
/>
))
.add("refund granted", () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: true,
grantedRefunds,
totalGrantedRefund: prepareMoney(),
totalAuthorized: prepareMoney(0),
totalCharged: prepareMoney(),
paymentStatus: PaymentChargeStatusEnum.FULLY_CHARGED,
transactions: transactions.chargeSuccess,
}}
/>
))
.add("refund completed", () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: true,
grantedRefunds,
totalRefunded: prepareMoney(),
totalAuthorized: prepareMoney(0),
totalCharged: prepareMoney(0),
paymentStatus: PaymentChargeStatusEnum.FULLY_REFUNDED,
transactions: transactions.refundCompleted,
}}
/>
))
.add("partial refund completed", () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: true,
grantedRefunds,
totalRefunded: prepareMoney(10),
totalAuthorized: prepareMoney(0),
totalCharged: prepareMoney(ORDER_AMOUNT - 10),
paymentStatus: PaymentChargeStatusEnum.PARTIALLY_REFUNDED,
transactions: transactions.refundPartial,
}}
/>
))
.add("paid with giftcard", () => (
<OrderDetailsPage
{...props}
order={
{
...props.order,
isPaid: true,
transactions: [],
paymentStatus: PaymentChargeStatusEnum.FULLY_CHARGED,
// gift cards are treated as dicounts
total: {
net: prepareMoney(0),
gross: prepareMoney(0),
tax: prepareMoney(0),
__typename: "TaxedMoney",
},
giftCards: [
{
__typename: "GiftCard",
id: "R2lmdENhcmQ6Ng==",
last4CodeChars: "43FA",
events: [
{
__typename: "GiftCardEvent",
id: "R2lmdENhcmRFdmVudDo1",
type: GiftCardEventsEnum.ISSUED,
orderId: null,
date: "2022-09-20T13:00:42.676174+00:00",
balance: {
__typename: "GiftCardEventBalance",
initialBalance: prepareMoney(),
currentBalance: prepareMoney(),
oldInitialBalance: null,
oldCurrentBalance: null,
},
},
{
__typename: "GiftCardEvent",
id: "R2lmdENhcmRFdmVudDo2",
type: GiftCardEventsEnum.USED_IN_ORDER,
orderId: props.order.id,
date: "2022-09-20T13:04:20.017419+00:00",
balance: {
__typename: "GiftCardEventBalance",
initialBalance: null,
currentBalance: prepareMoney(0),
oldInitialBalance: null,
oldCurrentBalance: prepareMoney(),
},
},
],
},
],
} as OrderDetailsFragment
}
/>
));
storiesOf("Views / Orders / Order details", module) export const Loading = () => <OrderDetailsPage {...props} order={undefined} />;
.addDecorator(Decorator)
.add("default", () => <OrderDetailsPage {...props} />) export const Cancelled = () => (
.add("loading", () => <OrderDetailsPage {...props} order={undefined} />)
.add("cancelled", () => (
<OrderDetailsPage <OrderDetailsPage
{...props} {...props}
order={{ order={{
@ -325,8 +147,9 @@ storiesOf("Views / Orders / Order details", module)
status: OrderStatus.CANCELED, status: OrderStatus.CANCELED,
}} }}
/> />
)) );
.add("fulfilled", () => (
export const Fulfilled = () => (
<OrderDetailsPage <OrderDetailsPage
{...props} {...props}
order={{ order={{
@ -334,8 +157,9 @@ storiesOf("Views / Orders / Order details", module)
status: OrderStatus.FULFILLED, status: OrderStatus.FULFILLED,
}} }}
/> />
)) );
.add("partially fulfilled", () => (
export const PartiallyFulfilled = () => (
<OrderDetailsPage <OrderDetailsPage
{...props} {...props}
order={{ order={{
@ -343,8 +167,9 @@ storiesOf("Views / Orders / Order details", module)
status: OrderStatus.PARTIALLY_FULFILLED, status: OrderStatus.PARTIALLY_FULFILLED,
}} }}
/> />
)) );
.add("unfulfilled", () => (
export const Unfulfilled = () => (
<OrderDetailsPage <OrderDetailsPage
{...props} {...props}
order={{ order={{
@ -352,8 +177,9 @@ storiesOf("Views / Orders / Order details", module)
status: OrderStatus.UNFULFILLED, status: OrderStatus.UNFULFILLED,
}} }}
/> />
)) );
.add("no shipping address", () => (
export const NoShippingAddress = () => (
<OrderDetailsPage <OrderDetailsPage
{...props} {...props}
order={{ order={{
@ -361,8 +187,9 @@ storiesOf("Views / Orders / Order details", module)
shippingAddress: null, shippingAddress: null,
}} }}
/> />
)) );
.add("no customer note", () => (
export const NoCustomerNote = () => (
<OrderDetailsPage <OrderDetailsPage
{...props} {...props}
order={{ order={{
@ -370,4 +197,4 @@ storiesOf("Views / Orders / Order details", module)
customerNote: "", customerNote: "",
}} }}
/> />
)); );

View file

@ -0,0 +1,235 @@
import {
GiftCardEventsEnum,
OrderDetailsFragment,
PaymentChargeStatusEnum,
} from "@dashboard/graphql";
import {
grantedRefunds,
order,
ORDER_AMOUNT,
prepareMoney,
shop,
transactions,
} from "@dashboard/orders/fixtures";
import React from "react";
import OrderDetailsPage, { OrderDetailsPageProps } from "./OrderDetailsPage";
const props: Omit<OrderDetailsPageProps, "classes"> = {
disabled: false,
onBillingAddressEdit: undefined,
onTransactionAction: () => undefined,
onFulfillmentApprove: () => undefined,
onFulfillmentCancel: () => undefined,
onFulfillmentTrackingNumberUpdate: () => undefined,
onInvoiceClick: () => undefined,
onInvoiceGenerate: () => undefined,
onInvoiceSend: () => undefined,
onNoteAdd: undefined,
onOrderCancel: undefined,
onOrderFulfill: undefined,
onOrderReturn: () => undefined,
onPaymentCapture: undefined,
onMarkAsPaid: undefined,
onPaymentVoid: undefined,
onPaymentRefund: undefined,
onProductClick: undefined,
onProfileView: () => undefined,
onShippingAddressEdit: undefined,
onSubmit: () => undefined,
onAddManualTransaction: () => undefined,
order: order(null),
errors: [],
shop,
saveButtonBarState: "default",
};
export default {
title: "Orders / Order details / transactions",
};
export const Preauthorized = () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: false,
totalAuthorized: prepareMoney(),
totalCharged: prepareMoney(0),
paymentStatus: PaymentChargeStatusEnum.NOT_CHARGED,
transactions: transactions.preauthorized,
}}
/>
);
export const Pending = () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: false,
paymentStatus: PaymentChargeStatusEnum.PENDING,
transactions: transactions.pendingCharge,
}}
/>
);
export const Success = () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: true,
totalAuthorized: prepareMoney(0),
totalCharged: prepareMoney(),
paymentStatus: PaymentChargeStatusEnum.FULLY_CHARGED,
transactions: transactions.chargeSuccess,
}}
/>
);
export const PartialCapture = () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: true,
totalAuthorized: prepareMoney(ORDER_AMOUNT - 10),
totalCharged: prepareMoney(10),
paymentStatus: PaymentChargeStatusEnum.PARTIALLY_CHARGED,
transactions: transactions.chargePartial,
}}
/>
);
export const Failed = () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: false,
paymentStatus: PaymentChargeStatusEnum.REFUSED,
transactions: transactions.chargeFail,
}}
/>
);
export const RefundRequested = () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: true,
totalAuthorized: prepareMoney(0),
totalCharged: prepareMoney(),
paymentStatus: PaymentChargeStatusEnum.FULLY_CHARGED,
transactions: transactions.refundRequested,
}}
/>
);
export const RefundGranted = () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: true,
grantedRefunds,
totalGrantedRefund: prepareMoney(),
totalAuthorized: prepareMoney(0),
totalCharged: prepareMoney(),
paymentStatus: PaymentChargeStatusEnum.FULLY_CHARGED,
transactions: transactions.chargeSuccess,
}}
/>
);
export const RefundCompleted = () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: true,
grantedRefunds,
totalRefunded: prepareMoney(),
totalAuthorized: prepareMoney(0),
totalCharged: prepareMoney(0),
paymentStatus: PaymentChargeStatusEnum.FULLY_REFUNDED,
transactions: transactions.refundCompleted,
}}
/>
);
export const PartialRefundCompleted = () => (
<OrderDetailsPage
{...props}
order={{
...props.order,
isPaid: true,
grantedRefunds,
totalRefunded: prepareMoney(10),
totalAuthorized: prepareMoney(0),
totalCharged: prepareMoney(ORDER_AMOUNT - 10),
paymentStatus: PaymentChargeStatusEnum.PARTIALLY_REFUNDED,
transactions: transactions.refundPartial,
}}
/>
);
export const PaidWithGiftcard = () => (
<OrderDetailsPage
{...props}
order={
{
...props.order,
isPaid: true,
transactions: [],
paymentStatus: PaymentChargeStatusEnum.FULLY_CHARGED,
// gift cards are treated as dicounts
total: {
net: prepareMoney(0),
gross: prepareMoney(0),
tax: prepareMoney(0),
__typename: "TaxedMoney",
},
giftCards: [
{
__typename: "GiftCard",
id: "R2lmdENhcmQ6Ng==",
last4CodeChars: "43FA",
events: [
{
__typename: "GiftCardEvent",
id: "R2lmdENhcmRFdmVudDo1",
type: GiftCardEventsEnum.ISSUED,
orderId: null,
date: "2022-09-20T13:00:42.676174+00:00",
balance: {
__typename: "GiftCardEventBalance",
initialBalance: prepareMoney(),
currentBalance: prepareMoney(),
oldInitialBalance: null,
oldCurrentBalance: null,
},
},
{
__typename: "GiftCardEvent",
id: "R2lmdENhcmRFdmVudDo2",
type: GiftCardEventsEnum.USED_IN_ORDER,
orderId: props.order.id,
date: "2022-09-20T13:04:20.017419+00:00",
balance: {
__typename: "GiftCardEventBalance",
initialBalance: null,
currentBalance: prepareMoney(0),
oldInitialBalance: null,
oldCurrentBalance: prepareMoney(),
},
},
],
},
],
} as OrderDetailsFragment
}
/>
);

View file

@ -9,11 +9,9 @@ import {
tabPageProps, tabPageProps,
} from "@dashboard/fixtures"; } from "@dashboard/fixtures";
import { OrderDraftListUrlSortField } from "@dashboard/orders/urls"; import { OrderDraftListUrlSortField } from "@dashboard/orders/urls";
import Decorator from "@dashboard/storybook/Decorator";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import { orders } from "../../fixtures"; import { orders } from "../../fixtures";
import OrderDraftListPage, { import OrderDraftListPage, {
OrderDraftListPageProps, OrderDraftListPageProps,
@ -48,14 +46,19 @@ const props: OrderDraftListPageProps = {
}, },
}; };
storiesOf("Orders / Draft order list", module) export default {
.addDecorator(Decorator) title: "Orders / Draft order list",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <OrderDraftListPage {...props} />) };
.add("loading", () => (
export const Default = () => <OrderDraftListPage {...props} />;
export const Loading = () => (
<OrderDraftListPage {...props} disabled orders={undefined} /> <OrderDraftListPage {...props} disabled orders={undefined} />
)) );
.add("when no data", () => <OrderDraftListPage {...props} orders={[]} />)
.add("limits reached", () => ( export const WhenNoData = () => <OrderDraftListPage {...props} orders={[]} />;
export const LimitsReached = () => (
<OrderDraftListPage {...props} limits={limitsReached} /> <OrderDraftListPage {...props} limits={limitsReached} />
)); );

View file

@ -6,11 +6,9 @@ import {
clients, clients,
draftOrder, draftOrder,
} from "@dashboard/orders/fixtures"; } from "@dashboard/orders/fixtures";
import Decorator from "@dashboard/storybook/Decorator";
import { MockedUserProvider } from "@dashboard/storybook/MockedUserProvider";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { MockedUserProvider } from "../../../../.storybook/helpers";
import OrderDraftPageComponent, { OrderDraftPageProps } from "./OrderDraftPage"; import OrderDraftPageComponent, { OrderDraftPageProps } from "./OrderDraftPage";
import { getDiscountsProvidersWrapper } from "./storybook.utils"; import { getDiscountsProvidersWrapper } from "./storybook.utils";
@ -79,24 +77,26 @@ const OrderDraftPage = props => {
); );
}; };
storiesOf("Orders / Order draft", module) export default {
.addDecorator(Decorator) title: "Orders / Order draft",
.addDecorator(DiscountsDecorator) decorators: [DiscountsDecorator],
.add("default", () => <OrderDraftPage {...props} />) };
.add("loading", () => (
export const Default = () => <OrderDraftPage {...props} />;
export const Loading = () => (
<OrderDraftPage <OrderDraftPage
{...props} {...props}
disabled={true} disabled={true}
order={undefined} order={undefined}
channelUsabilityData={undefined} channelUsabilityData={undefined}
/> />
)) );
.add("without lines", () => (
<OrderDraftPage {...props} order={{ ...order, lines: [] }} /> export const NoUserPermissions = () => (
))
.add("no user permissions", () => (
<OrderDraftPage {...props} customPermissions={[]} /> <OrderDraftPage {...props} customPermissions={[]} />
)) );
.add("with errors", () => (
export const WithErrors = () => (
<OrderDraftPage {...props} errors={finalizeErrors} /> <OrderDraftPage {...props} errors={finalizeErrors} />
)); );

View file

@ -1,7 +1,5 @@
import { OrderErrorCode } from "@dashboard/graphql"; import { OrderErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { warehouseList } from "@dashboard/warehouses/fixtures"; import { warehouseList } from "@dashboard/warehouses/fixtures";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { orderToFulfill } from "./fixtures"; import { orderToFulfill } from "./fixtures";
@ -18,13 +16,17 @@ const props: OrderFulfillPageProps = {
closeModal: () => undefined, closeModal: () => undefined,
}; };
storiesOf("Orders / Fulfill order", module) export default {
.addDecorator(Decorator) title: "Orders / Fulfill order",
.add("default", () => <OrderFulfillPage {...props} />) };
.add("loading", () => (
export const Default = () => <OrderFulfillPage {...props} />;
export const Loading = () => (
<OrderFulfillPage {...props} loading={true} order={undefined} /> <OrderFulfillPage {...props} loading={true} order={undefined} />
)) );
.add("error", () => (
export const Error = () => (
<OrderFulfillPage <OrderFulfillPage
{...props} {...props}
errors={[ errors={[
@ -39,5 +41,6 @@ storiesOf("Orders / Fulfill order", module)
}, },
]} ]}
/> />
)) );
.add("one warehouse", () => <OrderFulfillPage {...props} />);
export const OneWarehouse = () => <OrderFulfillPage {...props} />;

View file

@ -1,7 +1,5 @@
import placeholderImage from "@assets/images/placeholder60x60.png"; import placeholderImage from "@assets/images/placeholder60x60.png";
import { FulfillmentStatus } from "@dashboard/graphql"; import { FulfillmentStatus } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import OrderGrantRefundPage, { import OrderGrantRefundPage, {
@ -244,14 +242,17 @@ const props: OrderGrantRefundPageProps = {
onSubmit: data => console.log("onSubmit", data), onSubmit: data => console.log("onSubmit", data),
}; };
storiesOf("Views / Orders / Grant refund order", module) export default {
.addDecorator(Decorator) title: "Orders / Grant refund order",
.add("grant refund", () => <OrderGrantRefundPage {...props} />) };
.add("loading", () => (
export const GrantRefund = () => <OrderGrantRefundPage {...props} />;
export const Loading = () => (
<OrderGrantRefundPage <OrderGrantRefundPage
submitState="loading" submitState="loading"
order={null} order={null}
loading={true} loading={true}
onSubmit={() => undefined} onSubmit={() => undefined}
/> />
)); );

View file

@ -9,11 +9,9 @@ import {
import { OrderStatusFilter, PaymentChargeStatusEnum } from "@dashboard/graphql"; import { OrderStatusFilter, PaymentChargeStatusEnum } from "@dashboard/graphql";
import { orders } from "@dashboard/orders/fixtures"; import { orders } from "@dashboard/orders/fixtures";
import { OrderListUrlSortField } from "@dashboard/orders/urls"; import { OrderListUrlSortField } from "@dashboard/orders/urls";
import Decorator from "@dashboard/storybook/Decorator";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import { OrderFilterGiftCard } from "./filters"; import { OrderFilterGiftCard } from "./filters";
import OrderListPage, { OrderListPageProps } from "./OrderListPage"; import OrderListPage, { OrderListPageProps } from "./OrderListPage";
@ -86,20 +84,26 @@ const props: OrderListPageProps = {
onTabUpdate: () => undefined, onTabUpdate: () => undefined,
}; };
storiesOf("Orders / Order list", module) export default {
.addDecorator(Decorator) title: "Orders / Order list",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <OrderListPage {...props} />) };
.add("loading", () => (
export const Default = () => <OrderListPage {...props} />;
export const Loading = () => (
<OrderListPage <OrderListPage
{...props} {...props}
orders={undefined} orders={undefined}
currentTab={undefined} currentTab={undefined}
disabled={true} disabled={true}
/> />
)) );
.add("when no data", () => <OrderListPage {...props} orders={[]} />)
.add("no limits", () => <OrderListPage {...props} limits={undefined} />) export const WhenNoData = () => <OrderListPage {...props} orders={[]} />;
.add("limits reached", () => (
export const NoLimits = () => <OrderListPage {...props} limits={undefined} />;
export const LimitsReached = () => (
<OrderListPage {...props} limits={limitsReached} /> <OrderListPage {...props} limits={limitsReached} />
)); );

View file

@ -1,6 +1,4 @@
import placeholderImage from "@assets/images/placeholder60x60.png"; import placeholderImage from "@assets/images/placeholder60x60.png";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { orderToRefund } from "./fixtures"; import { orderToRefund } from "./fixtures";
@ -14,14 +12,18 @@ const props: OrderRefundPageProps = {
order: orderToRefund(placeholderImage), order: orderToRefund(placeholderImage),
}; };
storiesOf("Orders / Refund order", module) export default {
.addDecorator(Decorator) title: "Orders / Refund order",
.add("products", () => ( };
export const Products = () => (
<OrderRefundPage {...props} defaultType={OrderRefundType.PRODUCTS} /> <OrderRefundPage {...props} defaultType={OrderRefundType.PRODUCTS} />
)) );
.add("miscellaneous", () => (
export const Miscellaneous = () => (
<OrderRefundPage {...props} defaultType={OrderRefundType.MISCELLANEOUS} /> <OrderRefundPage {...props} defaultType={OrderRefundType.MISCELLANEOUS} />
)) );
.add("loading", () => (
export const Loading = () => (
<OrderRefundPage {...props} disabled={true} order={undefined} /> <OrderRefundPage {...props} disabled={true} order={undefined} />
)); );

View file

@ -1,5 +1,3 @@
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { order as orderFixture, prepareMoney } from "../../fixtures"; import { order as orderFixture, prepareMoney } from "../../fixtures";
@ -13,10 +11,13 @@ const props: OrderSendRefundPageProps = {
addManualRefundError: undefined, addManualRefundError: undefined,
}; };
storiesOf("Views / Orders / Send refund order", module) export default {
.addDecorator(Decorator) title: "Orders / Send refund order",
.add("settled", () => <OrderSendRefund {...props} />) };
.add("unsettled", () => (
export const Settled = () => <OrderSendRefund {...props} />;
export const Unsettled = () => (
<OrderSendRefund <OrderSendRefund
{...props} {...props}
order={{ order={{
@ -25,7 +26,8 @@ storiesOf("Views / Orders / Send refund order", module)
totalRemainingGrant: prepareMoney(10), totalRemainingGrant: prepareMoney(10),
}} }}
/> />
)) );
.add("loading", () => (
export const Loading = () => (
<OrderSendRefund {...props} order={null} loading={true} /> <OrderSendRefund {...props} order={null} loading={true} />
)); );

View file

@ -2,8 +2,6 @@ import {
orderSettings as orderSettingsFixture, orderSettings as orderSettingsFixture,
shopOrderSettings as shopOrderSettingsFixture, shopOrderSettings as shopOrderSettingsFixture,
} from "@dashboard/orders/fixtures"; } from "@dashboard/orders/fixtures";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import OrderSettings, { OrderSettingsPageProps } from "./OrderSettingsPage"; import OrderSettings, { OrderSettingsPageProps } from "./OrderSettingsPage";
@ -16,14 +14,17 @@ const props: OrderSettingsPageProps = {
saveButtonBarState: "default", saveButtonBarState: "default",
}; };
storiesOf(" Orders / Order settings", module) export default {
.addDecorator(Decorator) title: " Orders / Order settings",
.add("default", () => <OrderSettings {...props} />) };
.add("loading", () => (
export const Default = () => <OrderSettings {...props} />;
export const Loading = () => (
<OrderSettings <OrderSettings
{...props} {...props}
disabled={true} disabled={true}
orderSettings={undefined} orderSettings={undefined}
shop={undefined} shop={undefined}
/> />
)); );

View file

@ -5,8 +5,6 @@ import {
import OrderTransaction, { import OrderTransaction, {
OrderTransactionProps, OrderTransactionProps,
} from "@dashboard/orders/components/OrderTransaction"; } from "@dashboard/orders/components/OrderTransaction";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { prepareMoney } from "../fixtures"; import { prepareMoney } from "../fixtures";
@ -150,7 +148,10 @@ const longAmountProps: OrderTransactionProps = {
}, },
}; };
storiesOf("Orders / OrderTransaction", module) export default {
.addDecorator(Decorator) title: "Orders / OrderTransaction",
.add("default", () => <OrderTransaction {...props} />) };
.add("long amounts", () => <OrderTransaction {...longAmountProps} />);
export const Default = () => <OrderTransaction {...props} />;
export const LongAmounts = () => <OrderTransaction {...longAmountProps} />;

View file

@ -36,7 +36,7 @@ import OrderSendRefundComponent from "./views/OrderSendRefund";
import OrderSettings from "./views/OrderSettings"; import OrderSettings from "./views/OrderSettings";
const OrderList: React.FC<RouteComponentProps<any>> = ({ location }) => { const OrderList: React.FC<RouteComponentProps<any>> = ({ location }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: OrderListUrlQueryParams = asSortParams( const params: OrderListUrlQueryParams = asSortParams(
qs, qs,
OrderListUrlSortField, OrderListUrlSortField,
@ -46,7 +46,7 @@ const OrderList: React.FC<RouteComponentProps<any>> = ({ location }) => {
return <OrderListComponent params={params} />; return <OrderListComponent params={params} />;
}; };
const OrderDraftList: React.FC<RouteComponentProps<any>> = ({ location }) => { const OrderDraftList: React.FC<RouteComponentProps<any>> = ({ location }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: OrderDraftListUrlQueryParams = asSortParams( const params: OrderDraftListUrlQueryParams = asSortParams(
qs, qs,
OrderDraftListUrlSortField, OrderDraftListUrlSortField,
@ -61,7 +61,7 @@ const OrderDetails: React.FC<RouteComponentProps<any>> = ({
location, location,
match, match,
}) => { }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: OrderUrlQueryParams = qs; const params: OrderUrlQueryParams = qs;
const id = match.params.id; const id = match.params.id;
@ -72,7 +72,7 @@ const OrderFulfill: React.FC<RouteComponentProps<any>> = ({
location, location,
match, match,
}) => { }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: OrderFulfillUrlQueryParams = qs; const params: OrderFulfillUrlQueryParams = qs;
return ( return (
<OrderFulfillComponent <OrderFulfillComponent

View file

@ -1,6 +1,4 @@
import { PageErrorCode } from "@dashboard/graphql"; import { PageErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import PageTypeCreatePage, { import PageTypeCreatePage, {
@ -14,11 +12,15 @@ const props: Omit<PageTypeCreatePageProps, "classes"> = {
saveButtonBarState: "default", saveButtonBarState: "default",
}; };
storiesOf("Page types / Create page type", module) export default {
.addDecorator(Decorator) title: "Page types / Create page type",
.add("default", () => <PageTypeCreatePage {...props} />) };
.add("loading", () => <PageTypeCreatePage {...props} disabled={true} />)
.add("form errors", () => ( export const Default = () => <PageTypeCreatePage {...props} />;
export const Loading = () => <PageTypeCreatePage {...props} disabled={true} />;
export const FormErrors = () => (
<PageTypeCreatePage <PageTypeCreatePage
{...props} {...props}
errors={[ errors={[
@ -32,4 +34,4 @@ storiesOf("Page types / Create page type", module)
...err, ...err,
}))} }))}
/> />
)); );

View file

@ -1,7 +1,5 @@
import { listActionsProps } from "@dashboard/fixtures"; import { listActionsProps } from "@dashboard/fixtures";
import { PageErrorCode } from "@dashboard/graphql"; import { PageErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { pageType } from "../../fixtures"; import { pageType } from "../../fixtures";
@ -23,27 +21,22 @@ const props: Omit<PageTypeDetailsPageProps, "classes"> = {
saveButtonBarState: "default", saveButtonBarState: "default",
}; };
storiesOf("Page types / Page type details", module) export default {
.addDecorator(Decorator) title: "Page types / Page type details",
.add("default", () => <PageTypeDetailsPage {...props} />) };
.add("loading", () => (
export const Default = () => <PageTypeDetailsPage {...props} />;
export const Loading = () => (
<PageTypeDetailsPage <PageTypeDetailsPage
{...props} {...props}
disabled={true} disabled={true}
pageTitle={undefined} pageTitle={undefined}
pageType={undefined} pageType={undefined}
/> />
)) );
.add("no attributes", () => (
<PageTypeDetailsPage export const FormErrors = () => (
{...props}
pageType={{
...pageType,
attributes: [],
}}
/>
))
.add("form errors", () => (
<PageTypeDetailsPage <PageTypeDetailsPage
{...props} {...props}
errors={[ errors={[
@ -57,4 +50,4 @@ storiesOf("Page types / Page type details", module)
...err, ...err,
}))} }))}
/> />
)); );

View file

@ -6,11 +6,9 @@ import {
tabPageProps, tabPageProps,
} from "@dashboard/fixtures"; } from "@dashboard/fixtures";
import { PageTypeListUrlSortField } from "@dashboard/pageTypes/urls"; import { PageTypeListUrlSortField } from "@dashboard/pageTypes/urls";
import Decorator from "@dashboard/storybook/Decorator";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import { pageTypes } from "../../fixtures"; import { pageTypes } from "../../fixtures";
import PageTypeListPage, { PageTypeListPageProps } from "./PageTypeListPage"; import PageTypeListPage, { PageTypeListPageProps } from "./PageTypeListPage";
@ -27,11 +25,15 @@ const props: PageTypeListPageProps = {
pageTypes, pageTypes,
}; };
storiesOf("Page types / Page types list", module) export default {
.addDecorator(Decorator) title: "Page types / Page types list",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <PageTypeListPage {...props} />) };
.add("loading", () => (
export const Default = () => <PageTypeListPage {...props} />;
export const Loading = () => (
<PageTypeListPage {...props} disabled={true} pageTypes={undefined} /> <PageTypeListPage {...props} disabled={true} pageTypes={undefined} />
)) );
.add("no data", () => <PageTypeListPage {...props} pageTypes={[]} />);
export const NoData = () => <PageTypeListPage {...props} pageTypes={[]} />;

View file

@ -19,7 +19,7 @@ import PageTypeDetailsComponent from "./views/PageTypeDetails";
import PageTypeListComponent from "./views/PageTypeList"; import PageTypeListComponent from "./views/PageTypeList";
const PageTypeList: React.FC<RouteComponentProps<{}>> = ({ location }) => { const PageTypeList: React.FC<RouteComponentProps<{}>> = ({ location }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: PageTypeListUrlQueryParams = asSortParams( const params: PageTypeListUrlQueryParams = asSortParams(
qs, qs,
PageTypeListUrlSortField, PageTypeListUrlSortField,
@ -30,9 +30,9 @@ const PageTypeList: React.FC<RouteComponentProps<{}>> = ({ location }) => {
interface PageTypeDetailsRouteParams { interface PageTypeDetailsRouteParams {
id: string; id: string;
} }
const PageTypeDetails: React.FC<RouteComponentProps< const PageTypeDetails: React.FC<
PageTypeDetailsRouteParams RouteComponentProps<PageTypeDetailsRouteParams>
>> = ({ match }) => { > = ({ match }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1));
const params: PageTypeUrlQueryParams = qs; const params: PageTypeUrlQueryParams = qs;

View file

@ -2,8 +2,6 @@ import { fetchMoreProps } from "@dashboard/fixtures";
import { PageErrorCode } from "@dashboard/graphql"; import { PageErrorCode } from "@dashboard/graphql";
import { PageData } from "@dashboard/pages/components/PageDetailsPage/form"; import { PageData } from "@dashboard/pages/components/PageDetailsPage/form";
import { page } from "@dashboard/pages/fixtures"; import { page } from "@dashboard/pages/fixtures";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import PageDetailsPage, { PageDetailsPageProps } from "./PageDetailsPage"; import PageDetailsPage, { PageDetailsPageProps } from "./PageDetailsPage";
@ -25,16 +23,21 @@ const props: PageDetailsPageProps = {
fetchMoreAttributeValues: fetchMoreProps, fetchMoreAttributeValues: fetchMoreProps,
}; };
storiesOf("Pages / Page details", module) export default {
.addDecorator(Decorator) title: "Pages / Page details",
.add("default", () => <PageDetailsPage {...props} />) };
.add("loading", () => (
export const Default = () => <PageDetailsPage {...props} />;
export const Loading = () => (
<PageDetailsPage {...props} loading={true} page={undefined} /> <PageDetailsPage {...props} loading={true} page={undefined} />
)) );
.add("form errors", () => (
export const FormErrors = () => (
<PageDetailsPage <PageDetailsPage
{...props} {...props}
errors={([ errors={(
[
"title", "title",
"slug", "slug",
"content", "content",
@ -42,7 +45,8 @@ storiesOf("Pages / Page details", module)
"isPublished", "isPublished",
"seoDescription", "seoDescription",
"seoTitle", "seoTitle",
] as Array<keyof PageData>).map(field => ({ ] as Array<keyof PageData>
).map(field => ({
__typename: "PageError", __typename: "PageError",
attributes: [], attributes: [],
code: PageErrorCode.INVALID, code: PageErrorCode.INVALID,
@ -50,4 +54,4 @@ storiesOf("Pages / Page details", module)
message: "Page field error", message: "Page field error",
}))} }))}
/> />
)); );

View file

@ -5,11 +5,9 @@ import {
} from "@dashboard/fixtures"; } from "@dashboard/fixtures";
import { pageList } from "@dashboard/pages/fixtures"; import { pageList } from "@dashboard/pages/fixtures";
import { PageListUrlSortField } from "@dashboard/pages/urls"; import { PageListUrlSortField } from "@dashboard/pages/urls";
import Decorator from "@dashboard/storybook/Decorator";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import PageListPage, { PageListPageProps } from "./PageListPage"; import PageListPage, { PageListPageProps } from "./PageListPage";
const props: PageListPageProps = { const props: PageListPageProps = {
@ -30,11 +28,15 @@ const props: PageListPageProps = {
}, },
}; };
storiesOf("Pages / Page list", module) export default {
.addDecorator(Decorator) title: "Pages / Page list",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <PageListPage {...props} />) };
.add("loading", () => (
export const Default = () => <PageListPage {...props} />;
export const Loading = () => (
<PageListPage {...props} disabled={true} pages={undefined} /> <PageListPage {...props} disabled={true} pages={undefined} />
)) );
.add("no data", () => <PageListPage {...props} pages={[]} />);
export const NoData = () => <PageListPage {...props} pages={[]} />;

View file

@ -20,7 +20,7 @@ import PageDetailsComponent from "./views/PageDetails";
import PageListComponent from "./views/PageList"; import PageListComponent from "./views/PageList";
const PageList: React.FC<RouteComponentProps<{}>> = ({ location }) => { const PageList: React.FC<RouteComponentProps<{}>> = ({ location }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: PageListUrlQueryParams = asSortParams( const params: PageListUrlQueryParams = asSortParams(
qs, qs,
PageListUrlSortField, PageListUrlSortField,

View file

@ -1,6 +1,4 @@
import { permissions } from "@dashboard/fixtures"; import { permissions } from "@dashboard/fixtures";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { errorsOfPermissionGroupCreate } from "../../fixtures"; import { errorsOfPermissionGroupCreate } from "../../fixtures";
@ -16,15 +14,19 @@ const props: PermissionGroupCreatePageProps = {
saveButtonBarState: undefined, saveButtonBarState: undefined,
}; };
storiesOf("Permission Groups / Permission Group Create", module) export default {
.addDecorator(Decorator) title: "Permission Groups / Permission Group Create",
.add("default", () => <PermissionGroupCreatePage {...props} />) };
.add("loading", () => (
export const Default = () => <PermissionGroupCreatePage {...props} />;
export const Loading = () => (
<PermissionGroupCreatePage {...props} disabled={true} /> <PermissionGroupCreatePage {...props} disabled={true} />
)) );
.add("errors", () => (
export const Errors = () => (
<PermissionGroupCreatePage <PermissionGroupCreatePage
{...props} {...props}
errors={errorsOfPermissionGroupCreate} errors={errorsOfPermissionGroupCreate}
/> />
)); );

View file

@ -1,6 +1,4 @@
import { permissions } from "@dashboard/fixtures"; import { permissions } from "@dashboard/fixtures";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { emptyPermissionGroup, permissionGroup, users } from "../../fixtures"; import { emptyPermissionGroup, permissionGroup, users } from "../../fixtures";
@ -28,21 +26,25 @@ const props: PermissionGroupDetailsPageProps = {
toolbar: null, toolbar: null,
}; };
storiesOf("Permission Groups / Permission Group Details", module) export default {
.addDecorator(Decorator) title: "Permission Groups / Permission Group Details",
.add("default", () => <PermissionGroupDetailsPage {...props} />) };
.add("no members", () => (
export const Default = () => <PermissionGroupDetailsPage {...props} />;
export const NoMembers = () => (
<PermissionGroupDetailsPage <PermissionGroupDetailsPage
{...props} {...props}
members={[]} members={[]}
permissionGroup={emptyPermissionGroup} permissionGroup={emptyPermissionGroup}
/> />
)) );
.add("loading", () => (
export const Loading = () => (
<PermissionGroupDetailsPage <PermissionGroupDetailsPage
{...props} {...props}
disabled={true} disabled={true}
permissionGroup={undefined} permissionGroup={undefined}
permissions={undefined} permissions={undefined}
/> />
)); );

View file

@ -3,11 +3,9 @@ import {
pageListProps, pageListProps,
sortPageProps, sortPageProps,
} from "@dashboard/fixtures"; } from "@dashboard/fixtures";
import Decorator from "@dashboard/storybook/Decorator";
import { PaginatorContextDecorator } from "@dashboard/storybook/PaginatorContextDecorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { PaginatorContextDecorator } from "../../../../.storybook/decorators";
import { permissionGroups } from "../../fixtures"; import { permissionGroups } from "../../fixtures";
import { PermissionGroupListUrlSortField } from "../../urls"; import { PermissionGroupListUrlSortField } from "../../urls";
import PermissionGroupListPage, { import PermissionGroupListPage, {
@ -27,17 +25,17 @@ const props: PermissionGroupListPageProps = {
}, },
}; };
storiesOf("Permission Groups / Permission Group List", module) export default {
.addDecorator(Decorator) title: "Permission Groups / Permission Group List",
.addDecorator(PaginatorContextDecorator) decorators: [PaginatorContextDecorator],
.add("default", () => <PermissionGroupListPage {...props} />) };
.add("loading", () => (
export const Default = () => <PermissionGroupListPage {...props} />;
export const Loading = () => (
<PermissionGroupListPage <PermissionGroupListPage
{...props} {...props}
permissionGroups={undefined} permissionGroups={undefined}
disabled={true} disabled={true}
/> />
)) );
.add("no data", () => (
<PermissionGroupListPage {...props} permissionGroups={[]} disabled={true} />
));

View file

@ -1,4 +1,4 @@
import * as avatarImg from "@assets/images/avatars/avatar1.png"; import avatarImg from "@assets/images/avatars/avatar.png";
import { import {
PermissionEnum, PermissionEnum,
PermissionGroupDetailsFragment, PermissionGroupDetailsFragment,
@ -90,7 +90,8 @@ export const permissionGroups: PermissionGroupFragment[] = [
}, },
].map(edge => edge.node); ].map(edge => edge.node);
export const userPermissionGroups: StaffMemberDetailsFragment["permissionGroups"] = [ export const userPermissionGroups: StaffMemberDetailsFragment["permissionGroups"] =
[
{ {
id: "R3JvdXA6MQ==", id: "R3JvdXA6MQ==",
name: "Full Access", name: "Full Access",

View file

@ -22,7 +22,7 @@ import PermissionGroupListComponent from "./views/PermissionGroupList";
const permissionGroupList: React.FC<RouteComponentProps<{}>> = ({ const permissionGroupList: React.FC<RouteComponentProps<{}>> = ({
location, location,
}) => { }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: PermissionGroupListUrlQueryParams = asSortParams( const params: PermissionGroupListUrlQueryParams = asSortParams(
qs, qs,
PermissionGroupListUrlSortField, PermissionGroupListUrlSortField,
@ -34,10 +34,10 @@ const permissionGroupList: React.FC<RouteComponentProps<{}>> = ({
interface PermissionGroupDetailsRouteProps { interface PermissionGroupDetailsRouteProps {
id: string; id: string;
} }
const PermissionGroupDetails: React.FC<RouteComponentProps< const PermissionGroupDetails: React.FC<
PermissionGroupDetailsRouteProps RouteComponentProps<PermissionGroupDetailsRouteProps>
>> = ({ match }) => { > = ({ match }) => {
const qs = parseQs(location.search.substr(1)); const qs = parseQs(location.search.substr(1)) as any;
const params: PermissionGroupDetailsUrlQueryParams = asSortParams( const params: PermissionGroupDetailsUrlQueryParams = asSortParams(
qs, qs,
MembersListUrlSortField, MembersListUrlSortField,

View file

@ -1,6 +1,4 @@
import { PluginErrorCode } from "@dashboard/graphql"; import { PluginErrorCode } from "@dashboard/graphql";
import Decorator from "@dashboard/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import { plugin } from "../../fixtures"; import { plugin } from "../../fixtures";
@ -20,19 +18,25 @@ const props: PluginsDetailsPageProps = {
setSelectedChannelId: () => undefined, setSelectedChannelId: () => undefined,
}; };
storiesOf("Plugins / Plugin details", module) export default {
.addDecorator(Decorator) title: "Plugins / Plugin details",
.add("default", () => <PluginsDetailsPage {...props} />) };
.add("loading", () => (
export const Default = () => <PluginsDetailsPage {...props} />;
export const Loading = () => (
<PluginsDetailsPage {...props} disabled={true} plugin={undefined} /> <PluginsDetailsPage {...props} disabled={true} plugin={undefined} />
)) );
.add("form errors", () => (
export const FormErrors = () => (
<PluginsDetailsPage <PluginsDetailsPage
{...props} {...props}
errors={[ errors={[
...(["active", "Username or account", "Password or license"] as Array< ...(
["active", "Username or account", "Password or license"] as Array<
keyof PluginDetailsPageFormData keyof PluginDetailsPageFormData
>).map(field => ({ >
).map(field => ({
__typename: "PluginError" as "PluginError", __typename: "PluginError" as "PluginError",
code: PluginErrorCode.INVALID, code: PluginErrorCode.INVALID,
field, field,
@ -46,12 +50,13 @@ storiesOf("Plugins / Plugin details", module)
}, },
]} ]}
/> />
)) );
.add("not configurable", () => (
export const NotConfigurable = () => (
<PluginsDetailsPage <PluginsDetailsPage
{...props} {...props}
plugin={{ plugin={{
...plugin, ...plugin,
}} }}
/> />
)); );

Some files were not shown because too many files have changed in this diff Show more