Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions demo/api/.babelrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["@comet/admin-babel-preset"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems wrong, why is this necesssary?

}
68 changes: 68 additions & 0 deletions demo/api/.storybook/decorators/IntlProvider.decorator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { type Decorator } from "@storybook/react-webpack5";
import { de, enUS } from "date-fns/locale";
import { IntlProvider } from "react-intl";

enum LocaleOption {
German = "de",
English = "en",
}

function isLocaleOption(value: any): value is LocaleOption {
return value === "de" || value === "en";
}

type DateFnsLocale = typeof de;
const dateFnsLocales: Record<LocaleOption, DateFnsLocale> = {
[LocaleOption.German]: de,
[LocaleOption.English]: enUS,
};

// @TODO: use messages from lang-package
const messages: Record<LocaleOption, Record<string, string>> = {
en: {
"comet.core.deleteMutation.promptDelete": "Delete data?",
"comet.core.deleteMutation.yes": "Yes",
"comet.core.deleteMutation.no": "No",
"comet.core.dirtyHandler.discardChanges": "Discard unsaved changes?",
"comet.core.editDialog.edit": "Edit",
"comet.core.editDialog.add": "Add",
"comet.core.editDialog.cancel": "Cancel",
"comet.core.editDialog.save": "Save",
"comet.core.finalForm.abort": "Cancel",
"comet.core.finalForm.save": "Save",
"comet.core.router.confirmationDialog.confirm": "OK",
"comet.core.router.confirmationDialog.abort": "Cancel",
"comet.core.stack.stack.back": "Back",
"comet.core.table.addButton": "Add",
"comet.core.table.excelExportButton": "Export",
"comet.core.table.deleteButton": "Delete",
"comet.core.table.pagination.pageInfo": "Page {current} of {total}",
"comet.core.table.localChangesToolbar.save": "Save",
"comet.core.table.localChangesToolbar.unsavedItems":
"{count, plural, =0 {no unsaved changes} one {# unsaved change} other {# unsaved changes}}",
"comet.core.table.tableFilterFinalForm.resetButton": "Reset Filter",
"comet.core.table.tableQuery.error": "Error :( {error}",
Comment on lines +23 to +44
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the Admin messages. Could we just provide empty objects for now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just copied this from the existing storybook configurations 😅
But you're right, we can probably just use an empty object.

},
de: {
"comet.core.table.localChangesToolbar.unsavedItems":
"{count, plural, =0 {keine ungespeicherten Änderungen} one {# ungespeicherte Änderung} other {# ungespeicherte Änderungen}}",
"comet.core.table.tableQuery.error": "Fehler :( {error}",
},
};

export const IntlDecorator: Decorator = (fn, context) => {
const { locale: selectedLocale = LocaleOption.English } = context.globals;
const selecteDateFnsLocale = isLocaleOption(selectedLocale) ? dateFnsLocales[selectedLocale] : dateFnsLocales.en;

return (
<IntlProvider
locale={selectedLocale}
messages={isLocaleOption(selectedLocale) ? messages[selectedLocale] : {}}
onError={() => {
// disable error logging
}}
>
{fn()}
</IntlProvider>
);
};
10 changes: 10 additions & 0 deletions demo/api/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { StorybookConfig } from "@storybook/react-webpack5";

const config: StorybookConfig = {
stories: ["../src/**/*.mdx", "../src/**/__stories__/*.stories.@(js|jsx|mjs|ts|tsx)"],
staticDirs: ["./public"],

addons: ["@storybook/addon-docs", "storybook-addon-tag-badges", "@storybook/addon-webpack5-compiler-babel"],
framework: "@storybook/react-webpack5",
};
export default config;
14 changes: 14 additions & 0 deletions demo/api/.storybook/manager-head.html
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be deploy this to Netlify or Chromatic? If Chromatic, then we can remove this badge.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really see the need to deploy this for now, I'll remove it.
(I just copied this from the other storybook that is deployed to Chromatic, we probably should remove it there as well)

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<link rel="shortcut icon" href="/favicon.ico" />
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
var badge = document.createElement("div");
badge.style.position = "fixed";
badge.style.right = "5px";
badge.style.bottom = "5px";
badge.style.zIndex = "10";
badge.innerHTML =
'<a href="https://www.netlify.com"><img src="https://www.netlify.com/img/global/badges/netlify-color-accent.svg" alt="Deploys by Netlify" /></a>';

