@perses-dev/dashboards 0.54.0-beta.1 → 0.54.0-beta.3
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/dist/cjs/components/Panel/Panel.js +4 -1
- package/dist/cjs/components/Variables/VariableEditor.js +51 -17
- package/dist/cjs/context/DatasourceStoreProvider.js +4 -1
- package/dist/cjs/context/VariableProvider/VariableProvider.js +10 -6
- package/dist/components/AddGroupButton/AddGroupButton.js +1 -1
- package/dist/components/AddGroupButton/AddGroupButton.js.map +1 -1
- package/dist/components/AddPanelButton/AddPanelButton.js +1 -1
- package/dist/components/AddPanelButton/AddPanelButton.js.map +1 -1
- package/dist/components/Dashboard/Dashboard.js +1 -1
- package/dist/components/Dashboard/Dashboard.js.map +1 -1
- package/dist/components/DashboardLinks/DashboardLinksEditor.js +1 -1
- package/dist/components/DashboardLinks/DashboardLinksEditor.js.map +1 -1
- package/dist/components/DashboardLinks/EditDashboardLinksButton.js +1 -1
- package/dist/components/DashboardLinks/EditDashboardLinksButton.js.map +1 -1
- package/dist/components/DashboardStickyToolbar/DashboardStickyToolbar.js +1 -1
- package/dist/components/DashboardStickyToolbar/DashboardStickyToolbar.js.map +1 -1
- package/dist/components/DashboardToolbar/DashboardToolbar.js +1 -1
- package/dist/components/DashboardToolbar/DashboardToolbar.js.map +1 -1
- package/dist/components/Datasources/DatasourceEditor.d.ts.map +1 -1
- package/dist/components/Datasources/DatasourceEditor.js +1 -1
- package/dist/components/Datasources/DatasourceEditor.js.map +1 -1
- package/dist/components/Datasources/EditDatasourcesButton.js +1 -1
- package/dist/components/Datasources/EditDatasourcesButton.js.map +1 -1
- package/dist/components/DiscardChangesConfirmationDialog/DiscardChangesConfirmationDialog.js +1 -1
- package/dist/components/DiscardChangesConfirmationDialog/DiscardChangesConfirmationDialog.js.map +1 -1
- package/dist/components/DownloadButton/DownloadButton.js +1 -1
- package/dist/components/DownloadButton/DownloadButton.js.map +1 -1
- package/dist/components/EditButton/EditButton.js +1 -1
- package/dist/components/EditButton/EditButton.js.map +1 -1
- package/dist/components/EditJsonButton/EditJsonButton.js +1 -1
- package/dist/components/EditJsonButton/EditJsonButton.js.map +1 -1
- package/dist/components/EditJsonDialog/EditJsonDialog.js +1 -1
- package/dist/components/EditJsonDialog/EditJsonDialog.js.map +1 -1
- package/dist/components/EmptyDashboard/EmptyDashboard.js +1 -1
- package/dist/components/EmptyDashboard/EmptyDashboard.js.map +1 -1
- package/dist/components/GridLayout/GridContainer.js +1 -1
- package/dist/components/GridLayout/GridContainer.js.map +1 -1
- package/dist/components/GridLayout/GridItemContent.js +1 -1
- package/dist/components/GridLayout/GridItemContent.js.map +1 -1
- package/dist/components/GridLayout/GridLayout.js +1 -1
- package/dist/components/GridLayout/GridLayout.js.map +1 -1
- package/dist/components/GridLayout/GridTitle.js +1 -1
- package/dist/components/GridLayout/GridTitle.js.map +1 -1
- package/dist/components/GridLayout/Row.js +1 -1
- package/dist/components/GridLayout/Row.js.map +1 -1
- package/dist/components/LeaveDialog/LeaveDialog.js +1 -1
- package/dist/components/LeaveDialog/LeaveDialog.js.map +1 -1
- package/dist/components/LinksDisplay/LinksDisplay.js +1 -1
- package/dist/components/LinksDisplay/LinksDisplay.js.map +1 -1
- package/dist/components/Panel/Panel.js +5 -2
- package/dist/components/Panel/Panel.js.map +1 -1
- package/dist/components/Panel/PanelActions.js +1 -1
- package/dist/components/Panel/PanelActions.js.map +1 -1
- package/dist/components/Panel/PanelContent.js +1 -1
- package/dist/components/Panel/PanelContent.js.map +1 -1
- package/dist/components/Panel/PanelHeader.js +1 -1
- package/dist/components/Panel/PanelHeader.js.map +1 -1
- package/dist/components/Panel/PanelPluginLoader.js +1 -1
- package/dist/components/Panel/PanelPluginLoader.js.map +1 -1
- package/dist/components/Panel/useSelectionItemActions.js +1 -1
- package/dist/components/Panel/useSelectionItemActions.js.map +1 -1
- package/dist/components/PanelDrawer/PanelDrawer.js +1 -1
- package/dist/components/PanelDrawer/PanelDrawer.js.map +1 -1
- package/dist/components/PanelDrawer/PanelEditorForm.js +1 -1
- package/dist/components/PanelDrawer/PanelEditorForm.js.map +1 -1
- package/dist/components/PanelDrawer/PanelPreview.js +1 -1
- package/dist/components/PanelDrawer/PanelPreview.js.map +1 -1
- package/dist/components/PanelDrawer/PanelQueriesSharedControls.js +1 -1
- package/dist/components/PanelDrawer/PanelQueriesSharedControls.js.map +1 -1
- package/dist/components/PanelGroupDialog/PanelGroupDialog.js +1 -1
- package/dist/components/PanelGroupDialog/PanelGroupDialog.js.map +1 -1
- package/dist/components/PanelGroupDialog/PanelGroupEditorForm.js +1 -1
- package/dist/components/PanelGroupDialog/PanelGroupEditorForm.js.map +1 -1
- package/dist/components/QuerySummaryTable/QuerySummaryTable.js +1 -1
- package/dist/components/QuerySummaryTable/QuerySummaryTable.js.map +1 -1
- package/dist/components/QueryViewerDialog/QueryViewerDialog.js +1 -1
- package/dist/components/QueryViewerDialog/QueryViewerDialog.js.map +1 -1
- package/dist/components/SaveChangesConfirmationDialog/SaveChangesConfirmationDialog.js +1 -1
- package/dist/components/SaveChangesConfirmationDialog/SaveChangesConfirmationDialog.js.map +1 -1
- package/dist/components/Variables/EditVariablesButton.js +1 -1
- package/dist/components/Variables/EditVariablesButton.js.map +1 -1
- package/dist/components/Variables/ListVariableListBox.js +1 -1
- package/dist/components/Variables/ListVariableListBox.js.map +1 -1
- package/dist/components/Variables/Variable.js +2 -2
- package/dist/components/Variables/Variable.js.map +1 -1
- package/dist/components/Variables/VariableEditor.d.ts.map +1 -1
- package/dist/components/Variables/VariableEditor.js +56 -22
- package/dist/components/Variables/VariableEditor.js.map +1 -1
- package/dist/components/Variables/VariableList.js +1 -1
- package/dist/components/Variables/VariableList.js.map +1 -1
- package/dist/context/DashboardProvider/DashboardProvider.d.ts.map +1 -1
- package/dist/context/DashboardProvider/DashboardProvider.js +1 -1
- package/dist/context/DashboardProvider/DashboardProvider.js.map +1 -1
- package/dist/context/DatasourceStoreProvider.d.ts +1 -1
- package/dist/context/DatasourceStoreProvider.d.ts.map +1 -1
- package/dist/context/DatasourceStoreProvider.js +5 -2
- package/dist/context/DatasourceStoreProvider.js.map +1 -1
- package/dist/context/PanelEditorProvider/PanelEditorProvider.js +1 -1
- package/dist/context/PanelEditorProvider/PanelEditorProvider.js.map +1 -1
- package/dist/context/VariableProvider/VariableProvider.d.ts +2 -1
- package/dist/context/VariableProvider/VariableProvider.d.ts.map +1 -1
- package/dist/context/VariableProvider/VariableProvider.js +12 -8
- package/dist/context/VariableProvider/VariableProvider.js.map +1 -1
- package/dist/keyboard-shortcuts/PanelFocusProvider.js +1 -1
- package/dist/keyboard-shortcuts/PanelFocusProvider.js.map +1 -1
- package/dist/test/datasource-provider.d.ts +1 -1
- package/dist/test/datasource-provider.d.ts.map +1 -1
- package/dist/test/datasource-provider.js.map +1 -1
- package/dist/test/render.js +1 -1
- package/dist/test/render.js.map +1 -1
- package/dist/views/ViewDashboard/DashboardApp.js +1 -1
- package/dist/views/ViewDashboard/DashboardApp.js.map +1 -1
- package/dist/views/ViewDashboard/ViewDashboard.js +1 -1
- package/dist/views/ViewDashboard/ViewDashboard.js.map +1 -1
- package/package.json +6 -9
|
@@ -79,7 +79,10 @@ const Panel = /*#__PURE__*/ (0, _react.memo)(function Panel(props) {
|
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
81
|
try {
|
|
82
|
-
const plugin = await getPlugin(
|
|
82
|
+
const plugin = await getPlugin({
|
|
83
|
+
kind: 'Panel',
|
|
84
|
+
name: panelPluginKind
|
|
85
|
+
});
|
|
83
86
|
// More defensive checking for plugin and actions
|
|
84
87
|
if (!plugin || typeof plugin !== 'object' || !plugin.actions || !Array.isArray(plugin.actions) || plugin.actions.length === 0) {
|
|
85
88
|
setPluginActions([]);
|
|
@@ -166,25 +166,25 @@ function VariableEditor(props) {
|
|
|
166
166
|
};
|
|
167
167
|
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
|
|
168
168
|
children: [
|
|
169
|
-
currentEditingVariableDefinition && /*#__PURE__*/ (0, _jsxruntime.jsx)(
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
});
|
|
180
|
-
},
|
|
181
|
-
onClose: ()=>{
|
|
182
|
-
if (variableFormAction === 'create') {
|
|
183
|
-
removeVariable(variableEditIdx);
|
|
184
|
-
}
|
|
169
|
+
currentEditingVariableDefinition && /*#__PURE__*/ (0, _jsxruntime.jsx)(VariableEditorFormWithContext, {
|
|
170
|
+
variableDefinitions: variableDefinitions,
|
|
171
|
+
externalVariableDefinitions: externalVariableDefinitions,
|
|
172
|
+
builtinVariableDefinitions: builtinVariableDefinitions,
|
|
173
|
+
currentEditingVariableDefinition: currentEditingVariableDefinition,
|
|
174
|
+
variableFormAction: variableFormAction,
|
|
175
|
+
onActionChange: setVariableFormAction,
|
|
176
|
+
onSave: (definition)=>{
|
|
177
|
+
setVariableDefinitions((draft)=>{
|
|
178
|
+
draft[variableEditIdx] = definition;
|
|
185
179
|
setVariableEditIdx(null);
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
|
+
onClose: ()=>{
|
|
183
|
+
if (variableFormAction === 'create') {
|
|
184
|
+
removeVariable(variableEditIdx);
|
|
186
185
|
}
|
|
187
|
-
|
|
186
|
+
setVariableEditIdx(null);
|
|
187
|
+
}
|
|
188
188
|
}),
|
|
189
189
|
!currentEditingVariableDefinition && /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
|
|
190
190
|
children: [
|
|
@@ -535,6 +535,40 @@ function VariableEditor(props) {
|
|
|
535
535
|
const TableCell = (0, _material.styled)(_material.TableCell)(({ theme })=>({
|
|
536
536
|
borderBottom: `solid 1px ${theme.palette.divider}`
|
|
537
537
|
}));
|
|
538
|
+
function VariableEditorFormWithContext({ variableDefinitions, externalVariableDefinitions, builtinVariableDefinitions, currentEditingVariableDefinition, variableFormAction, onActionChange, onSave, onClose }) {
|
|
539
|
+
const { initialVariableValues, isLoading } = (0, _pluginsystem.useResolveListVariableValues)(variableDefinitions);
|
|
540
|
+
if (isLoading) {
|
|
541
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Stack, {
|
|
542
|
+
sx: {
|
|
543
|
+
display: 'flex',
|
|
544
|
+
alignItems: 'center',
|
|
545
|
+
justifyContent: 'center',
|
|
546
|
+
height: '100%',
|
|
547
|
+
width: '100%',
|
|
548
|
+
overflow: 'hidden'
|
|
549
|
+
},
|
|
550
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.CircularProgress, {
|
|
551
|
+
"aria-label": "loading"
|
|
552
|
+
})
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_context.VariableProvider, {
|
|
556
|
+
initialVariableDefinitions: variableDefinitions,
|
|
557
|
+
externalVariableDefinitions: externalVariableDefinitions,
|
|
558
|
+
builtinVariableDefinitions: builtinVariableDefinitions,
|
|
559
|
+
initialVariableValues: initialVariableValues,
|
|
560
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.ValidationProvider, {
|
|
561
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.VariableEditorForm, {
|
|
562
|
+
initialVariableDefinition: currentEditingVariableDefinition,
|
|
563
|
+
action: variableFormAction,
|
|
564
|
+
isDraft: true,
|
|
565
|
+
onActionChange: onActionChange,
|
|
566
|
+
onSave: onSave,
|
|
567
|
+
onClose: onClose
|
|
568
|
+
})
|
|
569
|
+
})
|
|
570
|
+
});
|
|
571
|
+
}
|
|
538
572
|
function VariableName(props) {
|
|
539
573
|
const { name, state } = props;
|
|
540
574
|
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
|
|
@@ -82,7 +82,10 @@ function DatasourceStoreProvider(props) {
|
|
|
82
82
|
const { kind } = selector;
|
|
83
83
|
const [{ spec, proxyUrl }, plugin] = await Promise.all([
|
|
84
84
|
findDatasource(selector),
|
|
85
|
-
getPlugin(
|
|
85
|
+
getPlugin({
|
|
86
|
+
kind: 'Datasource',
|
|
87
|
+
name: kind
|
|
88
|
+
})
|
|
86
89
|
]);
|
|
87
90
|
// allows extending client
|
|
88
91
|
const client = plugin.createClient(spec.plugin.spec, {
|
|
@@ -55,7 +55,6 @@ const _middleware = require("zustand/middleware");
|
|
|
55
55
|
const _shallow = require("zustand/shallow");
|
|
56
56
|
const _immer1 = require("immer");
|
|
57
57
|
const _pluginsystem = require("@perses-dev/plugin-system");
|
|
58
|
-
const _core = require("@perses-dev/core");
|
|
59
58
|
const _spec = require("@perses-dev/spec");
|
|
60
59
|
const _utils = require("./utils");
|
|
61
60
|
const _hydrationUtils = require("./hydrationUtils");
|
|
@@ -204,7 +203,7 @@ function PluginProvider({ children, builtinVariables }) {
|
|
|
204
203
|
kind: 'BuiltinVariable',
|
|
205
204
|
spec: {
|
|
206
205
|
name: '__range',
|
|
207
|
-
value: ()=>(0, _spec.formatDuration)((0,
|
|
206
|
+
value: ()=>(0, _spec.formatDuration)((0, _spec.intervalToDuration)(absoluteTimeRange)),
|
|
208
207
|
source: 'Dashboard',
|
|
209
208
|
display: {
|
|
210
209
|
name: '__range',
|
|
@@ -258,8 +257,12 @@ function PluginProvider({ children, builtinVariables }) {
|
|
|
258
257
|
})
|
|
259
258
|
});
|
|
260
259
|
}
|
|
261
|
-
function createVariableDefinitionStore({ initialVariableDefinitions = [], externalVariableDefinitions = [], queryParams }) {
|
|
262
|
-
const
|
|
260
|
+
function createVariableDefinitionStore({ initialVariableDefinitions = [], externalVariableDefinitions = [], queryParams, initialVariableValues }) {
|
|
261
|
+
const queryParamValues = (0, _queryparams.getInitalValuesFromQueryParameters)(queryParams ? queryParams[0] : {});
|
|
262
|
+
const initialParams = {
|
|
263
|
+
...queryParamValues,
|
|
264
|
+
...initialVariableValues
|
|
265
|
+
};
|
|
263
266
|
const store = (0, _zustand.createStore)()((0, _middleware.devtools)((0, _immer.immer)((set, get)=>({
|
|
264
267
|
variableState: (0, _hydrationUtils.hydrateVariableDefinitionStates)(initialVariableDefinitions, initialParams, externalVariableDefinitions),
|
|
265
268
|
variableDefinitions: initialVariableDefinitions,
|
|
@@ -365,10 +368,11 @@ function createVariableDefinitionStore({ initialVariableDefinitions = [], extern
|
|
|
365
368
|
}))));
|
|
366
369
|
return store;
|
|
367
370
|
}
|
|
368
|
-
function VariableProvider({ children, initialVariableDefinitions = [], externalVariableDefinitions = [], builtinVariableDefinitions = [] }) {
|
|
371
|
+
function VariableProvider({ children, initialVariableDefinitions = [], externalVariableDefinitions = [], builtinVariableDefinitions = [], initialVariableValues }) {
|
|
369
372
|
const [store] = (0, _react.useState)(()=>createVariableDefinitionStore({
|
|
370
373
|
initialVariableDefinitions,
|
|
371
|
-
externalVariableDefinitions
|
|
374
|
+
externalVariableDefinitions,
|
|
375
|
+
initialVariableValues
|
|
372
376
|
}));
|
|
373
377
|
return /*#__PURE__*/ (0, _jsxruntime.jsx)(VariableDefinitionStoreContext.Provider, {
|
|
374
378
|
value: store,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
2
|
// Copyright The Perses Authors
|
|
2
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,7 +11,6 @@
|
|
|
10
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
12
|
// See the License for the specific language governing permissions and
|
|
12
13
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
14
|
import { Button } from '@mui/material';
|
|
15
15
|
import AddGroupIcon from 'mdi-material-ui/PlusBoxOutline';
|
|
16
16
|
import { InfoTooltip } from '@perses-dev/components';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/AddGroupButton/AddGroupButton.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Button } from '@mui/material';\nimport AddGroupIcon from 'mdi-material-ui/PlusBoxOutline';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { ReactElement } from 'react';\nimport { TOOLTIP_TEXT, editButtonStyle } from '../../constants';\nimport { useDashboardActions } from '../../context';\n\nexport const AddGroupButton = (): ReactElement => {\n const { openAddPanelGroup } = useDashboardActions();\n\n return (\n <InfoTooltip description={TOOLTIP_TEXT.addGroup}>\n <Button\n startIcon={<AddGroupIcon />}\n onClick={openAddPanelGroup}\n aria-label={TOOLTIP_TEXT.addGroup}\n sx={editButtonStyle}\n >\n Panel Group\n </Button>\n </InfoTooltip>\n );\n};\n"],"names":["Button","AddGroupIcon","InfoTooltip","TOOLTIP_TEXT","editButtonStyle","useDashboardActions","AddGroupButton","openAddPanelGroup","description","addGroup","startIcon","onClick","aria-label","sx"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC
|
|
1
|
+
{"version":3,"sources":["../../../src/components/AddGroupButton/AddGroupButton.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Button } from '@mui/material';\nimport AddGroupIcon from 'mdi-material-ui/PlusBoxOutline';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { ReactElement } from 'react';\nimport { TOOLTIP_TEXT, editButtonStyle } from '../../constants';\nimport { useDashboardActions } from '../../context';\n\nexport const AddGroupButton = (): ReactElement => {\n const { openAddPanelGroup } = useDashboardActions();\n\n return (\n <InfoTooltip description={TOOLTIP_TEXT.addGroup}>\n <Button\n startIcon={<AddGroupIcon />}\n onClick={openAddPanelGroup}\n aria-label={TOOLTIP_TEXT.addGroup}\n sx={editButtonStyle}\n >\n Panel Group\n </Button>\n </InfoTooltip>\n );\n};\n"],"names":["Button","AddGroupIcon","InfoTooltip","TOOLTIP_TEXT","editButtonStyle","useDashboardActions","AddGroupButton","openAddPanelGroup","description","addGroup","startIcon","onClick","aria-label","sx"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,MAAM,QAAQ,gBAAgB;AACvC,OAAOC,kBAAkB,iCAAiC;AAC1D,SAASC,WAAW,QAAQ,yBAAyB;AAErD,SAASC,YAAY,EAAEC,eAAe,QAAQ,kBAAkB;AAChE,SAASC,mBAAmB,QAAQ,gBAAgB;AAEpD,OAAO,MAAMC,iBAAiB;IAC5B,MAAM,EAAEC,iBAAiB,EAAE,GAAGF;IAE9B,qBACE,KAACH;QAAYM,aAAaL,aAAaM,QAAQ;kBAC7C,cAAA,KAACT;YACCU,yBAAW,KAACT;YACZU,SAASJ;YACTK,cAAYT,aAAaM,QAAQ;YACjCI,IAAIT;sBACL;;;AAKP,EAAE"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
2
|
// Copyright The Perses Authors
|
|
2
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,7 +11,6 @@
|
|
|
10
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
12
|
// See the License for the specific language governing permissions and
|
|
12
13
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
14
|
import { Button } from '@mui/material';
|
|
15
15
|
import AddPanelIcon from 'mdi-material-ui/ChartBoxPlusOutline';
|
|
16
16
|
import { InfoTooltip } from '@perses-dev/components';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/AddPanelButton/AddPanelButton.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Button, ButtonProps } from '@mui/material';\nimport AddPanelIcon from 'mdi-material-ui/ChartBoxPlusOutline';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { ReactElement } from 'react';\nimport { TOOLTIP_TEXT, editButtonStyle } from '../../constants';\nimport { useDashboardActions } from '../../context';\n\nexport interface AddPanelButtonProps extends Pick<ButtonProps, 'fullWidth'> {\n /**\n * The variant to use to display the button.\n */\n variant?: 'text' | 'outlined';\n\n /**\n * The color to use to display the button.\n */\n color?: 'primary' | 'secondary';\n\n /**\n * The label used inside the button.\n */\n label?: string;\n}\n\nexport const AddPanelButton = ({\n variant = 'text',\n color = 'primary',\n label = 'Panel',\n fullWidth,\n}: AddPanelButtonProps): ReactElement => {\n const { openAddPanel } = useDashboardActions();\n\n return (\n <InfoTooltip description={TOOLTIP_TEXT.addPanel}>\n <Button\n startIcon={<AddPanelIcon />}\n onClick={openAddPanel}\n aria-label={TOOLTIP_TEXT.addPanel}\n variant={variant}\n color={color}\n fullWidth={fullWidth}\n sx={editButtonStyle}\n >\n {label}\n </Button>\n </InfoTooltip>\n );\n};\n"],"names":["Button","AddPanelIcon","InfoTooltip","TOOLTIP_TEXT","editButtonStyle","useDashboardActions","AddPanelButton","variant","color","label","fullWidth","openAddPanel","description","addPanel","startIcon","onClick","aria-label","sx"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC
|
|
1
|
+
{"version":3,"sources":["../../../src/components/AddPanelButton/AddPanelButton.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Button, ButtonProps } from '@mui/material';\nimport AddPanelIcon from 'mdi-material-ui/ChartBoxPlusOutline';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { ReactElement } from 'react';\nimport { TOOLTIP_TEXT, editButtonStyle } from '../../constants';\nimport { useDashboardActions } from '../../context';\n\nexport interface AddPanelButtonProps extends Pick<ButtonProps, 'fullWidth'> {\n /**\n * The variant to use to display the button.\n */\n variant?: 'text' | 'outlined';\n\n /**\n * The color to use to display the button.\n */\n color?: 'primary' | 'secondary';\n\n /**\n * The label used inside the button.\n */\n label?: string;\n}\n\nexport const AddPanelButton = ({\n variant = 'text',\n color = 'primary',\n label = 'Panel',\n fullWidth,\n}: AddPanelButtonProps): ReactElement => {\n const { openAddPanel } = useDashboardActions();\n\n return (\n <InfoTooltip description={TOOLTIP_TEXT.addPanel}>\n <Button\n startIcon={<AddPanelIcon />}\n onClick={openAddPanel}\n aria-label={TOOLTIP_TEXT.addPanel}\n variant={variant}\n color={color}\n fullWidth={fullWidth}\n sx={editButtonStyle}\n >\n {label}\n </Button>\n </InfoTooltip>\n );\n};\n"],"names":["Button","AddPanelIcon","InfoTooltip","TOOLTIP_TEXT","editButtonStyle","useDashboardActions","AddPanelButton","variant","color","label","fullWidth","openAddPanel","description","addPanel","startIcon","onClick","aria-label","sx"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,MAAM,QAAqB,gBAAgB;AACpD,OAAOC,kBAAkB,sCAAsC;AAC/D,SAASC,WAAW,QAAQ,yBAAyB;AAErD,SAASC,YAAY,EAAEC,eAAe,QAAQ,kBAAkB;AAChE,SAASC,mBAAmB,QAAQ,gBAAgB;AAmBpD,OAAO,MAAMC,iBAAiB,CAAC,EAC7BC,UAAU,MAAM,EAChBC,QAAQ,SAAS,EACjBC,QAAQ,OAAO,EACfC,SAAS,EACW;IACpB,MAAM,EAAEC,YAAY,EAAE,GAAGN;IAEzB,qBACE,KAACH;QAAYU,aAAaT,aAAaU,QAAQ;kBAC7C,cAAA,KAACb;YACCc,yBAAW,KAACb;YACZc,SAASJ;YACTK,cAAYb,aAAaU,QAAQ;YACjCN,SAASA;YACTC,OAAOA;YACPE,WAAWA;YACXO,IAAIb;sBAEHK;;;AAIT,EAAE"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
2
|
// Copyright The Perses Authors
|
|
2
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,7 +11,6 @@
|
|
|
10
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
12
|
// See the License for the specific language governing permissions and
|
|
12
13
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
14
|
import { Box } from '@mui/material';
|
|
15
15
|
import { ErrorBoundary, ErrorAlert } from '@perses-dev/components';
|
|
16
16
|
import { useRef } from 'react';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/Dashboard/Dashboard.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, BoxProps } from '@mui/material';\nimport { ErrorBoundary, ErrorAlert } from '@perses-dev/components';\nimport { ReactElement, useRef } from 'react';\nimport { usePanelGroupIds } from '../../context';\nimport { GridLayout } from '../GridLayout';\nimport { EmptyDashboard, EmptyDashboardProps } from '../EmptyDashboard';\nimport { PanelOptions } from '../Panel';\n\nexport type DashboardProps = BoxProps & {\n /**\n * Props for `EmptyDashboard` component that will be rendered when the dashboard\n * is empty (i.e. has no panel groups). If not specified, the defaults will\n * be used.\n */\n emptyDashboardProps?: EmptyDashboardProps;\n panelOptions?: PanelOptions;\n};\nconst HEADER_HEIGHT = 165; // Approximate height of the header in dashboard view (including the navbar and variables toolbar)\n\n/**\n * Renders a Dashboard for the provided Dashboard spec.\n */\nexport function Dashboard({ emptyDashboardProps, panelOptions, ...boxProps }: DashboardProps): ReactElement {\n const panelGroupIds = usePanelGroupIds();\n const boxRef = useRef<HTMLDivElement>(null);\n const isEmpty = !panelGroupIds.length;\n const dashboardTopPosition = boxRef.current?.getBoundingClientRect().top ?? HEADER_HEIGHT;\n const panelFullHeight = window.innerHeight - dashboardTopPosition - window.scrollY;\n\n return (\n <Box {...boxProps} sx={{ height: '100%' }} ref={boxRef}>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n {isEmpty && (\n <Box sx={{ height: '100%', display: 'flex', alignItems: 'center' }}>\n <EmptyDashboard {...emptyDashboardProps} />\n </Box>\n )}\n {!isEmpty &&\n panelGroupIds.map((panelGroupId) => (\n <GridLayout\n key={panelGroupId}\n panelGroupId={panelGroupId}\n panelOptions={panelOptions}\n panelFullHeight={panelFullHeight}\n />\n ))}\n </ErrorBoundary>\n </Box>\n );\n}\n"],"names":["Box","ErrorBoundary","ErrorAlert","useRef","usePanelGroupIds","GridLayout","EmptyDashboard","HEADER_HEIGHT","Dashboard","emptyDashboardProps","panelOptions","boxProps","panelGroupIds","boxRef","isEmpty","length","dashboardTopPosition","current","getBoundingClientRect","top","panelFullHeight","window","innerHeight","scrollY","sx","height","ref","FallbackComponent","display","alignItems","map","panelGroupId"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC
|
|
1
|
+
{"version":3,"sources":["../../../src/components/Dashboard/Dashboard.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, BoxProps } from '@mui/material';\nimport { ErrorBoundary, ErrorAlert } from '@perses-dev/components';\nimport { ReactElement, useRef } from 'react';\nimport { usePanelGroupIds } from '../../context';\nimport { GridLayout } from '../GridLayout';\nimport { EmptyDashboard, EmptyDashboardProps } from '../EmptyDashboard';\nimport { PanelOptions } from '../Panel';\n\nexport type DashboardProps = BoxProps & {\n /**\n * Props for `EmptyDashboard` component that will be rendered when the dashboard\n * is empty (i.e. has no panel groups). If not specified, the defaults will\n * be used.\n */\n emptyDashboardProps?: EmptyDashboardProps;\n panelOptions?: PanelOptions;\n};\nconst HEADER_HEIGHT = 165; // Approximate height of the header in dashboard view (including the navbar and variables toolbar)\n\n/**\n * Renders a Dashboard for the provided Dashboard spec.\n */\nexport function Dashboard({ emptyDashboardProps, panelOptions, ...boxProps }: DashboardProps): ReactElement {\n const panelGroupIds = usePanelGroupIds();\n const boxRef = useRef<HTMLDivElement>(null);\n const isEmpty = !panelGroupIds.length;\n const dashboardTopPosition = boxRef.current?.getBoundingClientRect().top ?? HEADER_HEIGHT;\n const panelFullHeight = window.innerHeight - dashboardTopPosition - window.scrollY;\n\n return (\n <Box {...boxProps} sx={{ height: '100%' }} ref={boxRef}>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n {isEmpty && (\n <Box sx={{ height: '100%', display: 'flex', alignItems: 'center' }}>\n <EmptyDashboard {...emptyDashboardProps} />\n </Box>\n )}\n {!isEmpty &&\n panelGroupIds.map((panelGroupId) => (\n <GridLayout\n key={panelGroupId}\n panelGroupId={panelGroupId}\n panelOptions={panelOptions}\n panelFullHeight={panelFullHeight}\n />\n ))}\n </ErrorBoundary>\n </Box>\n );\n}\n"],"names":["Box","ErrorBoundary","ErrorAlert","useRef","usePanelGroupIds","GridLayout","EmptyDashboard","HEADER_HEIGHT","Dashboard","emptyDashboardProps","panelOptions","boxProps","panelGroupIds","boxRef","isEmpty","length","dashboardTopPosition","current","getBoundingClientRect","top","panelFullHeight","window","innerHeight","scrollY","sx","height","ref","FallbackComponent","display","alignItems","map","panelGroupId"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,GAAG,QAAkB,gBAAgB;AAC9C,SAASC,aAAa,EAAEC,UAAU,QAAQ,yBAAyB;AACnE,SAAuBC,MAAM,QAAQ,QAAQ;AAC7C,SAASC,gBAAgB,QAAQ,gBAAgB;AACjD,SAASC,UAAU,QAAQ,gBAAgB;AAC3C,SAASC,cAAc,QAA6B,oBAAoB;AAYxE,MAAMC,gBAAgB,KAAK,kGAAkG;AAE7H;;CAEC,GACD,OAAO,SAASC,UAAU,EAAEC,mBAAmB,EAAEC,YAAY,EAAE,GAAGC,UAA0B;IAC1F,MAAMC,gBAAgBR;IACtB,MAAMS,SAASV,OAAuB;IACtC,MAAMW,UAAU,CAACF,cAAcG,MAAM;IACrC,MAAMC,uBAAuBH,OAAOI,OAAO,EAAEC,wBAAwBC,OAAOZ;IAC5E,MAAMa,kBAAkBC,OAAOC,WAAW,GAAGN,uBAAuBK,OAAOE,OAAO;IAElF,qBACE,KAACvB;QAAK,GAAGW,QAAQ;QAAEa,IAAI;YAAEC,QAAQ;QAAO;QAAGC,KAAKb;kBAC9C,cAAA,MAACZ;YAAc0B,mBAAmBzB;;gBAC/BY,yBACC,KAACd;oBAAIwB,IAAI;wBAAEC,QAAQ;wBAAQG,SAAS;wBAAQC,YAAY;oBAAS;8BAC/D,cAAA,KAACvB;wBAAgB,GAAGG,mBAAmB;;;gBAG1C,CAACK,WACAF,cAAckB,GAAG,CAAC,CAACC,6BACjB,KAAC1B;wBAEC0B,cAAcA;wBACdrB,cAAcA;wBACdU,iBAAiBA;uBAHZW;;;;AASnB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
1
2
|
// Copyright The Perses Authors
|
|
2
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,7 +11,6 @@
|
|
|
10
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
12
|
// See the License for the specific language governing permissions and
|
|
12
13
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
14
14
|
import { useState } from 'react';
|
|
15
15
|
import { Button, Stack, Box, Typography, IconButton, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Collapse } from '@mui/material';
|
|
16
16
|
import AddIcon from 'mdi-material-ui/Plus';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/DashboardLinks/DashboardLinksEditor.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { useState, ReactElement } from 'react';\nimport {\n Button,\n Stack,\n Box,\n Typography,\n IconButton,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n Collapse,\n} from '@mui/material';\nimport AddIcon from 'mdi-material-ui/Plus';\nimport TrashIcon from 'mdi-material-ui/TrashCan';\nimport ArrowUp from 'mdi-material-ui/ArrowUp';\nimport ArrowDown from 'mdi-material-ui/ArrowDown';\nimport PencilIcon from 'mdi-material-ui/Pencil';\nimport ChevronUp from 'mdi-material-ui/ChevronUp';\nimport { Link } from '@perses-dev/spec';\nimport { useImmer } from 'use-immer';\nimport { InfoTooltip, LinkEditorForm } from '@perses-dev/components';\nimport { useDiscardChangesConfirmationDialog } from '../../context';\n\nexport interface DashboardLinksEditorProps {\n links: Link[];\n onChange: (links: Link[]) => void;\n onCancel: () => void;\n}\n\nconst DEFAULT_LINK: Link = {\n url: '',\n name: '',\n tooltip: '',\n renderVariables: true,\n targetBlank: true,\n};\n\nexport function DashboardLinksEditor({\n links: initialLinks,\n onChange,\n onCancel,\n}: DashboardLinksEditorProps): ReactElement {\n const [links, setLinks] = useImmer(initialLinks);\n const [expandedIndex, setExpandedIndex] = useState<number | null>(null);\n\n const { openDiscardChangesConfirmationDialog, closeDiscardChangesConfirmationDialog } =\n useDiscardChangesConfirmationDialog();\n\n const handleCancel = (): void => {\n if (JSON.stringify(initialLinks) !== JSON.stringify(links)) {\n openDiscardChangesConfirmationDialog({\n onDiscardChanges: () => {\n closeDiscardChangesConfirmationDialog();\n onCancel();\n },\n onCancel: closeDiscardChangesConfirmationDialog,\n });\n } else {\n onCancel();\n }\n };\n\n const handleAdd = (): void => {\n setLinks((draft) => {\n draft.push({ ...DEFAULT_LINK });\n });\n setExpandedIndex(links.length);\n };\n\n const handleRemove = (index: number): void => {\n setLinks((draft) => {\n draft.splice(index, 1);\n });\n if (expandedIndex === index) {\n setExpandedIndex(null);\n } else if (expandedIndex !== null && expandedIndex > index) {\n setExpandedIndex(expandedIndex - 1);\n }\n };\n\n const handleMoveUp = (index: number): void => {\n if (index === 0) return;\n setLinks((draft) => {\n const temp = draft[index - 1];\n if (temp && draft[index]) {\n draft[index - 1] = draft[index]!;\n draft[index] = temp;\n }\n });\n if (expandedIndex === index) {\n setExpandedIndex(index - 1);\n } else if (expandedIndex === index - 1) {\n setExpandedIndex(index);\n }\n };\n\n const handleMoveDown = (index: number): void => {\n if (index >= links.length - 1) return;\n setLinks((draft) => {\n const temp = draft[index + 1];\n if (temp && draft[index]) {\n draft[index + 1] = draft[index]!;\n draft[index] = temp;\n }\n });\n if (expandedIndex === index) {\n setExpandedIndex(index + 1);\n } else if (expandedIndex === index + 1) {\n setExpandedIndex(index);\n }\n };\n\n const handleUpdateLink = (index: number, link: Link): void => {\n setLinks((draft) => {\n draft[index] = link;\n });\n };\n\n const isValid = links.every((link) => link.url.trim().length > 0);\n\n return (\n <>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n padding: (theme) => theme.spacing(1, 2),\n borderBottom: (theme) => `1px solid ${theme.palette.divider}`,\n }}\n >\n <Typography variant=\"h2\">Edit Dashboard Links</Typography>\n <Stack direction=\"row\" spacing={1} marginLeft=\"auto\">\n <Button disabled={!isValid} variant=\"contained\" onClick={() => onChange(links)}>\n Apply\n </Button>\n <Button color=\"secondary\" variant=\"outlined\" onClick={handleCancel}>\n Cancel\n </Button>\n </Stack>\n </Box>\n <Box padding={2} sx={{ overflowY: 'scroll' }}>\n <Stack spacing={2}>\n <TableContainer>\n <Table size=\"small\" sx={{ tableLayout: 'fixed', width: '100%' }} aria-label=\"table of dashboard links\">\n <TableHead>\n <TableRow>\n <TableCell>Name</TableCell>\n <TableCell>URL</TableCell>\n <TableCell width={80}>New Tab</TableCell>\n <TableCell align=\"right\" width={180}>\n Actions\n </TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {links.map((link, index) => (\n <LinkTableRow\n key={index}\n link={link}\n index={index}\n isFirst={index === 0}\n isLast={index === links.length - 1}\n isExpanded={expandedIndex === index}\n onToggleExpand={() => setExpandedIndex(expandedIndex === index ? null : index)}\n onUpdate={(updatedLink) => handleUpdateLink(index, updatedLink)}\n onRemove={() => handleRemove(index)}\n onMoveUp={() => handleMoveUp(index)}\n onMoveDown={() => handleMoveDown(index)}\n />\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n {links.length === 0 && (\n <Typography variant=\"body1\" color=\"text.secondary\" fontStyle=\"italic\" textAlign=\"center\" py={4}>\n No links defined. Click 'Add Link' to create one.\n </Typography>\n )}\n <Button variant=\"contained\" startIcon={<AddIcon />} onClick={handleAdd} sx={{ alignSelf: 'flex-start' }}>\n Add Link\n </Button>\n </Stack>\n </Box>\n </>\n );\n}\n\ninterface LinkTableRowProps {\n link: Link;\n index: number;\n isFirst: boolean;\n isLast: boolean;\n isExpanded: boolean;\n onToggleExpand: () => void;\n onUpdate: (link: Link) => void;\n onRemove: () => void;\n onMoveUp: () => void;\n onMoveDown: () => void;\n}\n\nfunction LinkTableRow({\n link,\n index,\n isFirst,\n isLast,\n isExpanded,\n onToggleExpand,\n onUpdate,\n onRemove,\n onMoveUp,\n onMoveDown,\n}: LinkTableRowProps): ReactElement {\n const displayName = link.name?.trim() || `Link ${index + 1}`;\n const hasError = link.url.trim().length === 0;\n\n return (\n <>\n <TableRow>\n <TableCell component=\"th\" scope=\"row\" sx={{ fontWeight: 'bold', overflow: 'hidden', textOverflow: 'ellipsis' }}>\n {displayName}\n </TableCell>\n <TableCell\n sx={{\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n color: hasError ? 'error.main' : undefined,\n }}\n >\n <InfoTooltip description={link.url} enterDelay={100}>\n {link.url || '(no URL)'}\n </InfoTooltip>\n </TableCell>\n <TableCell>{link.targetBlank ? 'Yes' : 'No'}</TableCell>\n <TableCell align=\"right\" sx={{ whiteSpace: 'nowrap' }}>\n <IconButton onClick={onMoveUp} disabled={isFirst} aria-label=\"Move link up\">\n <ArrowUp />\n </IconButton>\n <IconButton onClick={onMoveDown} disabled={isLast} aria-label=\"Move link down\">\n <ArrowDown />\n </IconButton>\n <IconButton onClick={onToggleExpand} aria-label={isExpanded ? 'Collapse link editor' : 'Edit link'}>\n {isExpanded ? <ChevronUp /> : <PencilIcon />}\n </IconButton>\n <IconButton onClick={onRemove} aria-label=\"Remove link\">\n <TrashIcon />\n </IconButton>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell colSpan={4} sx={{ paddingBottom: 0, paddingTop: 0, border: isExpanded ? undefined : 'none' }}>\n <Collapse in={isExpanded} timeout=\"auto\" unmountOnExit>\n <Box sx={{ margin: 2 }}>\n <LinkEditorForm\n mode=\"modalEmbedded\"\n url={{\n value: link.url,\n label: 'URL',\n error: { hasError: hasError, helperText: hasError ? 'URL is required' : undefined },\n placeholder: 'https://example.com/dashboard?var=$variable',\n onChange: (url) => onUpdate({ ...link, url }),\n }}\n name={{\n value: link.name ?? '',\n label: 'Display Name',\n onChange: (name) => onUpdate({ ...link, name }),\n }}\n tooltip={{\n value: link.tooltip ?? '',\n label: 'Tooltip',\n onChange: (tooltip) => onUpdate({ ...link, tooltip }),\n }}\n renderVariables={{\n value: link.renderVariables ?? true,\n label: 'Replace variables in URL',\n onChange: (renderVariables) => onUpdate({ ...link, renderVariables }),\n }}\n newTabOpen={{\n value: link.targetBlank ?? true,\n label: 'Open in new tab',\n onChange: (targetBlank) => onUpdate({ ...link, targetBlank }),\n }}\n />\n </Box>\n </Collapse>\n </TableCell>\n </TableRow>\n </>\n );\n}\n"],"names":["useState","Button","Stack","Box","Typography","IconButton","Table","TableBody","TableCell","TableContainer","TableHead","TableRow","Collapse","AddIcon","TrashIcon","ArrowUp","ArrowDown","PencilIcon","ChevronUp","useImmer","InfoTooltip","LinkEditorForm","useDiscardChangesConfirmationDialog","DEFAULT_LINK","url","name","tooltip","renderVariables","targetBlank","DashboardLinksEditor","links","initialLinks","onChange","onCancel","setLinks","expandedIndex","setExpandedIndex","openDiscardChangesConfirmationDialog","closeDiscardChangesConfirmationDialog","handleCancel","JSON","stringify","onDiscardChanges","handleAdd","draft","push","length","handleRemove","index","splice","handleMoveUp","temp","handleMoveDown","handleUpdateLink","link","isValid","every","trim","sx","display","alignItems","padding","theme","spacing","borderBottom","palette","divider","variant","direction","marginLeft","disabled","onClick","color","overflowY","size","tableLayout","width","aria-label","align","map","LinkTableRow","isFirst","isLast","isExpanded","onToggleExpand","onUpdate","updatedLink","onRemove","onMoveUp","onMoveDown","fontStyle","textAlign","py","startIcon","alignSelf","displayName","hasError","component","scope","fontWeight","overflow","textOverflow","whiteSpace","undefined","description","enterDelay","colSpan","paddingBottom","paddingTop","border","in","timeout","unmountOnExit","margin","mode","value","label","error","helperText","placeholder","newTabOpen"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/DashboardLinks/DashboardLinksEditor.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { useState, ReactElement } from 'react';\nimport {\n Button,\n Stack,\n Box,\n Typography,\n IconButton,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n Collapse,\n} from '@mui/material';\nimport AddIcon from 'mdi-material-ui/Plus';\nimport TrashIcon from 'mdi-material-ui/TrashCan';\nimport ArrowUp from 'mdi-material-ui/ArrowUp';\nimport ArrowDown from 'mdi-material-ui/ArrowDown';\nimport PencilIcon from 'mdi-material-ui/Pencil';\nimport ChevronUp from 'mdi-material-ui/ChevronUp';\nimport { Link } from '@perses-dev/spec';\nimport { useImmer } from 'use-immer';\nimport { InfoTooltip, LinkEditorForm } from '@perses-dev/components';\nimport { useDiscardChangesConfirmationDialog } from '../../context';\n\nexport interface DashboardLinksEditorProps {\n links: Link[];\n onChange: (links: Link[]) => void;\n onCancel: () => void;\n}\n\nconst DEFAULT_LINK: Link = {\n url: '',\n name: '',\n tooltip: '',\n renderVariables: true,\n targetBlank: true,\n};\n\nexport function DashboardLinksEditor({\n links: initialLinks,\n onChange,\n onCancel,\n}: DashboardLinksEditorProps): ReactElement {\n const [links, setLinks] = useImmer(initialLinks);\n const [expandedIndex, setExpandedIndex] = useState<number | null>(null);\n\n const { openDiscardChangesConfirmationDialog, closeDiscardChangesConfirmationDialog } =\n useDiscardChangesConfirmationDialog();\n\n const handleCancel = (): void => {\n if (JSON.stringify(initialLinks) !== JSON.stringify(links)) {\n openDiscardChangesConfirmationDialog({\n onDiscardChanges: () => {\n closeDiscardChangesConfirmationDialog();\n onCancel();\n },\n onCancel: closeDiscardChangesConfirmationDialog,\n });\n } else {\n onCancel();\n }\n };\n\n const handleAdd = (): void => {\n setLinks((draft) => {\n draft.push({ ...DEFAULT_LINK });\n });\n setExpandedIndex(links.length);\n };\n\n const handleRemove = (index: number): void => {\n setLinks((draft) => {\n draft.splice(index, 1);\n });\n if (expandedIndex === index) {\n setExpandedIndex(null);\n } else if (expandedIndex !== null && expandedIndex > index) {\n setExpandedIndex(expandedIndex - 1);\n }\n };\n\n const handleMoveUp = (index: number): void => {\n if (index === 0) return;\n setLinks((draft) => {\n const temp = draft[index - 1];\n if (temp && draft[index]) {\n draft[index - 1] = draft[index]!;\n draft[index] = temp;\n }\n });\n if (expandedIndex === index) {\n setExpandedIndex(index - 1);\n } else if (expandedIndex === index - 1) {\n setExpandedIndex(index);\n }\n };\n\n const handleMoveDown = (index: number): void => {\n if (index >= links.length - 1) return;\n setLinks((draft) => {\n const temp = draft[index + 1];\n if (temp && draft[index]) {\n draft[index + 1] = draft[index]!;\n draft[index] = temp;\n }\n });\n if (expandedIndex === index) {\n setExpandedIndex(index + 1);\n } else if (expandedIndex === index + 1) {\n setExpandedIndex(index);\n }\n };\n\n const handleUpdateLink = (index: number, link: Link): void => {\n setLinks((draft) => {\n draft[index] = link;\n });\n };\n\n const isValid = links.every((link) => link.url.trim().length > 0);\n\n return (\n <>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n padding: (theme) => theme.spacing(1, 2),\n borderBottom: (theme) => `1px solid ${theme.palette.divider}`,\n }}\n >\n <Typography variant=\"h2\">Edit Dashboard Links</Typography>\n <Stack direction=\"row\" spacing={1} marginLeft=\"auto\">\n <Button disabled={!isValid} variant=\"contained\" onClick={() => onChange(links)}>\n Apply\n </Button>\n <Button color=\"secondary\" variant=\"outlined\" onClick={handleCancel}>\n Cancel\n </Button>\n </Stack>\n </Box>\n <Box padding={2} sx={{ overflowY: 'scroll' }}>\n <Stack spacing={2}>\n <TableContainer>\n <Table size=\"small\" sx={{ tableLayout: 'fixed', width: '100%' }} aria-label=\"table of dashboard links\">\n <TableHead>\n <TableRow>\n <TableCell>Name</TableCell>\n <TableCell>URL</TableCell>\n <TableCell width={80}>New Tab</TableCell>\n <TableCell align=\"right\" width={180}>\n Actions\n </TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {links.map((link, index) => (\n <LinkTableRow\n key={index}\n link={link}\n index={index}\n isFirst={index === 0}\n isLast={index === links.length - 1}\n isExpanded={expandedIndex === index}\n onToggleExpand={() => setExpandedIndex(expandedIndex === index ? null : index)}\n onUpdate={(updatedLink) => handleUpdateLink(index, updatedLink)}\n onRemove={() => handleRemove(index)}\n onMoveUp={() => handleMoveUp(index)}\n onMoveDown={() => handleMoveDown(index)}\n />\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n {links.length === 0 && (\n <Typography variant=\"body1\" color=\"text.secondary\" fontStyle=\"italic\" textAlign=\"center\" py={4}>\n No links defined. Click 'Add Link' to create one.\n </Typography>\n )}\n <Button variant=\"contained\" startIcon={<AddIcon />} onClick={handleAdd} sx={{ alignSelf: 'flex-start' }}>\n Add Link\n </Button>\n </Stack>\n </Box>\n </>\n );\n}\n\ninterface LinkTableRowProps {\n link: Link;\n index: number;\n isFirst: boolean;\n isLast: boolean;\n isExpanded: boolean;\n onToggleExpand: () => void;\n onUpdate: (link: Link) => void;\n onRemove: () => void;\n onMoveUp: () => void;\n onMoveDown: () => void;\n}\n\nfunction LinkTableRow({\n link,\n index,\n isFirst,\n isLast,\n isExpanded,\n onToggleExpand,\n onUpdate,\n onRemove,\n onMoveUp,\n onMoveDown,\n}: LinkTableRowProps): ReactElement {\n const displayName = link.name?.trim() || `Link ${index + 1}`;\n const hasError = link.url.trim().length === 0;\n\n return (\n <>\n <TableRow>\n <TableCell component=\"th\" scope=\"row\" sx={{ fontWeight: 'bold', overflow: 'hidden', textOverflow: 'ellipsis' }}>\n {displayName}\n </TableCell>\n <TableCell\n sx={{\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n color: hasError ? 'error.main' : undefined,\n }}\n >\n <InfoTooltip description={link.url} enterDelay={100}>\n {link.url || '(no URL)'}\n </InfoTooltip>\n </TableCell>\n <TableCell>{link.targetBlank ? 'Yes' : 'No'}</TableCell>\n <TableCell align=\"right\" sx={{ whiteSpace: 'nowrap' }}>\n <IconButton onClick={onMoveUp} disabled={isFirst} aria-label=\"Move link up\">\n <ArrowUp />\n </IconButton>\n <IconButton onClick={onMoveDown} disabled={isLast} aria-label=\"Move link down\">\n <ArrowDown />\n </IconButton>\n <IconButton onClick={onToggleExpand} aria-label={isExpanded ? 'Collapse link editor' : 'Edit link'}>\n {isExpanded ? <ChevronUp /> : <PencilIcon />}\n </IconButton>\n <IconButton onClick={onRemove} aria-label=\"Remove link\">\n <TrashIcon />\n </IconButton>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell colSpan={4} sx={{ paddingBottom: 0, paddingTop: 0, border: isExpanded ? undefined : 'none' }}>\n <Collapse in={isExpanded} timeout=\"auto\" unmountOnExit>\n <Box sx={{ margin: 2 }}>\n <LinkEditorForm\n mode=\"modalEmbedded\"\n url={{\n value: link.url,\n label: 'URL',\n error: { hasError: hasError, helperText: hasError ? 'URL is required' : undefined },\n placeholder: 'https://example.com/dashboard?var=$variable',\n onChange: (url) => onUpdate({ ...link, url }),\n }}\n name={{\n value: link.name ?? '',\n label: 'Display Name',\n onChange: (name) => onUpdate({ ...link, name }),\n }}\n tooltip={{\n value: link.tooltip ?? '',\n label: 'Tooltip',\n onChange: (tooltip) => onUpdate({ ...link, tooltip }),\n }}\n renderVariables={{\n value: link.renderVariables ?? true,\n label: 'Replace variables in URL',\n onChange: (renderVariables) => onUpdate({ ...link, renderVariables }),\n }}\n newTabOpen={{\n value: link.targetBlank ?? true,\n label: 'Open in new tab',\n onChange: (targetBlank) => onUpdate({ ...link, targetBlank }),\n }}\n />\n </Box>\n </Collapse>\n </TableCell>\n </TableRow>\n </>\n );\n}\n"],"names":["useState","Button","Stack","Box","Typography","IconButton","Table","TableBody","TableCell","TableContainer","TableHead","TableRow","Collapse","AddIcon","TrashIcon","ArrowUp","ArrowDown","PencilIcon","ChevronUp","useImmer","InfoTooltip","LinkEditorForm","useDiscardChangesConfirmationDialog","DEFAULT_LINK","url","name","tooltip","renderVariables","targetBlank","DashboardLinksEditor","links","initialLinks","onChange","onCancel","setLinks","expandedIndex","setExpandedIndex","openDiscardChangesConfirmationDialog","closeDiscardChangesConfirmationDialog","handleCancel","JSON","stringify","onDiscardChanges","handleAdd","draft","push","length","handleRemove","index","splice","handleMoveUp","temp","handleMoveDown","handleUpdateLink","link","isValid","every","trim","sx","display","alignItems","padding","theme","spacing","borderBottom","palette","divider","variant","direction","marginLeft","disabled","onClick","color","overflowY","size","tableLayout","width","aria-label","align","map","LinkTableRow","isFirst","isLast","isExpanded","onToggleExpand","onUpdate","updatedLink","onRemove","onMoveUp","onMoveDown","fontStyle","textAlign","py","startIcon","alignSelf","displayName","hasError","component","scope","fontWeight","overflow","textOverflow","whiteSpace","undefined","description","enterDelay","colSpan","paddingBottom","paddingTop","border","in","timeout","unmountOnExit","margin","mode","value","label","error","helperText","placeholder","newTabOpen"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
1
2
|
// Copyright The Perses Authors
|
|
2
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,7 +11,6 @@
|
|
|
10
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
12
|
// See the License for the specific language governing permissions and
|
|
12
13
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
14
14
|
import { useState } from 'react';
|
|
15
15
|
import { Button } from '@mui/material';
|
|
16
16
|
import PencilIcon from 'mdi-material-ui/PencilOutline';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/DashboardLinks/EditDashboardLinksButton.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement, useState } from 'react';\nimport { Button, ButtonProps } from '@mui/material';\nimport PencilIcon from 'mdi-material-ui/PencilOutline';\nimport { Drawer, InfoTooltip } from '@perses-dev/components';\nimport { Link } from '@perses-dev/spec';\nimport { TOOLTIP_TEXT, editButtonStyle } from '../../constants';\nimport { useDashboardLinks, useDashboardLinksActions } from '../../context';\nimport { DashboardLinksEditor } from './DashboardLinksEditor';\n\nexport interface EditDashboardLinksButtonProps extends Pick<ButtonProps, 'fullWidth'> {\n /**\n * The variant to use to display the button.\n */\n variant?: 'text' | 'outlined';\n\n /**\n * The color to use to display the button.\n */\n color?: 'primary' | 'secondary';\n\n /**\n * The label used inside the button.\n */\n label?: string;\n}\n\nexport function EditDashboardLinksButton({\n variant = 'text',\n label = 'Links',\n color = 'primary',\n fullWidth,\n}: EditDashboardLinksButtonProps): ReactElement {\n const [isLinksEditorOpen, setIsLinksEditorOpen] = useState(false);\n const links = useDashboardLinks();\n const { setLinks } = useDashboardLinksActions();\n\n const openLinksEditor = (): void => {\n setIsLinksEditorOpen(true);\n };\n\n const closeLinksEditor = (): void => {\n setIsLinksEditorOpen(false);\n };\n\n return (\n <>\n <InfoTooltip description={TOOLTIP_TEXT.editLinks}>\n <Button\n startIcon={<PencilIcon />}\n onClick={openLinksEditor}\n aria-label={TOOLTIP_TEXT.editLinks}\n variant={variant}\n color={color}\n fullWidth={fullWidth}\n sx={editButtonStyle}\n >\n {label}\n </Button>\n </InfoTooltip>\n <Drawer\n isOpen={isLinksEditorOpen}\n onClose={closeLinksEditor}\n PaperProps={{ sx: { width: '50%' } }}\n data-testid=\"dashboard-links-editor\"\n >\n <DashboardLinksEditor\n links={links}\n onCancel={closeLinksEditor}\n onChange={(updatedLinks: Link[]) => {\n setLinks?.(updatedLinks);\n setIsLinksEditorOpen(false);\n }}\n />\n </Drawer>\n </>\n );\n}\n"],"names":["useState","Button","PencilIcon","Drawer","InfoTooltip","TOOLTIP_TEXT","editButtonStyle","useDashboardLinks","useDashboardLinksActions","DashboardLinksEditor","EditDashboardLinksButton","variant","label","color","fullWidth","isLinksEditorOpen","setIsLinksEditorOpen","links","setLinks","openLinksEditor","closeLinksEditor","description","editLinks","startIcon","onClick","aria-label","sx","isOpen","onClose","PaperProps","width","data-testid","onCancel","onChange","updatedLinks"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC
|
|
1
|
+
{"version":3,"sources":["../../../src/components/DashboardLinks/EditDashboardLinksButton.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement, useState } from 'react';\nimport { Button, ButtonProps } from '@mui/material';\nimport PencilIcon from 'mdi-material-ui/PencilOutline';\nimport { Drawer, InfoTooltip } from '@perses-dev/components';\nimport { Link } from '@perses-dev/spec';\nimport { TOOLTIP_TEXT, editButtonStyle } from '../../constants';\nimport { useDashboardLinks, useDashboardLinksActions } from '../../context';\nimport { DashboardLinksEditor } from './DashboardLinksEditor';\n\nexport interface EditDashboardLinksButtonProps extends Pick<ButtonProps, 'fullWidth'> {\n /**\n * The variant to use to display the button.\n */\n variant?: 'text' | 'outlined';\n\n /**\n * The color to use to display the button.\n */\n color?: 'primary' | 'secondary';\n\n /**\n * The label used inside the button.\n */\n label?: string;\n}\n\nexport function EditDashboardLinksButton({\n variant = 'text',\n label = 'Links',\n color = 'primary',\n fullWidth,\n}: EditDashboardLinksButtonProps): ReactElement {\n const [isLinksEditorOpen, setIsLinksEditorOpen] = useState(false);\n const links = useDashboardLinks();\n const { setLinks } = useDashboardLinksActions();\n\n const openLinksEditor = (): void => {\n setIsLinksEditorOpen(true);\n };\n\n const closeLinksEditor = (): void => {\n setIsLinksEditorOpen(false);\n };\n\n return (\n <>\n <InfoTooltip description={TOOLTIP_TEXT.editLinks}>\n <Button\n startIcon={<PencilIcon />}\n onClick={openLinksEditor}\n aria-label={TOOLTIP_TEXT.editLinks}\n variant={variant}\n color={color}\n fullWidth={fullWidth}\n sx={editButtonStyle}\n >\n {label}\n </Button>\n </InfoTooltip>\n <Drawer\n isOpen={isLinksEditorOpen}\n onClose={closeLinksEditor}\n PaperProps={{ sx: { width: '50%' } }}\n data-testid=\"dashboard-links-editor\"\n >\n <DashboardLinksEditor\n links={links}\n onCancel={closeLinksEditor}\n onChange={(updatedLinks: Link[]) => {\n setLinks?.(updatedLinks);\n setIsLinksEditorOpen(false);\n }}\n />\n </Drawer>\n </>\n );\n}\n"],"names":["useState","Button","PencilIcon","Drawer","InfoTooltip","TOOLTIP_TEXT","editButtonStyle","useDashboardLinks","useDashboardLinksActions","DashboardLinksEditor","EditDashboardLinksButton","variant","label","color","fullWidth","isLinksEditorOpen","setIsLinksEditorOpen","links","setLinks","openLinksEditor","closeLinksEditor","description","editLinks","startIcon","onClick","aria-label","sx","isOpen","onClose","PaperProps","width","data-testid","onCancel","onChange","updatedLinks"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAAuBA,QAAQ,QAAQ,QAAQ;AAC/C,SAASC,MAAM,QAAqB,gBAAgB;AACpD,OAAOC,gBAAgB,gCAAgC;AACvD,SAASC,MAAM,EAAEC,WAAW,QAAQ,yBAAyB;AAE7D,SAASC,YAAY,EAAEC,eAAe,QAAQ,kBAAkB;AAChE,SAASC,iBAAiB,EAAEC,wBAAwB,QAAQ,gBAAgB;AAC5E,SAASC,oBAAoB,QAAQ,yBAAyB;AAmB9D,OAAO,SAASC,yBAAyB,EACvCC,UAAU,MAAM,EAChBC,QAAQ,OAAO,EACfC,QAAQ,SAAS,EACjBC,SAAS,EACqB;IAC9B,MAAM,CAACC,mBAAmBC,qBAAqB,GAAGhB,SAAS;IAC3D,MAAMiB,QAAQV;IACd,MAAM,EAAEW,QAAQ,EAAE,GAAGV;IAErB,MAAMW,kBAAkB;QACtBH,qBAAqB;IACvB;IAEA,MAAMI,mBAAmB;QACvBJ,qBAAqB;IACvB;IAEA,qBACE;;0BACE,KAACZ;gBAAYiB,aAAahB,aAAaiB,SAAS;0BAC9C,cAAA,KAACrB;oBACCsB,yBAAW,KAACrB;oBACZsB,SAASL;oBACTM,cAAYpB,aAAaiB,SAAS;oBAClCX,SAASA;oBACTE,OAAOA;oBACPC,WAAWA;oBACXY,IAAIpB;8BAEHM;;;0BAGL,KAACT;gBACCwB,QAAQZ;gBACRa,SAASR;gBACTS,YAAY;oBAAEH,IAAI;wBAAEI,OAAO;oBAAM;gBAAE;gBACnCC,eAAY;0BAEZ,cAAA,KAACtB;oBACCQ,OAAOA;oBACPe,UAAUZ;oBACVa,UAAU,CAACC;wBACThB,WAAWgB;wBACXlB,qBAAqB;oBACvB;;;;;AAKV"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
2
|
// Copyright The Perses Authors
|
|
2
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,7 +11,6 @@
|
|
|
10
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
12
|
// See the License for the specific language governing permissions and
|
|
12
13
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
14
|
import { useState } from 'react';
|
|
15
15
|
import { AppBar, Box, IconButton, Stack, useMediaQuery, useScrollTrigger, useTheme } from '@mui/material';
|
|
16
16
|
import PinOutline from 'mdi-material-ui/PinOutline';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/DashboardStickyToolbar/DashboardStickyToolbar.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement, useState } from 'react';\nimport {\n AppBar,\n Box,\n IconButton,\n Stack,\n SxProps,\n Theme,\n useMediaQuery,\n useScrollTrigger,\n useTheme,\n} from '@mui/material';\nimport PinOutline from 'mdi-material-ui/PinOutline';\nimport PinOffOutline from 'mdi-material-ui/PinOffOutline';\nimport { TimeRangeControls, useTimeZoneParams } from '@perses-dev/plugin-system';\nimport { VariableList } from '../Variables';\n\ninterface DashboardStickyToolbarProps {\n initialVariableIsSticky?: boolean;\n sx?: SxProps<Theme>;\n}\n\nexport function DashboardStickyToolbar(props: DashboardStickyToolbarProps): ReactElement {\n const [isPin, setIsPin] = useState(props.initialVariableIsSticky);\n\n const scrollTrigger = useScrollTrigger({ disableHysteresis: true });\n const isSticky = scrollTrigger && props.initialVariableIsSticky && isPin;\n\n const isBiggerThanMd = useMediaQuery(useTheme().breakpoints.up('md'));\n\n const { timeZone, setTimeZone } = useTimeZoneParams('local');\n\n return (\n // marginBottom={-1} counteracts the marginBottom={1} on every variable input.\n // The margin on the inputs is for spacing between inputs, but is not meant to add space to bottom of the container.\n <Box marginBottom={-1} data-testid=\"variable-list\">\n <AppBar\n color=\"inherit\"\n position={isSticky ? 'fixed' : 'static'}\n elevation={isSticky ? 4 : 0}\n sx={{ backgroundColor: 'inherit', ...props.sx }}\n >\n <Box\n display=\"flex\"\n justifyContent=\"space-between\"\n sx={{\n flexDirection: isBiggerThanMd ? 'row' : 'column',\n }}\n >\n <Box\n display=\"flex\"\n flexWrap={!isSticky && isBiggerThanMd ? 'wrap' : 'nowrap'}\n maxWidth={isSticky || !isBiggerThanMd ? '100vw' : '100%'}\n pt={1}\n pl={isSticky ? 1 : 0}\n mt={isSticky && isBiggerThanMd ? 0.5 : 0}\n ml={isSticky && isBiggerThanMd ? 0.5 : 0}\n sx={{\n overflowX: !isSticky && isBiggerThanMd ? 'hidden' : 'auto',\n // Firefox:\n scrollbarWidth: 'thin',\n // Safari and Chrome:\n '&::-webkit-scrollbar': {\n height: '8px',\n backgroundColor: (theme) => theme.palette.grey['300'],\n },\n '&::-webkit-scrollbar-thumb': {\n background: (theme) => theme.palette.grey['600'],\n },\n }}\n gap={1}\n >\n <VariableList />\n {props.initialVariableIsSticky && (\n <IconButton style={{ width: 'fit-content', height: 'fit-content' }} onClick={() => setIsPin(!isPin)}>\n {isPin ? <PinOutline /> : <PinOffOutline />}\n </IconButton>\n )}\n </Box>\n {isSticky && (\n <Stack\n m={isBiggerThanMd ? 1.5 : 1}\n mt={isBiggerThanMd ? 1.5 : 0}\n ml={isBiggerThanMd ? 1.5 : 'auto'}\n direction=\"row\"\n justifyContent=\"end\"\n >\n <TimeRangeControls timeZone={timeZone} onTimeZoneChange={(tz) => setTimeZone(tz.value)} />\n </Stack>\n )}\n </Box>\n </AppBar>\n </Box>\n );\n}\n"],"names":["useState","AppBar","Box","IconButton","Stack","useMediaQuery","useScrollTrigger","useTheme","PinOutline","PinOffOutline","TimeRangeControls","useTimeZoneParams","VariableList","DashboardStickyToolbar","props","isPin","setIsPin","initialVariableIsSticky","scrollTrigger","disableHysteresis","isSticky","isBiggerThanMd","breakpoints","up","timeZone","setTimeZone","marginBottom","data-testid","color","position","elevation","sx","backgroundColor","display","justifyContent","flexDirection","flexWrap","maxWidth","pt","pl","mt","ml","overflowX","scrollbarWidth","height","theme","palette","grey","background","gap","style","width","onClick","m","direction","onTimeZoneChange","tz","value"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC
|
|
1
|
+
{"version":3,"sources":["../../../src/components/DashboardStickyToolbar/DashboardStickyToolbar.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement, useState } from 'react';\nimport {\n AppBar,\n Box,\n IconButton,\n Stack,\n SxProps,\n Theme,\n useMediaQuery,\n useScrollTrigger,\n useTheme,\n} from '@mui/material';\nimport PinOutline from 'mdi-material-ui/PinOutline';\nimport PinOffOutline from 'mdi-material-ui/PinOffOutline';\nimport { TimeRangeControls, useTimeZoneParams } from '@perses-dev/plugin-system';\nimport { VariableList } from '../Variables';\n\ninterface DashboardStickyToolbarProps {\n initialVariableIsSticky?: boolean;\n sx?: SxProps<Theme>;\n}\n\nexport function DashboardStickyToolbar(props: DashboardStickyToolbarProps): ReactElement {\n const [isPin, setIsPin] = useState(props.initialVariableIsSticky);\n\n const scrollTrigger = useScrollTrigger({ disableHysteresis: true });\n const isSticky = scrollTrigger && props.initialVariableIsSticky && isPin;\n\n const isBiggerThanMd = useMediaQuery(useTheme().breakpoints.up('md'));\n\n const { timeZone, setTimeZone } = useTimeZoneParams('local');\n\n return (\n // marginBottom={-1} counteracts the marginBottom={1} on every variable input.\n // The margin on the inputs is for spacing between inputs, but is not meant to add space to bottom of the container.\n <Box marginBottom={-1} data-testid=\"variable-list\">\n <AppBar\n color=\"inherit\"\n position={isSticky ? 'fixed' : 'static'}\n elevation={isSticky ? 4 : 0}\n sx={{ backgroundColor: 'inherit', ...props.sx }}\n >\n <Box\n display=\"flex\"\n justifyContent=\"space-between\"\n sx={{\n flexDirection: isBiggerThanMd ? 'row' : 'column',\n }}\n >\n <Box\n display=\"flex\"\n flexWrap={!isSticky && isBiggerThanMd ? 'wrap' : 'nowrap'}\n maxWidth={isSticky || !isBiggerThanMd ? '100vw' : '100%'}\n pt={1}\n pl={isSticky ? 1 : 0}\n mt={isSticky && isBiggerThanMd ? 0.5 : 0}\n ml={isSticky && isBiggerThanMd ? 0.5 : 0}\n sx={{\n overflowX: !isSticky && isBiggerThanMd ? 'hidden' : 'auto',\n // Firefox:\n scrollbarWidth: 'thin',\n // Safari and Chrome:\n '&::-webkit-scrollbar': {\n height: '8px',\n backgroundColor: (theme) => theme.palette.grey['300'],\n },\n '&::-webkit-scrollbar-thumb': {\n background: (theme) => theme.palette.grey['600'],\n },\n }}\n gap={1}\n >\n <VariableList />\n {props.initialVariableIsSticky && (\n <IconButton style={{ width: 'fit-content', height: 'fit-content' }} onClick={() => setIsPin(!isPin)}>\n {isPin ? <PinOutline /> : <PinOffOutline />}\n </IconButton>\n )}\n </Box>\n {isSticky && (\n <Stack\n m={isBiggerThanMd ? 1.5 : 1}\n mt={isBiggerThanMd ? 1.5 : 0}\n ml={isBiggerThanMd ? 1.5 : 'auto'}\n direction=\"row\"\n justifyContent=\"end\"\n >\n <TimeRangeControls timeZone={timeZone} onTimeZoneChange={(tz) => setTimeZone(tz.value)} />\n </Stack>\n )}\n </Box>\n </AppBar>\n </Box>\n );\n}\n"],"names":["useState","AppBar","Box","IconButton","Stack","useMediaQuery","useScrollTrigger","useTheme","PinOutline","PinOffOutline","TimeRangeControls","useTimeZoneParams","VariableList","DashboardStickyToolbar","props","isPin","setIsPin","initialVariableIsSticky","scrollTrigger","disableHysteresis","isSticky","isBiggerThanMd","breakpoints","up","timeZone","setTimeZone","marginBottom","data-testid","color","position","elevation","sx","backgroundColor","display","justifyContent","flexDirection","flexWrap","maxWidth","pt","pl","mt","ml","overflowX","scrollbarWidth","height","theme","palette","grey","background","gap","style","width","onClick","m","direction","onTimeZoneChange","tz","value"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAAuBA,QAAQ,QAAQ,QAAQ;AAC/C,SACEC,MAAM,EACNC,GAAG,EACHC,UAAU,EACVC,KAAK,EAGLC,aAAa,EACbC,gBAAgB,EAChBC,QAAQ,QACH,gBAAgB;AACvB,OAAOC,gBAAgB,6BAA6B;AACpD,OAAOC,mBAAmB,gCAAgC;AAC1D,SAASC,iBAAiB,EAAEC,iBAAiB,QAAQ,4BAA4B;AACjF,SAASC,YAAY,QAAQ,eAAe;AAO5C,OAAO,SAASC,uBAAuBC,KAAkC;IACvE,MAAM,CAACC,OAAOC,SAAS,GAAGhB,SAASc,MAAMG,uBAAuB;IAEhE,MAAMC,gBAAgBZ,iBAAiB;QAAEa,mBAAmB;IAAK;IACjE,MAAMC,WAAWF,iBAAiBJ,MAAMG,uBAAuB,IAAIF;IAEnE,MAAMM,iBAAiBhB,cAAcE,WAAWe,WAAW,CAACC,EAAE,CAAC;IAE/D,MAAM,EAAEC,QAAQ,EAAEC,WAAW,EAAE,GAAGd,kBAAkB;IAEpD,OACE,8EAA8E;IAC9E,oHAAoH;kBACpH,KAACT;QAAIwB,cAAc,CAAC;QAAGC,eAAY;kBACjC,cAAA,KAAC1B;YACC2B,OAAM;YACNC,UAAUT,WAAW,UAAU;YAC/BU,WAAWV,WAAW,IAAI;YAC1BW,IAAI;gBAAEC,iBAAiB;gBAAW,GAAGlB,MAAMiB,EAAE;YAAC;sBAE9C,cAAA,MAAC7B;gBACC+B,SAAQ;gBACRC,gBAAe;gBACfH,IAAI;oBACFI,eAAed,iBAAiB,QAAQ;gBAC1C;;kCAEA,MAACnB;wBACC+B,SAAQ;wBACRG,UAAU,CAAChB,YAAYC,iBAAiB,SAAS;wBACjDgB,UAAUjB,YAAY,CAACC,iBAAiB,UAAU;wBAClDiB,IAAI;wBACJC,IAAInB,WAAW,IAAI;wBACnBoB,IAAIpB,YAAYC,iBAAiB,MAAM;wBACvCoB,IAAIrB,YAAYC,iBAAiB,MAAM;wBACvCU,IAAI;4BACFW,WAAW,CAACtB,YAAYC,iBAAiB,WAAW;4BACpD,WAAW;4BACXsB,gBAAgB;4BAChB,qBAAqB;4BACrB,wBAAwB;gCACtBC,QAAQ;gCACRZ,iBAAiB,CAACa,QAAUA,MAAMC,OAAO,CAACC,IAAI,CAAC,MAAM;4BACvD;4BACA,8BAA8B;gCAC5BC,YAAY,CAACH,QAAUA,MAAMC,OAAO,CAACC,IAAI,CAAC,MAAM;4BAClD;wBACF;wBACAE,KAAK;;0CAEL,KAACrC;4BACAE,MAAMG,uBAAuB,kBAC5B,KAACd;gCAAW+C,OAAO;oCAAEC,OAAO;oCAAeP,QAAQ;gCAAc;gCAAGQ,SAAS,IAAMpC,SAAS,CAACD;0CAC1FA,sBAAQ,KAACP,gCAAgB,KAACC;;;;oBAIhCW,0BACC,KAAChB;wBACCiD,GAAGhC,iBAAiB,MAAM;wBAC1BmB,IAAInB,iBAAiB,MAAM;wBAC3BoB,IAAIpB,iBAAiB,MAAM;wBAC3BiC,WAAU;wBACVpB,gBAAe;kCAEf,cAAA,KAACxB;4BAAkBc,UAAUA;4BAAU+B,kBAAkB,CAACC,KAAO/B,YAAY+B,GAAGC,KAAK;;;;;;;AAOnG"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
1
2
|
// Copyright The Perses Authors
|
|
2
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,7 +11,6 @@
|
|
|
10
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
12
|
// See the License for the specific language governing permissions and
|
|
12
13
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
14
14
|
import { Typography, Stack, Button, Box, useTheme, useMediaQuery, Alert } from '@mui/material';
|
|
15
15
|
import { ErrorBoundary, ErrorAlert } from '@perses-dev/components';
|
|
16
16
|
import { TimeRangeControls, useTimeZoneParams } from '@perses-dev/plugin-system';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/DashboardToolbar/DashboardToolbar.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Typography, Stack, Button, Box, useTheme, useMediaQuery, Alert } from '@mui/material';\nimport { ErrorBoundary, ErrorAlert } from '@perses-dev/components';\nimport { TimeRangeControls, useTimeZoneParams } from '@perses-dev/plugin-system';\nimport { ReactElement, ReactNode } from 'react';\nimport { OnSaveDashboard, useEditMode, useDashboardLinks } from '../../context';\nimport { AddPanelButton } from '../AddPanelButton';\nimport { AddGroupButton } from '../AddGroupButton';\nimport { DownloadButton } from '../DownloadButton';\nimport { EditVariablesButton } from '../Variables';\nimport { EditDatasourcesButton } from '../Datasources';\nimport { EditButton } from '../EditButton';\nimport { EditJsonButton } from '../EditJsonButton';\nimport { SaveDashboardButton } from '../SaveDashboardButton';\nimport { DashboardStickyToolbar } from '../DashboardStickyToolbar';\nimport { EditDashboardLinksButton } from '../DashboardLinks';\nimport { LinksDisplay } from '../LinksDisplay';\n\nexport interface DashboardToolbarProps {\n dashboardName: string;\n dashboardTitleComponent?: ReactNode;\n initialVariableIsSticky?: boolean;\n isReadonly: boolean;\n isVariableEnabled: boolean;\n isDatasourceEnabled: boolean;\n isLinksEnabled?: boolean;\n onEditButtonClick: () => void;\n onCancelButtonClick: () => void;\n onSave?: OnSaveDashboard;\n}\n\nexport const DashboardToolbar = (props: DashboardToolbarProps): ReactElement => {\n const {\n dashboardName,\n dashboardTitleComponent,\n initialVariableIsSticky,\n isReadonly,\n isVariableEnabled,\n isDatasourceEnabled,\n isLinksEnabled = true,\n onEditButtonClick,\n onCancelButtonClick,\n onSave,\n } = props;\n\n const { isEditMode } = useEditMode();\n const { timeZone, setTimeZone } = useTimeZoneParams('local');\n const dashboardLinks = useDashboardLinks();\n\n const isBiggerThanSm = useMediaQuery(useTheme().breakpoints.up('sm'));\n const isBiggerThanMd = useMediaQuery(useTheme().breakpoints.up('md'));\n\n const dashboardTitle = dashboardTitleComponent ? (\n dashboardTitleComponent\n ) : (\n <Typography variant=\"h2\">{dashboardName}</Typography>\n );\n\n const testId = 'dashboard-toolbar';\n\n return (\n <>\n <Stack data-testid={testId}>\n <Box\n px={2}\n py={1.5}\n display=\"flex\"\n sx={{ gap: 2, backgroundColor: (theme) => theme.palette.primary.main + (isEditMode ? '30' : '0') }}\n >\n {dashboardTitle}\n {isLinksEnabled && (\n <Stack display=\"flex\" justifyItems=\"center\" alignItems=\"center\" justifyContent=\"center\">\n <LinksDisplay links={dashboardLinks} variant=\"dashboard\" />\n </Stack>\n )}\n {isEditMode ? (\n <Stack direction=\"row\" gap={1} ml=\"auto\">\n {isReadonly && (\n <Alert severity=\"warning\" sx={{ backgroundColor: 'transparent', padding: 0 }}>\n Dashboard managed via code only. Download JSON and commit changes to save.\n </Alert>\n )}\n <Stack direction=\"row\" spacing={0.5} ml={1} whiteSpace=\"nowrap\">\n {isVariableEnabled && <EditVariablesButton />}\n {isDatasourceEnabled && <EditDatasourcesButton />}\n {isLinksEnabled && <EditDashboardLinksButton />}\n <AddPanelButton />\n <AddGroupButton />\n </Stack>\n <SaveDashboardButton onSave={onSave} isDisabled={isReadonly} />\n <Button variant=\"outlined\" onClick={onCancelButtonClick}>\n Cancel\n </Button>\n </Stack>\n ) : (\n <>\n {isBiggerThanSm && (\n <Stack direction=\"row\" gap={1} ml=\"auto\">\n <EditButton onClick={onEditButtonClick} />\n </Stack>\n )}\n </>\n )}\n </Box>\n <Box\n sx={{\n display: 'flex',\n width: '100%',\n alignItems: 'start',\n padding: (theme) => theme.spacing(1, 2, 0, 2),\n flexDirection: isBiggerThanMd ? 'row' : 'column',\n flexWrap: 'nowrap',\n gap: 1,\n }}\n >\n <Box width=\"100%\">\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <DashboardStickyToolbar\n initialVariableIsSticky={initialVariableIsSticky}\n sx={{\n backgroundColor: ({ palette }) => palette.background.default,\n }}\n />\n </ErrorBoundary>\n </Box>\n <Stack direction=\"row\" ml=\"auto\" flexWrap=\"wrap\" justifyContent=\"end\">\n <Stack direction=\"row\" spacing={1} mt={1} ml={1}>\n <TimeRangeControls timeZone={timeZone} onTimeZoneChange={(tz) => setTimeZone(tz.value)} />\n <DownloadButton />\n <EditJsonButton isReadonly={!isEditMode} />\n </Stack>\n </Stack>\n </Box>\n </Stack>\n </>\n );\n};\n"],"names":["Typography","Stack","Button","Box","useTheme","useMediaQuery","Alert","ErrorBoundary","ErrorAlert","TimeRangeControls","useTimeZoneParams","useEditMode","useDashboardLinks","AddPanelButton","AddGroupButton","DownloadButton","EditVariablesButton","EditDatasourcesButton","EditButton","EditJsonButton","SaveDashboardButton","DashboardStickyToolbar","EditDashboardLinksButton","LinksDisplay","DashboardToolbar","props","dashboardName","dashboardTitleComponent","initialVariableIsSticky","isReadonly","isVariableEnabled","isDatasourceEnabled","isLinksEnabled","onEditButtonClick","onCancelButtonClick","onSave","isEditMode","timeZone","setTimeZone","dashboardLinks","isBiggerThanSm","breakpoints","up","isBiggerThanMd","dashboardTitle","variant","testId","data-testid","px","py","display","sx","gap","backgroundColor","theme","palette","primary","main","justifyItems","alignItems","justifyContent","links","direction","ml","severity","padding","spacing","whiteSpace","isDisabled","onClick","width","flexDirection","flexWrap","FallbackComponent","background","default","mt","onTimeZoneChange","tz","value"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC
|
|
1
|
+
{"version":3,"sources":["../../../src/components/DashboardToolbar/DashboardToolbar.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Typography, Stack, Button, Box, useTheme, useMediaQuery, Alert } from '@mui/material';\nimport { ErrorBoundary, ErrorAlert } from '@perses-dev/components';\nimport { TimeRangeControls, useTimeZoneParams } from '@perses-dev/plugin-system';\nimport { ReactElement, ReactNode } from 'react';\nimport { OnSaveDashboard, useEditMode, useDashboardLinks } from '../../context';\nimport { AddPanelButton } from '../AddPanelButton';\nimport { AddGroupButton } from '../AddGroupButton';\nimport { DownloadButton } from '../DownloadButton';\nimport { EditVariablesButton } from '../Variables';\nimport { EditDatasourcesButton } from '../Datasources';\nimport { EditButton } from '../EditButton';\nimport { EditJsonButton } from '../EditJsonButton';\nimport { SaveDashboardButton } from '../SaveDashboardButton';\nimport { DashboardStickyToolbar } from '../DashboardStickyToolbar';\nimport { EditDashboardLinksButton } from '../DashboardLinks';\nimport { LinksDisplay } from '../LinksDisplay';\n\nexport interface DashboardToolbarProps {\n dashboardName: string;\n dashboardTitleComponent?: ReactNode;\n initialVariableIsSticky?: boolean;\n isReadonly: boolean;\n isVariableEnabled: boolean;\n isDatasourceEnabled: boolean;\n isLinksEnabled?: boolean;\n onEditButtonClick: () => void;\n onCancelButtonClick: () => void;\n onSave?: OnSaveDashboard;\n}\n\nexport const DashboardToolbar = (props: DashboardToolbarProps): ReactElement => {\n const {\n dashboardName,\n dashboardTitleComponent,\n initialVariableIsSticky,\n isReadonly,\n isVariableEnabled,\n isDatasourceEnabled,\n isLinksEnabled = true,\n onEditButtonClick,\n onCancelButtonClick,\n onSave,\n } = props;\n\n const { isEditMode } = useEditMode();\n const { timeZone, setTimeZone } = useTimeZoneParams('local');\n const dashboardLinks = useDashboardLinks();\n\n const isBiggerThanSm = useMediaQuery(useTheme().breakpoints.up('sm'));\n const isBiggerThanMd = useMediaQuery(useTheme().breakpoints.up('md'));\n\n const dashboardTitle = dashboardTitleComponent ? (\n dashboardTitleComponent\n ) : (\n <Typography variant=\"h2\">{dashboardName}</Typography>\n );\n\n const testId = 'dashboard-toolbar';\n\n return (\n <>\n <Stack data-testid={testId}>\n <Box\n px={2}\n py={1.5}\n display=\"flex\"\n sx={{ gap: 2, backgroundColor: (theme) => theme.palette.primary.main + (isEditMode ? '30' : '0') }}\n >\n {dashboardTitle}\n {isLinksEnabled && (\n <Stack display=\"flex\" justifyItems=\"center\" alignItems=\"center\" justifyContent=\"center\">\n <LinksDisplay links={dashboardLinks} variant=\"dashboard\" />\n </Stack>\n )}\n {isEditMode ? (\n <Stack direction=\"row\" gap={1} ml=\"auto\">\n {isReadonly && (\n <Alert severity=\"warning\" sx={{ backgroundColor: 'transparent', padding: 0 }}>\n Dashboard managed via code only. Download JSON and commit changes to save.\n </Alert>\n )}\n <Stack direction=\"row\" spacing={0.5} ml={1} whiteSpace=\"nowrap\">\n {isVariableEnabled && <EditVariablesButton />}\n {isDatasourceEnabled && <EditDatasourcesButton />}\n {isLinksEnabled && <EditDashboardLinksButton />}\n <AddPanelButton />\n <AddGroupButton />\n </Stack>\n <SaveDashboardButton onSave={onSave} isDisabled={isReadonly} />\n <Button variant=\"outlined\" onClick={onCancelButtonClick}>\n Cancel\n </Button>\n </Stack>\n ) : (\n <>\n {isBiggerThanSm && (\n <Stack direction=\"row\" gap={1} ml=\"auto\">\n <EditButton onClick={onEditButtonClick} />\n </Stack>\n )}\n </>\n )}\n </Box>\n <Box\n sx={{\n display: 'flex',\n width: '100%',\n alignItems: 'start',\n padding: (theme) => theme.spacing(1, 2, 0, 2),\n flexDirection: isBiggerThanMd ? 'row' : 'column',\n flexWrap: 'nowrap',\n gap: 1,\n }}\n >\n <Box width=\"100%\">\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <DashboardStickyToolbar\n initialVariableIsSticky={initialVariableIsSticky}\n sx={{\n backgroundColor: ({ palette }) => palette.background.default,\n }}\n />\n </ErrorBoundary>\n </Box>\n <Stack direction=\"row\" ml=\"auto\" flexWrap=\"wrap\" justifyContent=\"end\">\n <Stack direction=\"row\" spacing={1} mt={1} ml={1}>\n <TimeRangeControls timeZone={timeZone} onTimeZoneChange={(tz) => setTimeZone(tz.value)} />\n <DownloadButton />\n <EditJsonButton isReadonly={!isEditMode} />\n </Stack>\n </Stack>\n </Box>\n </Stack>\n </>\n );\n};\n"],"names":["Typography","Stack","Button","Box","useTheme","useMediaQuery","Alert","ErrorBoundary","ErrorAlert","TimeRangeControls","useTimeZoneParams","useEditMode","useDashboardLinks","AddPanelButton","AddGroupButton","DownloadButton","EditVariablesButton","EditDatasourcesButton","EditButton","EditJsonButton","SaveDashboardButton","DashboardStickyToolbar","EditDashboardLinksButton","LinksDisplay","DashboardToolbar","props","dashboardName","dashboardTitleComponent","initialVariableIsSticky","isReadonly","isVariableEnabled","isDatasourceEnabled","isLinksEnabled","onEditButtonClick","onCancelButtonClick","onSave","isEditMode","timeZone","setTimeZone","dashboardLinks","isBiggerThanSm","breakpoints","up","isBiggerThanMd","dashboardTitle","variant","testId","data-testid","px","py","display","sx","gap","backgroundColor","theme","palette","primary","main","justifyItems","alignItems","justifyContent","links","direction","ml","severity","padding","spacing","whiteSpace","isDisabled","onClick","width","flexDirection","flexWrap","FallbackComponent","background","default","mt","onTimeZoneChange","tz","value"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatasourceEditor.d.ts","sourceRoot":"","sources":["../../../src/components/Datasources/DatasourceEditor.tsx"],"names":[],"mappings":"AA8BA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,YAAY,EAAY,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"DatasourceEditor.d.ts","sourceRoot":"","sources":["../../../src/components/Datasources/DatasourceEditor.tsx"],"names":[],"mappings":"AA8BA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,YAAY,EAAY,MAAM,OAAO,CAAC;AAK/C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC5C,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,KAAK,IAAI,CAAC;IAChE,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB,GAAG,YAAY,CA4Jf"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
1
2
|
// Copyright The Perses Authors
|
|
2
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,7 +11,6 @@
|
|
|
10
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
12
|
// See the License for the specific language governing permissions and
|
|
12
13
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
14
14
|
import { Box, Button, IconButton, Stack, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from '@mui/material';
|
|
15
15
|
import AddIcon from 'mdi-material-ui/Plus';
|
|
16
16
|
import PencilIcon from 'mdi-material-ui/Pencil';
|