diff --git a/package.json b/package.json index 2945242a54..c4975d54c0 100644 --- a/package.json +++ b/package.json @@ -6,11 +6,17 @@ "license": "AGPL-3.0-only", "private": true, "scripts": { + "type-check": "tsc -p tsconfig.json --noEmit", "build": "NODE_ENV=production webpack --progress --config scripts/webpack/webpack.prod.js", "dev": "NODE_ENV=development webpack serve --progress --color --config scripts/webpack/webpack.dev.js" }, "devDependencies": { + "@types/history": "4.7.11", + "@types/jquery": "^3.5.13", "@types/react-dom": "^18.0.11", + "@types/react-outside-click-handler": "^1.3.1", + "@emotion/react": "^11.10.6", + "@emotion/styled": "^11.10.6", "copy-webpack-plugin": "^11.0.0", "esbuild-loader": "^3.0.1", "expose-loader": "^4.1.0", diff --git a/public/app/app.tsx b/public/app/app.tsx index 9e5d8a784d..92e095b106 100644 --- a/public/app/app.tsx +++ b/public/app/app.tsx @@ -5,12 +5,17 @@ import { Provider } from 'react-redux'; import store, { persistor } from './redux/store'; import '@webapp/../sass/profile.scss'; import '@szhsin/react-menu/dist/index.css'; +import Notifications from '@webapp/ui/Notifications'; import { SingleView } from './pages/SingleView'; -const root = ReactDOM.createRoot(document.getElementById('reactRoot')); +const container = document.getElementById('reactRoot') as HTMLElement; +const root = ReactDOM.createRoot(container); + root.render( + + ); diff --git a/public/app/hooks/loadAppNames.ts b/public/app/hooks/loadAppNames.ts new file mode 100644 index 0000000000..ca202ec814 --- /dev/null +++ b/public/app/hooks/loadAppNames.ts @@ -0,0 +1,17 @@ +import { useEffect } from 'react'; +import { useAppDispatch } from '@webapp/redux/hooks'; +import { reloadAppNames } from '@webapp/redux/reducers/continuous'; + +export function loadAppNames() { + const dispatch = useAppDispatch(); + + useEffect(() => { + async function run() { + await dispatch(reloadAppNames()); + } + + run(); + }, [dispatch]); + + return []; +} diff --git a/public/app/overrides/ExportData.tsx b/public/app/overrides/ExportData.tsx new file mode 100644 index 0000000000..6aae038d43 --- /dev/null +++ b/public/app/overrides/ExportData.tsx @@ -0,0 +1,2 @@ +import Noop from './Noop'; +export default Noop; diff --git a/public/app/overrides/Noop.tsx b/public/app/overrides/Noop.tsx new file mode 100644 index 0000000000..fbe637b2b0 --- /dev/null +++ b/public/app/overrides/Noop.tsx @@ -0,0 +1,3 @@ +export default function () { + return
I am noop!!!!!!
; +} diff --git a/public/app/overrides/TimelineChart.tsx b/public/app/overrides/TimelineChart.tsx new file mode 100644 index 0000000000..15e6e3b442 --- /dev/null +++ b/public/app/overrides/TimelineChart.tsx @@ -0,0 +1,3 @@ +export default function () { + <>; +} diff --git a/public/app/overrides/services/appNames.ts b/public/app/overrides/services/appNames.ts new file mode 100644 index 0000000000..d33483f174 --- /dev/null +++ b/public/app/overrides/services/appNames.ts @@ -0,0 +1,32 @@ +import { App, appsModel } from '@webapp/models/app'; +import { Result } from '@webapp/util/fp'; +import { z } from 'zod'; +import type { ZodError } from 'zod'; +import type { RequestError } from '@webapp/services/base'; +import { parseResponse, request } from '@webapp/services/base'; + +export interface FetchAppsError { + message?: string; +} + +const appNamesResponse = z.array(z.string()).transform((names) => { + return names.map((name) => { + return { + name, + spyName: 'unknown', + units: 'unknown', + }; + }); +}); + +export async function fetchApps(): Promise< + Result +> { + const response = await request('/pyroscope/label-values?label=__name__'); + + if (response.isOk) { + return parseResponse(response, appNamesResponse); + } + + return Result.err(response.error); +} diff --git a/public/app/pages/SingleView.tsx b/public/app/pages/SingleView.tsx index 03396998c0..c879d24d6f 100644 --- a/public/app/pages/SingleView.tsx +++ b/public/app/pages/SingleView.tsx @@ -1,3 +1,8 @@ import ContinuousSingleView from '@webapp/pages/ContinuousSingleView'; +import { loadAppNames } from '../hooks/loadAppNames'; -export { ContinuousSingleView as SingleView }; +export function SingleView() { + loadAppNames(); + + return ; +} diff --git a/scripts/webpack/webpack.common.js b/scripts/webpack/webpack.common.js index 3a1e9e48c1..f05c3bdbfb 100644 --- a/scripts/webpack/webpack.common.js +++ b/scripts/webpack/webpack.common.js @@ -30,17 +30,49 @@ module.exports = { modules: ['node_modules', path.resolve('public')], // TODO: unify with tsconfig.json + // When using TsconfigPathsPlugin, paths overrides don't work + // For example, setting a) '@webapp/*' and b) '@webapp/components/ExportData' + // Would end up ignoring b) alias: { + // Specific Component overrides + '@webapp/components/ExportData': path.resolve( + __dirname, + '../../public/app/overrides/ExportData' + ), + '@webapp/services/apps': path.resolve( + __dirname, + '../../public/app/overrides/services/appNames' + ), + + // Common + '@pyroscope/webapp': path.resolve( + __dirname, + '../../node_modules/pyroscope-oss/webapp' + ), + '@pyroscope/flamegraph': path.resolve( + __dirname, + '../../node_modules/pyroscope-oss/packages/pyroscope-flamegraph' + ), + '@pyroscope/models': path.resolve( + __dirname, + '../../node_modules/pyroscope-oss/packages/pyroscope-models' + ), + + '@webapp': path.resolve( + __dirname, + '../../node_modules/pyroscope-oss/webapp/javascript' + ), + // Dependencies ...deps, }, plugins: [ // Use same alias from tsconfig.json - new TsconfigPathsPlugin({ - logLevel: 'info', - // TODO: figure out why it could not use the baseUrl from tsconfig.json - baseUrl: path.resolve(__dirname, '../../'), - }), + // new TsconfigPathsPlugin({ + // logLevel: 'info', + // // TODO: figure out why it could not use the baseUrl from tsconfig.json + // baseUrl: path.resolve(__dirname, '../../'), + // }), ], }, ignoreWarnings: [/export .* was not found in/], diff --git a/scripts/webpack/webpack.dev.js b/scripts/webpack/webpack.dev.js index 6a522ae82f..777e8599df 100644 --- a/scripts/webpack/webpack.dev.js +++ b/scripts/webpack/webpack.dev.js @@ -6,6 +6,9 @@ module.exports = merge(common, { mode: 'development', devServer: { port: 4040, + proxy: { + '/pyroscope': 'http://localhost:4100', + }, }, optimization: { runtimeChunk: 'single', diff --git a/tsconfig.json b/tsconfig.json index 8004c1b582..87048305cf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,9 +4,12 @@ "plugins": [{ "name": "typescript-plugin-css-modules" }], "paths": { "@pyroscope/webapp/*": ["./node_modules/pyroscope-oss/webapp/*"], - "@webapp/*": ["./node_modules/pyroscope-oss/webapp/javascript/*"], + "@webapp/redux/*": ["./node_modules/pyroscope-oss/webapp/javascript/redux/*"], "@pyroscope/flamegraph/*": ["./node_modules/pyroscope-oss/packages/pyroscope-flamegraph/*"], - "@pyroscope/models/*": ["./node_modules/pyroscope-oss/packages/pyroscope-models/*"] + "@pyroscope/models/*": ["./node_modules/pyroscope-oss/packages/pyroscope-models/*"], + "@webapp/components/ExportData": ["./public/app/overrides/ExportData"], + "@webapp/services/apps": ["./public/app/overrides/services/appNames"], + "@webapp/*": ["./node_modules/pyroscope-oss/webapp/javascript/*"] }, "target": "es5", "lib": [ @@ -31,9 +34,9 @@ "strictNullChecks": true }, "include": [ - "node_modules/pyroscope-oss/lib/", - "node_modules/pyroscope-oss/webapp/javascript/types", - "src" + "./node_modules/pyroscope-oss/lib/", + "./node_modules/pyroscope-oss/webapp/javascript/types", + "public" ] } diff --git a/yarn.lock b/yarn.lock index 1b5dc728c7..e374366808 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1162,7 +1162,7 @@ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f" integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== -"@emotion/react@^11.10.4": +"@emotion/react@^11.10.4", "@emotion/react@^11.10.6": version "11.10.6" resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.6.tgz#dbe5e650ab0f3b1d2e592e6ab1e006e75fd9ac11" integrity sha512-6HT8jBmcSkfzO7mc+N1L9uwvOnlcGoix8Zn7srt+9ga0MjREo6lRpuVX0kzo6Jp6oTqDhREOFsygN6Ew4fEQbw== @@ -1192,7 +1192,7 @@ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.1.tgz#0767e0305230e894897cadb6c8df2c51e61a6c2c" integrity sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA== -"@emotion/styled@^11.10.4": +"@emotion/styled@^11.10.4", "@emotion/styled@^11.10.6": version "11.10.6" resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.6.tgz#d886afdc51ef4d66c787ebde848f3cc8b117ebba" integrity sha512-OXtBzOmDSJo5Q0AFemHCfl+bUueT8BIcPSxu0EGTpGk6DmI5dnhSzQANm1e1ze0YZL7TDyAyy6s/b/zmGOS3Og== @@ -2733,7 +2733,7 @@ dependencies: history "*" -"@types/history@^4.7.11": +"@types/history@4.7.11", "@types/history@^4.7.11": version "4.7.11" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64" integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== @@ -2766,6 +2766,13 @@ "@types/through" "*" rxjs "^7.2.0" +"@types/jquery@^3.5.13": + version "3.5.16" + resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.5.16.tgz#632131baf30951915b0317d48c98e9890bdf051d" + integrity sha512-bsI7y4ZgeMkmpG9OM710RRzDFp+w4P1RGiIt30C1mSBT+ExCleeh4HObwgArnDFELmRrOpXgSYN9VF1hj+f1lw== + dependencies: + "@types/sizzle" "*" + "@types/js-levenshtein@^1.1.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/js-levenshtein/-/js-levenshtein-1.1.1.tgz#ba05426a43f9e4e30b631941e0aa17bf0c890ed5" @@ -2847,6 +2854,13 @@ dependencies: "@types/react" "*" +"@types/react-outside-click-handler@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/react-outside-click-handler/-/react-outside-click-handler-1.3.1.tgz#e4772ba550e1a548468203194d2615d8f06acdf9" + integrity sha512-0BNan5zIIDyO5k9LFSG+60ZxQ/0wf+LTF9BJx3oOUdOaJlZk6RCe52jRB75mlvLLJx2YLa61+NidOwBfptWMKw== + dependencies: + "@types/react" "*" + "@types/react-redux@^7.1.20": version "7.1.25" resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.25.tgz#de841631205b24f9dfb4967dd4a7901e048f9a88" @@ -2936,6 +2950,11 @@ dependencies: "@types/node" "*" +"@types/sizzle@*": + version "2.3.3" + resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.3.tgz#ff5e2f1902969d305225a047c8a0fd5c915cebef" + integrity sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ== + "@types/sockjs@^0.3.33": version "0.3.33" resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f"