document.body.appendChild(badge);
});
</script>
7 changes: 7 additions & 0 deletions demo/api/.storybook/manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { addons } from "storybook/manager-api";

import theme from "./theme";

addons.setConfig({
theme,
});
12 changes: 12 additions & 0 deletions demo/api/.storybook/middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export default function middleware(router) {
router.use((req, res, next) => {
const origin = req.headers.origin;

if (origin?.startsWith("http://localhost:")) {
res.setHeader("Access-Control-Allow-Origin", origin);
res.setHeader("Access-Control-Allow-Credentials", "true");
}

next();
});
}
19 changes: 19 additions & 0 deletions demo/api/.storybook/preview-head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<title>Comet</title>
<style>
body {
font-family: "Lato", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
font-size: 14px;
line-height: 1.4;
-webkit-font-smoothing: antialiased;
}

#root pre:not(.prismjs) {
background-color: #efefef;
font-size: 10px;
padding: 15px;
}

#root code {
font-size: 10px;
}
</style>
22 changes: 22 additions & 0 deletions demo/api/.storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { Preview } from "@storybook/react-webpack5";

import { IntlDecorator } from "./decorators/IntlProvider.decorator";

const preview: Preview = {
tags: ["autodocs"],
decorators: [IntlDecorator],

parameters: {
docs: {
codePanel: true,
},
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};

export default preview;
11 changes: 11 additions & 0 deletions demo/api/.storybook/public/comet-logo-header.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo/api/.storybook/public/favicon.ico
Binary file not shown.
10 changes: 10 additions & 0 deletions demo/api/.storybook/theme.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { create, type ThemeVars } from "storybook/theming";

import CometLogo from "./public/comet-logo-header.svg";

export default create({
base: "light",
brandTitle: "Comet",
brandUrl: "https://github.com/vivid-planet/comet",
brandImage: CometLogo,
}) as ThemeVars;
11 changes: 11 additions & 0 deletions demo/api/.storybook/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"jsx": "react-jsx",
"module": "ESNext",
"moduleResolution": "Bundler",
"noEmit": true
},
"exclude": ["../dist"],
"extends": "../tsconfig.json",
"include": ["../src/**/*.stories.ts", "../src/**/*.stories.tsx"]
}
2 changes: 2 additions & 0 deletions demo/api/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import eslintConfigNestJs from "@comet/eslint-config/future/nestjs.js";
import storybook from "eslint-plugin-storybook";

/** @type {import('eslint')} */
const config = [
{
ignores: ["src/db/migrations/**", "dist/**", "src/**/*.generated.ts", "src/**/generated/**"],
},
...eslintConfigNestJs,
...storybook.configs["flat/recommended"],
];

