@perses-dev/dashboards 0.2.1 → 0.4.0

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.
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Dashboard = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ // Copyright 2021 The Perses Authors
6
+ // Licensed under the Apache License, Version 2.0 (the "License");
7
+ // you may not use this file except in compliance with the License.
8
+ // You may obtain a copy of the License at
9
+ //
10
+ // http://www.apache.org/licenses/LICENSE-2.0
11
+ //
12
+ // Unless required by applicable law or agreed to in writing, software
13
+ // distributed under the License is distributed on an "AS IS" BASIS,
14
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ // See the License for the specific language governing permissions and
16
+ // limitations under the License.
17
+ const material_1 = require("@mui/material");
18
+ const components_1 = require("@perses-dev/components");
19
+ const GridLayout_1 = require("./GridLayout");
20
+ /**
21
+ * Renders a Dashboard for the provided Dashboard spec.
22
+ */
23
+ function Dashboard(props) {
24
+ const { spec, ...others } = props;
25
+ return ((0, jsx_runtime_1.jsx)(material_1.Box, { ...others, children: (0, jsx_runtime_1.jsx)(components_1.ErrorBoundary, { FallbackComponent: components_1.ErrorAlert, children: spec.layouts.map((layout, idx) => ((0, jsx_runtime_1.jsx)(GridLayout_1.GridLayout, { definition: layout, renderGridItemContent: (definition) => (0, jsx_runtime_1.jsx)(GridLayout_1.GridItemContent, { content: definition.content, spec: spec }) }, idx))) }) }));
26
+ }
27
+ exports.Dashboard = Dashboard;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GridItemContent = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ // Copyright 2021 The Perses Authors
6
+ // Licensed under the Apache License, Version 2.0 (the "License");
7
+ // you may not use this file except in compliance with the License.
8
+ // You may obtain a copy of the License at
9
+ //
10
+ // http://www.apache.org/licenses/LICENSE-2.0
11
+ //
12
+ // Unless required by applicable law or agreed to in writing, software
13
+ // distributed under the License is distributed on an "AS IS" BASIS,
14
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ // See the License for the specific language governing permissions and
16
+ // limitations under the License.
17
+ const components_1 = require("@perses-dev/components");
18
+ const core_1 = require("@perses-dev/core");
19
+ const Panel_1 = require("../Panel");
20
+ /**
21
+ * Resolves the reference to panel content in a GridItemDefinition and renders the panel.
22
+ */
23
+ function GridItemContent(props) {
24
+ const { content, spec } = props;
25
+ try {
26
+ const definition = (0, core_1.resolvePanelRef)(spec, content);
27
+ return (0, jsx_runtime_1.jsx)(Panel_1.Panel, { definition: definition });
28
+ }
29
+ catch (err) {
30
+ return (0, jsx_runtime_1.jsx)(components_1.ErrorAlert, { error: err });
31
+ }
32
+ }
33
+ exports.GridItemContent = GridItemContent;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GridLayout = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ // Copyright 2021 The Perses Authors
6
+ // Licensed under the Apache License, Version 2.0 (the "License");
7
+ // you may not use this file except in compliance with the License.
8
+ // You may obtain a copy of the License at
9
+ //
10
+ // http://www.apache.org/licenses/LICENSE-2.0
11
+ //
12
+ // Unless required by applicable law or agreed to in writing, software
13
+ // distributed under the License is distributed on an "AS IS" BASIS,
14
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ // See the License for the specific language governing permissions and
16
+ // limitations under the License.
17
+ const react_1 = require("react");
18
+ const material_1 = require("@mui/material");
19
+ const GridTitle_1 = require("./GridTitle");
20
+ const COLUMNS = 24;
21
+ /**
22
+ * Layout component that arranges children in a Grid based on the definition.
23
+ */
24
+ function GridLayout(props) {
25
+ var _a, _b;
26
+ const { definition: { display, items }, renderGridItemContent, ...others } = props;
27
+ const [isOpen, setIsOpen] = (0, react_1.useState)((_b = (_a = display === null || display === void 0 ? void 0 : display.collapse) === null || _a === void 0 ? void 0 : _a.open) !== null && _b !== void 0 ? _b : true);
28
+ const gridItems = [];
29
+ let mobileRowStart = 1;
30
+ items.forEach((item, idx) => {
31
+ // Try to maintain the chart's aspect ratio on mobile
32
+ const widthScale = COLUMNS / item.width;
33
+ const mobileRows = Math.floor(item.height * widthScale);
34
+ gridItems.push((0, jsx_runtime_1.jsx)(material_1.Box, { sx: {
35
+ gridColumn: {
36
+ xs: `1 / span ${COLUMNS}`,
37
+ sm: `${item.x + 1} / span ${item.width}`,
38
+ },
39
+ gridRow: {
40
+ xs: `${mobileRowStart} / span ${mobileRows}`,
41
+ sm: `${item.y + 1} / span ${item.height}`,
42
+ },
43
+ }, children: renderGridItemContent(item) }, idx));
44
+ mobileRowStart += mobileRows;
45
+ });
46
+ return ((0, jsx_runtime_1.jsxs)(material_1.Box, { ...others, component: "section", sx: { '& + &': { marginTop: (theme) => theme.spacing(1) } }, children: [display !== undefined && ((0, jsx_runtime_1.jsx)(GridTitle_1.GridTitle, { title: display.title, collapse: display.collapse === undefined
47
+ ? undefined
48
+ : { isOpen, onToggleOpen: () => setIsOpen((current) => !current) } })), (0, jsx_runtime_1.jsx)(material_1.Collapse, { in: isOpen, unmountOnExit: true, children: (0, jsx_runtime_1.jsx)(material_1.Box, { sx: {
49
+ display: 'grid',
50
+ gridTemplateColumns: `repeat(${COLUMNS}, 1fr)`,
51
+ gridAutoRows: {
52
+ xs: 24,
53
+ sm: 36,
54
+ },
55
+ columnGap: (theme) => theme.spacing(1),
56
+ rowGap: (theme) => theme.spacing(1),
57
+ }, children: gridItems }) })] }));
58
+ }
59
+ exports.GridLayout = GridLayout;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.GridTitle = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ // Copyright 2021 The Perses Authors
9
+ // Licensed under the Apache License, Version 2.0 (the "License");
10
+ // you may not use this file except in compliance with the License.
11
+ // You may obtain a copy of the License at
12
+ //
13
+ // http://www.apache.org/licenses/LICENSE-2.0
14
+ //
15
+ // Unless required by applicable law or agreed to in writing, software
16
+ // distributed under the License is distributed on an "AS IS" BASIS,
17
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ // See the License for the specific language governing permissions and
19
+ // limitations under the License.
20
+ const material_1 = require("@mui/material");
21
+ const ChevronUp_1 = __importDefault(require("mdi-material-ui/ChevronUp"));
22
+ const ChevronDown_1 = __importDefault(require("mdi-material-ui/ChevronDown"));
23
+ /**
24
+ * Renders the title for a Grid section, optionally also supporting expanding
25
+ * and collapsing
26
+ */
27
+ function GridTitle(props) {
28
+ const { title, collapse } = props;
29
+ const text = ((0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h5", sx: { marginLeft: collapse !== undefined ? 1 : undefined }, children: title }));
30
+ // If we don't need expand/collapse, just render the title text
31
+ if (collapse === undefined) {
32
+ return text;
33
+ }
34
+ // Otherwise render something clickable
35
+ return ((0, jsx_runtime_1.jsxs)(material_1.ButtonBase, { component: "header", sx: {
36
+ display: 'flex',
37
+ justifyContent: 'start',
38
+ alignItems: 'center',
39
+ }, onClick: collapse.onToggleOpen, children: [collapse.isOpen ? (0, jsx_runtime_1.jsx)(ChevronUp_1.default, {}) : (0, jsx_runtime_1.jsx)(ChevronDown_1.default, {}), text] }));
40
+ }
41
+ exports.GridTitle = GridTitle;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ // Copyright 2021 The Perses Authors
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
26
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ __exportStar(require("./GridLayout"), exports);
30
+ __exportStar(require("./GridItemContent"), exports);
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Panel = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ // Copyright 2021 The Perses Authors
9
+ // Licensed under the Apache License, Version 2.0 (the "License");
10
+ // you may not use this file except in compliance with the License.
11
+ // You may obtain a copy of the License at
12
+ //
13
+ // http://www.apache.org/licenses/LICENSE-2.0
14
+ //
15
+ // Unless required by applicable law or agreed to in writing, software
16
+ // distributed under the License is distributed on an "AS IS" BASIS,
17
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ // See the License for the specific language governing permissions and
19
+ // limitations under the License.
20
+ const react_1 = require("react");
21
+ const material_1 = require("@mui/material");
22
+ const plugin_system_1 = require("@perses-dev/plugin-system");
23
+ const components_1 = require("@perses-dev/components");
24
+ const use_resize_observer_1 = __importDefault(require("use-resize-observer"));
25
+ /**
26
+ * Renders a PanelDefinition's content inside of a Card.
27
+ */
28
+ function Panel(props) {
29
+ const { definition, ...others } = props;
30
+ const [contentElement, setContentElement] = (0, react_1.useState)(null);
31
+ const isStatsChart = definition.kind === 'StatChart';
32
+ const panelPadding = isStatsChart ? 0 : 2;
33
+ const { width, height } = (0, use_resize_observer_1.default)({ ref: contentElement });
34
+ const contentDimensions = (0, react_1.useMemo)(() => {
35
+ if (width === undefined || height === undefined)
36
+ return undefined;
37
+ return { width, height };
38
+ }, [width, height]);
39
+ return ((0, jsx_runtime_1.jsxs)(material_1.Card, { sx: {
40
+ ...others.sx,
41
+ width: '100%',
42
+ height: '100%',
43
+ display: 'flex',
44
+ flexFlow: 'column nowrap',
45
+ }, variant: "outlined", ...others, children: [(0, jsx_runtime_1.jsx)(material_1.CardHeader, { title: (0, jsx_runtime_1.jsx)(material_1.Typography, { component: "h2", variant: "body2", fontWeight: (theme) => theme.typography.fontWeightMedium, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", children: definition.display.name }), sx: {
46
+ display: 'block',
47
+ padding: (theme) => theme.spacing(1, 2),
48
+ } }), (0, jsx_runtime_1.jsx)(material_1.CardContent, { sx: {
49
+ position: 'relative',
50
+ overflow: 'hidden',
51
+ flexGrow: 1,
52
+ padding: (theme) => theme.spacing(panelPadding),
53
+ // Override MUI default style for last-child
54
+ ':last-child': {
55
+ padding: (theme) => theme.spacing(panelPadding),
56
+ },
57
+ }, ref: setContentElement, children: (0, jsx_runtime_1.jsx)(plugin_system_1.PluginBoundary, { loadingFallback: "Loading...", ErrorFallbackComponent: components_1.ErrorAlert, children: (0, jsx_runtime_1.jsx)(plugin_system_1.PanelComponent, { definition: definition, contentDimensions: contentDimensions }) }) })] }));
58
+ }
59
+ exports.Panel = Panel;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VariableAutocomplete = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ // Copyright 2021 The Perses Authors
6
+ // Licensed under the Apache License, Version 2.0 (the "License");
7
+ // you may not use this file except in compliance with the License.
8
+ // You may obtain a copy of the License at
9
+ //
10
+ // http://www.apache.org/licenses/LICENSE-2.0
11
+ //
12
+ // Unless required by applicable law or agreed to in writing, software
13
+ // distributed under the License is distributed on an "AS IS" BASIS,
14
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ // See the License for the specific language governing permissions and
16
+ // limitations under the License.
17
+ const react_1 = require("react");
18
+ const material_1 = require("@mui/material");
19
+ const plugin_system_1 = require("@perses-dev/plugin-system");
20
+ /**
21
+ * A MUI Autocomplete that displays variable options, loaded from the
22
+ * appropriate plugin.
23
+ */
24
+ function VariableAutocomplete(props) {
25
+ const { definition, state, onChange, onOptionsChange, TextFieldProps } = props;
26
+ const { value, options } = state;
27
+ const allValue = 'all_value' in definition.selection ? definition.selection.all_value : undefined;
28
+ const displayOptions = (0, react_1.useMemo)(() => {
29
+ let displayOptions = options;
30
+ // During initial loading, options will be undefined, so make sure we have
31
+ // an option for the current value
32
+ if (displayOptions === undefined) {
33
+ displayOptions = Array.isArray(value) ? value : [value];
34
+ }
35
+ // The All option is not actually stored in the options state, so make
36
+ // sure that exists at the start of the options array
37
+ if (allValue !== undefined && displayOptions[0] !== allValue) {
38
+ displayOptions = [allValue, ...displayOptions];
39
+ }
40
+ return displayOptions;
41
+ }, [options, value, allValue]);
42
+ // Load the options from the server and update state whenever that data
43
+ // changes
44
+ const { data, loading, error } = (0, plugin_system_1.useVariableOptions)(definition);
45
+ (0, react_1.useEffect)(() => {
46
+ if (loading)
47
+ return;
48
+ onOptionsChange(data);
49
+ // We don't want to fire this event every time we render if the user doesn't wrap onOptionsChange with useCallback
50
+ // eslint-disable-next-line react-hooks/exhaustive-deps
51
+ }, [data, loading]);
52
+ const handleChange = (e, nextValue) => {
53
+ onChange(nextValue);
54
+ };
55
+ return ((0, jsx_runtime_1.jsx)(material_1.Autocomplete, { options: displayOptions, loading: loading, value: value, multiple: Array.isArray(value), disableClearable: true, freeSolo: false, onChange: handleChange, renderInput: (params) => {
56
+ var _a;
57
+ return ((0, jsx_runtime_1.jsx)(material_1.TextField, { ...params, margin: "normal", label: definition.display.label, error: error !== undefined, helperText: (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '', ...TextFieldProps }));
58
+ }, getOptionLabel: (option) => (option === allValue ? 'All' : option), ChipProps: {
59
+ color: 'default',
60
+ variant: 'outlined',
61
+ } }));
62
+ }
63
+ exports.VariableAutocomplete = VariableAutocomplete;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VariableOptionsDrawer = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ // Copyright 2021 The Perses Authors
6
+ // Licensed under the Apache License, Version 2.0 (the "License");
7
+ // you may not use this file except in compliance with the License.
8
+ // You may obtain a copy of the License at
9
+ //
10
+ // http://www.apache.org/licenses/LICENSE-2.0
11
+ //
12
+ // Unless required by applicable law or agreed to in writing, software
13
+ // distributed under the License is distributed on an "AS IS" BASIS,
14
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ // See the License for the specific language governing permissions and
16
+ // limitations under the License.
17
+ const material_1 = require("@mui/material");
18
+ const components_1 = require("@perses-dev/components");
19
+ const plugin_system_1 = require("@perses-dev/plugin-system");
20
+ const context_1 = require("../context");
21
+ const VariableAutocomplete_1 = require("./VariableAutocomplete");
22
+ const DRAWER_WIDTH = 296;
23
+ /**
24
+ * Dashboard options drawer that includes variable inputs.
25
+ */
26
+ function VariableOptionsDrawer(props) {
27
+ const { variables, sx, ...others } = props;
28
+ const { variables: variablesState } = (0, plugin_system_1.useTemplateVariables)();
29
+ const { setValue, setOptions } = (0, context_1.useTemplateVariablesSetters)();
30
+ return ((0, jsx_runtime_1.jsxs)(material_1.Paper, { sx: (0, components_1.combineSx)({
31
+ width: DRAWER_WIDTH,
32
+ flexShrink: 0,
33
+ padding: (theme) => theme.spacing(1, 2),
34
+ borderLeft: (theme) => `1px solid ${theme.palette.divider}`,
35
+ }, sx), square: true, elevation: 0, ...others, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { component: "h2", variant: "h6", children: "Variables" }), Object.entries(variables).map(([variableName, variableDef]) => {
36
+ if (variableDef.display.hide === true)
37
+ return null;
38
+ const variableState = variablesState[variableName];
39
+ if (variableState === undefined) {
40
+ const error = new Error(`Variable state for '${variableName}' not found`);
41
+ return (0, jsx_runtime_1.jsx)(components_1.ErrorAlert, { error: error }, variableName);
42
+ }
43
+ return ((0, jsx_runtime_1.jsx)(plugin_system_1.PluginBoundary, { loadingFallback: "Loading...", ErrorFallbackComponent: components_1.ErrorAlert, children: (0, jsx_runtime_1.jsx)(VariableAutocomplete_1.VariableAutocomplete, { definition: variableDef, state: variableState, onChange: (value) => setValue(variableName, value), onOptionsChange: (options) => setOptions(variableName, options) }) }, variableName));
44
+ })] }));
45
+ }
46
+ exports.VariableOptionsDrawer = VariableOptionsDrawer;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ // Copyright 2021 The Perses Authors
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
26
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ __exportStar(require("./Dashboard"), exports);
30
+ __exportStar(require("./GridLayout"), exports);
31
+ __exportStar(require("./Panel"), exports);
32
+ __exportStar(require("./VariableAutocomplete"), exports);
33
+ __exportStar(require("./VariableOptionsDrawer"), exports);
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useTemplateVariablesSetters = exports.TemplateVariablesSettersContext = exports.TemplateVariablesProvider = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ // Copyright 2021 The Perses Authors
6
+ // Licensed under the Apache License, Version 2.0 (the "License");
7
+ // you may not use this file except in compliance with the License.
8
+ // You may obtain a copy of the License at
9
+ //
10
+ // http://www.apache.org/licenses/LICENSE-2.0
11
+ //
12
+ // Unless required by applicable law or agreed to in writing, software
13
+ // distributed under the License is distributed on an "AS IS" BASIS,
14
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ // See the License for the specific language governing permissions and
16
+ // limitations under the License.
17
+ const react_1 = require("react");
18
+ const use_immer_1 = require("use-immer");
19
+ const plugin_system_1 = require("@perses-dev/plugin-system");
20
+ /**
21
+ * Provider implementation that supplies the TemplateVariables at runtime.
22
+ */
23
+ function TemplateVariablesProvider(props) {
24
+ const { children, variableDefinitions } = props;
25
+ // TODO: Do we need to support re-init if variableDefinitions changes?
26
+ const [state, setState] = (0, use_immer_1.useImmer)(() => {
27
+ const variables = {};
28
+ Object.entries(variableDefinitions).forEach(([variableName, definition]) => {
29
+ variables[variableName] = {
30
+ value: definition.selection.default_value,
31
+ options: undefined,
32
+ };
33
+ });
34
+ return variables;
35
+ });
36
+ const setValue = (0, react_1.useCallback)((name, next) => {
37
+ const variableDef = variableDefinitions[name];
38
+ if (variableDef === undefined) {
39
+ throw new Error(`Unknown variable '${name}'`);
40
+ }
41
+ const defaultValue = variableDef.selection.default_value;
42
+ const allValue = 'all_value' in variableDef.selection ? variableDef.selection.all_value : undefined;
43
+ if (typeof defaultValue === 'object') {
44
+ // Shouldn't be able to assign a string to a multi select
45
+ if (typeof next !== 'object') {
46
+ throw new Error(`Invalid value '${next}' for multi-select`);
47
+ }
48
+ // If selections are completely removed, just go back to the default
49
+ // value
50
+ if (next.length === 0) {
51
+ next = defaultValue;
52
+ }
53
+ }
54
+ else {
55
+ // Shouldn't be able to assign a string[] to a single select
56
+ if (typeof next !== 'string') {
57
+ throw new Error(`Invalid value '${next}' for single-select`);
58
+ }
59
+ }
60
+ setState((draft) => {
61
+ const variableState = draft[name];
62
+ if (variableState === undefined) {
63
+ throw new Error(`Unknown variable '${name}'`);
64
+ }
65
+ // If the "All" value is in the next selections, we need to either
66
+ // remove it (because they selected something more specific) or
67
+ // ensure it's the only selection (because they just selected it)
68
+ if (allValue !== undefined && typeof next === 'object' && next.length > 1 && next.includes(allValue)) {
69
+ const current = variableState.value;
70
+ if (typeof current === 'object') {
71
+ const hasAll = current.includes(allValue);
72
+ if (hasAll) {
73
+ next = next.filter((val) => val !== allValue);
74
+ }
75
+ else {
76
+ next = [allValue];
77
+ }
78
+ }
79
+ }
80
+ variableState.value = next;
81
+ });
82
+ }, [setState, variableDefinitions]);
83
+ const setOptions = (0, react_1.useCallback)((name, options) => {
84
+ const variableDef = variableDefinitions[name];
85
+ if (variableDef === undefined) {
86
+ throw new Error(`Unknown variable '${name}'`);
87
+ }
88
+ let capturingRegex = undefined;
89
+ if (variableDef.capturing_regexp !== undefined) {
90
+ let pattern = variableDef.capturing_regexp;
91
+ let flags = '';
92
+ // Regex expressions can start with / so that flags can be provided
93
+ // at the end, so account for those
94
+ if (pattern.startsWith('/')) {
95
+ const endIdx = pattern.lastIndexOf('/');
96
+ if (endIdx > 0) {
97
+ flags = pattern.substring(endIdx + 1);
98
+ pattern = pattern.substring(1, endIdx);
99
+ }
100
+ }
101
+ // TODO: Do we need to account for stateful flags (gy) and create a
102
+ // new Regex each time to compare an option to?
103
+ capturingRegex = new RegExp(pattern, flags);
104
+ }
105
+ // Get the unique options, optionally running the capturing regex
106
+ const uniqueOptions = new Set();
107
+ options.forEach((option) => {
108
+ if (capturingRegex !== undefined) {
109
+ const match = capturingRegex.exec(option);
110
+ if (match !== null && match[0] !== undefined) {
111
+ option = match[0];
112
+ }
113
+ }
114
+ uniqueOptions.add(option);
115
+ });
116
+ // Set the options in variable state
117
+ setState((draft) => {
118
+ const variableState = draft[name];
119
+ if (variableState === undefined) {
120
+ throw new Error(`Unknown variable '${name}'`);
121
+ }
122
+ variableState.options = Array.from(uniqueOptions);
123
+ });
124
+ }, [setState, variableDefinitions]);
125
+ // Memo since it's being passed via context
126
+ const ctx = (0, react_1.useMemo)(() => ({ variables: state }), [state]);
127
+ const setters = (0, react_1.useMemo)(() => ({ setValue, setOptions }), [setValue, setOptions]);
128
+ return ((0, jsx_runtime_1.jsx)(exports.TemplateVariablesSettersContext.Provider, { value: setters, children: (0, jsx_runtime_1.jsx)(plugin_system_1.TemplateVariablesContext.Provider, { value: ctx, children: children }) }));
129
+ }
130
+ exports.TemplateVariablesProvider = TemplateVariablesProvider;
131
+ exports.TemplateVariablesSettersContext = (0, react_1.createContext)(undefined);
132
+ /**
133
+ * Gets the setters for Template Variables provided by the TemplateVariablesProvider at runtime.
134
+ */
135
+ function useTemplateVariablesSetters() {
136
+ const ctx = (0, react_1.useContext)(exports.TemplateVariablesSettersContext);
137
+ if (ctx === undefined) {
138
+ throw new Error('No TemplateVariablesSettersContext found. Did you forget a Provider?');
139
+ }
140
+ return ctx;
141
+ }
142
+ exports.useTemplateVariablesSetters = useTemplateVariablesSetters;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimeRangeStateProvider = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ // Copyright 2021 The Perses Authors
6
+ // Licensed under the Apache License, Version 2.0 (the "License");
7
+ // you may not use this file except in compliance with the License.
8
+ // You may obtain a copy of the License at
9
+ //
10
+ // http://www.apache.org/licenses/LICENSE-2.0
11
+ //
12
+ // Unless required by applicable law or agreed to in writing, software
13
+ // distributed under the License is distributed on an "AS IS" BASIS,
14
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ // See the License for the specific language governing permissions and
16
+ // limitations under the License.
17
+ const react_1 = require("react");
18
+ const core_1 = require("@perses-dev/core");
19
+ const plugin_system_1 = require("@perses-dev/plugin-system");
20
+ /**
21
+ * Provider implementation that supplies the TimeRangeState at runtime.
22
+ */
23
+ function TimeRangeStateProvider(props) {
24
+ const { initialValue, children } = props;
25
+ // Use initialValue to populate state (TODO: Will prob need to expose "setter" API eventually)
26
+ const [timeRange] = (0, react_1.useState)(() => {
27
+ if ('pastDuration' in initialValue) {
28
+ return (0, core_1.toAbsoluteTimeRange)(initialValue);
29
+ }
30
+ return initialValue;
31
+ });
32
+ const ctx = (0, react_1.useMemo)(() => ({ timeRange }), [timeRange]);
33
+ return (0, jsx_runtime_1.jsx)(plugin_system_1.TimeRangeContext.Provider, { value: ctx, children: children });
34
+ }
35
+ exports.TimeRangeStateProvider = TimeRangeStateProvider;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ // Copyright 2021 The Perses Authors
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
26
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ __exportStar(require("./TemplateVariablesProvider"), exports);
30
+ __exportStar(require("./TimeRangeStateProvider"), exports);
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ // Copyright 2021 The Perses Authors
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
26
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ __exportStar(require("./components"), exports);
30
+ __exportStar(require("./context"), exports);
31
+ __exportStar(require("./views"), exports);
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ViewDashboard = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ // Copyright 2021 The Perses Authors
6
+ // Licensed under the Apache License, Version 2.0 (the "License");
7
+ // you may not use this file except in compliance with the License.
8
+ // You may obtain a copy of the License at
9
+ //
10
+ // http://www.apache.org/licenses/LICENSE-2.0
11
+ //
12
+ // Unless required by applicable law or agreed to in writing, software
13
+ // distributed under the License is distributed on an "AS IS" BASIS,
14
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ // See the License for the specific language governing permissions and
16
+ // limitations under the License.
17
+ const material_1 = require("@mui/material");
18
+ const components_1 = require("@perses-dev/components");
19
+ const context_1 = require("../context");
20
+ const components_2 = require("../components");
21
+ /**
22
+ * The View for displaying a Dashboard, along with the UI for selecting variable values.
23
+ */
24
+ function ViewDashboard(props) {
25
+ const { dashboardResource, sx, children, ...others } = props;
26
+ return ((0, jsx_runtime_1.jsx)(context_1.TimeRangeStateProvider, { initialValue: { pastDuration: dashboardResource.spec.duration }, children: (0, jsx_runtime_1.jsx)(context_1.TemplateVariablesProvider, { variableDefinitions: dashboardResource.spec.variables, children: (0, jsx_runtime_1.jsxs)(material_1.Box, { sx: (0, components_1.combineSx)({
27
+ display: 'flex',
28
+ width: '100%',
29
+ height: '100%',
30
+ position: 'relative',
31
+ overflow: 'hidden',
32
+ }, sx), ...others, children: [(0, jsx_runtime_1.jsxs)(material_1.Box, { sx: {
33
+ padding: (theme) => theme.spacing(1, 2),
34
+ flexGrow: 1,
35
+ overflowX: 'hidden',
36
+ overflowY: 'auto',
37
+ }, children: [(0, jsx_runtime_1.jsx)(components_2.Dashboard, { spec: dashboardResource.spec }), children] }), (0, jsx_runtime_1.jsx)(components_2.VariableOptionsDrawer, { variables: dashboardResource.spec.variables })] }) }) }));
38
+ }
39
+ exports.ViewDashboard = ViewDashboard;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ // Copyright 2021 The Perses Authors
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
26
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ __exportStar(require("./ViewDashboard"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"Panel.d.ts","sourceRoot":"","sources":["../../src/components/Panel.tsx"],"names":[],"mappings":";AAcA,OAAO,EAAQ,SAAS,EAAuC,MAAM,eAAe,CAAC;AAIrF,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC3C,UAAU,EAAE,eAAe,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,eA+DtC"}
1
+ {"version":3,"file":"Panel.d.ts","sourceRoot":"","sources":["../../src/components/Panel.tsx"],"names":[],"mappings":";AAcA,OAAO,EAAQ,SAAS,EAAuC,MAAM,eAAe,CAAC;AAIrF,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC3C,UAAU,EAAE,eAAe,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,eA8DtC"}
@@ -1 +1 @@
1
- import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import{useState,useMemo}from"react";import{Card,CardHeader,CardContent,Typography}from"@mui/material";import{PluginBoundary,PanelComponent}from"@perses-dev/plugin-system";import{ErrorAlert}from"@perses-dev/components";import useResizeObserver from"use-resize-observer";export function Panel(e){const{definition:r,...i}=e,[o,n]=useState(null),t="StatChart"===r.kind,s=t?0:2,{width:a,height:d}=useResizeObserver({ref:o}),l=useMemo((()=>{if(void 0!==a&&void 0!==d)return{width:a,height:d}}),[a,d]);return _jsxs(Card,{sx:{...i.sx,width:"100%",height:"100%",display:"flex",flexFlow:"column nowrap",overflow:t?"hidden":"visible"},variant:"outlined",...i,children:[_jsx(CardHeader,{title:_jsx(Typography,{component:"h2",variant:"body2",fontWeight:e=>e.typography.fontWeightMedium,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",children:r.display.name}),sx:{display:"block",padding:e=>e.spacing(1,2)}}),_jsx(CardContent,{sx:{position:"relative",flexGrow:1,padding:e=>e.spacing(s),":last-child":{padding:e=>e.spacing(s)}},ref:n,children:_jsx(PluginBoundary,{loadingFallback:"Loading...",ErrorFallbackComponent:ErrorAlert,children:_jsx(PanelComponent,{definition:r,contentDimensions:l})})})]})}
1
+ import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import{useState,useMemo}from"react";import{Card,CardHeader,CardContent,Typography}from"@mui/material";import{PluginBoundary,PanelComponent}from"@perses-dev/plugin-system";import{ErrorAlert}from"@perses-dev/components";import useResizeObserver from"use-resize-observer";export function Panel(e){const{definition:r,...i}=e,[o,n]=useState(null),t="StatChart"===r.kind?0:2,{width:s,height:a}=useResizeObserver({ref:o}),d=useMemo((()=>{if(void 0!==s&&void 0!==a)return{width:s,height:a}}),[s,a]);return _jsxs(Card,{sx:{...i.sx,width:"100%",height:"100%",display:"flex",flexFlow:"column nowrap"},variant:"outlined",...i,children:[_jsx(CardHeader,{title:_jsx(Typography,{component:"h2",variant:"body2",fontWeight:e=>e.typography.fontWeightMedium,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",children:r.display.name}),sx:{display:"block",padding:e=>e.spacing(1,2)}}),_jsx(CardContent,{sx:{position:"relative",overflow:"hidden",flexGrow:1,padding:e=>e.spacing(t),":last-child":{padding:e=>e.spacing(t)}},ref:n,children:_jsx(PluginBoundary,{loadingFallback:"Loading...",ErrorFallbackComponent:ErrorAlert,children:_jsx(PanelComponent,{definition:r,contentDimensions:d})})})]})}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@perses-dev/dashboards",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "description": "The dashboards feature in Perses",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/perses/perses/blob/main/README.md",
@@ -12,24 +12,26 @@
12
12
  "url": "https://github.com/perses/perses/issues"
13
13
  },
14
14
  "module": "dist/index.js",
15
+ "main": "dist/cjs/index.js",
15
16
  "types": "dist/index.d.ts",
16
17
  "scripts": {
17
18
  "clean": "rimraf dist/",
18
- "build": "tsc",
19
+ "build": "tsc --build",
20
+ "build:cjs": "tsc --project ./tsconfig.cjs.json",
19
21
  "test": "echo 'no test to run' && exit 0",
20
22
  "lint": "eslint src --ext .ts,.tsx",
21
23
  "lint:fix": "eslint --fix src --ext .ts,.tsx"
22
24
  },
23
25
  "dependencies": {
24
- "@mui/material": "^5.5.1",
25
- "@perses-dev/components": "^0.2.1",
26
- "@perses-dev/core": "^0.2.1",
27
- "@perses-dev/plugin-system": "^0.2.1",
26
+ "@perses-dev/components": "^0.4.0",
27
+ "@perses-dev/core": "^0.4.0",
28
+ "@perses-dev/plugin-system": "^0.4.0",
28
29
  "immer": "^9.0.12",
29
30
  "use-immer": "^0.6.0",
30
31
  "use-resize-observer": "^8.0.0"
31
32
  },
32
33
  "peerDependencies": {
34
+ "@mui/material": "^5.5.1",
33
35
  "react": "^17.0.2"
34
36
  },
35
37
  "files": [