@grafana/scenes 0.0.19 → 0.0.20

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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
  <img
3
- src="./docs/img/grafana_icon.svg"
3
+ src="../../docs/img/grafana_icon.svg"
4
4
  alt="Grafana Logo"
5
5
  width="100px"
6
6
  padding="40px"
@@ -9,27 +9,37 @@
9
9
  <p>Create dashboard-like experiences in Grafana app plugins</p>
10
10
  </div>
11
11
 
12
- ## Important notice
12
+ ## About @grafana/scenes
13
13
 
14
- @grafana/scenes is in its early days. We do not encourage anyone to use it in plugins yet. APIs can (and probably will) change significantly in the months to come.
14
+ @grafana/scenes provides a framework to build dashboard-like experiences within Grafana's app plugins. It comes with the following features:
15
+
16
+ - Versatile layout options.
17
+ - Grafana panels rendering.
18
+ - Querying & transformations support
19
+ - Multiple time ranges support.
20
+ - Template variables support.
21
+ - URL sync.
22
+ - ... and more.
15
23
 
16
24
  ## Development
17
25
 
18
- ### Working with Grafana
26
+ To work on @grafana/scenes SDK, please follow the guides below.
27
+
28
+ ### Setting up local version of @grafana/scenes with local Grafana instance
19
29
 
20
- @grafana/scenes does not come with dedicated playground yet. It is currently possible to run Scene demos using Grafana. To do that, the following setup is required.
30
+ It is currently possible to run Scene demos using Grafana. To do that, the following setup is required.
21
31
 
22
- 1. Clone @grafana/scenes repository.
32
+ 1. Clone [Grafana Scenes repository](https://github.com/grafana/grafana/).
23
33
  1. Clone [Grafana](https://github.com/grafana/grafana/) repository and follow [Development guide](https://github.com/grafana/grafana/blob/main/contribute/developer-guide.md#developer-guide).
24
34
  1. Setup env variable `GRAFANA_PATH` to point to your Grafana repository directory, `export GRAFANA_PATH=<path-to-grafana-directory>`
25
- 1. From @grafana/scenes directory run `./scripts/dev.sh`. This will compile @grafana/scenes with watch mode enabled and link it to your Grafana.
35
+ 1. From Grafana Scenes root directory run `./scripts/dev.sh`. This will compile @grafana/scenes with watch mode enabled and link it to your Grafana.
26
36
  1. From Grafana directory run `yarn install`.
27
37
  1. Start Grafana with `scenes` [feature toggle enabled](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#feature_toggles)
28
38
  1. Navigate to `http://localhost:3000/scenes` to explore demo scenes.
29
39
 
30
- ### Working with Grafana app plugin
40
+ ### Setting up local version of @grafana/scenes with app plugin
31
41
 
32
- 1. Run `YARN_IGNORE_PATH=1 yarn link` from @grafana/scenes directory.
33
- 1. Run `yarn dev` from @grafana/scenes directory.
42
+ 1. Run `YARN_IGNORE_PATH=1 yarn link` from `packages/scenes` directory.
43
+ 1. Run `yarn dev` from `packages/scenes` directory.
34
44
  1. Run `yarn link @grafana/scenes` from app plugin directory.
35
45
  1. Start app plugin development server.
@@ -1,10 +1,7 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { Switch, Route, useRouteMatch } from 'react-router-dom';
3
- import { PluginPage } from '@grafana/runtime';
1
+ import React from 'react';
2
+ import { Switch, Route } from 'react-router-dom';
4
3
  import { SceneObjectBase } from '../../core/SceneObjectBase.js';
5
- import { useAppQueryParams, getLinkUrlWithAppUrlState } from './utils.js';
6
4
 
7
- const sceneCache = /* @__PURE__ */ new Map();
8
5
  class SceneApp extends SceneObjectBase {
9
6
  }
10
7
  SceneApp.Component = ({ model }) => {
@@ -20,145 +17,6 @@ SceneApp.Component = ({ model }) => {
20
17
  }
21
18
  })));
22
19
  };
23
- class SceneAppPage extends SceneObjectBase {
24
- }
25
- SceneAppPage.Component = SceneAppPageRenderer;
26
- function SceneAppPageRenderer({ model }) {
27
- var _a;
28
- const { tabs, drilldowns, url, routePath } = model.state;
29
- const routes = [];
30
- if (tabs) {
31
- for (const page2 of tabs) {
32
- routes.push(
33
- /* @__PURE__ */ React.createElement(Route, {
34
- exact: true,
35
- key: page2.state.url,
36
- path: (_a = page2.state.routePath) != null ? _a : page2.state.url,
37
- render: () => {
38
- return /* @__PURE__ */ React.createElement(page2.Component, {
39
- model: page2
40
- });
41
- }
42
- })
43
- );
44
- if (page2.state.drilldowns) {
45
- for (const drilldown of page2.state.drilldowns) {
46
- routes.push(
47
- /* @__PURE__ */ React.createElement(Route, {
48
- exact: false,
49
- key: drilldown.routePath,
50
- path: drilldown.routePath,
51
- render: () => {
52
- return /* @__PURE__ */ React.createElement(SceneAppDrilldownViewRender, {
53
- drilldown,
54
- parent: page2
55
- });
56
- }
57
- })
58
- );
59
- }
60
- }
61
- }
62
- return /* @__PURE__ */ React.createElement(Switch, null, routes);
63
- }
64
- if (drilldowns) {
65
- for (const drilldown of drilldowns) {
66
- routes.push(
67
- /* @__PURE__ */ React.createElement(Route, {
68
- key: drilldown.routePath,
69
- exact: false,
70
- path: drilldown.routePath,
71
- render: () => {
72
- return /* @__PURE__ */ React.createElement(SceneAppDrilldownViewRender, {
73
- drilldown,
74
- parent: model
75
- });
76
- }
77
- })
78
- );
79
- }
80
- }
81
- let page = /* @__PURE__ */ React.createElement(ScenePageRenderer, {
82
- page: model
83
- });
84
- if (model.parent instanceof SceneAppPage) {
85
- page = /* @__PURE__ */ React.createElement(ScenePageRenderer, {
86
- page: model.parent,
87
- activeTab: model,
88
- tabs: model.parent.state.tabs
89
- });
90
- }
91
- return /* @__PURE__ */ React.createElement(Switch, null, /* @__PURE__ */ React.createElement(Route, {
92
- key: url,
93
- exact: true,
94
- path: routePath != null ? routePath : url,
95
- render: () => {
96
- return page;
97
- }
98
- }), routes);
99
- }
100
- function ScenePageRenderer({ page, tabs, activeTab }) {
101
- const [isInitialized, setIsInitialized] = useState(false);
102
- const params = useAppQueryParams();
103
- const routeMatch = useRouteMatch();
104
- let scene = sceneCache.get(routeMatch.url);
105
- if (!scene) {
106
- scene = activeTab ? activeTab.state.getScene(routeMatch) : page.state.getScene(routeMatch);
107
- sceneCache.set(routeMatch.url, scene);
108
- }
109
- useEffect(() => {
110
- if (!isInitialized && scene) {
111
- scene.initUrlSync();
112
- setIsInitialized(true);
113
- }
114
- }, [isInitialized, scene]);
115
- if (!isInitialized) {
116
- return null;
117
- }
118
- const pageNav = {
119
- text: page.state.title,
120
- subTitle: page.state.subTitle,
121
- url: getLinkUrlWithAppUrlState(page.state.url, params, page.state.preserveUrlKeys),
122
- hideFromBreadcrumbs: page.state.hideFromBreadcrumbs,
123
- parentItem: getParentBreadcrumbs(page.state.getParentPage ? page.state.getParentPage() : page.parent, params)
124
- };
125
- if (tabs) {
126
- pageNav.children = tabs.map((tab) => {
127
- return {
128
- text: tab.state.title,
129
- active: activeTab === tab,
130
- url: getLinkUrlWithAppUrlState(tab.state.url, params, tab.state.preserveUrlKeys),
131
- parentItem: pageNav
132
- };
133
- });
134
- }
135
- return /* @__PURE__ */ React.createElement(PluginPage, {
136
- pageNav
137
- }, /* @__PURE__ */ React.createElement(scene.Component, {
138
- model: scene
139
- }));
140
- }
141
- function SceneAppDrilldownViewRender(props) {
142
- const routeMatch = useRouteMatch();
143
- const scene = props.drilldown.getPage(routeMatch, props.parent);
144
- return /* @__PURE__ */ React.createElement(scene.Component, {
145
- model: scene
146
- });
147
- }
148
- function getParentBreadcrumbs(parent, params) {
149
- if (parent instanceof SceneAppPage) {
150
- return {
151
- text: parent.state.title,
152
- url: getLinkUrlWithAppUrlState(parent.state.url, params, parent.state.preserveUrlKeys),
153
- hideFromBreadcrumbs: parent.state.hideFromBreadcrumbs,
154
- parentItem: getParentBreadcrumbs(
155
- parent.state.getParentPage ? parent.state.getParentPage() : parent.parent,
156
- params
157
- )
158
- };
159
- }
160
- return void 0;
161
- }
162
20
 
