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"