diff --git a/Dockerfile.demo b/Dockerfile.demo index febf4db9ba62e2b8c6e1b517c07b5845182e3fe8..49a0909afa9b6bbcfdafd74162a44775588f82bb 100644 --- a/Dockerfile.demo +++ b/Dockerfile.demo @@ -8,7 +8,7 @@ RUN ["pip", "install", "--disable-pip-version-check", "-r", "requirements.txt"] RUN ["python", "setup.py", "bdist_wheel"] RUN ["pip", "install", "--disable-pip-version-check", "--find-links=dist", "visualdl"] -WORKDIR frontend +WORKDIR /home/visualdl/frontend ENV SCOPE server ENV PUBLIC_PATH /paddle/visualdl/demo ENV API_URL /paddle/visualdl/demo/api diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index c6c92f6fbb77b6f017b4081c3d689302ad5aa4d2..3d07b21b5b7ad42a72ae6c24f2bbf6075afaa73b 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -9,20 +9,14 @@ module.exports = { ecmaVersion: 2018, sourceType: 'module' }, - ignorePatterns: ['node_modules/', 'dist/', 'output/', '_next'], + ignorePatterns: ['node_modules/', 'dist/', 'output/'], rules: { 'no-console': 'warn', 'sort-imports': 'error' }, overrides: [ { - files: [ - 'packages/cli/**/*', - 'packages/mock/**/*', - 'packages/demo/**/*', - 'packages/server/**/*', - 'packages/serverless/**/*' - ], + files: ['packages/cli/**/*', 'packages/mock/**/*', 'packages/demo/**/*', 'packages/server/**/*'], extends: [ 'plugin:@typescript-eslint/recommended', 'prettier/@typescript-eslint', @@ -36,7 +30,7 @@ module.exports = { } }, { - files: ['packages/core/**/*', 'packages/i18n/**/*'], + files: ['packages/core/**/*'], extends: [ 'plugin:@typescript-eslint/recommended', 'plugin:react/recommended', diff --git a/frontend/.huskyrc b/frontend/.huskyrc new file mode 100644 index 0000000000000000000000000000000000000000..5090235d60fb84da82e77b0e55590620c5fbf498 --- /dev/null +++ b/frontend/.huskyrc @@ -0,0 +1,5 @@ +{ + "hooks": { + "pre-commit": "lint-staged" + } +} diff --git a/frontend/README.md b/frontend/README.md index f1c2ec2296d5e96b735ee0708d8679ea468dd17a..d0a0af2d43ee3915404d7161578b7962897d2b26 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -59,9 +59,8 @@ yarn [core](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/core/README.md) [server](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/server/README.md) -[serverless](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/serverless/README.md) +[netron](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/netron/README.md) [cli](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/cli/README.md) -[i18n](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/i18n/README.md) [wasm](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/wasm/README.md) [mock](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/mock/README.md) diff --git a/frontend/README_cn.md b/frontend/README_cn.md index c39954f29e5b3758b79558c3afe2877dc3cd2602..22082087fd7a3ab7a23ad7c30b1dfc5b8b26a0a3 100644 --- a/frontend/README_cn.md +++ b/frontend/README_cn.md @@ -59,9 +59,8 @@ yarn [core](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/core/README.md) [server](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/server/README.md) -[serverless](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/serverless/README.md) +[netron](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/netron/README.md) [cli](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/cli/README.md) -[i18n](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/i18n/README.md) [wasm](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/wasm/README.md) [mock](https://github.com/PaddlePaddle/VisualDL/blob/develop/frontend/packages/mock/README.md) diff --git a/frontend/lint-staged.config.js b/frontend/lint-staged.config.js index 4f8d05af401bf18ca732b912aebf2086355e6386..59615c132cbb16bd7b77a7c2e5c4eea72bd95c25 100644 --- a/frontend/lint-staged.config.js +++ b/frontend/lint-staged.config.js @@ -1,6 +1,10 @@ const path = require('path'); const fs = require('fs'); +const getPackages = filenames => [ + ...new Set(filenames.map(filename => path.relative(path.join(__dirname, 'packages'), filename).split(path.sep)[0])) +]; + module.exports = { // lint all files when global package.json or eslint config changes. './(package.json|.eslintrc.js)': () => @@ -8,11 +12,7 @@ module.exports = { // check types when ts file or package.json changes. './(packages/*/package.json|packages/*/**/*.ts?(x))': filenames => - [ - ...new Set( - filenames.map(filename => path.relative(path.join(__dirname, 'packages'), filename).split(path.sep)[0]) - ) - ] + getPackages(filenames) .map(p => path.join(__dirname, 'packages', p, 'tsconfig.json')) .filter(p => { try { @@ -26,6 +26,15 @@ module.exports = { // lint changed files '**/*.(j|t)s?(x)': filenames => [ `eslint ${filenames.join(' ')}`, - `yarn test --silent --bail --findRelatedTests ${filenames.join(' ')}` + ...getPackages(filenames).map(p => { + const filename = path.join(__dirname, 'packages', p, 'package.json'); + const packageFile = JSON.parse(fs.readFileSync(filename, 'utf-8')); + if (packageFile.scripts.test === 'jest') { + return `yarn workspace @visualdl/${p} run test --silent --bail --findRelatedTests ${filenames.join( + ' ' + )}`; + } + return `yarn workspace @visualdl/${p} run test`; + }) ] }; diff --git a/frontend/package.json b/frontend/package.json index 7d6de4095d93b7bda8e30d01fd78639d39f9614c..17e3abf80634c9b455843e41f9e86a53fc050c1e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -29,29 +29,29 @@ "scripts": { "bootstrap": "lerna bootstrap", "build": "./scripts/build.sh", - "clean": "rimraf output *.log packages/*/dist packages/core/out packages/wasm/target packages/*/*.log", + "clean": "rimraf output packages/*/dist packages/wasm/target", "lint": "eslint --ext .tsx,.jsx.ts,.js --ignore-path .gitignore .", - "format": "prettier --write \"**/*.ts\" \"**/*.tsx\" \"**/*.js\"", + "format": "prettier --write \"**/*.{ts,tsx,js,jsx}\"", "test": "yarn workspaces run test", "prepublishOnly": "yarn lint && yarn test && yarn build", "preversion": "yarn lint", "version": "yarn format && git add -A" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "3.8.0", - "@typescript-eslint/parser": "3.8.0", - "eslint": "7.6.0", + "@typescript-eslint/eslint-plugin": "4.0.1", + "@typescript-eslint/parser": "4.0.1", + "eslint": "7.8.1", "eslint-config-prettier": "6.11.0", "eslint-plugin-prettier": "3.1.4", - "eslint-plugin-react": "7.20.5", - "eslint-plugin-react-hooks": "4.0.8", + "eslint-plugin-react": "7.20.6", + "eslint-plugin-react-hooks": "4.1.0", "husky": "4.2.5", "lerna": "3.22.1", - "lint-staged": "10.2.11", - "prettier": "2.0.5", + "lint-staged": "10.2.13", + "prettier": "2.1.1", "rimraf": "3.0.2", - "typescript": "3.9.7", - "yarn": "1.22.4" + "typescript": "4.0.2", + "yarn": "1.22.5" }, "engines": { "node": ">=10", diff --git a/frontend/packages/cli/package.json b/frontend/packages/cli/package.json index 239674de4322753e50499037eeb3466b32334709..ebe65a63693e6b1979a2eafa4f59159e69ab1585 100644 --- a/frontend/packages/cli/package.json +++ b/frontend/packages/cli/package.json @@ -23,10 +23,10 @@ "directory": "frontend/packages/cli" }, "scripts": { - "dev": "cross-env NODE_ENV=development ts-node index.ts", "build": "tsc", + "dev": "cross-env NODE_ENV=development ts-node index.ts", "start": "node index.js", - "test": "echo \"Error: no test specified\" && exit 0; #" + "test": "echo \"Error: no test specified\" && exit 0" }, "bin": "dist/index.js", "types": "dist/index.d.ts", @@ -35,28 +35,23 @@ ], "dependencies": { "@visualdl/server": "2.0.0", - "open": "7.1.0", - "ora": "4.0.5", - "pm2": "4.4.0", + "open": "7.2.1", + "ora": "5.0.0", + "pm2": "4.4.1", "yargs": "15.4.1" }, "devDependencies": { - "@types/node": "14.0.27", + "@types/node": "14.6.3", "@types/yargs": "15.0.5", "cross-env": "7.0.2", - "ts-node": "8.10.2", - "typescript": "3.9.7" + "ts-node": "9.0.0", + "typescript": "4.0.2" }, "engines": { - "node": ">=10", + "node": ">=12", "npm": ">=6" }, "publishConfig": { "access": "public" - }, - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } } } diff --git a/frontend/packages/core/.gitignore b/frontend/packages/core/.gitignore deleted file mode 100644 index 1fcb1529f8e5e43037c4710ce09da0becd28823a..0000000000000000000000000000000000000000 --- a/frontend/packages/core/.gitignore +++ /dev/null @@ -1 +0,0 @@ -out diff --git a/frontend/packages/core/.npmignore b/frontend/packages/core/.npmignore deleted file mode 100644 index 1f021963974592922af20dfc2302c593a425217f..0000000000000000000000000000000000000000 --- a/frontend/packages/core/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -dist -out diff --git a/frontend/packages/core/README.md b/frontend/packages/core/README.md index 023eeaebfc75d4d233ce3b46b93332343454cd96..ec61664ce35b49d2ef30e4fd09be906c86fbb0da 100644 --- a/frontend/packages/core/README.md +++ b/frontend/packages/core/README.md @@ -1,7 +1,6 @@ # VisualDL FrontEnd Core This is core contents of VisualDL pages. -DO NOT use it directly. ## Development @@ -12,9 +11,3 @@ yarn dev ``` Now open [http://localhost:3000](http://localhost:3000) with your browser. - -You can change the port with `PORT` environment variable: - -```bash -PORT=8999 yarn dev -``` diff --git a/frontend/packages/core/__mocks__/styleMock.js b/frontend/packages/core/__mocks__/styleMock.js deleted file mode 100644 index f053ebf7976e3726d11f3c03fade2170903889a5..0000000000000000000000000000000000000000 --- a/frontend/packages/core/__mocks__/styleMock.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = {}; diff --git a/frontend/packages/core/__tests__/404.test.tsx b/frontend/packages/core/__tests__/404.test.tsx deleted file mode 100644 index 0a0e3e45d271b27303d386e1c78a3904f4ba7d63..0000000000000000000000000000000000000000 --- a/frontend/packages/core/__tests__/404.test.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import Page404 from '../pages/404'; -import React from 'react'; -import {shallow} from 'enzyme'; - -describe('Page 404', () => { - test('page with content `404 - errors:page-not-found`', () => { - const page = shallow(); - expect(page.text()).toEqual('404 - errors:page-not-found'); - }); -}); diff --git a/frontend/packages/core/__tests__/Icon.spec.tsx b/frontend/packages/core/__tests__/Icon.spec.tsx deleted file mode 100644 index afaade96ffb304866d36daaedbf6479928be6e7b..0000000000000000000000000000000000000000 --- a/frontend/packages/core/__tests__/Icon.spec.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import Icon from '../components/Icon'; -import React from 'react'; -import {shallow} from 'enzyme'; - -describe('Icon component', () => { - const click = jest.fn(); - const icon = shallow(); - - test('icon has one empty `i` element', () => { - expect(icon.is('i')).toBe(true); - expect(icon.children().length).toBe(0); - }); - - test('icon has class name `vdl-icon`', () => { - expect(icon.hasClass('vdl-icon')).toBe(true); - }); - - test('icon with type has class name `icon-${type}`', () => { - expect(icon.hasClass('icon-close')).toBe(true); - }); - - test('icon click', () => { - icon.simulate('click'); - expect(click.mock.calls.length).toBe(1); - }); -}); diff --git a/frontend/packages/core/__tests__/tsconfig.json b/frontend/packages/core/__tests__/tsconfig.json deleted file mode 100644 index 206aeaf88e5c714448cd78dbd8ae8d2b773c5d01..0000000000000000000000000000000000000000 --- a/frontend/packages/core/__tests__/tsconfig.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "../tsconfig.test.json" -} diff --git a/frontend/packages/core/babel.config.js b/frontend/packages/core/babel.config.js index 1c11280dec8f7e9e72d7943711e40662ba052c4c..d253893fce84a83d8b12ba6eb4b0ea865a257e70 100644 --- a/frontend/packages/core/babel.config.js +++ b/frontend/packages/core/babel.config.js @@ -1,15 +1,4 @@ module.exports = { - presets: ['next/babel'], - plugins: [ - [ - 'styled-components', - { - ssr: true, - displayName: true, - preprocess: false - } - ], - ['emotion'], - ...(process.env.NODE_ENV !== 'production' ? ['typescript-to-proptypes'] : []) - ] + extends: '@snowpack/app-scripts-react/babel.config.json', + plugins: ['styled-components'] }; diff --git a/frontend/packages/core/build.ts b/frontend/packages/core/build.ts deleted file mode 100644 index c1ae7a6fa901e18b80c839a5c83a188ddb0e74c0..0000000000000000000000000000000000000000 --- a/frontend/packages/core/build.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* eslint-disable no-console */ - -import ora from 'ora'; -import path from 'path'; -import {spawn} from 'child_process'; -import {writeFileSync} from 'fs'; - -const next = require.resolve('next/dist/bin/next'); -export const projectRoot = path.dirname(require.resolve('@visualdl/core')); - -export default function (action: 'build' | 'export', ...args: string[]): Promise { - return new Promise((resolve, reject) => { - const capitalizedAction = action.replace(/^./, w => w.toUpperCase()); - - const spinner = ora(`${capitalizedAction} in process...`).start(); - - const log = path.join(process.cwd(), `${action}.log`); - writeFileSync(log, '', {flag: 'w'}); - - const p = spawn(next, [action, ...args], { - cwd: projectRoot, - env: { - ...process.env, - NODE_ENV: 'production' - } - }); - - p.stdout.on('data', data => writeFileSync(log, data, {flag: 'a'})); - p.stderr.on('data', data => writeFileSync(log, data, {flag: 'a'})); - - p.on('close', code => { - if (code) { - spinner.fail(`${capitalizedAction} failed!`); - console.error(`Please refer to ${log} for more detail.`); - reject(code); - } else { - spinner.succeed(`${capitalizedAction} complete!`); - resolve(code); - } - }); - }); -} diff --git a/frontend/packages/core/builder/dev-server.js b/frontend/packages/core/builder/dev-server.js new file mode 100644 index 0000000000000000000000000000000000000000..ff4ac9dacb3d302cdc70090d12a76ba18d69f021 --- /dev/null +++ b/frontend/packages/core/builder/dev-server.js @@ -0,0 +1,24 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ + +const express = require('express'); +const mock = require('./mock'); +const icons = require('./icons'); +const netron = require('./netron'); +const wasm = require('./wasm'); + +const argv = require('yargs').nargs('port', 1).number('port').nargs('host', 1).argv; + +const app = express(); + +app.use(mock.pathname, mock.middleware()); + +app.use(icons.pathname, icons.middleware()); + +app.use(netron.pathname, express.static(netron.root, {index: false})); + +app.get(`${wasm.pathname}/${wasm.out}`, (_req, res) => { + res.type('application/wasm'); + res.sendFile(wasm.source); +}); + +app.listen(argv.port, argv.host); diff --git a/frontend/packages/core/builder/environment.js b/frontend/packages/core/builder/environment.js new file mode 100644 index 0000000000000000000000000000000000000000..c3a1595a2dab9538fd43b262d71e3f2c843cd0bd --- /dev/null +++ b/frontend/packages/core/builder/environment.js @@ -0,0 +1,7 @@ +process.env.SNOWPACK_PUBLIC_PATH = + process.env.PUBLIC_PATH === '/' || !process.env.PUBLIC_PATH ? '' : process.env.PUBLIC_PATH; +process.env.SNOWPACK_PUBLIC_API_URL = process.env.API_URL || `${process.env.SNOWPACK_PUBLIC_PATH}/api`; +process.env.SNOWPACK_PUBLIC_TELEMETRY_ID = process.env.TELEMETRY_ID || ''; +process.env.SNOWPACK_PUBLIC_API_TOKEN_KEY = process.env.API_TOKEN_KEY || ''; +process.env.SNOWPACK_PUBLIC_LANGUAGES = process.env.LANGUAGES || 'en,zh'; +process.env.SNOWPACK_PUBLIC_DEFAULT_LANGUAGE = process.env.DEFAULT_LANGUAGE || 'en'; diff --git a/frontend/packages/core/builder/icons.js b/frontend/packages/core/builder/icons.js new file mode 100644 index 0000000000000000000000000000000000000000..9a442790204c28b441f48ea7f27e15e982771311 --- /dev/null +++ b/frontend/packages/core/builder/icons.js @@ -0,0 +1,68 @@ +/* eslint-disable no-console */ +/* eslint-disable @typescript-eslint/no-var-requires */ + +const path = require('path'); +const {promises: fs} = require('fs'); +const {default: svgr} = require('@svgr/core'); +const babel = require('@babel/core'); +const {camelCase} = require('lodash'); +const {ensureDir} = require('fs-extra'); + +const root = path.resolve(__dirname, '../public/icons'); +const pathname = '/icons'; +const dist = path.resolve(__dirname, '../dist'); +const dest = path.join(dist, pathname); + +async function transform(file, minified) { + const basename = path.basename(file, '.svg'); + let jsx = await svgr( + await fs.readFile(file, 'utf-8'), + { + icon: true, + svgProps: { + fill: 'currentColor', + className: 'vdl-icon' + } + }, + {componentName: camelCase(basename).replace(/./, w => w.toUpperCase())} + ); + jsx = jsx.replace('import * as React from "react";', 'import React from "../web_modules/react.js";'); + const result = await babel.transformAsync(jsx, { + filename: basename + '.jsx', + presets: ['@babel/preset-react'], + minified + }); + return result.code; +} + +async function build() { + await ensureDir(dest); + const files = await fs.readdir(root); + for (const file of files) { + if (path.extname(file) === '.svg') { + const js = await transform(path.join(root, file), false); + await fs.writeFile(path.join(dest, path.basename(file, '.svg') + '.js'), js, 'utf-8'); + } + } + console.log('Icons copied!'); +} + +if (require.main === module) { + build(); +} + +const middleware = () => { + return async (req, res) => { + const file = path.join(root, req.path.replace(/\.js$/, '.svg')); + if ((await fs.stat(file)).isFile()) { + res.type('js'); + res.send(await transform(file, false)); + } + }; +}; + +module.exports = { + middleware, + root, + pathname +}; diff --git a/frontend/packages/core/builder/mock.js b/frontend/packages/core/builder/mock.js new file mode 100644 index 0000000000000000000000000000000000000000..39e5c0ef988f9b51072e9cfda6d7c5c0540813ff --- /dev/null +++ b/frontend/packages/core/builder/mock.js @@ -0,0 +1,8 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ + +const {middleware} = require('@visualdl/mock'); + +module.exports = { + middleware, + pathname: '/api' +}; diff --git a/frontend/packages/core/builder/netron.js b/frontend/packages/core/builder/netron.js new file mode 100644 index 0000000000000000000000000000000000000000..64b3a44a4eb2370222d4b58d1181472a62be7b40 --- /dev/null +++ b/frontend/packages/core/builder/netron.js @@ -0,0 +1,26 @@ +/* eslint-disable no-console */ +/* eslint-disable @typescript-eslint/no-var-requires */ + +const path = require('path'); +const fs = require('fs-extra'); + +const root = path.dirname(require('enhanced-resolve').sync(__dirname, '@visualdl/netron')); +const pathname = '/netron'; +const dist = path.resolve(__dirname, '../dist'); +const dest = path.join(dist, pathname); + +async function build() { + await fs.ensureDir(dest); + await fs.copy(root, dest, {preserveTimestamps: true}); + console.log('Netron copied!'); +} + +if (require.main === module) { + build(); +} + +module.exports = { + root, + dest, + pathname +}; diff --git a/frontend/packages/core/builder/wasm.js b/frontend/packages/core/builder/wasm.js new file mode 100644 index 0000000000000000000000000000000000000000..a1146229ef3d645e3425554637914f491f50949d --- /dev/null +++ b/frontend/packages/core/builder/wasm.js @@ -0,0 +1,29 @@ +/* eslint-disable no-console */ +/* eslint-disable @typescript-eslint/no-var-requires */ + +const path = require('path'); +const fs = require('fs-extra'); + +const root = path.dirname(require('enhanced-resolve').sync(__dirname, '@visualdl/wasm')); +const source = path.join(root, 'index_bg.wasm'); +const dist = path.resolve(__dirname, '../dist'); +const pathname = '/wasm'; +const out = 'visualdl.wasm'; +const dest = path.join(dist, pathname, out); + +async function build() { + await fs.ensureDir(path.join(dist, pathname)); + await fs.copy(source, dest, {preserveTimestamps: true}); + console.log('WebAssembly copied!'); +} + +if (require.main === module) { + build(); +} + +module.exports = { + dest, + source, + pathname, + out +}; diff --git a/frontend/packages/core/components/Icon.tsx b/frontend/packages/core/components/Icon.tsx deleted file mode 100644 index ecddcbe3b00c1399435263bb7c97f83015db7ef1..0000000000000000000000000000000000000000 --- a/frontend/packages/core/components/Icon.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React, {FunctionComponent} from 'react'; - -import {WithStyled} from '~/utils/style'; - -type IconProps = { - type: string; - onClick?: () => unknown; -}; - -const Icon: FunctionComponent = ({type, onClick, className}) => { - return onClick?.()}>; -}; - -export default Icon; diff --git a/frontend/packages/core/components/Layout.tsx b/frontend/packages/core/components/Layout.tsx deleted file mode 100644 index 425190f512ddc0a830154af7f32099446f89e2f1..0000000000000000000000000000000000000000 --- a/frontend/packages/core/components/Layout.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, {FunctionComponent} from 'react'; -import {headerHeight, position, size} from '~/utils/style'; - -import Navbar from '~/components/Navbar'; -import styled from 'styled-components'; - -const Main = styled.main` - padding-top: ${headerHeight}; -`; - -const Header = styled.header` - z-index: 10000; - - ${size(headerHeight, '100%')} - ${position('fixed', 0, 0, null, 0)} -`; - -const Layout: FunctionComponent = ({children}) => ( -
-
- -
- {children} -
-); - -export default Layout; diff --git a/frontend/packages/core/components/Preloader.tsx b/frontend/packages/core/components/Preloader.tsx deleted file mode 100644 index 28e0e914def51d2d1d2c64db9dbcfc883b9496d9..0000000000000000000000000000000000000000 --- a/frontend/packages/core/components/Preloader.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React, {FunctionComponent} from 'react'; - -import Head from 'next/head'; - -type PreloaderProps = { - url: string; - as?: - | 'audio' - | 'document' - | 'embed' - | 'fetch' - | 'font' - | 'image' - | 'object' - | 'script' - | 'style' - | 'track' - | 'worker' - | 'video'; -}; - -const Preloader: FunctionComponent = ({url, as}) => - process.env.API_TOKEN_KEY ? null : ( - - - - ); - -export default Preloader; diff --git a/frontend/packages/core/components/Title.tsx b/frontend/packages/core/components/Title.tsx deleted file mode 100644 index b2025a807f38c18ce3ae201fb821c4c0d0962c8b..0000000000000000000000000000000000000000 --- a/frontend/packages/core/components/Title.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React, {FunctionComponent} from 'react'; - -import Head from 'next/head'; - -const Title: FunctionComponent = ({children: title}) => ( - - - {'string' === typeof title ? `${title} - ` : ''} - {process.env.title} - - -); - -export default Title; diff --git a/frontend/packages/core/hooks/useHeavyWork.ts b/frontend/packages/core/hooks/useHeavyWork.ts deleted file mode 100644 index f4dfa905ac576c367cf9fbc372ef98144274d35b..0000000000000000000000000000000000000000 --- a/frontend/packages/core/hooks/useHeavyWork.ts +++ /dev/null @@ -1,55 +0,0 @@ -import {useCallback, useEffect, useRef, useState} from 'react'; - -const useHeavyWork = ( - createWasm: (() => Promise<(arg: P) => T> | null) | null, - createWorker: (() => Worker | null) | null, - fallback: ((arg: P) => T) | null, - params: P -) => { - const wasm = useRef>>(null); - const worker = useRef>>(null); - - const [result, setResult] = useState(undefined); - - const runFallback = useCallback((p: P) => fallback && setResult(fallback(p)), [fallback]); - - useEffect(() => { - if (process.browser) { - try { - if (createWasm && typeof WebAssembly !== 'undefined') { - if (!wasm.current) { - wasm.current = createWasm(); - } - wasm.current - ?.then((work: (arg: P) => T) => setResult(work(params))) - .catch(() => runFallback(params)); - return; - } - - if (createWorker && typeof Worker !== 'undefined') { - if (!worker.current) { - worker.current = createWorker(); - } - worker.current?.postMessage(params); - worker.current?.addEventListener('message', ({data}: MessageEvent & {data: T}) => setResult(data)); - worker.current?.addEventListener('error', () => runFallback(params)); - return; - } - } catch (e) { - if (process.env.NODE_ENV === 'development') { - // eslint-disable-next-line no-console - console.error('Error during heavy work, trying to use fallback'); - // eslint-disable-next-line no-console - console.error(e); - } - runFallback(params); - } - } - - runFallback(params); - }, [createWasm, createWorker, runFallback, params]); - - return result; -}; - -export default useHeavyWork; diff --git a/frontend/packages/core/index.js b/frontend/packages/core/index.js deleted file mode 100644 index dde39dcdd7faaaaba2c08461ecab798ba57ec744..0000000000000000000000000000000000000000 --- a/frontend/packages/core/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('next'); diff --git a/frontend/packages/core/jest.config.js b/frontend/packages/core/jest.config.js index 8de452ac9080458b9cebf52b72e9f6c6653434d1..85a476e6f2f9dd9507eee17610b5e095c527da0f 100644 --- a/frontend/packages/core/jest.config.js +++ b/frontend/packages/core/jest.config.js @@ -1,23 +1,5 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ + module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - moduleFileExtensions: ['ts', 'tsx', 'js'], - transform: { - '^.+\\.(ts|tsx)$': 'ts-jest' - }, - testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.[jt]sx?$', - setupFilesAfterEnv: ['/jest.setup.ts'], - coveragePathIgnorePatterns: ['/next.config.js', '/node_modules/'], - testPathIgnorePatterns: ['/dist/', '/out/', '/node_modules/'], - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], - moduleNameMapper: { - '\\.css$': '/__mocks__/styleMock.js', - '~/(.*)': '/$1' - }, - snapshotSerializers: ['enzyme-to-json/serializer'], - globals: { - 'ts-jest': { - tsConfig: '/tsconfig.test.json' - } - } + ...require('@snowpack/app-scripts-react/jest.config.js')() }; diff --git a/frontend/packages/core/jest.setup.js b/frontend/packages/core/jest.setup.js new file mode 100644 index 0000000000000000000000000000000000000000..74b1a275a0ea7df518f17bcea5375abf003abe55 --- /dev/null +++ b/frontend/packages/core/jest.setup.js @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom/extend-expect'; diff --git a/frontend/packages/core/jest.setup.ts b/frontend/packages/core/jest.setup.ts deleted file mode 100644 index 2b88ea9e896a7cb6634d32f2f729501cab03701a..0000000000000000000000000000000000000000 --- a/frontend/packages/core/jest.setup.ts +++ /dev/null @@ -1,4 +0,0 @@ -import ReactSixteenAdapter from 'enzyme-adapter-react-16'; -import {configure} from 'enzyme'; - -configure({adapter: new ReactSixteenAdapter()}); diff --git a/frontend/packages/core/next-env.d.ts b/frontend/packages/core/next-env.d.ts deleted file mode 100644 index 7b7aa2c7727d88b33b62bee640d607d57cc79599..0000000000000000000000000000000000000000 --- a/frontend/packages/core/next-env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// diff --git a/frontend/packages/core/next.config.d.ts b/frontend/packages/core/next.config.d.ts deleted file mode 100644 index 3b4b131a16750cc9f8ab52ea44f58c9079bde0c9..0000000000000000000000000000000000000000 --- a/frontend/packages/core/next.config.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -declare type NextEnv = { - PUBLIC_PATH: string; - API_URL: string; - DEFAULT_LANGUAGE: string; - LANGUAGES: string[]; - LOCALE_PATH: string; -}; - -declare interface NextConfig { - env: NextEnv; -} - -const nextConfig: NextConfig; - -export default nextConfig; - -export const env: NextEnv; diff --git a/frontend/packages/core/next.config.js b/frontend/packages/core/next.config.js deleted file mode 100644 index 74615d248e6aeb38f2cbeb0164a3905c609f475f..0000000000000000000000000000000000000000 --- a/frontend/packages/core/next.config.js +++ /dev/null @@ -1,80 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ - -const path = require('path'); -const pkg = require('./package.json'); - -const publicPath = process.env.PUBLIC_PATH || ''; -const apiUrl = process.env.API_URL || '/api'; -const distDir = 'dist'; - -const APP = { - name: pkg.name, - version: pkg.version, - title: pkg.title, - description: pkg.description, - author: pkg.author, - keywords: pkg.keywords.join(',') -}; - -const DEFAULT_LANGUAGE = 'en'; -const LOCALE_PATH = 'public/locales'; -const LANGUAGES = ['en', 'zh']; -const otherLanguages = LANGUAGES.filter(lang => lang !== DEFAULT_LANGUAGE); - -module.exports = { - assetPrefix: publicPath, - distDir, - poweredByHeader: false, - env: { - ...APP, - DEFAULT_LANGUAGE, - LOCALE_PATH, - LANGUAGES, - API_URL: apiUrl, - PUBLIC_PATH: publicPath, - API_TOKEN_KEY: process.env.API_TOKEN_KEY || '' - }, - exportPathMap: defaultPathMap => ({ - ...defaultPathMap, - ...Object.entries(defaultPathMap).reduce((prev, [path, router]) => { - otherLanguages.forEach(lang => (prev[`/${lang}${path}`] = router)); - return prev; - }, {}) - }), - experimental: { - basePath: publicPath - }, - webpack: config => { - const WorkerPlugin = require('worker-plugin'); - const CopyWebpackPlugin = require('copy-webpack-plugin'); - - config.resolve = config.resolve || {}; - config.resolve.alias = config.resolve.alias || {}; - config.resolve.alias['~'] = path.resolve(__dirname); - - config.node = Object.assign({}, config.node, { - // eslint-disable-next-line @typescript-eslint/naming-convention - child_process: 'empty', - fs: 'empty' - }); - - config.plugins = [ - ...(config.plugins || []), - new WorkerPlugin({ - globalObject: 'self' - }), - new CopyWebpackPlugin({ - patterns: [ - { - context: path.dirname(require('enhanced-resolve').sync(__dirname, '@visualdl/netron')), - from: '**/*', - to: 'static/netron', - toType: 'dir' - } - ] - }) - ]; - - return config; - } -}; diff --git a/frontend/packages/core/package.json b/frontend/packages/core/package.json index 35e8332fead3a5a21a419ac5a6738def95a66f9d..ab2a506a4e7bdcadac11fa1370dcf649d0ea80a8 100644 --- a/frontend/packages/core/package.json +++ b/frontend/packages/core/package.json @@ -1,7 +1,6 @@ { "name": "@visualdl/core", "version": "2.0.0", - "title": "VisualDL", "description": "A platform to visualize the deep learning process and result.", "keywords": [ "visualdl", @@ -24,90 +23,87 @@ "directory": "frontend/packages/core" }, "scripts": { - "dev": "next", - "build": "echo 'This package does not need to build. Please use @visualdl/server or @visualdl/serverless to build from source.'; echo 'If you want to test build function, please run `build:next` instead.'", - "build:next": "next build", - "export": "next export", - "start": "next start", - "test": "NODE_OPTIONS=\"--max-old-space-size=4096\" jest", - "test:coverage": "NODE_OPTIONS=\"--max-old-space-size=4096\" jest --coverage" + "dev": "snowpack dev", + "build": "snowpack build", + "start": "yarn dev --reload", + "test": "jest" }, + "main": "dist/index.html", + "files": [ + "dist" + ], "dependencies": { "@tippyjs/react": "4.1.0", - "@visualdl/i18n": "2.0.0", "@visualdl/netron": "2.0.0", "@visualdl/wasm": "2.0.0", "bignumber.js": "9.0.0", - "d3-format": "1.4.4", - "echarts": "4.8.0", + "d3-format": "2.0.0", + "echarts": "4.9.0", "echarts-gl": "1.1.1", - "eventemitter3": "4.0.4", + "eventemitter3": "4.0.7", "file-saver": "2.0.2", - "isomorphic-unfetch": "3.0.0", - "lodash": "4.17.19", + "i18next": "19.7.0", + "i18next-browser-languagedetector": "6.0.1", + "i18next-fetch-backend": "3.0.0", + "lodash": "4.17.20", "mime-types": "2.1.27", "moment": "2.27.0", - "next": "9.4.4", "nprogress": "0.2.0", - "polished": "3.6.5", - "prop-types": "15.7.2", + "polished": "3.6.6", "query-string": "6.13.1", "react": "16.13.1", "react-dom": "16.13.1", + "react-helmet": "6.1.0", + "react-i18next": "11.7.2", "react-input-range": "1.3.0", "react-is": "16.13.1", "react-rangeslider": "2.2.0", + "react-router-dom": "5.2.0", "react-spinners": "0.9.0", "react-toastify": "6.0.8", - "save-svg-as-png": "1.4.17", "styled-components": "5.1.1", "swr": "0.3.0", "tippy.js": "6.2.6" }, "devDependencies": { - "@babel/core": "7.11.1", + "@babel/core": "7.11.5", + "@babel/preset-react": "7.10.4", + "@snowpack/app-scripts-react": "1.10.0", + "@snowpack/plugin-dotenv": "2.0.1", + "@snowpack/plugin-run-script": "2.1.1", + "@svgr/core": "5.4.0", + "@testing-library/jest-dom": "5.11.4", + "@testing-library/react": "10.4.9", "@types/d3-format": "1.3.1", - "@types/echarts": "4.6.4", - "@types/enzyme": "3.10.5", - "@types/enzyme-adapter-react-16": "1.0.6", + "@types/echarts": "4.6.5", "@types/file-saver": "2.0.1", - "@types/jest": "26.0.8", - "@types/lodash": "4.14.158", + "@types/jest": "26.0.13", + "@types/loadable__component": "5.13.0", + "@types/lodash": "4.14.161", "@types/mime-types": "2.1.0", - "@types/node": "14.0.27", "@types/nprogress": "0.2.0", - "@types/react": "16.9.44", + "@types/react": "16.9.49", "@types/react-dom": "16.9.8", + "@types/react-helmet": "6.1.0", "@types/react-rangeslider": "2.2.3", - "@types/styled-components": "5.1.2", + "@types/react-router-dom": "5.1.5", + "@types/snowpack-env": "2.3.0", + "@types/styled-components": "5.1.3", "@visualdl/mock": "2.0.0", - "babel-plugin-emotion": "10.0.33", "babel-plugin-styled-components": "1.11.1", - "babel-plugin-typescript-to-proptypes": "1.4.0", - "copy-webpack-plugin": "6.0.3", - "core-js": "3.6.5", - "cross-env": "7.0.2", - "css-loader": "4.2.0", "enhanced-resolve": "4.3.0", - "enzyme": "3.11.0", - "enzyme-adapter-react-16": "1.15.2", - "enzyme-to-json": "3.5.0", - "jest": "26.2.2", - "ora": "4.0.5", - "ts-jest": "26.1.4", - "typescript": "3.9.7", - "worker-plugin": "4.0.3" + "express": "4.17.1", + "fs-extra": "9.0.1", + "jest": "26.4.2", + "snowpack": "2.10.1", + "typescript": "4.0.2", + "yargs": "15.4.1" }, "engines": { - "node": ">=10", + "node": ">=12", "npm": ">=6" }, "publishConfig": { "access": "public" - }, - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } } } diff --git a/frontend/packages/core/pages/404.tsx b/frontend/packages/core/pages/404.tsx deleted file mode 100644 index cb36d4b571ac0f12b016f64c62abb4dc8a8f806f..0000000000000000000000000000000000000000 --- a/frontend/packages/core/pages/404.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import {NextI18NextPage, useTranslation} from '~/utils/i18n'; -import {headerHeight, rem} from '~/utils/style'; - -import React from 'react'; -import styled from 'styled-components'; - -const Error = styled.div` - height: calc(100vh - ${headerHeight}); - display: flex; - justify-content: center; - align-items: center; - font-size: ${rem(20)}; -`; - -const Error404: NextI18NextPage = () => { - const {t} = useTranslation('errors'); - - return 404 - {t('errors:page-not-found')}; -}; - -// 404 page cannot have getInitialProps or getServerSideProps -// we need next-i18next support getStaticProps -// https://github.com/zeit/next.js/blob/master/errors/404-get-initial-props.md -// https://github.com/isaachinman/next-i18next/issues/652 -// Error404.getInitialProps = () => { -// return { -// namespacesRequired: ['errors'] -// }; -// }; - -export default Error404; diff --git a/frontend/packages/core/pages/_app.tsx b/frontend/packages/core/pages/_app.tsx deleted file mode 100644 index 6cf4747d80fe8d5344b5cde1d21225f693df3f06..0000000000000000000000000000000000000000 --- a/frontend/packages/core/pages/_app.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import {Router, appWithTranslation} from '~/utils/i18n'; -import {fetcher, getApiToken} from '~/utils/fetch'; - -import App from 'next/app'; -import {GlobalStyle} from '~/utils/style'; -import Head from 'next/head'; -import Layout from '~/components/Layout'; -import NProgress from 'nprogress'; -import React from 'react'; -import {SWRConfig} from 'swr'; -import {ToastContainer} from 'react-toastify'; -import queryString from 'query-string'; -import {withRouter} from 'next/router'; - -const API_TOKEN_KEY = process.env.API_TOKEN_KEY; -const PUBLIC_PATH = process.env.PUBLIC_PATH; - -class VDLApp extends App { - componentDidMount() { - Router.events.on('routeChangeStart', () => NProgress.start()); - Router.events.on('routeChangeComplete', (url: string) => { - NProgress.done(); - if (API_TOKEN_KEY) { - const id = getApiToken(); - const parsed = queryString.parseUrl(url); - if (id && !parsed.query[API_TOKEN_KEY]) { - this.props.router.replace( - queryString.stringifyUrl({ - url: parsed.url, - query: { - ...parsed.query, - [API_TOKEN_KEY]: id - } - }), - undefined, - {shallow: true} - ); - } - } - }); - Router.events.on('routeChangeError', () => NProgress.done()); - } - - render() { - const {Component, pageProps} = this.props; - - return ( - <> - - {process.env.title} - - - - - - - - - - - - - - - ); - } -} - -export default appWithTranslation(withRouter(VDLApp)); diff --git a/frontend/packages/core/pages/_document.tsx b/frontend/packages/core/pages/_document.tsx deleted file mode 100644 index e8cd97dc4398ea3b94862d7eefc547b6ecc462bc..0000000000000000000000000000000000000000 --- a/frontend/packages/core/pages/_document.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import Document, { - DocumentContext, - DocumentInitialProps, - DocumentProps, - Head, - Html, - Main, - NextScript -} from 'next/document'; - -import {ServerStyleSheet} from '~/utils/style'; - -interface VDLDocumentProps extends DocumentProps { - language: string; - languageDir: string; -} - -export default class VDLDocument extends Document { - static async getInitialProps(ctx: DocumentContext): Promise { - // https://github.com/zeit/next.js/blob/canary/examples/with-typescript-styled-components/pages/_document.tsx - const sheet = new ServerStyleSheet(); - const originalRenderPage = ctx.renderPage; - - try { - ctx.renderPage = () => - originalRenderPage({ - enhanceApp: App => props => sheet.collectStyles() - }); - - const initialProps = await Document.getInitialProps(ctx); - // steal from https://github.com/isaachinman/next-i18next/issues/20#issuecomment-558799264 - // FIXME: https://github.com/i18next/i18next-express-middleware/blob/master/src/index.js#L23-L26 - const additionalProps = { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ...((ctx.res as any)?.locals || {}) - }; - - return { - ...initialProps, - ...additionalProps, - styles: ( - <> - {initialProps.styles} - {sheet.getStyleElement()} - - ) - }; - } finally { - sheet.seal(); - } - } - - render(): JSX.Element { - const {language, languageDir} = this.props; - return ( - - - -
- - - - ); - } -} diff --git a/frontend/packages/core/pages/_error.tsx b/frontend/packages/core/pages/_error.tsx deleted file mode 100644 index e0d4436a69490125fe876a108f36ffec47e5bdc0..0000000000000000000000000000000000000000 --- a/frontend/packages/core/pages/_error.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import {NextI18NextPage, useTranslation} from '~/utils/i18n'; -import {headerHeight, rem} from '~/utils/style'; - -import styled from 'styled-components'; - -const ErrorDiv = styled.div` - height: calc(100vh - ${headerHeight}); - display: flex; - justify-content: center; - align-items: center; - font-size: ${rem(20)}; -`; - -interface ErrorProps { - statusCode?: number | null; -} - -const Error: NextI18NextPage = ({statusCode}) => { - const {t} = useTranslation('errors'); - - return ( - - {statusCode ? t('errors:error-with-status', {statusCode}) : t('errors:error-without-status')} - - ); -}; - -Error.getInitialProps = ({res, err}) => { - let statusCode = null; - if (res) { - ({statusCode} = res); - } else if (err) { - ({statusCode} = err); - } - return { - namespacesRequired: ['errors'], - statusCode - }; -}; - -export default Error; diff --git a/frontend/packages/core/pages/api/[...method].ts b/frontend/packages/core/pages/api/[...method].ts deleted file mode 100644 index 1a07c8002cb51af5ecb3cc1370d8c63dde95a286..0000000000000000000000000000000000000000 --- a/frontend/packages/core/pages/api/[...method].ts +++ /dev/null @@ -1,5 +0,0 @@ -import mock from '@visualdl/mock'; - -const delay = Number.parseInt(process.env.DELAY || '', 10); - -export default mock({delay: delay ? () => Math.random() * delay : 0}); diff --git a/frontend/packages/core/public/icons/audio.svg b/frontend/packages/core/public/icons/audio.svg new file mode 100755 index 0000000000000000000000000000000000000000..91405e7675b1b05106c1c834d508ea567676b919 --- /dev/null +++ b/frontend/packages/core/public/icons/audio.svg @@ -0,0 +1,5 @@ + + +audio + + diff --git a/frontend/packages/core/public/icons/check-mark.svg b/frontend/packages/core/public/icons/check-mark.svg new file mode 100755 index 0000000000000000000000000000000000000000..1723e1ef5bdab32d5dc6c85c30a4b883e384e2ef --- /dev/null +++ b/frontend/packages/core/public/icons/check-mark.svg @@ -0,0 +1,5 @@ + + +check-mark + + diff --git a/frontend/packages/core/public/icons/chevron-down.svg b/frontend/packages/core/public/icons/chevron-down.svg new file mode 100755 index 0000000000000000000000000000000000000000..ff6a42e118a01680a1c4ac33ff3dac80e655dd35 --- /dev/null +++ b/frontend/packages/core/public/icons/chevron-down.svg @@ -0,0 +1,5 @@ + + +chevron-down + + diff --git a/frontend/packages/core/public/icons/close.svg b/frontend/packages/core/public/icons/close.svg new file mode 100755 index 0000000000000000000000000000000000000000..acd31eac6130061577370584cef6dabea3c3501f --- /dev/null +++ b/frontend/packages/core/public/icons/close.svg @@ -0,0 +1,5 @@ + + +close + + diff --git a/frontend/packages/core/public/icons/dimension.svg b/frontend/packages/core/public/icons/dimension.svg new file mode 100755 index 0000000000000000000000000000000000000000..46a3449d1c9be75a7ebe85dbb056fbba9bb93eba --- /dev/null +++ b/frontend/packages/core/public/icons/dimension.svg @@ -0,0 +1,7 @@ + + +dimension + + + + diff --git a/frontend/packages/core/public/icons/download.svg b/frontend/packages/core/public/icons/download.svg new file mode 100755 index 0000000000000000000000000000000000000000..9bf7efcff9584da98309bd9d5b9f34ebb579fe0c --- /dev/null +++ b/frontend/packages/core/public/icons/download.svg @@ -0,0 +1,5 @@ + + +download + + diff --git a/frontend/packages/core/public/icons/histogram.svg b/frontend/packages/core/public/icons/histogram.svg new file mode 100755 index 0000000000000000000000000000000000000000..a985a781a5b41aa8c3c19c5f8d7d2833db843220 --- /dev/null +++ b/frontend/packages/core/public/icons/histogram.svg @@ -0,0 +1,8 @@ + + +histogram + + + + + diff --git a/frontend/packages/core/public/icons/image.svg b/frontend/packages/core/public/icons/image.svg new file mode 100755 index 0000000000000000000000000000000000000000..b963e18f6ba0d698b3d4db1f8a57678280ab41da --- /dev/null +++ b/frontend/packages/core/public/icons/image.svg @@ -0,0 +1,7 @@ + + +image + + + + diff --git a/frontend/packages/core/public/icons/log-axis.svg b/frontend/packages/core/public/icons/log-axis.svg new file mode 100755 index 0000000000000000000000000000000000000000..9726170a08db907fed0b2547603c8a5ef54653ee --- /dev/null +++ b/frontend/packages/core/public/icons/log-axis.svg @@ -0,0 +1,8 @@ + + +log-axis + + + + + diff --git a/frontend/packages/core/public/icons/maximize.svg b/frontend/packages/core/public/icons/maximize.svg new file mode 100755 index 0000000000000000000000000000000000000000..9847ecd6fd1be3bb5506c5e4d4bc6c57d8323cad --- /dev/null +++ b/frontend/packages/core/public/icons/maximize.svg @@ -0,0 +1,5 @@ + + +maximize + + diff --git a/frontend/packages/core/public/icons/minimize.svg b/frontend/packages/core/public/icons/minimize.svg new file mode 100755 index 0000000000000000000000000000000000000000..c314dee90a8124cd5475abc1e5e911df8b9145db --- /dev/null +++ b/frontend/packages/core/public/icons/minimize.svg @@ -0,0 +1,8 @@ + + +minimize + + + + + diff --git a/frontend/packages/core/public/icons/minus.svg b/frontend/packages/core/public/icons/minus.svg new file mode 100755 index 0000000000000000000000000000000000000000..0ab7a3bdf106602845322b3a632e211d7a7c6fd8 --- /dev/null +++ b/frontend/packages/core/public/icons/minus.svg @@ -0,0 +1,5 @@ + + +minus + + diff --git a/frontend/packages/core/public/icons/mute.svg b/frontend/packages/core/public/icons/mute.svg new file mode 100755 index 0000000000000000000000000000000000000000..d612dbf4786b9afcbe34628ec379a86fb61aa013 --- /dev/null +++ b/frontend/packages/core/public/icons/mute.svg @@ -0,0 +1,5 @@ + + +mute + + diff --git a/frontend/packages/core/public/icons/pause.svg b/frontend/packages/core/public/icons/pause.svg new file mode 100755 index 0000000000000000000000000000000000000000..e29e3da4e69f7aaa387b1c68c17414d7c6bd88a4 --- /dev/null +++ b/frontend/packages/core/public/icons/pause.svg @@ -0,0 +1,6 @@ + + +pause + + + diff --git a/frontend/packages/core/public/icons/play.svg b/frontend/packages/core/public/icons/play.svg new file mode 100755 index 0000000000000000000000000000000000000000..6018e5c6a490196fe28f0c4503203e444e6ccc1d --- /dev/null +++ b/frontend/packages/core/public/icons/play.svg @@ -0,0 +1,5 @@ + + +play + + diff --git a/frontend/packages/core/public/icons/plus.svg b/frontend/packages/core/public/icons/plus.svg new file mode 100755 index 0000000000000000000000000000000000000000..c121b35cae455f93d6a38f0b0676b40ed6c8a8cc --- /dev/null +++ b/frontend/packages/core/public/icons/plus.svg @@ -0,0 +1,5 @@ + + +plus + + diff --git a/frontend/packages/core/public/icons/question-circle.svg b/frontend/packages/core/public/icons/question-circle.svg new file mode 100755 index 0000000000000000000000000000000000000000..8d2bb142d6bcedb90f1df139cb7ba344e8a26810 --- /dev/null +++ b/frontend/packages/core/public/icons/question-circle.svg @@ -0,0 +1,5 @@ + + +question-circle + + diff --git a/frontend/packages/core/public/icons/reduction.svg b/frontend/packages/core/public/icons/reduction.svg new file mode 100755 index 0000000000000000000000000000000000000000..f50bb43acbac3ffea3053fb24c3f1bec01c1f0fe --- /dev/null +++ b/frontend/packages/core/public/icons/reduction.svg @@ -0,0 +1,9 @@ + + +reduction + + + + + + diff --git a/frontend/packages/core/public/icons/refresh.svg b/frontend/packages/core/public/icons/refresh.svg new file mode 100755 index 0000000000000000000000000000000000000000..e03f0fb20dcc0e7c4c2c2c608d1b891d3daa8218 --- /dev/null +++ b/frontend/packages/core/public/icons/refresh.svg @@ -0,0 +1,5 @@ + + +refresh + + diff --git a/frontend/packages/core/public/icons/restore-size.svg b/frontend/packages/core/public/icons/restore-size.svg new file mode 100755 index 0000000000000000000000000000000000000000..a0b3f1908f08813d6e3ed1c79e0050746cc897c5 --- /dev/null +++ b/frontend/packages/core/public/icons/restore-size.svg @@ -0,0 +1,6 @@ + + +restore-size + + + diff --git a/frontend/packages/core/public/icons/revert.svg b/frontend/packages/core/public/icons/revert.svg new file mode 100755 index 0000000000000000000000000000000000000000..dbdfb22288cd79aaf616fb49feb7fe8201804df8 --- /dev/null +++ b/frontend/packages/core/public/icons/revert.svg @@ -0,0 +1,5 @@ + + +revert + + diff --git a/frontend/packages/core/public/icons/scalar.svg b/frontend/packages/core/public/icons/scalar.svg new file mode 100755 index 0000000000000000000000000000000000000000..29a41af45581febf212f255937a32bf4c68b2e41 --- /dev/null +++ b/frontend/packages/core/public/icons/scalar.svg @@ -0,0 +1,6 @@ + + +scalar + + + diff --git a/frontend/packages/core/public/icons/search.svg b/frontend/packages/core/public/icons/search.svg new file mode 100755 index 0000000000000000000000000000000000000000..21eedd5b0ccfc32b1fa7cb0d77b4da11c7bf3385 --- /dev/null +++ b/frontend/packages/core/public/icons/search.svg @@ -0,0 +1,5 @@ + + +search + + diff --git a/frontend/packages/core/public/icons/text.svg b/frontend/packages/core/public/icons/text.svg new file mode 100755 index 0000000000000000000000000000000000000000..6c02ce9d2fb410580fb8ab147ee4200f27bc2c91 --- /dev/null +++ b/frontend/packages/core/public/icons/text.svg @@ -0,0 +1,10 @@ + + +text + + + + + + + diff --git a/frontend/packages/core/public/icons/upload.svg b/frontend/packages/core/public/icons/upload.svg new file mode 100755 index 0000000000000000000000000000000000000000..00bc7cd8ba78f36f2ab8dffdb3608b16cb06f7d4 --- /dev/null +++ b/frontend/packages/core/public/icons/upload.svg @@ -0,0 +1,6 @@ + + +upload + + + diff --git a/frontend/packages/core/public/icons/volumn-low.svg b/frontend/packages/core/public/icons/volumn-low.svg new file mode 100755 index 0000000000000000000000000000000000000000..ef75219ce58858495aef82000691b1bb13f16b66 --- /dev/null +++ b/frontend/packages/core/public/icons/volumn-low.svg @@ -0,0 +1,6 @@ + + +volumn-low + + + diff --git a/frontend/packages/core/public/icons/volumn.svg b/frontend/packages/core/public/icons/volumn.svg new file mode 100755 index 0000000000000000000000000000000000000000..a52297fea6316b6475fe483f8b1a1caa317f9f60 --- /dev/null +++ b/frontend/packages/core/public/icons/volumn.svg @@ -0,0 +1,7 @@ + + +volumn + + + + diff --git a/frontend/packages/core/public/icons/zoom-in.svg b/frontend/packages/core/public/icons/zoom-in.svg new file mode 100755 index 0000000000000000000000000000000000000000..62daa53ebe1994265abf281d915c78289c1e4ec3 --- /dev/null +++ b/frontend/packages/core/public/icons/zoom-in.svg @@ -0,0 +1,6 @@ + + +zoom-in + + + diff --git a/frontend/packages/core/public/icons/zoom-out.svg b/frontend/packages/core/public/icons/zoom-out.svg new file mode 100755 index 0000000000000000000000000000000000000000..cac8fbb16e93d1c403d48217ec980c6bad9f731d --- /dev/null +++ b/frontend/packages/core/public/icons/zoom-out.svg @@ -0,0 +1,6 @@ + + +zoom-out + + + diff --git a/frontend/packages/core/public/index.html b/frontend/packages/core/public/index.html new file mode 100644 index 0000000000000000000000000000000000000000..8bbf1c09f9288ad63e45b66d02f70973de11dcf8 --- /dev/null +++ b/frontend/packages/core/public/index.html @@ -0,0 +1,14 @@ + + + + + + + VisualDL + + +
+ + + + diff --git a/frontend/packages/core/public/locales/en/scalar.json b/frontend/packages/core/public/locales/en/scalar.json index cdd8fed20b5c732a603aa1423350ff2eb7e1c178..04777686379bd03764efe0c0f5c865e90e3d5323 100644 --- a/frontend/packages/core/public/locales/en/scalar.json +++ b/frontend/packages/core/public/locales/en/scalar.json @@ -1,7 +1,9 @@ { "download-image": "Download image", "ignore-outliers": "Ignore outliers in chart scaling", + "max": "Max", "maximize": "Maximize", + "min": "Min", "minimize": "Minimize", "restore": "Selection restore", "smoothed": "Smoothed", diff --git a/frontend/packages/core/public/locales/zh/scalar.json b/frontend/packages/core/public/locales/zh/scalar.json index 6cfbb67e3fc3840b966ada19f9cfcf06bd9efe86..06dae8904b9c8980e3ef1b1f10c07262c919a642 100644 --- a/frontend/packages/core/public/locales/zh/scalar.json +++ b/frontend/packages/core/public/locales/zh/scalar.json @@ -1,13 +1,15 @@ { "download-image": "下载图片", "ignore-outliers": "图表缩放时忽略极端值", + "max": "最大值", "maximize": "最大化", + "min": "最小值", "minimize": "最小化", "restore": "还原图表框选", "smoothed": "Smoothed", "smoothing": "平滑度", "toggle-log-axis": "切换对数坐标轴", - "tooltip-sorting": "标签排序方法", + "tooltip-sorting": "详情数据排序", "tooltip-sorting-value": { "ascending": "升序", "default": "默认", diff --git a/frontend/packages/core/public/style/fonts/vdl-icon.svg b/frontend/packages/core/public/style/fonts/vdl-icon.svg deleted file mode 100755 index 1525518c447ae9ef96ee0f337455717d17f10aa4..0000000000000000000000000000000000000000 --- a/frontend/packages/core/public/style/fonts/vdl-icon.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - -Generated by IcoMoon - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/frontend/packages/core/public/style/fonts/vdl-icon.ttf b/frontend/packages/core/public/style/fonts/vdl-icon.ttf deleted file mode 100755 index a282f53956a39e5565631f17b52a463a1667d789..0000000000000000000000000000000000000000 Binary files a/frontend/packages/core/public/style/fonts/vdl-icon.ttf and /dev/null differ diff --git a/frontend/packages/core/public/style/fonts/vdl-icon.woff b/frontend/packages/core/public/style/fonts/vdl-icon.woff deleted file mode 100755 index 0abaaa3d4557c3be838cc12e9c46c629dc02e916..0000000000000000000000000000000000000000 Binary files a/frontend/packages/core/public/style/fonts/vdl-icon.woff and /dev/null differ diff --git a/frontend/packages/core/public/style/vdl-icon.css b/frontend/packages/core/public/style/vdl-icon.css deleted file mode 100755 index dd9cd8de7081050026f78a3db485a09ef61a8a71..0000000000000000000000000000000000000000 --- a/frontend/packages/core/public/style/vdl-icon.css +++ /dev/null @@ -1,102 +0,0 @@ -.vdl-icon { - /* use !important to prevent issues with browser extensions that change fonts */ - font-family: 'vdl-icon' !important; - speak: never; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - - /* Better Font Rendering =========== */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.icon-mute:before { - content: '\e918'; -} -.icon-volumn-low:before { - content: '\e91b'; -} -.icon-volumn:before { - content: '\e91c'; -} -.icon-pause:before { - content: '\e919'; -} -.icon-play:before { - content: '\e91a'; -} -.icon-question-circle:before { - content: '\e913'; -} -.icon-minus:before { - content: '\e914'; -} -.icon-plus:before { - content: '\e915'; -} -.icon-close:before { - content: '\e916'; -} -.icon-upload:before { - content: '\e917'; -} -.icon-zoom-out:before { - content: '\e911'; -} -.icon-zoom-in:before { - content: '\e912'; -} -.icon-refresh:before { - content: '\e90c'; -} -.icon-restore-size:before { - content: '\e90d'; -} -.icon-minimize:before { - content: '\e90e'; -} -.icon-log-axis:before { - content: '\e90f'; -} -.icon-maximize:before { - content: '\e910'; -} -.icon-chevron-down:before { - content: '\e90a'; -} -.icon-reduction:before { - content: '\e900'; -} -.icon-dimension:before { - content: '\e901'; -} -.icon-revert:before { - content: '\e902'; -} -.icon-download:before { - content: '\e903'; -} -.icon-text:before { - content: '\e904'; -} -.icon-audio:before { - content: '\e905'; -} -.icon-scalar:before { - content: '\e906'; -} -.icon-histogram:before { - content: '\e907'; -} -.icon-search:before { - content: '\e908'; -} -.icon-image:before { - content: '\e909'; -} -.icon-check-mark:before { - content: '\e90b'; -} diff --git a/frontend/packages/core/resource/histogram/index.ts b/frontend/packages/core/resource/histogram/index.ts deleted file mode 100644 index 69199c516a00d4608ac89eccf3524d11aa06ab3c..0000000000000000000000000000000000000000 --- a/frontend/packages/core/resource/histogram/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {Modes} from './types'; - -export const modes = [Modes.Offset, Modes.Overlay] as const; - -export * from './types'; -export * from './chart'; -export * from './data'; diff --git a/frontend/packages/core/resource/pr-curve/index.ts b/frontend/packages/core/resource/pr-curve/index.ts deleted file mode 100644 index c42ca2029f1fc798c1af49db6a0ba71b392608dd..0000000000000000000000000000000000000000 --- a/frontend/packages/core/resource/pr-curve/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './types'; -export * from './chart'; -export * from './data'; diff --git a/frontend/packages/core/snowpack.config.js b/frontend/packages/core/snowpack.config.js new file mode 100644 index 0000000000000000000000000000000000000000..78a3d5006e5b036778b5c4674ae3db617404716b --- /dev/null +++ b/frontend/packages/core/snowpack.config.js @@ -0,0 +1,51 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ + +require('./builder/environment'); +const mock = require('./builder/mock'); +const icons = require('./builder/icons'); +const netron = require('./builder/netron'); +const wasm = require('./builder/wasm'); + +const port = Number.parseInt(process.env.PORT || 3000, 10); +const devServer = { + port: port + 1, + host: '127.0.0.1' +}; + +module.exports = { + extends: '@snowpack/app-scripts-react', + plugins: [ + '@snowpack/plugin-dotenv', + [ + '@snowpack/plugin-run-script', + { + cmd: 'node builder/icons.js && node builder/netron.js && node builder/wasm.js', + watch: `node builder/dev-server.js --port ${devServer.port} --host ${devServer.host}`, + output: 'dashboard' + } + ] + ], + install: ['@visualdl/wasm'], + alias: { + '~': './src' + }, + proxy: { + ...[mock.pathname, icons.pathname, netron.pathname, wasm.pathname].reduce((m, pathname) => { + m[(process.env.PUBLIC_PATH || '') + pathname] = `http://${devServer.host}:${devServer.port}${pathname}`; + return m; + }, {}) + }, + devOptions: { + out: 'dist', + hostname: process.env.HOST || 'localhost', + port + }, + buildOptions: { + baseUrl: process.env.PUBLIC_PATH || '/', + clean: true + }, + installOptions: { + polyfillNode: true, + namedExports: ['file-saver'] + } +}; diff --git a/frontend/packages/core/src/App.tsx b/frontend/packages/core/src/App.tsx new file mode 100644 index 0000000000000000000000000000000000000000..8c1dc84702925f3fa8a28719d06c3468171fdf73 --- /dev/null +++ b/frontend/packages/core/src/App.tsx @@ -0,0 +1,110 @@ +import React, {FunctionComponent, Suspense, useEffect, useMemo, useState} from 'react'; +import {Redirect, Route, BrowserRouter as Router, Switch, useLocation} from 'react-router-dom'; +import {headerHeight, position, size} from '~/utils/style'; + +import BodyLoading from '~/components/BodyLoading'; +import {Helmet} from 'react-helmet'; +import NProgress from 'nprogress'; +import Navbar from '~/components/Navbar'; +import {SWRConfig} from 'swr'; +import {fetcher} from '~/utils/fetch'; +import init from '@visualdl/wasm'; +import routes from '~/routes'; +import styled from 'styled-components'; +import {useTranslation} from 'react-i18next'; + +const PUBLIC_PATH: string = import.meta.env.SNOWPACK_PUBLIC_PATH; + +const Main = styled.main` + padding-top: ${headerHeight}; +`; + +const Header = styled.header` + z-index: 10000; + + ${size(headerHeight, '100%')} + ${position('fixed', 0, 0, null, 0)} +`; + +const defaultRoute = routes.find(route => route.default); +const routers = routes.reduce[]>((m, route) => { + if (route.children) { + m.push(...route.children); + } else { + m.push(route); + } + return m; +}, []); + +const Progress: FunctionComponent = () => { + useEffect(() => { + NProgress.start(); + return () => { + NProgress.done(); + }; + }, []); + + return null; +}; + +const Telemetry: FunctionComponent = () => { + const location = useLocation(); + useEffect(() => { + globalThis._hmt.push(['_trackPageview', PUBLIC_PATH + location.pathname]); + }, [location.pathname]); + return null; +}; + +const App: FunctionComponent = () => { + const {i18n} = useTranslation(); + + const dir = useMemo(() => (i18n.language ? i18n.dir(i18n.language) : ''), [i18n]); + + const [inited, setInited] = useState(false); + useEffect(() => { + (async () => { + if (!inited) { + await init(`${PUBLIC_PATH}/wasm/visualdl.wasm`); + setInited(true); + } + })(); + }, [inited]); + + return ( +
+ + + + + {!inited ? ( + + ) : ( +
+ + +
+ +
+ }> + + + {routers.map(route => ( + + ))} + + +
+
+ )} +
+
+ ); +}; + +export default App; diff --git a/frontend/packages/core/public/images/logo.svg b/frontend/packages/core/src/assets/images/logo.svg similarity index 100% rename from frontend/packages/core/public/images/logo.svg rename to frontend/packages/core/src/assets/images/logo.svg diff --git a/frontend/packages/core/public/images/netron.png b/frontend/packages/core/src/assets/images/netron.png similarity index 100% rename from frontend/packages/core/public/images/netron.png rename to frontend/packages/core/src/assets/images/netron.png diff --git a/frontend/packages/core/components/Aside.tsx b/frontend/packages/core/src/components/Aside.tsx similarity index 100% rename from frontend/packages/core/components/Aside.tsx rename to frontend/packages/core/src/components/Aside.tsx diff --git a/frontend/packages/core/components/Audio.tsx b/frontend/packages/core/src/components/Audio.tsx similarity index 85% rename from frontend/packages/core/components/Audio.tsx rename to frontend/packages/core/src/components/Audio.tsx index e85f41aa552a017f82a75ce63b9db04151173ce9..fc91d084f16f7ff57905c954fbf1ff4816cc6537 100644 --- a/frontend/packages/core/components/Audio.tsx +++ b/frontend/packages/core/src/components/Audio.tsx @@ -24,7 +24,7 @@ import moment from 'moment'; import {saveAs} from 'file-saver'; import styled from 'styled-components'; import useRequest from '~/hooks/useRequest'; -import {useTranslation} from '~/utils/i18n'; +import {useTranslation} from 'react-i18next'; const Container = styled.div` background-color: ${primaryBackgroundColor}; @@ -230,42 +230,40 @@ const Audio = React.forwardRef( }, [volumn]); useEffect(() => { - if (process.browser) { - let p: AudioPlayer | null = null; - if (data) { - (async () => { - setDecoding(true); - onLoading?.(); - setOffset(0); - setSliderValue(0); - setDuration('00:00'); - p = new AudioPlayer({ - context: audioContext, - onplay: () => { - setPlaying(true); - startTimer(); - }, - onstop: () => { - setPlaying(false); - stopTimer(); - } - }); - const buffer = await data.data.arrayBuffer(); - await p.load(buffer, data.type != null ? mime.extension(data.type) || undefined : undefined); - setDecoding(false); - setDuration(formatDuration(p.duration)); - onLoad?.({sampleRate: p.sampleRate, duration: p.duration}); - player.current = p; - })(); - } - return () => { - if (p) { - setPlaying(false); - p.dispose(); - player.current = null; - } - }; + let p: AudioPlayer | null = null; + if (data) { + (async () => { + setDecoding(true); + onLoading?.(); + setOffset(0); + setSliderValue(0); + setDuration('00:00'); + p = new AudioPlayer({ + context: audioContext, + onplay: () => { + setPlaying(true); + startTimer(); + }, + onstop: () => { + setPlaying(false); + stopTimer(); + } + }); + const buffer = await data.data.arrayBuffer(); + await p.load(buffer, data.type != null ? mime.extension(data.type) || undefined : undefined); + setDecoding(false); + setDuration(formatDuration(p.duration)); + onLoad?.({sampleRate: p.sampleRate, duration: p.duration}); + player.current = p; + })(); } + return () => { + if (p) { + setPlaying(false); + p.dispose(); + player.current = null; + } + }; }, [data, startTimer, stopTimer, onLoading, onLoad, audioContext]); const volumnIcon = useMemo(() => { diff --git a/frontend/packages/core/src/components/BodyLoading.tsx b/frontend/packages/core/src/components/BodyLoading.tsx new file mode 100644 index 0000000000000000000000000000000000000000..6b005ae28cb29c1f252e5daae6b807579841586f --- /dev/null +++ b/frontend/packages/core/src/components/BodyLoading.tsx @@ -0,0 +1,26 @@ +import React, {FunctionComponent} from 'react'; +import {position, primaryColor, size} from '~/utils/style'; + +import HashLoader from 'react-spinners/HashLoader'; +import styled from 'styled-components'; + +const Wrapper = styled.div` + ${size('100vh', '100vw')} + ${position('fixed', 0, 0, 0, 0)} + background-color: rgba(255, 255, 255, 0.8); + display: flex; + justify-content: center; + align-items: center; + overscroll-behavior: none; + cursor: progress; +`; + +const BodyLoading: FunctionComponent = () => { + return ( + + + + ); +}; + +export default BodyLoading; diff --git a/frontend/packages/core/components/Button.tsx b/frontend/packages/core/src/components/Button.tsx similarity index 97% rename from frontend/packages/core/components/Button.tsx rename to frontend/packages/core/src/components/Button.tsx index b11254a3cb0d4f7f9c92fb0da375c4a46fdd9358..43d0263552c4631fee087afb429906642131f18b 100644 --- a/frontend/packages/core/components/Button.tsx +++ b/frontend/packages/core/src/components/Button.tsx @@ -22,6 +22,7 @@ import { transitionProps } from '~/utils/style'; +import type {Icons} from '~/components/Icon'; import RawIcon from '~/components/Icon'; import styled from 'styled-components'; @@ -85,7 +86,7 @@ const Icon = styled(RawIcon)` type ButtonProps = { rounded?: boolean; - icon?: string; + icon?: Icons; type?: colorTypes; disabled?: boolean; onClick?: () => unknown; diff --git a/frontend/packages/core/components/Chart.tsx b/frontend/packages/core/src/components/Chart.tsx similarity index 86% rename from frontend/packages/core/components/Chart.tsx rename to frontend/packages/core/src/components/Chart.tsx index 2cf4c2b9a618bd12b7a277e324e0b1937cb7fb06..c5f10cc928d0970e81a50065f6749d5860623d89 100644 --- a/frontend/packages/core/components/Chart.tsx +++ b/frontend/packages/core/src/components/Chart.tsx @@ -15,11 +15,11 @@ import { import ee from '~/utils/event'; import styled from 'styled-components'; -const Div = styled.div<{maximized?: boolean; width?: string; height?: string}>` +const Div = styled.div<{maximized?: boolean; divWidth?: string; divHeight?: string}>` ${props => size( - props.maximized ? `calc(100vh - ${headerHeight} - ${rem(40)})` : props.height || 'auto', - props.maximized ? '100%' : props.width || '100%' + props.maximized ? `calc(100vh - ${headerHeight} - ${rem(40)})` : props.divHeight || 'auto', + props.maximized ? '100%' : props.divWidth || '100%' )} background-color: ${backgroundColor}; ${sameBorder({radius: math(`${borderRadius} * 2`)})} @@ -58,8 +58,8 @@ const Chart: FunctionComponent = ({cid, width, height, return (
{children} diff --git a/frontend/packages/core/components/ChartCollapse.tsx b/frontend/packages/core/src/components/ChartCollapse.tsx similarity index 100% rename from frontend/packages/core/components/ChartCollapse.tsx rename to frontend/packages/core/src/components/ChartCollapse.tsx diff --git a/frontend/packages/core/components/ChartPage.tsx b/frontend/packages/core/src/components/ChartPage.tsx similarity index 96% rename from frontend/packages/core/components/ChartPage.tsx rename to frontend/packages/core/src/components/ChartPage.tsx index d5e3523990c5dd4fd5e069a99753ca13265148fa..bbf787f0d192f757fd17183c9b1cca3ce52a25e3 100644 --- a/frontend/packages/core/components/ChartPage.tsx +++ b/frontend/packages/core/src/components/ChartPage.tsx @@ -1,5 +1,5 @@ import React, {FunctionComponent, PropsWithChildren, useCallback, useEffect, useMemo, useState} from 'react'; -import {Trans, useTranslation} from '~/utils/i18n'; +import {Trans, useTranslation} from 'react-i18next'; import {WithStyled, backgroundColor, headerHeight, link, primaryColor, rem, textLighterColor} from '~/utils/style'; import BarLoader from 'react-spinners/BarLoader'; @@ -11,7 +11,7 @@ import groupBy from 'lodash/groupBy'; import styled from 'styled-components'; import useSearchValue from '~/hooks/useSearchValue'; -const PUBLIC_PATH = process.env.PUBLIC_PATH; +const PUBLIC_PATH: string = import.meta.env.SNOWPACK_PUBLIC_PATH; const StyledPagination = styled(Pagination)` margin-top: ${rem(20)}; @@ -131,7 +131,7 @@ const ChartPage = ({ } return 0; }), - [items] + [items] // eslint-disable-line react-hooks/exhaustive-deps ); const total = useMemo(() => Math.ceil(matchedTags.length / pageSize), [matchedTags]); @@ -173,7 +173,7 @@ const ChartPage = ({ )} ), - [withChart, loading, chartSize, t] + [withChart, loading, chartSize, t] // eslint-disable-line react-hooks/exhaustive-deps ); return ( diff --git a/frontend/packages/core/components/ChartToolbox.tsx b/frontend/packages/core/src/components/ChartToolbox.tsx similarity index 97% rename from frontend/packages/core/components/ChartToolbox.tsx rename to frontend/packages/core/src/components/ChartToolbox.tsx index eb6d5a5f68f4e97b76d7655d14eeff86492b4b82..d650c9e5beb7bc9c5b683bf2a86ba97755a9ef3c 100644 --- a/frontend/packages/core/components/ChartToolbox.tsx +++ b/frontend/packages/core/src/components/ChartToolbox.tsx @@ -13,12 +13,14 @@ import { } from '~/utils/style'; import Icon from '~/components/Icon'; +import type {Icons} from '~/components/Icon'; import Tippy from '@tippyjs/react'; import styled from 'styled-components'; const Toolbox = styled.div<{reversed?: boolean}>` font-size: ${em(16)}; line-height: 1; + height: 1em; display: flex; flex-direction: ${props => (props.reversed ? 'row-reverse' : 'row')}; align-items: center; @@ -43,7 +45,7 @@ const ToolboxItem = styled.a<{active?: boolean; reversed?: boolean}>` `; type BaseChartToolboxItem = { - icon: string; + icon: Icons; tooltip?: string; }; @@ -54,7 +56,7 @@ type NormalChartToolboxItem = { type ToggleChartToolboxItem = { toggle: true; - activeIcon?: string; + activeIcon?: Icons; activeTooltip?: string; onClick?: (value: boolean) => unknown; } & BaseChartToolboxItem; diff --git a/frontend/packages/core/components/Checkbox.tsx b/frontend/packages/core/src/components/Checkbox.tsx similarity index 100% rename from frontend/packages/core/components/Checkbox.tsx rename to frontend/packages/core/src/components/Checkbox.tsx diff --git a/frontend/packages/core/components/Content.tsx b/frontend/packages/core/src/components/Content.tsx similarity index 62% rename from frontend/packages/core/components/Content.tsx rename to frontend/packages/core/src/components/Content.tsx index a0acad009d80898d312fabb9fd354211fbb41978..ee53ad5979ec22dc0c8731a64a20f03be67025e7 100644 --- a/frontend/packages/core/components/Content.tsx +++ b/frontend/packages/core/src/components/Content.tsx @@ -1,7 +1,7 @@ import React, {FunctionComponent} from 'react'; -import {backgroundColor, contentHeight, contentMargin, headerHeight, position, primaryColor, size} from '~/utils/style'; +import {backgroundColor, contentHeight, contentMargin, headerHeight, position} from '~/utils/style'; -import HashLoader from 'react-spinners/HashLoader'; +import BodyLoading from '~/components/BodyLoading'; import styled from 'styled-components'; const Section = styled.section` @@ -23,17 +23,6 @@ const Aside = styled.aside` overflow-y: auto; `; -const Loading = styled.div` - ${size('100vh', '100vw')} - ${position('fixed', 0, 0, 0, 0)} - background-color: rgba(255, 255, 255, 0.8); - display: flex; - justify-content: center; - align-items: center; - overscroll-behavior: none; - cursor: progress; -`; - type ContentProps = { aside?: React.ReactNode; loading?: boolean; @@ -43,11 +32,7 @@ const Content: FunctionComponent = ({children, aside, loading}) =>
{children}
{aside && } - {loading && ( - - - - )} + {loading && }
); diff --git a/frontend/packages/core/components/Error.tsx b/frontend/packages/core/src/components/Error.tsx similarity index 96% rename from frontend/packages/core/components/Error.tsx rename to frontend/packages/core/src/components/Error.tsx index 402f80ff3114a6094bfd5c4ca77569b84bb63b4a..adca7e90cec13397cc03066b43a716a36c989881 100644 --- a/frontend/packages/core/components/Error.tsx +++ b/frontend/packages/core/src/components/Error.tsx @@ -1,10 +1,10 @@ import React, {FunctionComponent} from 'react'; -import {Trans, useTranslation} from '~/utils/i18n'; +import {Trans, useTranslation} from 'react-i18next'; import {WithStyled, backgroundColor, em, link, rem, size, textColor, textLightColor} from '~/utils/style'; import styled from 'styled-components'; -const PUBLIC_PATH = process.env.PUBLIC_PATH; +const PUBLIC_PATH: string = import.meta.env.SNOWPACK_PUBLIC_PATH; const Wrapper = styled.div` display: flex; diff --git a/frontend/packages/core/components/Field.tsx b/frontend/packages/core/src/components/Field.tsx similarity index 100% rename from frontend/packages/core/components/Field.tsx rename to frontend/packages/core/src/components/Field.tsx diff --git a/frontend/packages/core/components/GraphPage/Argument.tsx b/frontend/packages/core/src/components/GraphPage/Argument.tsx similarity index 97% rename from frontend/packages/core/components/GraphPage/Argument.tsx rename to frontend/packages/core/src/components/GraphPage/Argument.tsx index 6ccb67055730aeba9f57596fd4b5d6f57674efb9..86de606c962e9ef39f9654fecccf5d6cd2a12063 100644 --- a/frontend/packages/core/components/GraphPage/Argument.tsx +++ b/frontend/packages/core/src/components/GraphPage/Argument.tsx @@ -1,4 +1,4 @@ -import {Argument as ArgumentType, Property as PropertyType} from '~/resource/graph/types'; +import type {Argument as ArgumentType, Property as PropertyType} from '~/resource/graph/types'; import React, {FunctionComponent, useMemo, useState} from 'react'; import {borderColor, em, sameBorder, textLightColor, textLighterColor} from '~/utils/style'; diff --git a/frontend/packages/core/components/GraphPage/Graph.tsx b/frontend/packages/core/src/components/GraphPage/Graph.tsx similarity index 90% rename from frontend/packages/core/components/GraphPage/Graph.tsx rename to frontend/packages/core/src/components/GraphPage/Graph.tsx index 65c6ec8fda3128d393d022892e8e83ed34601e45..bdcc30fbe2eb41fb17a3b8d4b80b344075c0253a 100644 --- a/frontend/packages/core/components/GraphPage/Graph.tsx +++ b/frontend/packages/core/src/components/GraphPage/Graph.tsx @@ -1,14 +1,15 @@ -import {Documentation, Properties, SearchItem, SearchResult} from '~/resource/graph/types'; +import type {Documentation, Properties, SearchItem, SearchResult} from '~/resource/graph/types'; import React, {useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react'; import {backgroundColor, borderColor, contentHeight, position, primaryColor, rem, size} from '~/utils/style'; import ChartToolbox from '~/components/ChartToolbox'; import HashLoader from 'react-spinners/HashLoader'; +import logo from '~/assets/images/netron.png'; import styled from 'styled-components'; import {toast} from 'react-toastify'; -import {useTranslation} from '~/utils/i18n'; +import {useTranslation} from 'react-i18next'; -const PUBLIC_PATH = process.env.PUBLIC_PATH; +const PUBLIC_PATH: string = import.meta.env.SNOWPACK_PUBLIC_PATH; const toolboxHeight = rem(40); @@ -158,24 +159,20 @@ const Graph = React.forwardRef( [onRendered, onSearch, onShowModelProperties, onShowNodeProperties, onShowNodeDocumentation] ); const dispatch = useCallback((type: string, data?: unknown) => { - if (process.browser) { - iframe.current?.contentWindow?.postMessage( - { - type, - data - }, - `${window.location.protocol}//${window.location.host}` - ); - } + iframe.current?.contentWindow?.postMessage( + { + type, + data + }, + `${window.location.protocol}//${window.location.host}` + ); }, []); useEffect(() => { - if (process.browser) { - window.addEventListener('message', handler); - dispatch('ready'); - return () => { - window.removeEventListener('message', handler); - }; - } + window.addEventListener('message', handler); + dispatch('ready'); + return () => { + window.removeEventListener('message', handler); + }; }, [handler, dispatch]); useEffect(() => (ready && dispatch('change-files', files)) || undefined, [dispatch, files, ready]); @@ -256,7 +253,7 @@ const Graph = React.forwardRef(