163
- export { SceneApp, SceneAppDrilldownViewRender, SceneAppPage };
21
+ export { SceneApp };
164
22
  //# sourceMappingURL=SceneApp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SceneApp.js","sources":["../../../../src/components/SceneApp/SceneApp.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react';\nimport { Route, Switch, useRouteMatch } from 'react-router-dom';\n\nimport { NavModelItem, UrlQueryMap } from '@grafana/data';\nimport { PluginPage } from '@grafana/runtime';\n\nimport { SceneComponentProps, SceneObject, SceneObjectStatePlain } from '../../core/types';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { getLinkUrlWithAppUrlState, useAppQueryParams } from './utils';\nimport { EmbeddedScene } from '../EmbeddedScene';\n\nconst sceneCache = new Map<string, EmbeddedScene>();\n\nexport interface SceneAppState extends SceneObjectStatePlain {\n // Array of SceneAppPage objects that are considered app's top level pages\n pages: SceneAppPage[];\n}\n\nexport interface SceneRouteMatch<Params extends { [K in keyof Params]?: string } = {}> {\n params: Params;\n isExact: boolean;\n path: string;\n url: string;\n}\n\nexport interface SceneAppRoute {\n path: string;\n page?: SceneAppPage;\n drilldown?: SceneAppDrilldownView;\n}\n\n/**\n * Responsible for top level pages routing\n */\nexport class SceneApp extends SceneObjectBase<SceneAppState> {\n public static Component = ({ model }: SceneComponentProps<SceneApp>) => {\n const { pages } = model.useState();\n\n return (\n <Switch>\n {pages.map((page) => (\n <Route\n key={page.state.url}\n exact={false}\n path={page.state.url}\n render={() => {\n return page && <page.Component model={page} />;\n }}\n ></Route>\n ))}\n </Switch>\n );\n };\n}\n\nexport interface SceneAppPageState extends SceneObjectStatePlain {\n title: string;\n subTitle?: string;\n // Use to provide page absolute URL, i.e. /app/overview\n url: string;\n // Use to provide parametrized page URL, i.e. /app/overview/:clusterId\n routePath?: string;\n // Whether or not page should be visible in the breadcrumbs path\n hideFromBreadcrumbs?: boolean;\n // Array of SceneAppPage objects that are used as page tabs displayed on top of the page\n tabs?: SceneAppPage[];\n // Function that returns a scene object for the page\n getScene: (routeMatch: SceneRouteMatch) => EmbeddedScene;\n // Array of scenes used for drilldown views\n drilldowns?: SceneAppDrilldownView[];\n // Function that returns a parent page object, used to create breadcrumbs structure\n getParentPage?: () => SceneAppPage;\n // Array of query params that will be preserved in breadcrumb and page tab links, i.e. ['from', 'to', 'var-datacenter',...]\n preserveUrlKeys?: string[];\n}\n\n/**\n * Responsible for page's drilldown & tabs routing\n */\nexport class SceneAppPage extends SceneObjectBase<SceneAppPageState> {\n public static Component = SceneAppPageRenderer;\n}\n\nfunction SceneAppPageRenderer({ model }: SceneComponentProps<SceneAppPage>) {\n const { tabs, drilldowns, url, routePath } = model.state;\n const routes: React.ReactNode[] = [];\n\n if (tabs) {\n for (const page of tabs) {\n routes.push(\n <Route\n exact={true}\n key={page.state.url}\n path={page.state.routePath ?? page.state.url}\n render={() => {\n return <page.Component model={page} />;\n }}\n ></Route>\n );\n\n if (page.state.drilldowns) {\n for (const drilldown of page.state.drilldowns) {\n routes.push(\n <Route\n exact={false}\n key={drilldown.routePath}\n path={drilldown.routePath}\n render={() => {\n return <SceneAppDrilldownViewRender drilldown={drilldown} parent={page} />;\n }}\n ></Route>\n );\n }\n }\n }\n\n return <Switch>{routes}</Switch>;\n }\n\n if (drilldowns) {\n for (const drilldown of drilldowns) {\n routes.push(\n <Route\n key={drilldown.routePath}\n exact={false}\n path={drilldown.routePath}\n render={() => {\n return <SceneAppDrilldownViewRender drilldown={drilldown} parent={model} />;\n }}\n ></Route>\n );\n }\n }\n\n let page = <ScenePageRenderer page={model} />;\n\n // if parent is a SceneAppPage we are a tab\n if (model.parent instanceof SceneAppPage) {\n page = <ScenePageRenderer page={model.parent} activeTab={model} tabs={model.parent.state.tabs} />;\n }\n\n return (\n <Switch>\n {/* page route */}\n <Route\n key={url}\n exact={true}\n path={routePath ?? url}\n render={() => {\n return page;\n }}\n ></Route>\n\n {/* drilldown routes */}\n {routes}\n </Switch>\n );\n}\n\ninterface ScenePageRenderProps {\n page: SceneAppPage;\n tabs?: SceneAppPage[];\n activeTab?: SceneAppPage;\n}\n\nfunction ScenePageRenderer({ page, tabs, activeTab }: ScenePageRenderProps) {\n /**\n * We use this flag to make sure the URL sync is enabled before the scene is actually rendered.\n */\n const [isInitialized, setIsInitialized] = useState(false);\n const params = useAppQueryParams();\n const routeMatch = useRouteMatch();\n\n let scene = sceneCache.get(routeMatch!.url);\n if (!scene) {\n // If we are rendering a tab, we need to get the scene f rom the tab, otherwise, use page's scene\n scene = activeTab ? activeTab.state.getScene(routeMatch) : page.state.getScene(routeMatch);\n sceneCache.set(routeMatch!.url, scene);\n }\n\n useEffect(() => {\n // Before rendering scene components, we are making sure the URL sync is enabled for.\n if (!isInitialized && scene) {\n scene.initUrlSync();\n setIsInitialized(true);\n }\n }, [isInitialized, scene]);\n\n if (!isInitialized) {\n return null;\n }\n\n const pageNav: NavModelItem = {\n text: page.state.title,\n subTitle: page.state.subTitle,\n url: getLinkUrlWithAppUrlState(page.state.url, params, page.state.preserveUrlKeys),\n hideFromBreadcrumbs: page.state.hideFromBreadcrumbs,\n parentItem: getParentBreadcrumbs(page.state.getParentPage ? page.state.getParentPage() : page.parent, params),\n };\n\n if (tabs) {\n pageNav.children = tabs.map((tab) => {\n return {\n text: tab.state.title,\n active: activeTab === tab,\n url: getLinkUrlWithAppUrlState(tab.state.url, params, tab.state.preserveUrlKeys),\n parentItem: pageNav,\n };\n });\n }\n\n return (\n <PluginPage pageNav={pageNav} /*hideFooter={true}*/>\n <scene.Component model={scene} />\n </PluginPage>\n );\n}\n\nexport interface SceneAppDrilldownView {\n // Use to provide parametrized drilldown URL, i.e. /app/clusters/:clusterId\n routePath: string;\n // Function that returns a page object for a given drilldown route match. Use parent to configure drilldown view parent SceneAppPage via getParentPage method.\n getPage: (routeMatch: SceneRouteMatch<any>, parent: SceneAppPage) => SceneAppPage;\n}\n\nexport function SceneAppDrilldownViewRender(props: { drilldown: SceneAppDrilldownView; parent: SceneAppPage }) {\n const routeMatch = useRouteMatch();\n const scene = props.drilldown.getPage(routeMatch, props.parent);\n return <scene.Component model={scene} />;\n}\n\nfunction getParentBreadcrumbs(parent: SceneObject | undefined, params: UrlQueryMap): NavModelItem | undefined {\n if (parent instanceof SceneAppPage) {\n return {\n text: parent.state.title,\n url: getLinkUrlWithAppUrlState(parent.state.url, params, parent.state.preserveUrlKeys),\n hideFromBreadcrumbs: parent.state.hideFromBreadcrumbs,\n parentItem: getParentBreadcrumbs(\n parent.state.getParentPage ? parent.state.getParentPage() : parent.parent,\n params\n ),\n };\n }\n\n return undefined;\n}\n"],"names":["page"],"mappings":"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"}
