Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

frontend migrations #971

Merged
merged 29 commits into from
Jul 20, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
210fb05
rmf-auth
aaronchongth Jul 16, 2024
041b756
Migrate admin
aaronchongth Jul 16, 2024
86922aa
Migrate doors
aaronchongth Jul 16, 2024
48d31d2
Migrate dashboard deps, configs, scripts, storybook
aaronchongth Jul 16, 2024
8e384a6
Migrate delivery alert store
aaronchongth Jul 16, 2024
d0d608c
Lifts
aaronchongth Jul 16, 2024
903805f
Add react-error-boundary
aaronchongth Jul 16, 2024
960765b
robot and task summaries and components
aaronchongth Jul 16, 2024
13db0e3
Merge branch 'koonpeng/hammer-jazzy-base' into ac/fix-build
aaronchongth Jul 16, 2024
d027eea
More fixes, changes and migrations
aaronchongth Jul 16, 2024
3e0a42f
Merge branch 'koonpeng/hammer-jazzy-base' into ac/fix-build
aaronchongth Jul 17, 2024
c5fb09c
Migration of using key=value labels
aaronchongth Jul 17, 2024
4484e98
Fix build error in dynamic module and react-scheduler peer dep
aaronchongth Jul 17, 2024
98180a6
Merge branch 'koonpeng/hammer-jazzy-base' into ac/fix-build
aaronchongth Jul 18, 2024
2e08838
Revert default config public url
aaronchongth Jul 18, 2024
2b7ff44
rmf-auth install jest-environment-jsdom
aaronchongth Jul 18, 2024
21d236c
Fix react-components ci
aaronchongth Jul 18, 2024
5a1db57
Provide default trajectory server URL in minimal rmf build
aaronchongth Jul 18, 2024
2208678
react-components, install jest-environment-jsdom
aaronchongth Jul 18, 2024
ec7faa4
dashboard, revert env in minimal rmf, user DOTENV_CONFIG_PATH
aaronchongth Jul 18, 2024
9408632
dashboard, make test async
aaronchongth Jul 18, 2024
c47724c
api-server, asgi.scope instead of scope
aaronchongth Jul 18, 2024
5bfb091
Merge branch 'koonpeng/hammer-jazzy-base' into ac/fix-build
aaronchongth Jul 19, 2024
2a9b623
remove yarn from gitignore
aaronchongth Jul 19, 2024
f335f2a
Remove usage of requests in task app, fix unix_millis_warn_time usage…
aaronchongth Jul 19, 2024
a2c44e8
dashboard fix filter by labels
aaronchongth Jul 19, 2024
f44b95c
Fix task summary
aaronchongth Jul 19, 2024
a49c580
Fix for getting task definition id from labels
aaronchongth Jul 19, 2024
c298927
revert react-scheduler from latest to 2.7.8, due to race condition of…
aaronchongth Jul 20, 2024
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
5 changes: 5 additions & 0 deletions packages/api-client/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Alert,
BeaconState,
BuildingMap,
DeliveryAlert,
DispenserState,
DoorState,
FleetState,
Expand Down Expand Up @@ -103,6 +104,10 @@ export class SioClient {
subscribeAlerts(listener: Listener<Alert>): Subscription {
return this.subscribe<Alert>(`/alerts`, listener);
}

subscribeDeliveryAlerts(listener: Listener<DeliveryAlert>): Subscription {
return this.subscribe<DeliveryAlert>('/delivery_alerts', listener);
}
}

export * from './openapi';
2 changes: 1 addition & 1 deletion packages/api-client/lib/version.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// THIS FILE IS GENERATED
export const version = {
rmfServer: '4fe30cc47dcabe4d029fafc04f6d7feb52a11021',
rmfServer: '4484e98b95f71637026e2ce89d14d31033e5d615',
openapiGenerator: '',
};
2 changes: 1 addition & 1 deletion packages/api-server/api_server/default_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# url that rmf-server is being served on.
# When being a proxy, this must be the url that rmf-server is mounted on.
# E.g. https://example.com/rmf/api/v1
"public_url": "",
"public_url": "http://localhost:8000",
"cache_directory": "run/cache", # The directory where cached files should be stored.
"log_level": "WARNING", # https://docs.python.org/3.8/library/logging.html#levels
# a user that is automatically given admin privileges, note that this does not guarantee that the user exists in the identity provider.
Expand Down
7 changes: 5 additions & 2 deletions packages/api-server/api_server/fast_io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from reactivex.abc import DisposableBase
from starlette.routing import compile_path

