@grafana/create-plugin 5.3.8-canary.1080.86cb597.0 → 5.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +2 -2
  3. package/templates/app/src/components/App/App.test.tsx +3 -3
  4. package/templates/app/src/components/App/App.tsx +15 -10
  5. package/templates/app/src/components/AppConfig/AppConfig.test.tsx +1 -1
  6. package/templates/app/src/components/AppConfig/AppConfig.tsx +3 -1
  7. package/templates/app/src/module.tsx +26 -0
  8. package/templates/app/src/pages/PageFour.tsx +3 -1
  9. package/templates/app/src/pages/PageOne.tsx +3 -1
  10. package/templates/app/src/pages/PageThree.tsx +3 -1
  11. package/templates/app/src/pages/PageTwo.tsx +3 -1
  12. package/templates/common/.config/jest-setup.js +3 -3
  13. package/templates/common/_package.json +1 -1
  14. package/templates/scenes-app/src/components/App/App.tsx +9 -9
  15. package/templates/scenes-app/src/components/AppConfig/AppConfig.tsx +4 -2
  16. package/templates/scenes-app/src/components/Routes/Routes.tsx +5 -5
  17. package/templates/scenes-app/src/module.tsx +26 -0
  18. package/templates/scenes-app/src/pages/HelloWorld/HelloWorld.tsx +3 -1
  19. package/templates/scenes-app/src/pages/Home/Home.tsx +4 -1
  20. package/templates/scenes-app/src/pages/WithDrilldown/WithDrilldown.tsx +3 -1
  21. package/templates/scenes-app/src/pages/WithTabs/WithTabs.tsx +3 -1
  22. package/templates/app/src/components/App/index.tsx +0 -1
  23. package/templates/app/src/components/AppConfig/index.tsx +0 -1
  24. package/templates/app/src/module.ts +0 -10
  25. package/templates/app/src/pages/index.tsx +0 -4
  26. package/templates/scenes-app/src/components/App/index.tsx +0 -1
  27. package/templates/scenes-app/src/components/AppConfig/index.tsx +0 -1
  28. package/templates/scenes-app/src/components/Routes/index.tsx +0 -1
  29. package/templates/scenes-app/src/module.ts +0 -10
  30. package/templates/scenes-app/src/pages/HelloWorld/index.tsx +0 -1
  31. package/templates/scenes-app/src/pages/Home/index.tsx +0 -1
  32. package/templates/scenes-app/src/pages/WithDrilldown/index.tsx +0 -1
  33. package/templates/scenes-app/src/pages/WithTabs/index.tsx +0 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ # v5.3.8 (Thu Sep 05 2024)
