mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Move Storybook back into web (#13219)
GitOrigin-RevId: 61b69b5fd178dd4f5ab26858c434f959dfc410bc
This commit is contained in:
parent
b228c9016e
commit
76d195cd39
11 changed files with 7034 additions and 1466 deletions
8153
package-lock.json
generated
8153
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -49,7 +49,6 @@
|
|||
"services/third-party-datastore",
|
||||
"services/third-party-references",
|
||||
"services/tpdsworker",
|
||||
"services/web",
|
||||
"tools/storybook"
|
||||
"services/web"
|
||||
]
|
||||
}
|
||||
|
|
62
services/web/.storybook/main.ts
Normal file
62
services/web/.storybook/main.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
import type { StorybookConfig } from '@storybook/react-webpack5'
|
||||
import path from 'node:path'
|
||||
|
||||
const rootDir = path.resolve(__dirname, '..')
|
||||
|
||||
// NOTE: must be set before webpack config is imported
|
||||
process.env.SHARELATEX_CONFIG = path.join(rootDir, 'config/settings.webpack.js')
|
||||
|
||||
const config: StorybookConfig = {
|
||||
core: {
|
||||
disableTelemetry: true,
|
||||
},
|
||||
staticDirs: [path.join(rootDir, 'public')],
|
||||
stories: [
|
||||
path.join(rootDir, 'frontend/stories/**/*.stories.{js,jsx,ts,tsx}'),
|
||||
path.join(rootDir, 'modules/**/stories/**/*.stories.{js,jsx,ts,tsx}'),
|
||||
],
|
||||
addons: [
|
||||
'@storybook/addon-links',
|
||||
'@storybook/addon-essentials',
|
||||
'@storybook/addon-interactions',
|
||||
'@storybook/addon-a11y',
|
||||
],
|
||||
framework: {
|
||||
name: '@storybook/react-webpack5',
|
||||
options: {},
|
||||
},
|
||||
docs: {
|
||||
autodocs: 'tag',
|
||||
},
|
||||
babel: options => {
|
||||
return {
|
||||
...options,
|
||||
plugins: [
|
||||
// ensure that TSX files are transformed before other plugins run
|
||||
['@babel/plugin-transform-typescript', { isTSX: true }],
|
||||
...(options.plugins ?? []),
|
||||
],
|
||||
}
|
||||
},
|
||||
webpackFinal: storybookConfig => {
|
||||
return {
|
||||
...storybookConfig,
|
||||
resolve: {
|
||||
...storybookConfig.resolve,
|
||||
fallback: {
|
||||
...storybookConfig.resolve?.fallback,
|
||||
fs: false,
|
||||
os: false,
|
||||
module: false,
|
||||
},
|
||||
extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx', '.json'],
|
||||
alias: {
|
||||
...storybookConfig.resolve?.alias,
|
||||
// custom prefixes for import paths
|
||||
'@': path.join(rootDir, 'frontend/js/'),
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
export default config
|
3
services/web/.storybook/manager.css
Normal file
3
services/web/.storybook/manager.css
Normal file
|
@ -0,0 +1,3 @@
|
|||
.sidebar-container a[title='Overleaf'] {
|
||||
max-width: 100px;
|
||||
}
|
15
services/web/.storybook/manager.ts
Normal file
15
services/web/.storybook/manager.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { addons } from '@storybook/addons'
|
||||
import { create } from '@storybook/theming'
|
||||
|
||||
import './manager.css'
|
||||
|
||||
import brandImage from '../public/img/ol-brand/overleaf.svg'
|
||||
|
||||
const theme = create({
|
||||
base: 'light',
|
||||
brandTitle: 'Overleaf',
|
||||
brandUrl: 'https://www.overleaf.com',
|
||||
brandImage,
|
||||
})
|
||||
|
||||
addons.setConfig({ theme })
|
101
services/web/.storybook/preview.tsx
Normal file
101
services/web/.storybook/preview.tsx
Normal file
|
@ -0,0 +1,101 @@
|
|||
import type { Preview } from '@storybook/react'
|
||||
|
||||
// Storybook does not (currently) support async loading of "stories". Therefore
|
||||
// the strategy in frontend/js/i18n.js does not work (because we cannot wait on
|
||||
// the promise to resolve).
|
||||
// Therefore we have to use the synchronous method for configuring
|
||||
// react-i18next. Because this, we can only hard-code a single language.
|
||||
import i18n from 'i18next'
|
||||
import { initReactI18next } from 'react-i18next'
|
||||
// @ts-ignore
|
||||
import en from '../../../services/web/locales/en.json'
|
||||
import { ExposedSettings } from '../types/exposed-settings'
|
||||
import { User } from '../types/user'
|
||||
|
||||
window.i18n = window.i18n || {}
|
||||
window.i18n.currentLangCode = window.i18n.currentLangCode || 'en'
|
||||
i18n.use(initReactI18next).init({
|
||||
lng: 'en',
|
||||
|
||||
// still using the v3 plural suffixes
|
||||
compatibilityJSON: 'v3',
|
||||
|
||||
resources: {
|
||||
en: { translation: en },
|
||||
},
|
||||
|
||||
react: {
|
||||
useSuspense: false,
|
||||
transSupportBasicHtmlNodes: false,
|
||||
},
|
||||
|
||||
interpolation: {
|
||||
prefix: '__',
|
||||
suffix: '__',
|
||||
unescapeSuffix: 'HTML',
|
||||
skipOnVariables: true,
|
||||
escapeValue: false,
|
||||
defaultVariables: {
|
||||
appName: 'Overleaf',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// avoid some errors by creating these objects in advance
|
||||
window.user = {} as User
|
||||
window.ExposedSettings = {} as ExposedSettings
|
||||
|
||||
const preview: Preview = {
|
||||
parameters: {
|
||||
// Automatically mark prop-types like onClick, onToggle, etc as Storybook
|
||||
// "actions", so that they are logged in the Actions pane at the bottom of the
|
||||
// viewer
|
||||
actions: { argTypesRegex: '^on.*' },
|
||||
docs: {
|
||||
// render stories in iframes, to isolate modals
|
||||
inlineStories: false,
|
||||
},
|
||||
},
|
||||
globalTypes: {
|
||||
theme: {
|
||||
name: 'Theme',
|
||||
description: 'Editor theme',
|
||||
defaultValue: 'main-',
|
||||
toolbar: {
|
||||
icon: 'circlehollow',
|
||||
items: [
|
||||
{ value: 'main-', title: 'Default' },
|
||||
{ value: 'main-light-', title: 'Light' },
|
||||
{ value: 'main-ieee-', title: 'IEEE' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
loaders: [
|
||||
async ({ globals }) => {
|
||||
const { theme } = globals
|
||||
|
||||
return {
|
||||
// NOTE: this uses `${theme}style.less` rather than `${theme}.less`
|
||||
// so that webpack only bundles files ending with "style.less"
|
||||
activeStyle: await import(
|
||||
`!!to-string-loader!css-loader!less-loader!../../../services/web/frontend/stylesheets/${theme}style.less`
|
||||
),
|
||||
}
|
||||
},
|
||||
],
|
||||
decorators: [
|
||||
(Story, context) => {
|
||||
const { activeStyle } = context.loaded
|
||||
|
||||
return (
|
||||
<>
|
||||
{activeStyle && <style>{activeStyle.default}</style>}
|
||||
<Story {...context} />
|
||||
</>
|
||||
)
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export default preview
|
|
@ -552,6 +552,15 @@ tar:
|
|||
COMPOSE_PROJECT_NAME=tar_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) run --rm tar
|
||||
COMPOSE_PROJECT_NAME=tar_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) down -v -t 0
|
||||
|
||||
build_storybook:
|
||||
npm run build-storybook
|
||||
if [[ -n "$(BRANCH_NAME)" ]]; then \
|
||||
echo "Renaming storybook-static -> $(BRANCH_NAME)."; \
|
||||
d=$$(dirname "$(BRANCH_NAME)"); \
|
||||
mkdir -p "storybook-output/$$d"; \
|
||||
mv storybook-static "storybook-output/$$d/$$(basename "$(BRANCH_NAME)")/"; \
|
||||
fi
|
||||
|
||||
MODULE_TARGETS = \
|
||||
$(TEST_ACCEPTANCE_MODULES_SAAS) \
|
||||
$(TEST_ACCEPTANCE_MODULES_SERVER_CE) \
|
||||
|
|
78
services/web/cloudbuild-storybook-index.html.m4
Normal file
78
services/web/cloudbuild-storybook-index.html.m4
Normal file
|
@ -0,0 +1,78 @@
|
|||
divert(`-1')
|
||||
define(`foreach', `pushdef(`$1')_foreach($@)popdef(`$1')')
|
||||
define(`_arg1', `$1')
|
||||
define(`_foreach', `ifelse(`$2', `()', `',
|
||||
`define(`$1', _arg1$2)$3`'$0(`$1', (shift$2), `$3')')')
|
||||
divert`'dnl
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Overleaf Storybook builds</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #fff;
|
||||
color: #5d6879;
|
||||
font-family: Lato,sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.5625;
|
||||
min-height: 100%;
|
||||
position: relative;
|
||||
margin: 0px;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: rgb(80, 80, 80);
|
||||
font-family: Merriweather, serif;
|
||||
font-weight: 500;
|
||||
line-height: 1.35;
|
||||
}
|
||||
h1 {
|
||||
margin-top: 0px;
|
||||
padding-top: 100px;
|
||||
}
|
||||
.navbar-default {
|
||||
background-color: #1e2530;
|
||||
border-color: transparent;
|
||||
height: 68px;
|
||||
padding: 15px 10px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
}
|
||||
.navbar-default .navbar-brand {
|
||||
background-image: url(https://cdn.overleaf.com/images/overleaf-white-65b70e33f35fccdf6f8d.svg);
|
||||
background-position: 0;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
bottom: 5px;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
width: 130px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar-default">
|
||||
<a class="navbar-brand" href="https://www.overleaf.com/"></a>
|
||||
</nav>
|
||||
<h1>Overleaf Storybook builds</h1>
|
||||
<h2>Branches:</h2>
|
||||
<ul>
|
||||
foreach(DIR, (LIST),
|
||||
<li>
|
||||
<a href="DIR/">DIR/</a>
|
||||
<a href="https://github.com/overleaf/internal/tree/DIR">
|
||||
<img src="https://github.com/favicon.ico" alt="GitHub" width="15em">
|
||||
</a>
|
||||
</li>
|
||||
)
|
||||
</ul>
|
||||
<small>
|
||||
Last updated on syscmd(date)dnl
|
||||
for ifdef(`BRANCH_NAME',<a href="BRANCH_NAME/">BRANCH_NAME</a>,unknown branch)
|
||||
(<a href="https://console.cloud.google.com/cloud-build/builds?project=overleaf-dev&pageState=(%22builds%22:(%22f%22:%22%255B%257B_22k_22_3A_22Trigger%2520Name_22_2C_22t_22_3A10_2C_22v_22_3A_22_5C_22storybook-pr-trigger_5C_22_22_2C_22s_22_3Atrue_2C_22i_22_3A_22triggerName_22%257D_2C%257B_22k_22_3A_22_22_2C_22t_22_3A10_2C_22v_22_3A_22_5C_22OR_5C_22_22_2C_22o_22_3Atrue_2C_22s_22_3Atrue%257D_2C%257B_22k_22_3A_22Trigger%2520Name_22_2C_22t_22_3A10_2C_22v_22_3A_22_5C_22storybook-push-trigger_5C_22_22_2C_22s_22_3Atrue_2C_22i_22_3A_22triggerName_22%257D%255D%22))">build history</a>).
|
||||
</small>
|
||||
</body>
|
||||
</html>
|
63
services/web/cloudbuild-storybook.yaml
Normal file
63
services/web/cloudbuild-storybook.yaml
Normal file
|
@ -0,0 +1,63 @@
|
|||
steps:
|
||||
- id: build-storybook
|
||||
name: 'node:18.18.2'
|
||||
env:
|
||||
- 'BRANCH_NAME=$BRANCH_NAME'
|
||||
- 'BUILD_ID=$BUILD_ID'
|
||||
script: |
|
||||
#!/bin/bash
|
||||
set -e
|
||||
make -C services/web BRANCH_NAME="${BRANCH_NAME:-$BUILD_ID}" build_storybook
|
||||
|
||||
- id: deploy-storybook
|
||||
name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
|
||||
env:
|
||||
- 'BRANCH_NAME=$BRANCH_NAME'
|
||||
- 'BUILD_ID=$BUILD_ID'
|
||||
- 'BUCKET=gs://overleaf-dev-storybook'
|
||||
dir: services/web
|
||||
script: |
|
||||
#!/bin/bash
|
||||
: ${BRANCH_NAME:=$BUILD_ID}
|
||||
[[ "$BRANCH_NAME" ]] || {
|
||||
echo 1>&2 "ERROR: BRANCH_NAME not set"
|
||||
exit 2
|
||||
}
|
||||
gsutil -m copy -r storybook-output/* "${BUCKET}/"
|
||||
waitFor:
|
||||
- build-storybook
|
||||
|
||||
- id: read-storybook-bucket
|
||||
name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
|
||||
dir: services/web
|
||||
env:
|
||||
- 'BUCKET=gs://overleaf-dev-storybook'
|
||||
script: |
|
||||
#!/bin/bash
|
||||
set -ex
|
||||
gsutil ls "${BUCKET}/" \
|
||||
| sed -E "s@^${BUCKET}/([^/]+)/@\1@" \
|
||||
> storybook-bucket-listing.txt
|
||||
waitFor:
|
||||
- deploy-storybook
|
||||
|
||||
- id: create-storybook-index
|
||||
name: 'node:18.18.2'
|
||||
dir: services/web
|
||||
env:
|
||||
- 'BRANCH_NAME=$BRANCH_NAME'
|
||||
script: |
|
||||
#!/bin/bash
|
||||
set -ex
|
||||
LIST=$(tr '\n' , < storybook-bucket-listing.txt)
|
||||
m4 -DLIST="$LIST" -DBRANCH_NAME="$BRANCH_NAME" cloudbuild-storybook-index.html.m4 > storybook-index.html
|
||||
waitFor:
|
||||
- read-storybook-bucket
|
||||
|
||||
- id: update-storybook-index
|
||||
name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
|
||||
dir: services/web
|
||||
entrypoint: 'gsutil'
|
||||
args: [ "copy", "storybook-index.html", "gs://overleaf-dev-storybook/index.html" ]
|
||||
waitFor:
|
||||
- create-storybook-index
|
|
@ -39,6 +39,8 @@
|
|||
"lezer-latex:benchmark": "node scripts/lezer-latex/benchmark.mjs",
|
||||
"lezer-latex:benchmark-incremental": "node scripts/lezer-latex/test-incremental-parser.mjs",
|
||||
"routes": "bin/routes",
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"build-storybook": "storybook build",
|
||||
"local:nodemon": "set -a;. ../../config/dev-environment.env;. ./docker-compose.common.env;. ../../config/local-dev.env;. ./local-dev.env;. ../../config/local.env; set +a; echo $SHARELATEX_CONFIG; WEB_PORT=13000 LISTEN_ADDRESS=0.0.0.0 npm run nodemon",
|
||||
"local:webpack": "set -a;. ../../config/dev-environment.env;. ./docker-compose.common.env;. ../../config/local-dev.env;. ./local-dev.env;. ../../config/local.env; set +a; PORT=13808 SHARELATEX_CONFIG=$(pwd)/config/settings.webpack.js npm run webpack",
|
||||
"local:test:acceptance:run_dir": "set -a;. $(pwd)/docker-compose.common.env;. $(pwd)/local-test.env; set +a; npm run test:acceptance:run_dir",
|
||||
|
@ -211,6 +213,15 @@
|
|||
"@replit/codemirror-indentation-markers": "overleaf/codemirror-indentation-markers#1b1f93c0bcd04293aea6986aa2275185b2c56803",
|
||||
"@replit/codemirror-vim": "overleaf/codemirror-vim#07f1b50f4b2e703792da75a29e9e1e479b6b7067",
|
||||
"@sentry/browser": "^7.8.1",
|
||||
"@storybook/addon-a11y": "^7.5.1",
|
||||
"@storybook/addon-essentials": "^7.5.1",
|
||||
"@storybook/addon-interactions": "^7.5.1",
|
||||
"@storybook/addon-links": "^7.5.1",
|
||||
"@storybook/addons": "^7.5.1",
|
||||
"@storybook/blocks": "^7.5.1",
|
||||
"@storybook/react": "^7.5.1",
|
||||
"@storybook/react-webpack5": "^7.5.1",
|
||||
"@storybook/testing-library": "^0.2.2",
|
||||
"@testing-library/cypress": "^10.0.1",
|
||||
"@testing-library/dom": "^9.3.0",
|
||||
"@testing-library/react": "^12.1.5",
|
||||
|
@ -332,6 +343,7 @@
|
|||
"sinon-chai": "^3.7.0",
|
||||
"sinon-mongoose": "^2.3.0",
|
||||
"socket.io-mock": "^1.3.1",
|
||||
"storybook": "^7.4.0",
|
||||
"strict-event-emitter": "^0.5.1",
|
||||
"terser-webpack-plugin": "^5.3.9",
|
||||
"thread-loader": "^4.0.2",
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
"modules/**/test/frontend/**/*.*",
|
||||
"frontend/stories/**/*.*",
|
||||
"modules/**/stories/**/*.*",
|
||||
".storybook/*.*",
|
||||
"cypress",
|
||||
"types"
|
||||
],
|
||||
|
|
Loading…
Reference in a new issue