from api_server.logging import LoggerAdapter, get_logger
from api_server.logging import LoggerAdapter, default_logger, get_logger
from api_server.models.user import User

from .errors import *
Expand Down Expand Up @@ -244,7 +244,10 @@ def _match_routes(
return None

async def _on_connect(self, sid: str, environ: dict, auth: dict | None = None):
logger = get_logger(HTTPConnection(environ))
if "asgi.scope" in environ:
logger = get_logger(HTTPConnection(environ["asgi.scope"]))
else:
logger = default_logger
user = (
await self._socketio_connect(sid, environ, auth)
if self._socketio_connect
Expand Down
2 changes: 2 additions & 0 deletions packages/dashboard/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ yarn-debug.log*
yarn-error.log*
aaronchongth marked this conversation as resolved.
Show resolved Hide resolved

/.rmf

*storybook.log
13 changes: 0 additions & 13 deletions packages/dashboard/.storybook/main.js

This file was deleted.

20 changes: 20 additions & 0 deletions packages/dashboard/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { StorybookConfig } from '@storybook/react-webpack5';

const config: StorybookConfig = {
stories: ['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@storybook/addon-webpack5-compiler-babel',
'@storybook/addon-onboarding',
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/react-webpack5',
options: {},
},
docs: {
autodocs: 'tag',
},
};
export default config;
3 changes: 0 additions & 3 deletions packages/dashboard/.storybook/preview.js

This file was deleted.

14 changes: 14 additions & 0 deletions packages/dashboard/.storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Preview } from '@storybook/react';

const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};

export default preview;
7 changes: 7 additions & 0 deletions packages/dashboard/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
presets: [
'@babel/preset-env',
['@babel/preset-react', { runtime: 'automatic' }],
'@babel/preset-typescript',
],
};
102 changes: 102 additions & 0 deletions packages/dashboard/config/env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
'use strict';

const fs = require('fs');
const path = require('path');
const paths = require('./paths');

// Make sure that including paths.js after env.js will read .env variables.
delete require.cache[require.resolve('./paths')];

const NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV) {
throw new Error('The NODE_ENV environment variable is required but was not specified.');
}

// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
const dotenvFiles = [
`${paths.dotenv}.${NODE_ENV}.local`,
// Don't include `.env.local` for `test` environment
// since normally you expect tests to produce the same
// results for everyone
NODE_ENV !== 'test' && `${paths.dotenv}.local`,
`${paths.dotenv}.${NODE_ENV}`,
paths.dotenv,
].filter(Boolean);

// Load environment variables from .env* files. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set. Variable expansion is supported in .env files.
// https://github.com/motdotla/dotenv
// https://github.com/motdotla/dotenv-expand
dotenvFiles.forEach((dotenvFile) => {
if (fs.existsSync(dotenvFile)) {
require('dotenv-expand')(
require('dotenv').config({
path: dotenvFile,
}),
);
}
});

// We support resolving modules according to `NODE_PATH`.
// This lets you use absolute paths in imports inside large monorepos:
// https://github.com/facebook/create-react-app/issues/253.
// It works similar to `NODE_PATH` in Node itself:
// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
// Otherwise, we risk importing Node.js core modules into an app instead of webpack shims.
// https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421
// We also resolve them to make sure all tools using them work consistently.
const appDirectory = fs.realpathSync(process.cwd());
process.env.NODE_PATH = (process.env.NODE_PATH || '')
.split(path.delimiter)
.filter((folder) => folder && !path.isAbsolute(folder))
.map((folder) => path.resolve(appDirectory, folder))
.join(path.delimiter);

// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
// injected into the application via DefinePlugin in webpack configuration.
const REACT_APP = /^REACT_APP_/i;

function getClientEnvironment(publicUrl) {
const raw = Object.keys(process.env)
.filter((key) => REACT_APP.test(key))
.reduce(
(env, key) => {
env[key] = process.env[key];
return env;
},
{
// Useful for determining whether we’re running in production mode.
// Most importantly, it switches React into the correct mode.
NODE_ENV: process.env.NODE_ENV || 'development',
// Useful for resolving the correct path to static assets in `public`.
// For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
// This should only be used as an escape hatch. Normally you would put
// images into the `src` and `import` them in code to get their paths.
PUBLIC_URL: publicUrl,
// We support configuring the sockjs pathname during development.
// These settings let a developer run multiple simultaneous projects.
// They are used as the connection `hostname`, `pathname` and `port`
// in webpackHotDevClient. They are used as the `sockHost`, `sockPath`
// and `sockPort` options in webpack-dev-server.
WDS_SOCKET_HOST: process.env.WDS_SOCKET_HOST,
WDS_SOCKET_PATH: process.env.WDS_SOCKET_PATH,
WDS_SOCKET_PORT: process.env.WDS_SOCKET_PORT,
// Whether or not react-refresh is enabled.
// It is defined here so it is available in the webpackHotDevClient.
FAST_REFRESH: process.env.FAST_REFRESH !== 'false',
},
);
// Stringify all values so we can feed into webpack DefinePlugin
const stringified = {
'process.env': Object.keys(raw).reduce((env, key) => {
env[key] = JSON.stringify(raw[key]);
return env;
}, {}),
};

return { raw, stringified };
}