1
+ {"version":3,"file":"SceneApp.js","sources":["../../../../src/components/SceneApp/SceneApp.tsx"],"sourcesContent":["import React from 'react';\nimport { Route, Switch } from 'react-router-dom';\n\nimport { SceneComponentProps } from '../../core/types';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneAppState } from './types';\n\n/**\n * Responsible for top level pages routing\n */\nexport class SceneApp extends SceneObjectBase<SceneAppState> {\n public static Component = ({ model }: SceneComponentProps<SceneApp>) => {\n const { pages } = model.useState();\n\n return (\n <Switch>\n {pages.map((page) => (\n <Route\n key={page.state.url}\n exact={false}\n path={page.state.url}\n render={() => {\n return page && <page.Component model={page} />;\n }}\n ></Route>\n ))}\n </Switch>\n );\n };\n}\n"],"names":[],"mappings":";;;;AAUO,MAAM,iBAAiB,eAA+B,CAAA;AAmB7D,CAAA;AAnBa,QAAA,CACG,SAAY,GAAA,CAAC,EAAE,KAAA,EAA2C,KAAA;AACtE,EAAA,MAAM,EAAE,KAAA,EAAU,GAAA,KAAA,CAAM,QAAS,EAAA,CAAA;AAEjC,EAAA,2CACG,MACE,EAAA,IAAA,EAAA,KAAA,CAAM,GAAI,CAAA,CAAC,yBACT,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,IACC,GAAA,EAAK,KAAK,KAAM,CAAA,GAAA;AAAA,IAChB,KAAO,EAAA,KAAA;AAAA,IACP,IAAA,EAAM,KAAK,KAAM,CAAA,GAAA;AAAA,IACjB,QAAQ,MAAM;AACZ,MAAO,OAAA,IAAA,oBAAS,KAAA,CAAA,aAAA,CAAA,IAAA,CAAK,SAAL,EAAA;AAAA,QAAe,KAAO,EAAA,IAAA;AAAA,OAAM,CAAA,CAAA;AAAA,KAC9C;AAAA,GACD,CACF,CACH,CAAA,CAAA;AAEJ,CAAA;;;;"}
@@ -0,0 +1,151 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { PluginPage } from '@grafana/runtime';
3
+ import { Route, Switch, useRouteMatch } from 'react-router-dom';
4
+ import { SceneObjectBase } from '../../core/SceneObjectBase.js';
5
+ import { useAppQueryParams, getLinkUrlWithAppUrlState } from './utils.js';
6
+
7
+ const sceneCache = /* @__PURE__ */ new Map();
8
+ class SceneAppPage extends SceneObjectBase {
9
+ }
10
+ SceneAppPage.Component = SceneAppPageRenderer;
11
+ function SceneAppPageRenderer({ model }) {
12
+ var _a;
13
+ const { tabs, drilldowns, url, routePath } = model.state;
14
+ const routes = [];
15
+ if (tabs) {
16
+ for (const page2 of tabs) {
17
+ routes.push(
18
+ /* @__PURE__ */ React.createElement(Route, {
19
+ exact: true,
20
+ key: page2.state.url,
21
+ path: (_a = page2.state.routePath) != null ? _a : page2.state.url,
22
+ render: () => {
23
+ return /* @__PURE__ */ React.createElement(page2.Component, {
24
+ model: page2
25
+ });
26
+ }
27
+ })
28
+ );
29
+ if (page2.state.drilldowns) {
30
+ for (const drilldown of page2.state.drilldowns) {
31
+ routes.push(
32
+ /* @__PURE__ */ React.createElement(Route, {
33
+ exact: false,
34
+ key: drilldown.routePath,
35
+ path: drilldown.routePath,
36
+ render: () => {
37
+ return /* @__PURE__ */ React.createElement(SceneAppDrilldownViewRender, {
38
+ drilldown,
39
+ parent: page2
40
+ });
41
+ }
42
+ })
43
+ );
44
+ }
45
+ }
46
+ }
47
+ return /* @__PURE__ */ React.createElement(Switch, null, routes);
48
+ }
49
+ if (drilldowns) {
50
+ for (const drilldown of drilldowns) {
51
+ routes.push(
52
+ /* @__PURE__ */ React.createElement(Route, {
53
+ key: drilldown.routePath,
54
+ exact: false,
55
+ path: drilldown.routePath,
56
+ render: () => {
57
+ return /* @__PURE__ */ React.createElement(SceneAppDrilldownViewRender, {
58
+ drilldown,
59
+ parent: model
60
+ });
61
+ }
62
+ })
63
+ );
64
+ }
65
+ }
66
+ let page = /* @__PURE__ */ React.createElement(ScenePageRenderer, {
67
+ page: model
68
+ });
69
+ if (model.parent instanceof SceneAppPage) {
70
+ page = /* @__PURE__ */ React.createElement(ScenePageRenderer, {
71
+ page: model.parent,
72
+ activeTab: model,
73
+ tabs: model.parent.state.tabs
74
+ });
75
+ }
76
+ return /* @__PURE__ */ React.createElement(Switch, null, /* @__PURE__ */ React.createElement(Route, {
77
+ key: url,
78
+ exact: true,
79
+ path: routePath != null ? routePath : url,
80
+ render: () => {
81
+ return page;
82
+ }
83
+ }), routes);
84
+ }
85
+ function ScenePageRenderer({ page, tabs, activeTab }) {
86
+ const [isInitialized, setIsInitialized] = useState(false);
87
+ const params = useAppQueryParams();
88
+ const routeMatch = useRouteMatch();
89
+ let scene = sceneCache.get(routeMatch.url);
90
+ if (!scene) {
91
+ scene = activeTab ? activeTab.state.getScene(routeMatch) : page.state.getScene(routeMatch);
92
+ sceneCache.set(routeMatch.url, scene);
93
+ }
94
+ useEffect(() => {
95
+ if (!isInitialized && scene) {
96
+ scene.initUrlSync();
97
+ setIsInitialized(true);
98
+ }
99
+ }, [isInitialized, scene]);
100
+ if (!isInitialized) {
101
+ return null;
102
+ }
103
+ const pageNav = {
104
+ text: page.state.title,
105
+ subTitle: page.state.subTitle,
106
+ img: page.state.titleImg,
107
+ icon: page.state.titleIcon,
108
+ url: getLinkUrlWithAppUrlState(page.state.url, params, page.state.preserveUrlKeys),
109
+ hideFromBreadcrumbs: page.state.hideFromBreadcrumbs,
110
+ parentItem: getParentBreadcrumbs(page.state.getParentPage ? page.state.getParentPage() : page.parent, params)
111
+ };
112
+ if (tabs) {
113
+ pageNav.children = tabs.map((tab) => {
114
+ return {
115
+ text: tab.state.title,
116
+ active: activeTab === tab,
117
+ url: getLinkUrlWithAppUrlState(tab.state.url, params, tab.state.preserveUrlKeys),
118
+ parentItem: pageNav
119
+ };
120
+ });
121
+ }
122
+ return /* @__PURE__ */ React.createElement(PluginPage, {
123
+ pageNav
124
+ }, /* @__PURE__ */ React.createElement(scene.Component, {
125
+ model: scene
126
+ }));
127
+ }
128
+ function SceneAppDrilldownViewRender(props) {
129
+ const routeMatch = useRouteMatch();
130
+ const scene = props.drilldown.getPage(routeMatch, props.parent);
131
+ return /* @__PURE__ */ React.createElement(scene.Component, {
132
+ model: scene
133
+ });
134
+ }
135
+ function getParentBreadcrumbs(parent, params) {
136
+ if (parent instanceof SceneAppPage) {
137
+ return {
138
+ text: parent.state.title,
139
+ url: getLinkUrlWithAppUrlState(parent.state.url, params, parent.state.preserveUrlKeys),
140
+ hideFromBreadcrumbs: parent.state.hideFromBreadcrumbs,
141
+ parentItem: getParentBreadcrumbs(
142
+ parent.state.getParentPage ? parent.state.getParentPage() : parent.parent,
143
+ params
144
+ )
145
+ };
146
+ }
147
+ return void 0;
148
+ }
149
+
150
+ export { SceneAppPage };
151
+ //# sourceMappingURL=SceneAppPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SceneAppPage.js","sources":["../../../../src/components/SceneApp/SceneAppPage.tsx"],"sourcesContent":["import React, { useState, useEffect } from 'react';\nimport { NavModelItem, UrlQueryMap } from '@grafana/data';\nimport { PluginPage } from '@grafana/runtime';\nimport { Route, Switch, useRouteMatch } from 'react-router-dom';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneComponentProps, SceneObject } from '../../core/types';\nimport { EmbeddedScene } from '../EmbeddedScene';\nimport { SceneAppDrilldownView, SceneAppPageLike, SceneAppPageState } from './types';\nimport { getLinkUrlWithAppUrlState, useAppQueryParams } from './utils';\n\nconst sceneCache = new Map<string, EmbeddedScene>();\n\n/**\n * Responsible for page's drilldown & tabs routing\n */\nexport class SceneAppPage extends SceneObjectBase<SceneAppPageState> {\n public static Component = SceneAppPageRenderer;\n}\n\nfunction SceneAppPageRenderer({ model }: SceneComponentProps<SceneAppPage>) {\n const { tabs, drilldowns, url, routePath } = model.state;\n const routes: React.ReactNode[] = [];\n\n if (tabs) {\n for (const page of tabs) {\n routes.push(\n <Route\n exact={true}\n key={page.state.url}\n path={page.state.routePath ?? page.state.url}\n render={() => {\n return <page.Component model={page} />;\n }}\n ></Route>\n );\n\n if (page.state.drilldowns) {\n for (const drilldown of page.state.drilldowns) {\n routes.push(\n <Route\n exact={false}\n key={drilldown.routePath}\n path={drilldown.routePath}\n render={() => {\n return <SceneAppDrilldownViewRender drilldown={drilldown} parent={page} />;\n }}\n ></Route>\n );\n }\n }\n }\n\n return <Switch>{routes}</Switch>;\n }\n\n if (drilldowns) {\n for (const drilldown of drilldowns) {\n routes.push(\n <Route\n key={drilldown.routePath}\n exact={false}\n path={drilldown.routePath}\n render={() => {\n return <SceneAppDrilldownViewRender drilldown={drilldown} parent={model} />;\n }}\n ></Route>\n );\n }\n }\n\n let page = <ScenePageRenderer page={model} />;\n\n // if parent is a SceneAppPage we are a tab\n if (model.parent instanceof SceneAppPage) {\n page = <ScenePageRenderer page={model.parent} activeTab={model} tabs={model.parent.state.tabs} />;\n }\n\n return (\n <Switch>\n {/* page route */}\n <Route\n key={url}\n exact={true}\n path={routePath ?? url}\n render={() => {\n return page;\n }}\n ></Route>\n\n {/* drilldown routes */}\n {routes}\n </Switch>\n );\n}\n\ninterface ScenePageRenderProps {\n page: SceneAppPageLike;\n tabs?: SceneAppPageLike[];\n activeTab?: SceneAppPage;\n}\n\nfunction ScenePageRenderer({ page, tabs, activeTab }: ScenePageRenderProps) {\n /**\n * We use this flag to make sure the URL sync is enabled before the scene is actually rendered.\n */\n const [isInitialized, setIsInitialized] = useState(false);\n const params = useAppQueryParams();\n const routeMatch = useRouteMatch();\n\n let scene = sceneCache.get(routeMatch!.url);\n if (!scene) {\n // If we are rendering a tab, we need to get the scene f rom the tab, otherwise, use page's scene\n scene = activeTab ? activeTab.state.getScene(routeMatch) : page.state.getScene(routeMatch);\n sceneCache.set(routeMatch!.url, scene);\n }\n\n useEffect(() => {\n // Before rendering scene components, we are making sure the URL sync is enabled for.\n if (!isInitialized && scene) {\n scene.initUrlSync();\n setIsInitialized(true);\n }\n }, [isInitialized, scene]);\n\n if (!isInitialized) {\n return null;\n }\n\n const pageNav: NavModelItem = {\n text: page.state.title,\n subTitle: page.state.subTitle,\n img: page.state.titleImg,\n icon: page.state.titleIcon,\n url: getLinkUrlWithAppUrlState(page.state.url, params, page.state.preserveUrlKeys),\n hideFromBreadcrumbs: page.state.hideFromBreadcrumbs,\n parentItem: getParentBreadcrumbs(page.state.getParentPage ? page.state.getParentPage() : page.parent, params),\n };\n\n if (tabs) {\n pageNav.children = tabs.map((tab) => {\n return {\n text: tab.state.title,\n active: activeTab === tab,\n url: getLinkUrlWithAppUrlState(tab.state.url, params, tab.state.preserveUrlKeys),\n parentItem: pageNav,\n };\n });\n }\n\n return (\n <PluginPage pageNav={pageNav}>\n <scene.Component model={scene} />\n </PluginPage>\n );\n}\n\nfunction SceneAppDrilldownViewRender(props: { drilldown: SceneAppDrilldownView; parent: SceneAppPageLike }) {\n const routeMatch = useRouteMatch();\n const scene = props.drilldown.getPage(routeMatch, props.parent);\n return <scene.Component model={scene} />;\n}\n\nfunction getParentBreadcrumbs(parent: SceneObject | undefined, params: UrlQueryMap): NavModelItem | undefined {\n if (parent instanceof SceneAppPage) {\n return {\n text: parent.state.title,\n url: getLinkUrlWithAppUrlState(parent.state.url, params, parent.state.preserveUrlKeys),\n hideFromBreadcrumbs: parent.state.hideFromBreadcrumbs,\n parentItem: getParentBreadcrumbs(\n parent.state.getParentPage ? parent.state.getParentPage() : parent.parent,\n params\n ),\n };\n }\n\n return undefined;\n}\n"],"names":["page"],"mappings":"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"}
@@ -22,7 +22,8 @@ function FlexLayoutRenderer({ model, isEditing }) {
22
22
  display: "flex",
23
23
  gap: "8px",
24
24
  flexWrap: wrap,
25
- alignContent: "baseline"
25
+ alignContent: "baseline",
26
+ minHeight: 0
26
27
  };