2
+
3
+ #### 🐛 Bug Fix
4
+
5
+ - Create Plugin: Code split scaffolded apps [#1072](https://github.com/grafana/plugin-tools/pull/1072) ([@jackw](https://github.com/jackw))
6
+
7
+ #### Authors: 1
8
+
9
+ - Jack Westbrook ([@jackw](https://github.com/jackw))
10
+
11
+ ---
12
+
1
13
  # v5.3.7 (Fri Aug 30 2024)
2
14
 
3
15
  #### 🐛 Bug Fix
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grafana/create-plugin",
3
- "version": "5.3.8-canary.1080.86cb597.0",
3
+ "version": "5.3.8",
4
4
  "repository": {
5
5
  "directory": "packages/create-plugin",
6
6
  "url": "https://github.com/grafana/plugin-tools"
@@ -87,5 +87,5 @@
87
87
  "engines": {
88
88
  "node": ">=20"
89
89
  },
90
- "gitHead": "86cb5973144e4be53b365c72da54aadee3fe44f4"
90
+ "gitHead": "cdc6abf8bf0cb3210e1f5433e6d4cd011d74e816"
91
91
  }
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { BrowserRouter } from 'react-router-dom';
3
3
  import { AppRootProps, PluginType } from '@grafana/data';
4
4
  import { render, screen } from '@testing-library/react';
5
- import { App } from './App';
5
+ import App from './App';
6
6
 
7
7
  describe('Components/App', () => {
8
8
  let props: AppRootProps;
@@ -25,13 +25,13 @@ describe('Components/App', () => {
25
25
  } as unknown as AppRootProps;
26
26
  });
27
27
 
28
- test('renders without an error"', () => {
28
+ test('renders without an error"', async () => {
29
29
  render(
30
30
  <BrowserRouter>
31
31
  <App {...props} />
32
32
  </BrowserRouter>
33
33
  );
34
34
 
35
- expect(screen.queryByText(/this is page one./i)).toBeInTheDocument();
35
+ expect(await screen.findByText(/this is page one./i)).toBeInTheDocument();
36
36
  });
37
37
  });
@@ -2,19 +2,24 @@ import React from 'react';
2
2
  import { Route, Routes } from 'react-router-dom';
3
3
  import { AppRootProps } from '@grafana/data';
4
4
  import { ROUTES } from '../../constants';
5
- import { PageFour, PageOne, PageThree, PageTwo } from '../../pages';
5
+ const PageOne = React.lazy(() => import('../../pages/PageOne'));
6
+ const PageTwo = React.lazy(() => import('../../pages/PageTwo'));
7
+ const PageThree = React.lazy(() => import('../../pages/PageThree'));
8
+ const PageFour = React.lazy(() => import('../../pages/PageFour'));
6
9
 
7
- export function App(props: AppRootProps) {
10
+ function App(props: AppRootProps) {
8
11
  return (
9
- <Routes>
10
- <Route path={ROUTES.Two} element={<PageTwo />} />
11
- <Route path={`${ROUTES.Three}/:id?`} element={<PageThree />} />
12
+ <Routes>
13
+ <Route path={ROUTES.Two} element={<PageTwo />} />
14
+ <Route path={`${ROUTES.Three}/:id?`} element={<PageThree />} />
12
15
 
13
- {/* Full-width page (this page will have no side navigation) */}
14
- <Route path={ROUTES.Four} element={<PageFour />} />
16
+ {/* Full-width page (this page will have no side navigation) */}
17
+ <Route path={ROUTES.Four} element={<PageFour />} />
15
18
 
16
- {/* Default page */}
17
- <Route path="*" element={<PageOne />} />
18
- </Routes>
19
+ {/* Default page */}
20
+ <Route path="*" element={<PageOne />} />
21
+ </Routes>
19
22
  );
20
23
  }
24
+
25
+ export default App;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { render, screen } from '@testing-library/react';
3
3
  import { PluginType } from '@grafana/data';
4
- import { AppConfig, AppConfigProps } from './AppConfig';
4
+ import AppConfig, { AppConfigProps } from './AppConfig';
5
5
  import { testIds } from 'components/testIds';
6
6
 
7
7
  describe('Components/AppConfig', () => {
@@ -21,7 +21,7 @@ type State = {
21
21
 
22
22
  export interface AppConfigProps extends PluginConfigPageProps<AppPluginMeta<AppPluginSettings>> {}
23
23
 
24
- export const AppConfig = ({ plugin }: AppConfigProps) => {
24
+ const AppConfig = ({ plugin }: AppConfigProps) => {
25
25
  const s = useStyles2(getStyles);
26
26
  const { enabled, pinned, jsonData, secureJsonFields } = plugin.meta;
27
27
  const [state, setState] = useState<State>({
@@ -110,6 +110,8 @@ export const AppConfig = ({ plugin }: AppConfigProps) => {
110
110
  );
111
111
  };
112
112
 
113
+ export default AppConfig;
114
+
113
115
  const getStyles = (theme: GrafanaTheme2) => ({
114
116
  colorWeak: css`
115
117
  color: ${theme.colors.text.secondary};
@@ -0,0 +1,26 @@
1
+ import React, { Suspense, lazy } from 'react';
2
+ import { AppPlugin, type AppRootProps } from '@grafana/data';
3
+ import { LoadingPlaceholder } from '@grafana/ui';
4
+ import type { AppConfigProps } from './components/AppConfig/AppConfig';
5
+
6
+ const LazyApp = lazy(() => import('./components/App/App'));
7
+ const LazyAppConfig = lazy(() => import('./components/AppConfig/AppConfig'));
8
+
9
+ const App = (props: AppRootProps) => (
10
+ <Suspense fallback={<LoadingPlaceholder text="" />}>
11
+ <LazyApp {...props} />
12
+ </Suspense>
13
+ );
14
+
15
+ const AppConfig = (props: AppConfigProps) => (
16
+ <Suspense fallback={<LoadingPlaceholder text="" />}>
17
+ <LazyAppConfig {...props} />
18
+ </Suspense>
19
+ );
20
+
21
+ export const plugin = new AppPlugin<{}>().setRootPage(App).addConfigPage({
22
+ title: 'Configuration',
23
+ icon: 'cog',
24
+ body: AppConfig,
25
+ id: 'configuration',
26
+ });
@@ -7,7 +7,7 @@ import { prefixRoute } from '../utils/utils.routing';
7
7
  import { testIds } from '../components/testIds';
8
8
  import { PluginPage } from '@grafana/runtime';
9
9
 
10
- export function PageFour() {
10
+ function PageFour() {
11
11
  const s = useStyles2(getStyles);
12
12
 
13
13
  return (
@@ -24,6 +24,8 @@ export function PageFour() {
24
24
  );
25
25
  }
26
26
 
27
+ export default PageFour;
28
+
27
29
  const getStyles = (theme: GrafanaTheme2) => ({
28
30
  page: css`
29
31
  padding: ${theme.spacing(3)};
@@ -7,7 +7,7 @@ import { ROUTES } from '../constants';
7
7
  import { testIds } from '../components/testIds';
8
8
  import { PluginPage } from '@grafana/runtime';
9
9
 
10
- export function PageOne() {
10
+ function PageOne() {
11
11
  const s = useStyles2(getStyles);
12
12
 
13
13
  return (
@@ -24,6 +24,8 @@ export function PageOne() {
24
24
  );
25
25
  }
26
26
 
27
+ export default PageOne;
28
+
27
29
  const getStyles = (theme: GrafanaTheme2) => ({
28
30
  marginTop: css`
29
31
  margin-top: ${theme.spacing(2)};
@@ -8,7 +8,7 @@ import { ROUTES } from '../constants';
8
8
  import { testIds } from '../components/testIds';
9
9
  import { PluginPage } from '@grafana/runtime';
10
10
 
11
- export function PageThree() {
11
+ function PageThree() {
12
12
  const s = useStyles2(getStyles);
13
13
  const { id } = useParams<{ id: string }>();
14
14
 
@@ -39,6 +39,8 @@ export function PageThree() {
39
39
  );
40
40
  }
41
41
 
42
+ export default PageThree;
43
+
42
44
  const getStyles = (theme: GrafanaTheme2) => ({
43
45
  link: css`
44
46
  color: ${theme.colors.text.link};
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { testIds } from '../components/testIds';
3
3
  import { PluginPage } from '@grafana/runtime';
4
4
 
5
- export function PageTwo() {
5
+ function PageTwo() {
6
6
  return (
7
7
  <PluginPage>
8
8
  <div data-testid={testIds.pageTwo.container}>
@@ -11,3 +11,5 @@ export function PageTwo() {
11
11
  </PluginPage>
12
12
  );
13
13
  }
14
+
15
+ export default PageTwo;
@@ -7,13 +7,13 @@
7
7
 
8
8
  import '@testing-library/jest-dom';
9
9
  import { TextEncoder, TextDecoder } from 'util';
10
-
10
+
11
11
  Object.assign(global, { TextDecoder, TextEncoder });
12
12
 
13
13
  // https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
14
14
  Object.defineProperty(global, 'matchMedia', {
15
15
  writable: true,
16
- value: jest.fn().mockImplementation((query) => ({
16
+ value: (query) => ({
17
17
  matches: false,
18
18
  media: query,
19
19
  onchange: null,
@@ -22,7 +22,7 @@ Object.defineProperty(global, 'matchMedia', {
22
22
  addEventListener: jest.fn(),
23
23
  removeEventListener: jest.fn(),
24
24
  dispatchEvent: jest.fn(),
25
- })),
25
+ }),
26
26
  });
27
27
 
28
28
  HTMLCanvasElement.prototype.getContext = () => {};
@@ -69,7 +69,7 @@
69
69
  "@grafana/runtime": "^11.2.0",
70
70
  "@grafana/ui": "^11.2.0",
71
71
  "@grafana/schema": "^10.4.0",{{#if_eq pluginType "scenesapp"}}
72
- "@grafana/scenes": "^5.11.1",{{/if_eq}}
72
+ "@grafana/scenes": "^5.10.1",{{/if_eq}}
73
73
  "react": "18.2.0",
74
74
  "react-dom": "18.2.0",{{#if isAppType}}
75
75
  "react-router-dom": "^{{ reactRouterVersion }}",
@@ -1,14 +1,14 @@
1
1
  import React from 'react';
2
2
  import { AppRootProps } from '@grafana/data';
3
3
  import { PluginPropsContext } from '../../utils/utils.plugin';
4
- import { Routes } from '../Routes';
4
+ import { Routes } from '../Routes/Routes';
5
5
 
6
- export class App extends React.PureComponent<AppRootProps> {
7
- render() {
8
- return (
9
- <PluginPropsContext.Provider value={this.props}>
10
- <Routes />
11
- </PluginPropsContext.Provider>
12
- );
13
- }
6
+ function App(props: AppRootProps) {
7
+ return (
8
+ <PluginPropsContext.Provider value={props}>
9
+ <Routes />
10
+ </PluginPropsContext.Provider>
11
+ );
14
12
  }
13
+
14
+ export default App;
@@ -22,9 +22,9 @@ type State = {
22
22
  apiKey: string;
23
23
  };
24
24
 
25
- interface Props extends PluginConfigPageProps<AppPluginMeta<JsonData>> {}
25
+ export interface AppConfigProps extends PluginConfigPageProps<AppPluginMeta<JsonData>> {}
26
26
 
27
- export const AppConfig = ({ plugin }: Props) => {
27
+ const AppConfig = ({ plugin }: AppConfigProps) => {
28
28
  const s = useStyles2(getStyles);
29
29
  const { enabled, pinned, jsonData } = plugin.meta;
30
30
  const [state, setState] = useState<State>({
@@ -114,6 +114,8 @@ export const AppConfig = ({ plugin }: Props) => {
114
114
  );
115
115
  };
116
116
 
117
+ export default AppConfig;
118
+
117
119
  const getStyles = (theme: GrafanaTheme2) => ({
118
120
  colorWeak: css`
119
121
  color: ${theme.colors.text.secondary};
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
2
  import { Redirect, Route, Switch } from 'react-router-dom';
3
- import { HomePage } from '../../pages/Home';
4
- import { PageWithTabs } from '../../pages/WithTabs';
5
- import { WithDrilldown } from '../../pages/WithDrilldown';
6
3
  import { prefixRoute } from '../../utils/utils.routing';
7
4
  import { ROUTES } from '../../constants';
8
- import { HelloWorldPluginPage } from '../../pages/HelloWorld';
5
+ const HomePage = React.lazy(() => import('../../pages/Home/Home'));
6
+ const PageWithTabs = React.lazy(() => import('../../pages/WithTabs/WithTabs'));
7
+ const WithDrilldown = React.lazy(() => import('../../pages/WithDrilldown/WithDrilldown'));
8
+ const HelloWorld = React.lazy(() => import('../../pages/HelloWorld/HelloWorld'));
9
9
 
10
10
  export const Routes = () => {
11
11
  return (
@@ -13,7 +13,7 @@ export const Routes = () => {
13
13
  <Route path={prefixRoute(`${ROUTES.WithTabs}`)} component={PageWithTabs} />
14
14
  <Route path={prefixRoute(`${ROUTES.WithDrilldown}`)} component={WithDrilldown} />
15
15
  <Route path={prefixRoute(`${ROUTES.Home}`)} component={HomePage} />
16
- <Route path={prefixRoute(`${ROUTES.HelloWorld}`)} component={HelloWorldPluginPage} />
16
+ <Route path={prefixRoute(`${ROUTES.HelloWorld}`)} component={HelloWorld} />
17
17
  <Redirect to={prefixRoute(ROUTES.Home)} />
18
18
  </Switch>
19
19
  );
@@ -0,0 +1,26 @@
1
+ import React, { Suspense, lazy } from 'react';
2
+ import { AppPlugin, type AppRootProps } from '@grafana/data';
3
+ import { LoadingPlaceholder } from '@grafana/ui';
4
+ import type { AppConfigProps } from './components/AppConfig/AppConfig';
5
+
6
+ const LazyApp = lazy(() => import('./components/App/App'));
7
+ const LazyAppConfig = lazy(() => import('./components/AppConfig/AppConfig'));
8
+
9
+ const App = (props: AppRootProps) => (
10
+ <Suspense fallback={<LoadingPlaceholder text="" />}>
11
+ <LazyApp {...props} />
12
+ </Suspense>
13
+ );
14
+
15
+ const AppConfig = (props: AppConfigProps) => (
16
+ <Suspense fallback={<LoadingPlaceholder text="" />}>
17
+ <LazyAppConfig {...props} />
18
+ </Suspense>
19
+ );
20
+
21
+ export const plugin = new AppPlugin<{}>().setRootPage(App).addConfigPage({
22
+ title: 'Configuration',
23
+ icon: 'cog',
24
+ body: AppConfig,
25
+ id: 'configuration',
26
+ });
@@ -1,8 +1,10 @@
1
1
  import React from 'react';
2
2
  import { getScene } from './helloWorldScene';
3
3
 
4
- export const HelloWorldPluginPage = () => {
4
+ const HelloWorld = () => {
5
5
  const scene = getScene();
6
6
 
7
7
  return <scene.Component model={scene} />;
8
8
  };
9
+
10
+ export default HelloWorld;
@@ -22,7 +22,8 @@ const getScene = () => {
22
22
  ],
23
23
  });
24
24
  };
25
- export const HomePage = () => {
25
+
26
+ const HomePage = () => {
26
27
  const scene = useMemo(() => getScene(), []);
27
28
 
28
29
  return (
@@ -47,3 +48,5 @@ export const HomePage = () => {
47
48
  </>
48
49
  );
49
50
  };
51
+
52
+ export default HomePage;
@@ -93,8 +93,10 @@ const getDrilldownsAppScene = () => {
93
93
  });
94
94
  };
95
95
 
96
- export const WithDrilldown = () => {
96
+ const WithDrilldown = () => {
97
97
  const scene = useMemo(() => getDrilldownsAppScene(), []);
98
98
 
99
99
  return <scene.Component model={scene} />;
100
100
  };
101
+
102
+ export default WithDrilldown;
@@ -38,8 +38,10 @@ const getScene = () =>
38
38
  ],
39
39
  });
40
40
 
41
- export const PageWithTabs = () => {
41
+ const PageWithTabs = () => {
42
42
  const scene = useMemo(() => getScene(), []);
43
43
 
44
44
  return <scene.Component model={scene} />;
45
45
  };
46
+
47
+ export default PageWithTabs;
@@ -1 +0,0 @@
1
- export * from './App';
@@ -1 +0,0 @@
1
- export * from './AppConfig';
@@ -1,10 +0,0 @@
1
- import { AppPlugin } from '@grafana/data';
2
- import { App } from './components/App';
3
- import { AppConfig } from './components/AppConfig';
4
-
5
- export const plugin = new AppPlugin<{}>().setRootPage(App).addConfigPage({
6
- title: 'Configuration',
7
- icon: 'cog',
8
- body: AppConfig,
9
- id: 'configuration',
10
- });
@@ -1,4 +0,0 @@
1
- export { PageFour } from './PageFour';
2
- export { PageOne } from './PageOne';
3
- export { PageThree } from './PageThree';
4
- export { PageTwo } from './PageTwo';
@@ -1 +0,0 @@
1
- export * from './App';
@@ -1 +0,0 @@
1
- export * from './AppConfig';
@@ -1 +0,0 @@
1
- export * from './Routes';
@@ -1,10 +0,0 @@
1
- import { AppPlugin } from '@grafana/data';
2
- import { App } from './components/App';
3
- import { AppConfig } from './components/AppConfig';
4
-
5
- export const plugin = new AppPlugin<{}>().setRootPage(App).addConfigPage({
6
- title: 'Configuration',
7
- icon: 'cog',
8
- body: AppConfig,
9
- id: 'configuration',
10
- });
@@ -1 +0,0 @@
1
- export * from './HelloWorld';
@@ -1 +0,0 @@
1
- export * from './Home';
@@ -1 +0,0 @@
1
- export * from './WithDrilldown';
@@ -1 +0,0 @@
1
- export * from './WithTabs';