module.exports = getClientEnvironment;
60 changes: 60 additions & 0 deletions packages/dashboard/config/getHttpsConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use strict';

const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const chalk = require('react-dev-utils/chalk');
const paths = require('./paths');

// Ensure the certificate and key provided are valid and if not
// throw an easy to debug error
function validateKeyAndCerts({ cert, key, keyFile, crtFile }) {
let encrypted;
try {
// publicEncrypt will throw an error with an invalid cert
encrypted = crypto.publicEncrypt(cert, Buffer.from('test'));
} catch (err) {
throw new Error(`The certificate "${chalk.yellow(crtFile)}" is invalid.\n${err.message}`);
}

try {
// privateDecrypt will throw an error with an invalid key
crypto.privateDecrypt(key, encrypted);
} catch (err) {
throw new Error(`The certificate key "${chalk.yellow(keyFile)}" is invalid.\n${err.message}`);
}
}

// Read file and throw an error if it doesn't exist
function readEnvFile(file, type) {
if (!fs.existsSync(file)) {
throw new Error(
`You specified ${chalk.cyan(type)} in your env, but the file "${chalk.yellow(
file,
)}" can't be found.`,
);
}
return fs.readFileSync(file);
}

// Get the https config
// Return cert files if provided in env, otherwise just true or false
function getHttpsConfig() {
const { SSL_CRT_FILE, SSL_KEY_FILE, HTTPS } = process.env;
const isHttps = HTTPS === 'true';

if (isHttps && SSL_CRT_FILE && SSL_KEY_FILE) {
const crtFile = path.resolve(paths.appPath, SSL_CRT_FILE);
const keyFile = path.resolve(paths.appPath, SSL_KEY_FILE);
const config = {
cert: readEnvFile(crtFile, 'SSL_CRT_FILE'),
key: readEnvFile(keyFile, 'SSL_KEY_FILE'),
};

validateKeyAndCerts({ ...config, keyFile, crtFile });
return config;
}
return isHttps;
}

module.exports = getHttpsConfig;
29 changes: 29 additions & 0 deletions packages/dashboard/config/jest/babelTransform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';

const babelJest = require('babel-jest').default;

const hasJsxRuntime = (() => {
if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') {
return false;
}

try {
require.resolve('react/jsx-runtime');
return true;
} catch (e) {
return false;
}
})();

module.exports = babelJest.createTransformer({
presets: [
[
require.resolve('babel-preset-react-app'),
{
runtime: hasJsxRuntime ? 'automatic' : 'classic',
},
],
],
babelrc: false,
configFile: false,
});
14 changes: 14 additions & 0 deletions packages/dashboard/config/jest/cssTransform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use strict';

// This is a custom Jest transformer turning style imports into empty objects.
// http://facebook.github.io/jest/docs/en/webpack.html

module.exports = {
process() {
return 'module.exports = {};';
},
getCacheKey() {
// The output is always the same.
return 'cssTransform';
},
};
40 changes: 40 additions & 0 deletions packages/dashboard/config/jest/fileTransform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict';

const path = require('path');
const camelcase = require('camelcase');

// This is a custom Jest transformer turning file imports into filenames.
// http://facebook.github.io/jest/docs/en/webpack.html

module.exports = {
process(src, filename) {
const assetFilename = JSON.stringify(path.basename(filename));

if (filename.match(/\.svg$/)) {
// Based on how SVGR generates a component name:
// https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6
const pascalCaseFilename = camelcase(path.parse(filename).name, {
pascalCase: true,
});
const componentName = `Svg${pascalCaseFilename}`;
return `const React = require('react');
module.exports = {
__esModule: true,
default: ${assetFilename},
ReactComponent: React.forwardRef(function ${componentName}(props, ref) {
return {
$$typeof: Symbol.for('react.element'),
type: 'svg',
ref: ref,
key: null,
props: Object.assign({}, props, {
children: ${assetFilename}
})
};
}),
};`;
}

return `module.exports = ${assetFilename};`;
},
};
Loading
Loading