27
28
  return /* @__PURE__ */ React.createElement("div", {
28
29
  style
@@ -1 +1 @@
1
- {"version":3,"file":"SceneFlexLayout.js","sources":["../../../../src/components/layout/SceneFlexLayout.tsx"],"sourcesContent":["import React, { CSSProperties } from 'react';\n\nimport { Field, RadioButtonGroup } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport {\n SceneComponentProps,\n SceneLayoutChild,\n SceneLayoutState,\n SceneLayoutChildOptions,\n SceneLayout,\n} from '../../core/types';\n\nexport type FlexLayoutDirection = 'column' | 'row';\n\ninterface SceneFlexLayoutState extends SceneLayoutState {\n direction?: FlexLayoutDirection;\n wrap?: CSSProperties['flexWrap'];\n}\n\nexport class SceneFlexLayout extends SceneObjectBase<SceneFlexLayoutState> implements SceneLayout {\n public static Component = FlexLayoutRenderer;\n public static Editor = FlexLayoutEditor;\n\n public toggleDirection() {\n this.setState({\n direction: this.state.direction === 'row' ? 'column' : 'row',\n });\n }\n\n public isDraggable(): boolean {\n return false;\n }\n}\n\nfunction FlexLayoutRenderer({ model, isEditing }: SceneComponentProps<SceneFlexLayout>) {\n const { direction = 'row', children, wrap } = model.useState();\n\n const style: CSSProperties = {\n flexGrow: 1,\n flexDirection: direction,\n display: 'flex',\n gap: '8px',\n flexWrap: wrap,\n alignContent: 'baseline',\n };\n\n return (\n <div style={style}>\n {children.map((item) => (\n <FlexLayoutChildComponent key={item.state.key} item={item} direction={direction} isEditing={isEditing} />\n ))}\n </div>\n );\n}\n\nfunction FlexLayoutChildComponent({\n item,\n direction,\n isEditing,\n}: {\n item: SceneLayoutChild;\n direction: FlexLayoutDirection;\n isEditing?: boolean;\n}) {\n const { placement } = item.useState();\n\n return (\n <div style={getItemStyles(direction, placement)}>\n <item.Component model={item} isEditing={isEditing} />\n </div>\n );\n}\n\nfunction getItemStyles(direction: FlexLayoutDirection, layout: SceneLayoutChildOptions = {}) {\n const { xSizing = 'fill', ySizing = 'fill' } = layout;\n\n const style: CSSProperties = {\n display: 'flex',\n flexDirection: direction,\n minWidth: layout.minWidth,\n minHeight: layout.minHeight,\n position: 'relative',\n };\n\n if (direction === 'column') {\n if (layout.height) {\n style.height = layout.height;\n } else {\n style.flexGrow = ySizing === 'fill' ? 1 : 0;\n }\n\n if (layout.width) {\n style.width = layout.width;\n } else {\n style.alignSelf = xSizing === 'fill' ? 'stretch' : 'flex-start';\n }\n } else {\n if (layout.height) {\n style.height = layout.height;\n } else {\n style.alignSelf = ySizing === 'fill' ? 'stretch' : 'flex-start';\n }\n\n if (layout.width) {\n style.width = layout.width;\n } else {\n style.flexGrow = xSizing === 'fill' ? 1 : 0;\n }\n }\n\n return style;\n}\n\nfunction FlexLayoutEditor({ model }: SceneComponentProps<SceneFlexLayout>) {\n const { direction = 'row' } = model.useState();\n const options = [\n { icon: 'arrow-right', value: 'row' },\n { icon: 'arrow-down', value: 'column' },\n ];\n\n return (\n <Field label=\"Direction\">\n <RadioButtonGroup\n options={options}\n value={direction}\n onChange={(value) => model.setState({ direction: value as FlexLayoutDirection })}\n />\n </Field>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SceneFlexLayout.js","sources":["../../../../src/components/layout/SceneFlexLayout.tsx"],"sourcesContent":["import React, { CSSProperties } from 'react';\n\nimport { Field, RadioButtonGroup } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport {\n SceneComponentProps,\n SceneLayoutChild,\n SceneLayoutState,\n SceneLayoutChildOptions,\n SceneLayout,\n} from '../../core/types';\n\nexport type FlexLayoutDirection = 'column' | 'row';\n\ninterface SceneFlexLayoutState extends SceneLayoutState {\n direction?: FlexLayoutDirection;\n wrap?: CSSProperties['flexWrap'];\n}\n\nexport class SceneFlexLayout extends SceneObjectBase<SceneFlexLayoutState> implements SceneLayout {\n public static Component = FlexLayoutRenderer;\n public static Editor = FlexLayoutEditor;\n\n public toggleDirection() {\n this.setState({\n direction: this.state.direction === 'row' ? 'column' : 'row',\n });\n }\n\n public isDraggable(): boolean {\n return false;\n }\n}\n\nfunction FlexLayoutRenderer({ model, isEditing }: SceneComponentProps<SceneFlexLayout>) {\n const { direction = 'row', children, wrap } = model.useState();\n const style: CSSProperties = {\n flexGrow: 1,\n flexDirection: direction,\n display: 'flex',\n gap: '8px',\n flexWrap: wrap,\n alignContent: 'baseline',\n minHeight: 0,\n };\n\n return (\n <div style={style}>\n {children.map((item) => (\n <FlexLayoutChildComponent key={item.state.key} item={item} direction={direction} isEditing={isEditing} />\n ))}\n </div>\n );\n}\n\nfunction FlexLayoutChildComponent({\n item,\n direction,\n isEditing,\n}: {\n item: SceneLayoutChild;\n direction: FlexLayoutDirection;\n isEditing?: boolean;\n}) {\n const { placement } = item.useState();\n\n return (\n <div style={getItemStyles(direction, placement)}>\n <item.Component model={item} isEditing={isEditing} />\n </div>\n );\n}\n\nfunction getItemStyles(direction: FlexLayoutDirection, layout: SceneLayoutChildOptions = {}) {\n const { xSizing = 'fill', ySizing = 'fill' } = layout;\n\n const style: CSSProperties = {\n display: 'flex',\n flexDirection: direction,\n minWidth: layout.minWidth,\n minHeight: layout.minHeight,\n position: 'relative',\n };\n\n if (direction === 'column') {\n if (layout.height) {\n style.height = layout.height;\n } else {\n style.flexGrow = ySizing === 'fill' ? 1 : 0;\n }\n\n if (layout.width) {\n style.width = layout.width;\n } else {\n style.alignSelf = xSizing === 'fill' ? 'stretch' : 'flex-start';\n }\n } else {\n if (layout.height) {\n style.height = layout.height;\n } else {\n style.alignSelf = ySizing === 'fill' ? 'stretch' : 'flex-start';\n }\n\n if (layout.width) {\n style.width = layout.width;\n } else {\n style.flexGrow = xSizing === 'fill' ? 1 : 0;\n }\n }\n\n return style;\n}\n\nfunction FlexLayoutEditor({ model }: SceneComponentProps<SceneFlexLayout>) {\n const { direction = 'row' } = model.useState();\n const options = [\n { icon: 'arrow-right', value: 'row' },\n { icon: 'arrow-down', value: 'column' },\n ];\n\n return (\n <Field label=\"Direction\">\n <RadioButtonGroup\n options={options}\n value={direction}\n onChange={(value) => model.setState({ direction: value as FlexLayoutDirection })}\n />\n </Field>\n );\n}\n"],"names":[],"mappings":"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"}
package/dist/esm/index.js CHANGED
@@ -32,5 +32,6 @@ export { SceneControlsSpacer } from './components/SceneControlsSpacer.js';
32
32
  export { SceneFlexLayout } from './components/layout/SceneFlexLayout.js';
33
33
  export { SceneGridLayout } from './components/layout/SceneGridLayout.js';
34
34
  export { SceneGridRow } from './components/layout/SceneGridRow.js';
35
- export { SceneApp, SceneAppPage } from './components/SceneApp/SceneApp.js';
35
+ export { SceneApp } from './components/SceneApp/SceneApp.js';
36
+ export { SceneAppPage } from './components/SceneApp/SceneAppPage.js';
36
37
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"formatRegistry.js","sources":["../../../../src/variables/interpolation/formatRegistry.ts"],"sourcesContent":["import { isArray, map, replace } from 'lodash';\n\nimport { dateTime, Registry, RegistryItem, textUtil, escapeRegex } from '@grafana/data';\nimport { VariableType } from '@grafana/schema';\n\nimport { VariableValue, VariableValueSingle } from '../types';\nimport { ALL_VARIABLE_VALUE } from '../constants';\n\nexport interface FormatRegistryItem extends RegistryItem {\n formatter(value: VariableValue, args: string[], variable: FormatVariable): string;\n}\n\n/**\n * Slimmed down version of the SceneVariable interface so that it only contains what the formatters actually use.\n * This is useful as we have some implementations of this interface that does not need to be full scene objects.\n * For example ScopedVarsVariable and LegacyVariableWrapper.\n */\nexport interface FormatVariable {\n state: {\n name: string;\n type: VariableType | string;\n };\n\n getValue(fieldPath?: string): VariableValue | undefined | null;\n getValueText?(fieldPath?: string): string;\n}\n\nexport enum FormatRegistryID {\n lucene = 'lucene',\n raw = 'raw',\n regex = 'regex',\n pipe = 'pipe',\n distributed = 'distributed',\n csv = 'csv',\n html = 'html',\n json = 'json',\n percentEncode = 'percentencode',\n singleQuote = 'singlequote',\n doubleQuote = 'doublequote',\n sqlString = 'sqlstring',\n date = 'date',\n glob = 'glob',\n text = 'text',\n queryParam = 'queryparam',\n}\n\nexport const formatRegistry = new Registry<FormatRegistryItem>(() => {\n const formats: FormatRegistryItem[] = [\n {\n id: FormatRegistryID.lucene,\n name: 'Lucene',\n description: 'Values are lucene escaped and multi-valued variables generate an OR expression',\n formatter: (value) => {\n if (typeof value === 'string') {\n return luceneEscape(value);\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return '__empty__';\n }\n const quotedValues = map(value, (val: string) => {\n return '\"' + luceneEscape(val) + '\"';\n });\n return '(' + quotedValues.join(' OR ') + ')';\n } else {\n return luceneEscape(`${value}`);\n }\n },\n },\n {\n id: FormatRegistryID.raw,\n name: 'raw',\n description: 'Keep value as is',\n formatter: (value) => String(value),\n },\n {\n id: FormatRegistryID.regex,\n name: 'Regex',\n description: 'Values are regex escaped and multi-valued variables generate a (<value>|<value>) expression',\n formatter: (value) => {\n if (typeof value === 'string') {\n return escapeRegex(value);\n }\n\n if (Array.isArray(value)) {\n const escapedValues = value.map((item) => {\n if (typeof item === 'string') {\n return escapeRegex(item);\n } else {\n return escapeRegex(String(item));\n }\n });\n\n if (escapedValues.length === 1) {\n return escapedValues[0];\n }\n\n return '(' + escapedValues.join('|') + ')';\n }\n\n return escapeRegex(`${value}`);\n },\n },\n {\n id: FormatRegistryID.pipe,\n name: 'Pipe',\n description: 'Values are separated by | character',\n formatter: (value) => {\n if (typeof value === 'string') {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.join('|');\n }\n\n return `${value}`;\n },\n },\n {\n id: FormatRegistryID.distributed,\n name: 'Distributed',\n description: 'Multiple values are formatted like variable=value',\n formatter: (value, args, variable) => {\n if (typeof value === 'string') {\n return value;\n }\n\n if (Array.isArray(value)) {\n value = map(value, (val: string, index: number) => {\n if (index !== 0) {\n return variable.state.name + '=' + val;\n } else {\n return val;\n }\n });\n\n return value.join(',');\n }\n\n return `${value}`;\n },\n },\n {\n id: FormatRegistryID.csv,\n name: 'Csv',\n description: 'Comma-separated values',\n formatter: (value) => {\n if (typeof value === 'string') {\n return value;\n }\n\n if (isArray(value)) {\n return value.join(',');\n }\n\n return String(value);\n },\n },\n {\n id: FormatRegistryID.html,\n name: 'HTML',\n description: 'HTML escaping of values',\n formatter: (value) => {\n if (typeof value === 'string') {\n return textUtil.escapeHtml(value);\n }\n\n if (isArray(value)) {\n return textUtil.escapeHtml(value.join(', '));\n }\n\n return textUtil.escapeHtml(String(value));\n },\n },\n {\n id: FormatRegistryID.json,\n name: 'JSON',\n description: 'JSON stringify value',\n formatter: (value) => {\n if (typeof value === 'string') {\n return value\n }\n return JSON.stringify(value);\n },\n },\n {\n id: FormatRegistryID.percentEncode,\n name: 'Percent encode',\n description: 'Useful for URL escaping values',\n formatter: (value) => {\n // like glob, but url escaped\n if (isArray(value)) {\n return encodeURIComponentStrict('{' + value.join(',') + '}');\n }\n\n return encodeURIComponentStrict(value);\n },\n },\n {\n id: FormatRegistryID.singleQuote,\n name: 'Single quote',\n description: 'Single quoted values',\n formatter: (value) => {\n // escape single quotes with backslash\n const regExp = new RegExp(`'`, 'g');\n\n if (isArray(value)) {\n return map(value, (v: string) => `'${replace(v, regExp, `\\\\'`)}'`).join(',');\n }\n\n let strVal = typeof value === 'string' ? value : String(value);\n return `'${replace(strVal, regExp, `\\\\'`)}'`;\n },\n },\n {\n id: FormatRegistryID.doubleQuote,\n name: 'Double quote',\n description: 'Double quoted values',\n formatter: (value) => {\n // escape double quotes with backslash\n const regExp = new RegExp('\"', 'g');\n if (isArray(value)) {\n return map(value, (v: string) => `\"${replace(v, regExp, '\\\\\"')}\"`).join(',');\n }\n\n let strVal = typeof value === 'string' ? value : String(value);\n return `\"${replace(strVal, regExp, '\\\\\"')}\"`;\n },\n },\n {\n id: FormatRegistryID.sqlString,\n name: 'SQL string',\n description: 'SQL string quoting and commas for use in IN statements and other scenarios',\n formatter: (value) => {\n // escape single quotes by pairing them\n const regExp = new RegExp(`'`, 'g');\n if (isArray(value)) {\n return map(value, (v: string) => `'${replace(v, regExp, \"''\")}'`).join(',');\n }\n\n let strVal = typeof value === 'string' ? value : String(value);\n return `'${replace(strVal, regExp, \"''\")}'`;\n },\n },\n {\n id: FormatRegistryID.date,\n name: 'Date',\n description: 'Format date in different ways',\n formatter: (value, args) => {\n let nrValue = NaN;\n\n if (typeof value === 'number') {\n nrValue = value;\n } else if (typeof value === 'string') {\n nrValue = parseInt(value, 10);\n }\n\n if (isNaN(nrValue)) {\n return 'NaN';\n }\n\n const arg = args[0] ?? 'iso';\n switch (arg) {\n case 'ms':\n return String(value);\n case 'seconds':\n return `${Math.round(nrValue! / 1000)}`;\n case 'iso':\n return dateTime(nrValue).toISOString();\n default:\n if ((args || []).length > 1) {\n return dateTime(nrValue).format(args.join(':'));\n }\n return dateTime(nrValue).format(arg);\n }\n },\n },\n {\n id: FormatRegistryID.glob,\n name: 'Glob',\n description: 'Format multi-valued variables using glob syntax, example {value1,value2}',\n formatter: (value) => {\n if (isArray(value) && value.length > 1) {\n return '{' + value.join(',') + '}';\n }\n return String(value);\n },\n },\n {\n id: FormatRegistryID.text,\n name: 'Text',\n description: 'Format variables in their text representation. Example in multi-variable scenario A + B + C.',\n formatter: (value, _args, variable) => {\n if (variable.getValueText) {\n return variable.getValueText();\n }\n\n return String(value);\n },\n },\n {\n id: FormatRegistryID.queryParam,\n name: 'Query parameter',\n description:\n 'Format variables as URL parameters. Example in multi-variable scenario A + B + C => var-foo=A&var-foo=B&var-foo=C.',\n formatter: (value, _args, variable) => {\n if (Array.isArray(value)) {\n return value.map((v) => formatQueryParameter(variable.state.name, v)).join('&');\n }\n return formatQueryParameter(variable.state.name, value);\n },\n },\n ];\n\n return formats;\n});\n\nfunction luceneEscape(value: string) {\n if (isNaN(+value) === false) {\n return value;\n }\n\n return value.replace(/([\\!\\*\\+\\-\\=<>\\s\\&\\|\\(\\)\\[\\]\\{\\}\\^\\~\\?\\:\\\\/\"])/g, '\\\\$1');\n}\n\n/**\n * encode string according to RFC 3986; in contrast to encodeURIComponent()\n * also the sub-delims \"!\", \"'\", \"(\", \")\" and \"*\" are encoded;\n * unicode handling uses UTF-8 as in ECMA-262.\n */\nfunction encodeURIComponentStrict(str: VariableValueSingle) {\n if (typeof str === 'object') {\n str = String(str);\n }\n\n return encodeURIComponent(str).replace(/[!'()*]/g, (c) => {\n return '%' + c.charCodeAt(0).toString(16).toUpperCase();\n });\n}\n\nfunction formatQueryParameter(name: string, value: VariableValueSingle): string {\n return `var-${name}=${encodeURIComponentStrict(value)}`;\n}\n\nexport function isAllValue(value: VariableValueSingle) {\n return value === ALL_VARIABLE_VALUE || (Array.isArray(value) && value[0] === ALL_VARIABLE_VALUE);\n}\n"],"names":["FormatRegistryID"],"mappings":"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"}
1
+ {"version":3,"file":"formatRegistry.js","sources":["../../../../src/variables/interpolation/formatRegistry.ts"],"sourcesContent":["import { isArray, map, replace } from 'lodash';\n\nimport { dateTime, Registry, RegistryItem, textUtil, escapeRegex } from '@grafana/data';\nimport { VariableType } from '@grafana/schema';\n\nimport { VariableValue, VariableValueSingle } from '../types';\nimport { ALL_VARIABLE_VALUE } from '../constants';\n\nexport interface FormatRegistryItem extends RegistryItem {\n formatter(value: VariableValue, args: string[], variable: FormatVariable): string;\n}\n\n/**\n * Slimmed down version of the SceneVariable interface so that it only contains what the formatters actually use.\n * This is useful as we have some implementations of this interface that does not need to be full scene objects.\n * For example ScopedVarsVariable and LegacyVariableWrapper.\n */\nexport interface FormatVariable {\n state: {\n name: string;\n type: VariableType | string;\n };\n\n getValue(fieldPath?: string): VariableValue | undefined | null;\n getValueText?(fieldPath?: string): string;\n}\n\nexport enum FormatRegistryID {\n lucene = 'lucene',\n raw = 'raw',\n regex = 'regex',\n pipe = 'pipe',\n distributed = 'distributed',\n csv = 'csv',\n html = 'html',\n json = 'json',\n percentEncode = 'percentencode',\n singleQuote = 'singlequote',\n doubleQuote = 'doublequote',\n sqlString = 'sqlstring',\n date = 'date',\n glob = 'glob',\n text = 'text',\n queryParam = 'queryparam',\n}\n\nexport const formatRegistry = new Registry<FormatRegistryItem>(() => {\n const formats: FormatRegistryItem[] = [\n {\n id: FormatRegistryID.lucene,\n name: 'Lucene',\n description: 'Values are lucene escaped and multi-valued variables generate an OR expression',\n formatter: (value) => {\n if (typeof value === 'string') {\n return luceneEscape(value);\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return '__empty__';\n }\n const quotedValues = map(value, (val: string) => {\n return '\"' + luceneEscape(val) + '\"';\n });\n return '(' + quotedValues.join(' OR ') + ')';\n } else {\n return luceneEscape(`${value}`);\n }\n },\n },\n {\n id: FormatRegistryID.raw,\n name: 'raw',\n description: 'Keep value as is',\n formatter: (value) => String(value),\n },\n {\n id: FormatRegistryID.regex,\n name: 'Regex',\n description: 'Values are regex escaped and multi-valued variables generate a (<value>|<value>) expression',\n formatter: (value) => {\n if (typeof value === 'string') {\n return escapeRegex(value);\n }\n\n if (Array.isArray(value)) {\n const escapedValues = value.map((item) => {\n if (typeof item === 'string') {\n return escapeRegex(item);\n } else {\n return escapeRegex(String(item));\n }\n });\n\n if (escapedValues.length === 1) {\n return escapedValues[0];\n }\n\n return '(' + escapedValues.join('|') + ')';\n }\n\n return escapeRegex(`${value}`);\n },\n },\n {\n id: FormatRegistryID.pipe,\n name: 'Pipe',\n description: 'Values are separated by | character',\n formatter: (value) => {\n if (typeof value === 'string') {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.join('|');\n }\n\n return `${value}`;\n },\n },\n {\n id: FormatRegistryID.distributed,\n name: 'Distributed',\n description: 'Multiple values are formatted like variable=value',\n formatter: (value, args, variable) => {\n if (typeof value === 'string') {\n return value;\n }\n\n if (Array.isArray(value)) {\n value = map(value, (val: string, index: number) => {\n if (index !== 0) {\n return variable.state.name + '=' + val;\n } else {\n return val;\n }\n });\n\n return value.join(',');\n }\n\n return `${value}`;\n },\n },\n {\n id: FormatRegistryID.csv,\n name: 'Csv',\n description: 'Comma-separated values',\n formatter: (value) => {\n if (typeof value === 'string') {\n return value;\n }\n\n if (isArray(value)) {\n return value.join(',');\n }\n\n return String(value);\n },\n },\n {\n id: FormatRegistryID.html,\n name: 'HTML',\n description: 'HTML escaping of values',\n formatter: (value) => {\n if (typeof value === 'string') {\n return textUtil.escapeHtml(value);\n }\n\n if (isArray(value)) {\n return textUtil.escapeHtml(value.join(', '));\n }\n\n return textUtil.escapeHtml(String(value));\n },\n },\n {\n id: FormatRegistryID.json,\n name: 'JSON',\n description: 'JSON stringify value',\n formatter: (value) => {\n if (typeof value === 'string') {\n return value;\n }\n return JSON.stringify(value);\n },\n },\n {\n id: FormatRegistryID.percentEncode,\n name: 'Percent encode',\n description: 'Useful for URL escaping values',\n formatter: (value) => {\n // like glob, but url escaped\n if (isArray(value)) {\n return encodeURIComponentStrict('{' + value.join(',') + '}');\n }\n\n return encodeURIComponentStrict(value);\n },\n },\n {\n id: FormatRegistryID.singleQuote,\n name: 'Single quote',\n description: 'Single quoted values',\n formatter: (value) => {\n // escape single quotes with backslash\n const regExp = new RegExp(`'`, 'g');\n\n if (isArray(value)) {\n return map(value, (v: string) => `'${replace(v, regExp, `\\\\'`)}'`).join(',');\n }\n\n let strVal = typeof value === 'string' ? value : String(value);\n return `'${replace(strVal, regExp, `\\\\'`)}'`;\n },\n },\n {\n id: FormatRegistryID.doubleQuote,\n name: 'Double quote',\n description: 'Double quoted values',\n formatter: (value) => {\n // escape double quotes with backslash\n const regExp = new RegExp('\"', 'g');\n if (isArray(value)) {\n return map(value, (v: string) => `\"${replace(v, regExp, '\\\\\"')}\"`).join(',');\n }\n\n let strVal = typeof value === 'string' ? value : String(value);\n return `\"${replace(strVal, regExp, '\\\\\"')}\"`;\n },\n },\n {\n id: FormatRegistryID.sqlString,\n name: 'SQL string',\n description: 'SQL string quoting and commas for use in IN statements and other scenarios',\n formatter: (value) => {\n // escape single quotes by pairing them\n const regExp = new RegExp(`'`, 'g');\n if (isArray(value)) {\n return map(value, (v: string) => `'${replace(v, regExp, \"''\")}'`).join(',');\n }\n\n let strVal = typeof value === 'string' ? value : String(value);\n return `'${replace(strVal, regExp, \"''\")}'`;\n },\n },\n {\n id: FormatRegistryID.date,\n name: 'Date',\n description: 'Format date in different ways',\n formatter: (value, args) => {\n let nrValue = NaN;\n\n if (typeof value === 'number') {\n nrValue = value;\n } else if (typeof value === 'string') {\n nrValue = parseInt(value, 10);\n }\n\n if (isNaN(nrValue)) {\n return 'NaN';\n }\n\n const arg = args[0] ?? 'iso';\n switch (arg) {\n case 'ms':\n return String(value);\n case 'seconds':\n return `${Math.round(nrValue! / 1000)}`;\n case 'iso':\n return dateTime(nrValue).toISOString();\n default:\n if ((args || []).length > 1) {\n return dateTime(nrValue).format(args.join(':'));\n }\n return dateTime(nrValue).format(arg);\n }\n },\n },\n {\n id: FormatRegistryID.glob,\n name: 'Glob',\n description: 'Format multi-valued variables using glob syntax, example {value1,value2}',\n formatter: (value) => {\n if (isArray(value) && value.length > 1) {\n return '{' + value.join(',') + '}';\n }\n return String(value);\n },\n },\n {\n id: FormatRegistryID.text,\n name: 'Text',\n description: 'Format variables in their text representation. Example in multi-variable scenario A + B + C.',\n formatter: (value, _args, variable) => {\n if (variable.getValueText) {\n return variable.getValueText();\n }\n\n return String(value);\n },\n },\n {\n id: FormatRegistryID.queryParam,\n name: 'Query parameter',\n description:\n 'Format variables as URL parameters. Example in multi-variable scenario A + B + C => var-foo=A&var-foo=B&var-foo=C.',\n formatter: (value, _args, variable) => {\n if (Array.isArray(value)) {\n return value.map((v) => formatQueryParameter(variable.state.name, v)).join('&');\n }\n return formatQueryParameter(variable.state.name, value);\n },\n },\n ];\n\n return formats;\n});\n\nfunction luceneEscape(value: string) {\n if (isNaN(+value) === false) {\n return value;\n }\n\n return value.replace(/([\\!\\*\\+\\-\\=<>\\s\\&\\|\\(\\)\\[\\]\\{\\}\\^\\~\\?\\:\\\\/\"])/g, '\\\\$1');\n}\n\n/**\n * encode string according to RFC 3986; in contrast to encodeURIComponent()\n * also the sub-delims \"!\", \"'\", \"(\", \")\" and \"*\" are encoded;\n * unicode handling uses UTF-8 as in ECMA-262.\n */\nfunction encodeURIComponentStrict(str: VariableValueSingle) {\n if (typeof str === 'object') {\n str = String(str);\n }\n\n return encodeURIComponent(str).replace(/[!'()*]/g, (c) => {\n return '%' + c.charCodeAt(0).toString(16).toUpperCase();\n });\n}\n\nfunction formatQueryParameter(name: string, value: VariableValueSingle): string {\n return `var-${name}=${encodeURIComponentStrict(value)}`;\n}\n\nexport function isAllValue(value: VariableValueSingle) {\n return value === ALL_VARIABLE_VALUE || (Array.isArray(value) && value[0] === ALL_VARIABLE_VALUE);\n}\n"],"names":["FormatRegistryID"],"mappings":"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"}