export default config;
12 changes: 11 additions & 1 deletion demo/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"lint:tsc": "tsc --project ./tsconfig.lint.json",
"mikro-orm": "dotenv -e .env.secrets -e .env.local -e .env -e .env.site-configs -- mikro-orm",
"repl": "pnpm run start --entryFile repl",
"storybook": "storybook dev -p 4004 --no-open",
"start": "pnpm clean && pnpm intl:compile && dotenv -e .env.secrets -e .env.local -e .env -e .env.site-configs -- nest start --debug --watch --preserveWatchOutput",
"start:dev": "pnpm check-node-version && run-p dev:*",
"start:prod": "node dist/main"
Expand Down Expand Up @@ -74,7 +75,8 @@
"rimraf": "^6.1.2",
"rxjs": "^7.8.2",
"slugify": "^1.6.6",
"uuid": "^11.1.0"
"uuid": "^11.1.0",
"react": "^18.3.1"
},
"devDependencies": {
"@comet/api-generator": "workspace:*",
Expand All @@ -84,12 +86,17 @@
"@nestjs/schematics": "^11.0.9",
"@types/cli-progress": "^3.11.6",
"@types/compression": "^1.8.1",
"react-intl": "^7.1.11",
"@types/cookie-parser": "^1.4.10",
"@types/express": "^5.0.3",
"@types/inquirer": "^8.2.12",
"@types/node": "^24.9.1",
"@types/react": "^18.3.1",
"@types/response-time": "^2.3.9",
"check-node-version": "^4.2.1",
"@storybook/addon-docs": "^9.1.10",
"@storybook/addon-webpack5-compiler-babel": "^3.0.6",
"@storybook/react-webpack5": "^9.1.10",
"chokidar-cli": "^3.0.0",
"dotenv-cli": "^9.0.0",
"eslint": "^9.30.1",
Expand All @@ -98,6 +105,9 @@
"rimraf": "^6.1.2",
"ts-node": "^10.9.2",
"tsconfig-paths": "^3.15.0",
"eslint-plugin-storybook": "^9.1.10",
"storybook": "^9.1.10",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Storybook V10 is already available. Should we update to the latest version?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to keep it the same as in the other packages to:

  • avoid avoid issues due to installing multiple versions of the same package (I remember this being an issue in the past, not sure if this is still relevant)
  • I assumed this was necessary to include the stroybook in the global storybook

"storybook-addon-tag-badges": "^2.0.1",
"typescript": "5.9.3"
},
"mikro-orm": {
Expand Down
17 changes: 17 additions & 0 deletions demo/api/src/products/__stories__/ProductPublishedMail.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { type Meta, type StoryObj } from "@storybook/react-webpack5";
import React from "react";

const config: Meta = {
title: "products/ProductPublishedMail",
};

export default config;

export const ProductPublishedMailStory: StoryObj = {
render: () => (
<>
<h1>ProductPublishedMail</h1>
<p>In the future, this story will render the (currently non-existing) ProductPublishedMail component, built with MJML and React</p>
</>
),
};
1 change: 1 addition & 0 deletions demo/api/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"inlineSources": true,
"sourceRoot": "/dist"
},
"exclude": ["**/__stories__/**", "**/*.stories.js", "**/*.stories.tsx", "**/*.stories.ts", ".storybook"],
"extends": "./tsconfig.json"
}
1 change: 1 addition & 0 deletions demo/api/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"compilerOptions": {
"baseUrl": "./",
"jsx": "react-jsx",
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"experimentalDecorators": true,
Expand Down
5 changes: 5 additions & 0 deletions dev-pm.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,5 +227,10 @@ export default defineConfig({
group: ["storybook", "docs"],
waitOn: waitOnPackages("@comet/admin"),
},
{
name: "storybook-demo-api",
script: "pnpm --filter comet-demo-api run storybook",
group: ["storybook", "docs"],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be in the demo-api group instead? IMO it doesn't make sense to add this to the global Storybook as it's a Demo API specific feature.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, will change this

},
],
});
2 changes: 1 addition & 1 deletion knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
],
"project": ["./src/**/*.{ts,tsx}"],
"ignoreDependencies": ["@as-integrations/express5"],
"ignore": ["./src/**/generated/**", "**/graphql.generated.ts"]
"ignore": ["./src/**/generated/**", "**/graphql.generated.ts", ".storybook/middleware.js"]
},
"demo/site": {
"entry": ["./src/app/**", "./cache-handler.ts", "./server.ts", "./opentelemetry-metrics.ts"],
Expand Down
24 changes: 24 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion storybook/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { StorybookConfig } from "@storybook/react-webpack5";
import remarkGfm from "remark-gfm";
import { type StorybookConfigRaw } from "storybook/internal/types";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using an internal type is risky. Could we instead use something from Storybook's public API?


const config: StorybookConfig = {
framework: "@storybook/react-webpack5",
Expand All @@ -24,12 +25,21 @@ const config: StorybookConfig = {
}),
staticDirs: ["../public"],
refs: (config, { configType }) => {
return {
const refs: StorybookConfigRaw["refs"] = {
"@comet/admin": {
title: "@comet/admin",
url: configType === "DEVELOPMENT" ? "http://localhost:26646/" : "https://main--68e7b70f15b8f51dac492af6.chromatic.com", // TODO: support pull request previews,
},
};

if (configType === "DEVELOPMENT") {
refs["demo/api"] = {
title: "demo/api",
url: "http://localhost:4004/",
};
}
Comment on lines +35 to +40
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add this Storybook to the global Storybook?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, maybe this is unnecessary 🤔


return refs;
},
};

Expand Down