@ssa-ui-kit/infra-dash 0.0.2 → 0.2.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.
package/dist/index.js CHANGED
@@ -65,13 +65,16 @@ __webpack_require__.d(__webpack_exports__, {
65
65
  DashboardEditorInternal: () => (/* reexport */ DashboardEditorInternal),
66
66
  DashboardViewer: () => (/* reexport */ DashboardViewer),
67
67
  InfraDashProvider: () => (/* reexport */ InfraDashProvider),
68
+ PeriodSelector: () => (/* reexport */ PeriodSelector),
68
69
  RestInfraDashTransport: () => (/* reexport */ RestInfraDashTransport),
69
70
  useCreateDashboard: () => (/* reexport */ useCreateDashboard),
70
71
  useDashboard: () => (/* reexport */ useDashboard),
71
72
  useDashboards: () => (/* reexport */ useDashboards),
72
73
  useDeleteDashboard: () => (/* reexport */ useDeleteDashboard),
73
74
  useInfraDashContext: () => (/* reexport */ useInfraDashContext),
75
+ useInfraDashPanelDataPeriodContext: () => (/* reexport */ useInfraDashPanelDataPeriodContext),
74
76
  useMutationClient: () => (/* reexport */ useMutationClient),
77
+ usePublishedDashboards: () => (/* reexport */ usePublishedDashboards),
75
78
  useQueryClient: () => (/* reexport */ useQueryClient),
76
79
  useTransport: () => (/* reexport */ useTransport),
77
80
  useUpdateDashboard: () => (/* reexport */ useUpdateDashboard)
@@ -550,7 +553,7 @@ function partialMatchKey(a, b) {
550
553
  }
551
554
  ;// external "@ssa-ui-kit/hooks"
552
555
  const hooks_namespaceObject = require("@ssa-ui-kit/hooks");
553
- ;// ./src/shared/context.ts
556
+ ;// ./src/shared/context/root.ts
554
557
 
555
558
  const [InfraDashInternalProvider, useInfraDashContext] = (0,hooks_namespaceObject.createSafeContext)('useInfraDashContext must be used within a InfraDashProvider');
556
559
  ;// ./src/shared/query/useQuery.ts
@@ -662,6 +665,17 @@ const useDashboard = (dashboardId, options) => {
662
665
  }, queryOptions);
663
666
  return result;
664
667
  };
668
+ const usePublishedDashboards = options => {
669
+ const {
670
+ transport,
671
+ ...queryOptions
672
+ } = options || {};
673
+ const _transport = useTransport(transport);
674
+ const result = useQuery(['dashboards', 'published'], async signal => {
675
+ return await _transport.getPublishedDashboards(signal);
676
+ }, queryOptions);
677
+ return result;
678
+ };
665
679
  const useCreateDashboard = options => {
666
680
  const {
667
681
  transport,
@@ -670,16 +684,17 @@ const useCreateDashboard = options => {
670
684
  const _transport = useTransport(transport);
671
685
  const result = useMutation(['create-dashboard'], async (payload, signal) => {
672
686
  const panels = payload.panels.map(panel => ({
673
- ...panel,
674
- id: panel.panelDefinition.source.panelId
687
+ panelDefinition: panel.panelDefinition,
688
+ source: panel.source
675
689
  }));
676
- const dashboardsUid = new Set(panels.map(panel => panel.panelDefinition.source.dashboardUid));
690
+ const dashboardsUid = new Set(panels.map(panel => panel.source.dashboardUid));
677
691
  if (!dashboardsUid.size) {
678
692
  throw new Error('At least one panel must be provided');
679
693
  }
680
694
  return await _transport.createDashboard({
681
- ...payload,
682
- dashboardUid: dashboardsUid.values().next().value,
695
+ title: payload.title,
696
+ published: payload.published,
697
+ dashboardDefinition: payload.dashboardDefinition,
683
698
  panels
684
699
  }, signal);
685
700
  }, mutationOptions);
@@ -693,15 +708,17 @@ const useUpdateDashboard = (dashboardId, options) => {
693
708
  const _transport = useTransport(transport);
694
709
  const result = useMutation(['update-dashboard', dashboardId], async (payload, signal) => {
695
710
  const panels = payload.panels.map(panel => ({
696
- ...panel,
697
- id: panel.panelDefinition.source.panelId
711
+ panelDefinition: panel.panelDefinition,
712
+ source: panel.source
698
713
  }));
699
- const dashboardsUid = new Set(panels.map(panel => panel.panelDefinition.source.dashboardUid));
714
+ const dashboardsUid = new Set(panels.map(panel => panel.source.dashboardUid));
700
715
  if (!dashboardsUid.size) {
701
716
  throw new Error('At least one panel must be provided');
702
717
  }
703
718
  return await _transport.updateDashboard({
704
- ...payload,
719
+ title: payload.title,
720
+ published: payload.published,
721
+ dashboardDefinition: payload.dashboardDefinition,
705
722
  panels,
706
723
  dashboardId
707
724
  }, signal);
@@ -719,6 +736,86 @@ const useDeleteDashboard = (dashboardId, options) => {
719
736
  }, mutationOptions);
720
737
  return result;
721
738
  };
739
+ ;// ./src/shared/panel.ts
740
+ /**
741
+ * Defines the configuration and positioning information for a dashboard panel.
742
+ * Contains both the component configuration and grid layout positioning.
743
+ */
744
+
745
+ /**
746
+ * Represents a complete dashboard panel with its metadata, schema, and definition.
747
+ * Combines panel identity, display information, data schema, and component configuration.
748
+ */
749
+
750
+ /**
751
+ * Optional schema defining the structure of props this component expects.
752
+ * Used for validation and form generation in configuration UIs.
753
+ */
754
+
755
+ /**
756
+ * Configuration object for registering a panel component type.
757
+ * Defines how a specific component should be rendered and what panel types it supports.
758
+ */
759
+
760
+ /**
761
+ * Constant object defining available panel data sources.
762
+ * Currently only supports Grafana as a data source.
763
+ */
764
+ const PANEL_DATA_SOURCE = {
765
+ GRAFANA: 'grafana'
766
+ };
767
+ /**
768
+ * Pattern matching utility function for handling different panel data sources.
769
+ * Provides type-safe way to handle operations based on the data source type.
770
+ *
771
+ * @param source - The panel data source to match against
772
+ * @param handlers - Object containing handler functions for each data source type
773
+ */
774
+ const matchPanelDataSource = (source, handlers) => {
775
+ switch (source) {
776
+ case PANEL_DATA_SOURCE.GRAFANA:
777
+ return handlers.grafana();
778
+ default:
779
+ {
780
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
781
+ const _ = source;
782
+ throw new Error(`Unsupported panel data source: ${source}`);
783
+ }
784
+ }
785
+ };
786
+
787
+ /**
788
+ * Represents panel data with its source and associated data.
789
+ * Currently only supports Grafana as a data source.
790
+ */
791
+
792
+ const PANEL_DATA_PERIOD = {
793
+ LAST_HOUR: 0,
794
+ LAST_6_HOURS: 1,
795
+ LAST_24_HOURS: 2,
796
+ LAST_7_DAYS: 3,
797
+ LAST_30_DAYS: 4
798
+ };
799
+ ;// ./src/shared/context/panelDataPeriod.ts
800
+
801
+
802
+ const useInfraDashPanelDataPeriod = ({
803
+ defaultPeriod,
804
+ period: providedPeriod,
805
+ onPeriodChange
806
+ } = {}) => {
807
+ const [period, changePeriod] = (0,hooks_namespaceObject.useUncontrolled)({
808
+ value: providedPeriod,
809
+ defaultValue: defaultPeriod,
810
+ finalValue: PANEL_DATA_PERIOD.LAST_HOUR,
811
+ onChange: onPeriodChange
812
+ });
813
+ return {
814
+ period,
815
+ changePeriod
816
+ };
817
+ };
818
+ const [InfraDashPanelDataPeriodProvider, useInfraDashPanelDataPeriodContext] = (0,hooks_namespaceObject.createSafeContext)('useInfraDashPanelDataPeriodContext must be used within a InfraDashPanelDataPeriodProvider');
722
819
  ;// external "react-grid-layout"
723
820
  const external_react_grid_layout_namespaceObject = require("react-grid-layout");
724
821
  var external_react_grid_layout_default = /*#__PURE__*/__webpack_require__.n(external_react_grid_layout_namespaceObject);
@@ -782,8 +879,8 @@ function DashboardPanelGrid_EMOTION_STRINGIFIED_CSS_ERROR_() { return "You have
782
879
 
783
880
 
784
881
  var DashboardPanelGrid_ref2 = true ? {
785
- name: "52s4fb",
786
- styles: "width:100%;.react-grid-item.cssTransforms{transition-property:none;}.react-grid-layout{transition:none;}"
882
+ name: "tu5rj9",
883
+ styles: "width:100%;.react-grid-item.cssTransforms{transition-property:none;}.react-grid-layout{transition:none;}.react-grid-item.react-grid-placeholder{background-color:transparent;}"
787
884
  } : 0;
788
885
  var _ref3 = true ? {
789
886
  name: "k9eird",
@@ -816,11 +913,13 @@ const DashboardPanelGrid = ({
816
913
  (0,external_react_namespaceObject.useEffect)(() => {
817
914
  if (refetchIntervalMs) {
818
915
  queryClient.invalidateQueries({
819
- key: ['panel-data']
916
+ key: ['panel-data'],
917
+ type: 'active'
820
918
  });
821
919
  const intervalId = setInterval(() => {
822
920
  queryClient.invalidateQueries({
823
- key: ['panel-data']
921
+ key: ['panel-data'],
922
+ type: 'active'
824
923
  });
825
924
  }, refetchIntervalMs);
826
925
  return () => clearInterval(intervalId);
@@ -908,8 +1007,8 @@ const DashboardPanelGrid = ({
908
1007
  });
909
1008
  };
910
1009
  var DashboardPanelGrid_ref = true ? {
911
- name: "p3gkp4",
912
- styles: ".react-resizable-handle-se{z-index:1;}"
1010
+ name: "ujxn9q",
1011
+ styles: ".react-resizable-handle-se{z-index:1;padding:0;::after{right:0;bottom:0;}}"
913
1012
  } : 0;
914
1013
  const GridItem = /*#__PURE__*/(0,external_react_namespaceObject.forwardRef)(function GridItem({
915
1014
  children,
@@ -929,6 +1028,7 @@ const GridItem = /*#__PURE__*/(0,external_react_namespaceObject.forwardRef)(func
929
1028
 
930
1029
 
931
1030
 
1031
+
932
1032
  const DashboardViewer = ({
933
1033
  dashboard,
934
1034
  dashboardId,
@@ -937,16 +1037,29 @@ const DashboardViewer = ({
937
1037
  const dashboardById = useDashboard(dashboardId ?? -1, {
938
1038
  enabled: !!dashboardId && !dashboard
939
1039
  });
940
- if (dashboard) {
941
- return (0,jsx_runtime_namespaceObject.jsx)(external_react_error_boundary_namespaceObject.ErrorBoundary, {
942
- fallback: (0,jsx_runtime_namespaceObject.jsx)(DashboardError, {
943
- children: "Something went wrong"
944
- }),
945
- children: (0,jsx_runtime_namespaceObject.jsx)(DashboardPanelGrid, {
946
- ...props,
947
- dashboard: dashboard
1040
+ const DashboardWrapper = ({
1041
+ dashboard
1042
+ }) => {
1043
+ const panelDataPeriod = useInfraDashPanelDataPeriod({
1044
+ ...props
1045
+ });
1046
+ return (0,jsx_runtime_namespaceObject.jsx)(InfraDashPanelDataPeriodProvider, {
1047
+ value: panelDataPeriod,
1048
+ children: (0,jsx_runtime_namespaceObject.jsx)(external_react_error_boundary_namespaceObject.ErrorBoundary, {
1049
+ fallback: (0,jsx_runtime_namespaceObject.jsx)(DashboardError, {
1050
+ children: "Something went wrong"
1051
+ }),
1052
+ children: (0,jsx_runtime_namespaceObject.jsx)(DashboardPanelGrid, {
1053
+ ...props,
1054
+ dashboard: dashboard
1055
+ })
948
1056
  })
949
1057
  });
1058
+ };
1059
+ if (dashboard) {
1060
+ return (0,jsx_runtime_namespaceObject.jsx)(DashboardWrapper, {
1061
+ dashboard: dashboard
1062
+ });
950
1063
  }
951
1064
  if (!dashboardById.isLoaded) {
952
1065
  return (0,jsx_runtime_namespaceObject.jsx)(LoadingDashboard, {});
@@ -954,18 +1067,37 @@ const DashboardViewer = ({
954
1067
  if (dashboardById.error) {
955
1068
  return (0,jsx_runtime_namespaceObject.jsx)(DashboardError, {});
956
1069
  }
957
- return (0,jsx_runtime_namespaceObject.jsx)(external_react_error_boundary_namespaceObject.ErrorBoundary, {
958
- fallback: (0,jsx_runtime_namespaceObject.jsx)(DashboardError, {
959
- children: "Something went wrong"
960
- }),
961
- children: (0,jsx_runtime_namespaceObject.jsx)(DashboardPanelGrid, {
962
- ...props,
963
- dashboard: dashboardById.data
964
- })
1070
+ return (0,jsx_runtime_namespaceObject.jsx)(DashboardWrapper, {
1071
+ dashboard: dashboardById.data
965
1072
  });
966
1073
  };
967
1074
  ;// ./src/widgets/DashboardViewer/index.ts
968
1075
 
1076
+ ;// ./src/components/PeriodSelector/PeriodSelector.tsx
1077
+
1078
+
1079
+
1080
+
1081
+ const PeriodSelector = () => {
1082
+ const {
1083
+ period,
1084
+ changePeriod
1085
+ } = useInfraDashPanelDataPeriodContext();
1086
+ const handlePeriodSelect = period => {
1087
+ changePeriod(period);
1088
+ };
1089
+ const options = [[PANEL_DATA_PERIOD.LAST_HOUR, 'Last Hour'], [PANEL_DATA_PERIOD.LAST_6_HOURS, 'Last 6 Hours'], [PANEL_DATA_PERIOD.LAST_24_HOURS, 'Last 24 Hours'], [PANEL_DATA_PERIOD.LAST_7_DAYS, 'Last 7 Days'], [PANEL_DATA_PERIOD.LAST_30_DAYS, 'Last 30 Days']];
1090
+ return (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Typeahead, {
1091
+ filterOptions: false,
1092
+ selectedItems: [period],
1093
+ onChange: componentId => handlePeriodSelect(componentId),
1094
+ children: options.map(([value, label]) => (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.TypeaheadOption, {
1095
+ value: value,
1096
+ label: label,
1097
+ children: label
1098
+ }, value))
1099
+ });
1100
+ };
969
1101
  ;// ./src/shared/icons/DashboardIcon.tsx
970
1102
 
971
1103
  const DashboardIcon = ({
@@ -987,58 +1119,6 @@ const DashboardIcon = ({
987
1119
  fill: fill
988
1120
  })]
989
1121
  });
990
- ;// ./src/shared/panel.ts
991
- /**
992
- * Defines the configuration and positioning information for a dashboard panel.
993
- * Contains both the component configuration and grid layout positioning.
994
- */
995
-
996
- /**
997
- * Represents a complete dashboard panel with its metadata, schema, and definition.
998
- * Combines panel identity, display information, data schema, and component configuration.
999
- */
1000
-
1001
- /**
1002
- * Optional schema defining the structure of props this component expects.
1003
- * Used for validation and form generation in configuration UIs.
1004
- */
1005
-
1006
- /**
1007
- * Configuration object for registering a panel component type.
1008
- * Defines how a specific component should be rendered and what panel types it supports.
1009
- */
1010
-
1011
- /**
1012
- * Constant object defining available panel data sources.
1013
- * Currently only supports Grafana as a data source.
1014
- */
1015
- const PANEL_DATA_SOURCE = {
1016
- GRAFANA: 'grafana'
1017
- };
1018
- /**
1019
- * Pattern matching utility function for handling different panel data sources.
1020
- * Provides type-safe way to handle operations based on the data source type.
1021
- *
1022
- * @param source - The panel data source to match against
1023
- * @param handlers - Object containing handler functions for each data source type
1024
- */
1025
- const matchPanelDataSource = (source, handlers) => {
1026
- switch (source) {
1027
- case PANEL_DATA_SOURCE.GRAFANA:
1028
- return handlers.grafana();
1029
- default:
1030
- {
1031
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1032
- const _ = source;
1033
- throw new Error(`Unsupported panel data source: ${source}`);
1034
- }
1035
- }
1036
- };
1037
-
1038
- /**
1039
- * Represents panel data with its source and associated data.
1040
- * Currently only supports Grafana as a data source.
1041
- */
1042
1122
  ;// ./src/widgets/DashboardEditor/components/DashboardSelectorDrawer.tsx
1043
1123
  function DashboardSelectorDrawer_EMOTION_STRINGIFIED_CSS_ERROR_() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; }
1044
1124
 
@@ -1046,8 +1126,8 @@ function DashboardSelectorDrawer_EMOTION_STRINGIFIED_CSS_ERROR_() { return "You
1046
1126
 
1047
1127
 
1048
1128
  var DashboardSelectorDrawer_ref = true ? {
1049
- name: "1gk49vx",
1050
- styles: "width:400px;padding:24px 32px"
1129
+ name: "u5gcpt",
1130
+ styles: "width:400px;padding:24px 32px;z-index:10"
1051
1131
  } : 0;
1052
1132
  var DashboardSelectorDrawer_ref2 = true ? {
1053
1133
  name: "13udsys",
@@ -1123,8 +1203,8 @@ function PanelSettingsDrawer_EMOTION_STRINGIFIED_CSS_ERROR_() { return "You have
1123
1203
 
1124
1204
 
1125
1205
  var PanelSettingsDrawer_ref = true ? {
1126
- name: "1c73qam",
1127
- styles: "max-width:400px;padding:24px 32px"
1206
+ name: "12ld9rx",
1207
+ styles: "max-width:400px;padding:24px 32px;z-index:10"
1128
1208
  } : 0;
1129
1209
  var PanelSettingsDrawer_ref2 = true ? {
1130
1210
  name: "1d3w5wq",
@@ -1210,6 +1290,7 @@ function ExternalDashboardsList_EMOTION_STRINGIFIED_CSS_ERROR_() { return "You h
1210
1290
 
1211
1291
 
1212
1292
 
1293
+
1213
1294
  var ExternalDashboardsList_ref = true ? {
1214
1295
  name: "tc4e7",
1215
1296
  styles: "justify-content:center;height:100%;padding:8px"
@@ -1224,14 +1305,13 @@ var ExternalDashboardsList_ref3 = true ? {
1224
1305
  } : 0;
1225
1306
  const ExternalPanelList = ({
1226
1307
  dashboard,
1308
+ panels,
1309
+ isLoaded,
1310
+ error,
1227
1311
  onPanelClick
1228
1312
  }) => {
1229
1313
  const theme = (0,react_namespaceObject.useTheme)();
1230
- const {
1231
- panelRegistry
1232
- } = useInfraDashContext();
1233
- const externalPanels = useGrafanaPanels(dashboard.id);
1234
- if (!externalPanels.isLoaded) {
1314
+ if (!isLoaded) {
1235
1315
  return (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Wrapper, {
1236
1316
  direction: "column",
1237
1317
  css: ExternalDashboardsList_ref,
@@ -1253,7 +1333,7 @@ const ExternalPanelList = ({
1253
1333
  })
1254
1334
  });
1255
1335
  }
1256
- if (externalPanels.error) {
1336
+ if (error) {
1257
1337
  return (0,jsx_runtime_namespaceObject.jsxs)(core_namespaceObject.Wrapper, {
1258
1338
  direction: "column",
1259
1339
  css: ExternalDashboardsList_ref2,
@@ -1262,7 +1342,7 @@ const ExternalPanelList = ({
1262
1342
  })]
1263
1343
  });
1264
1344
  }
1265
- if (!externalPanels.data.length) {
1345
+ if (!panels.length) {
1266
1346
  return (0,jsx_runtime_namespaceObject.jsxs)(core_namespaceObject.Wrapper, {
1267
1347
  direction: "column",
1268
1348
  css: ExternalDashboardsList_ref3,
@@ -1271,15 +1351,8 @@ const ExternalPanelList = ({
1271
1351
  })]
1272
1352
  });
1273
1353
  }
1274
- const availablePanels = externalPanels.data.filter(panel => {
1275
- if (!panel.panelSchema?.type) {
1276
- return false;
1277
- }
1278
- const availableComponents = panelRegistry.findPanelConfigsByType(panel.panelSchema.type);
1279
- return availableComponents.length > 0;
1280
- });
1281
1354
  return (0,jsx_runtime_namespaceObject.jsx)(jsx_runtime_namespaceObject.Fragment, {
1282
- children: availablePanels.map(panel => (0,jsx_runtime_namespaceObject.jsxs)(core_namespaceObject.Button, {
1355
+ children: panels.map(panel => (0,jsx_runtime_namespaceObject.jsxs)(core_namespaceObject.Button, {
1283
1356
  variant: "tertiary",
1284
1357
  className: /*#__PURE__*/(0,css_namespaceObject.css)("width:100%;min-height:34px;gap:8px;padding:8px 14px 8px 34px!important;justify-content:space-between;text-align:left;& svg{& path{stroke:", theme.colors.greyDarker, ";stroke-width:1.4px;}}" + ( true ? "" : 0), true ? "" : 0),
1285
1358
  onClick: () => onPanelClick?.(dashboard, panel),
@@ -1290,6 +1363,75 @@ const ExternalPanelList = ({
1290
1363
  }, panel.id))
1291
1364
  });
1292
1365
  };
1366
+ const DashboardAccordionItem = ({
1367
+ dashboard,
1368
+ search,
1369
+ onPanelClick,
1370
+ ...accordionProps
1371
+ }) => {
1372
+ const theme = (0,react_namespaceObject.useTheme)();
1373
+ const {
1374
+ panelRegistry
1375
+ } = useInfraDashContext();
1376
+ const panelsQuery = useGrafanaPanels(dashboard.id);
1377
+ const loadedPanels = panelsQuery.data ?? [];
1378
+ const availablePanels = loadedPanels.filter(panel => {
1379
+ if (!panel.panelSchema?.type) {
1380
+ return false;
1381
+ }
1382
+ if (search && !panel.title.toLowerCase().includes(search.toLowerCase())) {
1383
+ return false;
1384
+ }
1385
+ const availableComponents = panelRegistry.findPanelConfigsByType(panel.panelSchema.type);
1386
+ return availableComponents.length > 0;
1387
+ });
1388
+ if (search && panelsQuery.isLoaded && !availablePanels.length) {
1389
+ return null;
1390
+ }
1391
+ return (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Accordion, {
1392
+ id: dashboard.id,
1393
+ title: dashboard.title,
1394
+ className: /*#__PURE__*/(0,css_namespaceObject.css)( true ? {
1395
+ name: "2zzvc7",
1396
+ styles: "padding:0!important;align-items:start!important"
1397
+ } : 0),
1398
+ renderTitle: ({
1399
+ title,
1400
+ isOpened,
1401
+ onClick
1402
+ }) => (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Button, {
1403
+ onClick: onClick,
1404
+ variant: "tertiary",
1405
+ className: /*#__PURE__*/(0,css_namespaceObject.css)("width:100%;min-height:34px;gap:8px;padding:8px 14px!important;text-align:left;& svg{& path{stroke:", theme.colors.greyDarker, ";stroke-width:1.4px;}}" + ( true ? "" : 0), true ? "" : 0),
1406
+ startIcon: isOpened ? (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Icon, {
1407
+ name: "carrot-down",
1408
+ size: 12
1409
+ }) : (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Icon, {
1410
+ name: "carrot-right",
1411
+ size: 12
1412
+ }),
1413
+ children: title
1414
+ }),
1415
+ renderContent: ({
1416
+ isOpened
1417
+ }) => (0,jsx_runtime_namespaceObject.jsx)("div", {
1418
+ css: /*#__PURE__*/(0,react_namespaceObject.css)({
1419
+ width: '100%',
1420
+ display: isOpened ? 'block' : 'none',
1421
+ fontWeight: 500,
1422
+ fontSize: '14px'
1423
+ }, true ? "" : 0, true ? "" : 0),
1424
+ children: (0,jsx_runtime_namespaceObject.jsx)(ExternalPanelList, {
1425
+ panels: availablePanels,
1426
+ isLoaded: panelsQuery.isLoaded,
1427
+ error: panelsQuery.error,
1428
+ dashboard: dashboard,
1429
+ onPanelClick: onPanelClick
1430
+ })
1431
+ }),
1432
+ ...accordionProps
1433
+ }, dashboard.id);
1434
+ };
1293
1435
  var _ref4 = true ? {
1294
1436
  name: "67cb9k",
1295
1437
  styles: "justify-content:center;height:100%"
@@ -1303,14 +1445,19 @@ var _ref6 = true ? {
1303
1445
  styles: "justify-content:center;height:100%"
1304
1446
  } : 0;
1305
1447
  var _ref7 = true ? {
1306
- name: "1qmr6ab",
1307
- styles: "overflow:auto"
1448
+ name: "1d0nbku",
1449
+ styles: "margin-top:24px"
1450
+ } : 0;
1451
+ var _ref8 = true ? {
1452
+ name: "1yghct1",
1453
+ styles: "overflow:auto;width:100%"
1308
1454
  } : 0;
1309
1455
  const ExternalDashboardsList = ({
1310
1456
  onPanelClick,
1311
1457
  ...divProps
1312
1458
  }) => {
1313
1459
  const theme = (0,react_namespaceObject.useTheme)();
1460
+ const [search, setSearch] = (0,external_react_namespaceObject.useState)('');
1314
1461
  const dashboardsQuery = useGrafanaDashboards();
1315
1462
  if (!dashboardsQuery.isLoaded) {
1316
1463
  return (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Wrapper, {
@@ -1355,51 +1502,30 @@ const ExternalDashboardsList = ({
1355
1502
  })]
1356
1503
  });
1357
1504
  }
1358
- return (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.AccordionGroupContextProvider, {
1359
- children: (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.AccordionGroup, {
1360
- size: "small",
1361
- css: _ref7,
1362
- ...divProps,
1363
- children: dashboardsQuery.data.map(dashboard => (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Accordion, {
1364
- id: dashboard.id,
1365
- title: dashboard.title,
1366
- className: /*#__PURE__*/(0,css_namespaceObject.css)( true ? {
1367
- name: "2zzvc7",
1368
- styles: "padding:0!important;align-items:start!important"
1369
- } : 0),
1370
- renderTitle: ({
1371
- title,
1372
- isOpened,
1373
- onClick
1374
- }) => (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Button, {
1375
- onClick: onClick,
1376
- variant: "tertiary",
1377
- className: /*#__PURE__*/(0,css_namespaceObject.css)("width:100%;min-height:34px;gap:8px;padding:8px 14px!important;text-align:left;& svg{& path{stroke:", theme.colors.greyDarker, ";stroke-width:1.4px;}}" + ( true ? "" : 0), true ? "" : 0),
1378
- startIcon: isOpened ? (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Icon, {
1379
- name: "carrot-down",
1380
- size: 12
1381
- }) : (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Icon, {
1382
- name: "carrot-right",
1383
- size: 12
1384
- }),
1385
- children: title
1386
- }),
1387
- renderContent: ({
1388
- isOpened
1389
- }) => (0,jsx_runtime_namespaceObject.jsx)("div", {
1390
- css: /*#__PURE__*/(0,react_namespaceObject.css)({
1391
- width: '100%',
1392
- display: isOpened ? 'block' : 'none',
1393
- fontWeight: 500,
1394
- fontSize: '14px'
1395
- }, true ? "" : 0, true ? "" : 0),
1396
- children: (0,jsx_runtime_namespaceObject.jsx)(ExternalPanelList, {
1397
- dashboard: dashboard,
1398
- onPanelClick: onPanelClick
1399
- })
1400
- })
1401
- }, dashboard.id))
1402
- })
1505
+ return (0,jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, {
1506
+ children: [(0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Input, {
1507
+ name: "panel-search",
1508
+ placeholder: "Search...",
1509
+ inputProps: {
1510
+ value: search,
1511
+ onChange: e => setSearch(e.target.value)
1512
+ },
1513
+ css: _ref7
1514
+ }), (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.AccordionGroupContextProvider, {
1515
+ children: (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.AccordionGroup, {
1516
+ size: "small",
1517
+ css: _ref8,
1518
+ ...divProps,
1519
+ children: dashboardsQuery.data.map(dashboard => (0,jsx_runtime_namespaceObject.jsx)(DashboardAccordionItem
1520
+ // id is required by AccordionGroup logic
1521
+ , {
1522
+ id: dashboard.id,
1523
+ dashboard: dashboard,
1524
+ search: search,
1525
+ onPanelClick: onPanelClick
1526
+ }, dashboard.id))
1527
+ })
1528
+ })]
1403
1529
  });
1404
1530
  };
1405
1531
  ;// ./src/widgets/DashboardEditor/helpers.ts
@@ -1428,13 +1554,13 @@ const appendPanel = params => {
1428
1554
  const newPanel = {
1429
1555
  id: -Date.now(),
1430
1556
  // use a negative ID to indicate a new panel
1557
+ source: {
1558
+ type: 'grafana',
1559
+ dashboardUid: grafanaDashboard.id,
1560
+ panelId: grafanaPanel.id
1561
+ },
1431
1562
  panelDefinition: {
1432
1563
  version: 1,
1433
- source: {
1434
- type: 'grafana',
1435
- dashboardUid: grafanaDashboard.id,
1436
- panelId: grafanaPanel.id
1437
- },
1438
1564
  component: {
1439
1565
  id: defaultComponentConfig.componentId,
1440
1566
  props: {}
@@ -1489,20 +1615,36 @@ const applyNewLayout = ({
1489
1615
  }) => {
1490
1616
  const newLayoutMap = newLayout.reduce((map, {
1491
1617
  i,
1492
- ...layout
1618
+ x,
1619
+ y,
1620
+ w,
1621
+ h
1493
1622
  }) => ({
1494
1623
  ...map,
1495
- [i]: layout
1496
- }), {});
1497
- dashboard.panels.forEach(panel => {
1498
- const newGridPos = newLayoutMap[panel.id.toString()];
1499
- if (!newGridPos) {
1500
- throw new Error(`New position for the ${panel.id} not fount`);
1624
+ [i]: {
1625
+ x,
1626
+ y,
1627
+ w,
1628
+ h
1501
1629
  }
1502
- panel.panelDefinition.gridPos = newGridPos;
1503
- return panel;
1504
- });
1505
- return dashboard;
1630
+ }), {});
1631
+ const newDashboard = {
1632
+ ...dashboard,
1633
+ panels: dashboard.panels.map(panel => {
1634
+ const newGridPos = newLayoutMap[panel.id.toString()];
1635
+ if (!newGridPos) {
1636
+ throw new Error(`New position for the panel ${panel.id} not found`);
1637
+ }
1638
+ return {
1639
+ ...panel,
1640
+ panelDefinition: {
1641
+ ...panel.panelDefinition,
1642
+ gridPos: newGridPos
1643
+ }
1644
+ };
1645
+ })
1646
+ };
1647
+ return newDashboard;
1506
1648
  };
1507
1649
  ;// ./src/widgets/DashboardEditor/components/PanelControl.tsx
1508
1650
  function PanelControl_EMOTION_STRINGIFIED_CSS_ERROR_() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; }
@@ -1563,10 +1705,15 @@ const PanelControlContent = ({
1563
1705
  })]
1564
1706
  });
1565
1707
  };
1708
+ var PanelControl_ref3 = true ? {
1709
+ name: "1jyo0em",
1710
+ styles: "margin-right:5px;margin-top:5px"
1711
+ } : 0;
1566
1712
  const PanelControl = props => {
1567
1713
  return (0,jsx_runtime_namespaceObject.jsxs)(core_namespaceObject.Popover, {
1568
1714
  children: [(0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.PopoverTrigger, {
1569
1715
  variant: "tertiary",
1716
+ css: PanelControl_ref3,
1570
1717
  children: (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Icon, {
1571
1718
  name: "more-vertical",
1572
1719
  size: 14
@@ -1716,6 +1863,7 @@ function DashboardEditor_EMOTION_STRINGIFIED_CSS_ERROR_() { return "You have tri
1716
1863
 
1717
1864
 
1718
1865
 
1866
+
1719
1867
  var DashboardEditor_ref = true ? {
1720
1868
  name: "1st9kbp",
1721
1869
  styles: "height:100%;position:relative"
@@ -1744,7 +1892,7 @@ var DashboardEditor_ref7 = true ? {
1744
1892
  name: "1lsto0t",
1745
1893
  styles: "max-width:250px"
1746
1894
  } : 0;
1747
- var _ref8 = true ? {
1895
+ var DashboardEditor_ref8 = true ? {
1748
1896
  name: "1yxfaqj",
1749
1897
  styles: "height:46px"
1750
1898
  } : 0;
@@ -1784,6 +1932,7 @@ const DashboardEditorInternal = ({
1784
1932
  },
1785
1933
  id: -1,
1786
1934
  panels: [],
1935
+ published: false,
1787
1936
  title: 'New Dashboard'
1788
1937
  },
1789
1938
  onChange
@@ -1840,12 +1989,7 @@ const DashboardEditorInternal = ({
1840
1989
  if (dashboard.id > 0) {
1841
1990
  updateDashboard(dashboard).then(() => onSaved?.(dashboard)).catch(error => onError?.(error));
1842
1991
  } else {
1843
- createDashboard({
1844
- panels: dashboard.panels,
1845
- dashboardDefinition: dashboard.dashboardDefinition,
1846
- title: dashboard.title,
1847
- dashboardUid: dashboard.id.toString()
1848
- }).then(() => onCreate?.()).catch(error => onError?.(error));
1992
+ createDashboard(dashboard).then(() => onCreate?.()).catch(error => onError?.(error));
1849
1993
  }
1850
1994
  };
1851
1995
  const selectedPanel = selectedPanelId !== null ? dashboard.panels.find(p => p.id === selectedPanelId) : null;
@@ -1885,9 +2029,16 @@ const DashboardEditorInternal = ({
1885
2029
  })
1886
2030
  },
1887
2031
  css: DashboardEditor_ref7
1888
- }), (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Button, {
2032
+ }), (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Checkbox, {
2033
+ text: "Publish",
2034
+ initialState: dashboard.published,
2035
+ onChange: published => setDashboard({
2036
+ ...dashboard,
2037
+ published
2038
+ })
2039
+ }), (0,jsx_runtime_namespaceObject.jsx)(PeriodSelector, {}), (0,jsx_runtime_namespaceObject.jsx)(core_namespaceObject.Button, {
1889
2040
  variant: "info",
1890
- css: _ref8,
2041
+ css: DashboardEditor_ref8,
1891
2042
  isDisabled: cannotPersist,
1892
2043
  onClick: handlePersistDashboard,
1893
2044
  children: dashboard.id > 0 ? 'Save' : 'Create'
@@ -1928,15 +2079,26 @@ const DashboardEditor = ({
1928
2079
  const dashboardById = useDashboard(dashboardId ?? -1, {
1929
2080
  enabled: !!dashboardId && !dashboard && !defaultDashboard
1930
2081
  });
1931
- if (!dashboardId) {
1932
- return (0,jsx_runtime_namespaceObject.jsx)(external_react_error_boundary_namespaceObject.ErrorBoundary, {
1933
- fallback: (0,jsx_runtime_namespaceObject.jsx)(DashboardError, {
1934
- children: "Something went wrong"
1935
- }),
1936
- children: (0,jsx_runtime_namespaceObject.jsx)(DashboardEditorInternal, {
1937
- ...props
2082
+ const DashboardWrapper = editorProps => {
2083
+ const panelDataPeriod = useInfraDashPanelDataPeriod({
2084
+ ...props
2085
+ });
2086
+ return (0,jsx_runtime_namespaceObject.jsx)(InfraDashPanelDataPeriodProvider, {
2087
+ value: panelDataPeriod,
2088
+ children: (0,jsx_runtime_namespaceObject.jsx)(external_react_error_boundary_namespaceObject.ErrorBoundary, {
2089
+ fallback: (0,jsx_runtime_namespaceObject.jsx)(DashboardError, {
2090
+ children: "Something went wrong"
2091
+ }),
2092
+ children: (0,jsx_runtime_namespaceObject.jsx)(DashboardEditorInternal, {
2093
+ ...editorProps
2094
+ })
1938
2095
  })
1939
2096
  });
2097
+ };
2098
+ if (!dashboardId) {
2099
+ return (0,jsx_runtime_namespaceObject.jsx)(DashboardWrapper, {
2100
+ ...props
2101
+ });
1940
2102
  }
1941
2103
  if (!dashboardById.isLoaded) {
1942
2104
  return (0,jsx_runtime_namespaceObject.jsx)(LoadingDashboard, {});
@@ -1944,14 +2106,9 @@ const DashboardEditor = ({
1944
2106
  if (dashboardById.error) {
1945
2107
  return (0,jsx_runtime_namespaceObject.jsx)(DashboardError, {});
1946
2108
  }
1947
- return (0,jsx_runtime_namespaceObject.jsx)(external_react_error_boundary_namespaceObject.ErrorBoundary, {
1948
- fallback: (0,jsx_runtime_namespaceObject.jsx)(DashboardError, {
1949
- children: "Something went wrong"
1950
- }),
1951
- children: (0,jsx_runtime_namespaceObject.jsx)(DashboardEditorInternal, {
1952
- ...props,
1953
- defaultDashboard: dashboardById.data
1954
- })
2109
+ return (0,jsx_runtime_namespaceObject.jsx)(DashboardWrapper, {
2110
+ ...props,
2111
+ defaultDashboard: dashboardById.data
1955
2112
  });
1956
2113
  };
1957
2114
  ;// ./src/widgets/DashboardEditor/index.ts
@@ -2023,23 +2180,24 @@ class RestInfraDashTransport {
2023
2180
  }
2024
2181
  async getGrafanaPanelData({
2025
2182
  dashboardUid,
2026
- panelId
2183
+ panelId,
2184
+ period
2027
2185
  }, signal) {
2028
- const request = new Request(this.getUrl(`/grafana/dashboards/${dashboardUid}/panel/${panelId}`), {
2186
+ const request = new Request(this.getUrl(`/grafana/dashboards/${dashboardUid}/panel/${panelId}?period=${period ?? 0}`), {
2029
2187
  method: 'POST',
2030
2188
  signal
2031
2189
  });
2032
2190
  return await this.makeRequest(request);
2033
2191
  }
2034
- async getPanelData(panelId, signal) {
2035
- const request = new Request(this.getUrl(`/dashboards/panels/${panelId}`), {
2036
- method: 'POST',
2192
+ async getDashboards(signal) {
2193
+ const request = new Request(this.getUrl(`/dashboards`), {
2194
+ method: 'GET',
2037
2195
  signal
2038
2196
  });
2039
2197
  return await this.makeRequest(request);
2040
2198
  }
2041
- async getDashboards(signal) {
2042
- const request = new Request(this.getUrl(`/dashboards`), {
2199
+ async getPublishedDashboards(signal) {
2200
+ const request = new Request(this.getUrl(`/dashboards/published`), {
2043
2201
  method: 'GET',
2044
2202
  signal
2045
2203
  });
@@ -2090,6 +2248,8 @@ class RestInfraDashTransport {
2090
2248
 
2091
2249
 
2092
2250
 
2251
+ ;// ./src/components/PeriodSelector/index.ts
2252
+
2093
2253
  ;// ./src/shared/query/query.ts
2094
2254
 
2095
2255
  class QueryEntry {
@@ -2117,6 +2277,9 @@ class QueryEntry {
2117
2277
  }
2118
2278
  });
2119
2279
  }
2280
+ isActive() {
2281
+ return this.subscribers.size && this.options.enabled;
2282
+ }
2120
2283
  updateEntity(fetcher, options) {
2121
2284
  this.fetcher = fetcher;
2122
2285
  this.options = {
@@ -2243,10 +2406,17 @@ class QueryClient {
2243
2406
  invalidateQueries({
2244
2407
  key,
2245
2408
  exact,
2246
- reset
2409
+ reset,
2410
+ type = 'all'
2247
2411
  }) {
2248
2412
  const matchingEntries = [];
2249
2413
  for (const [hash, entry] of this.cache.entries()) {
2414
+ if (type !== 'all') {
2415
+ const active = entry.isActive();
2416
+ if (type === 'active' && !active || type === 'inactive' && active) {
2417
+ continue; // skip entries that don't match the type
2418
+ }
2419
+ }
2250
2420
  if (exact) {
2251
2421
  if (hash === hashKey(key)) {
2252
2422
  matchingEntries.push(entry);
@@ -2462,10 +2632,17 @@ const LoadingPanel = ({
2462
2632
 
2463
2633
 
2464
2634
 
2635
+
2465
2636
  const usePanelData = (panel, options = {}) => {
2466
2637
  const _transport = useTransport(options?.transport);
2467
- const panelSource = panel.panelDefinition.source;
2468
- const result = useQuery(['panel-data', panelSource], async signal => {
2638
+ const {
2639
+ period
2640
+ } = useInfraDashPanelDataPeriodContext();
2641
+ const panelSource = panel.source;
2642
+ const result = useQuery(['panel-data', {
2643
+ panelSource,
2644
+ period
2645
+ }], async signal => {
2469
2646
  if (panelSource.type === PANEL_DATA_SOURCE.GRAFANA) {
2470
2647
  const {
2471
2648
  dashboardUid,
@@ -2473,7 +2650,8 @@ const usePanelData = (panel, options = {}) => {
2473
2650
  } = panelSource;
2474
2651
  const data = await _transport.getGrafanaPanelData({
2475
2652
  dashboardUid,
2476
- panelId
2653
+ panelId,
2654
+ period
2477
2655
  }, signal);
2478
2656
  return {
2479
2657
  source: PANEL_DATA_SOURCE.GRAFANA,
@@ -2580,7 +2758,8 @@ const grafanaDataAdapter = ({
2580
2758
  const TimeseriesPanel = ({
2581
2759
  panel,
2582
2760
  panelData,
2583
- title: providedTitle
2761
+ title: providedTitle,
2762
+ xAxisHoverFormat
2584
2763
  }) => {
2585
2764
  const {
2586
2765
  ref,
@@ -2618,7 +2797,8 @@ const TimeseriesPanel = ({
2618
2797
  r: 50
2619
2798
  },
2620
2799
  xaxis: {
2621
- tickmode: 'auto'
2800
+ tickmode: 'auto',
2801
+ hoverformat: xAxisHoverFormat
2622
2802
  },
2623
2803
  yaxis2: {
2624
2804
  ticksuffix: valueSuffix,
@@ -2641,6 +2821,11 @@ const panelConfig = {
2641
2821
  title: {
2642
2822
  type: 'string',
2643
2823
  title: 'Panel Title'
2824
+ },
2825
+ xAxisHoverFormat: {
2826
+ type: 'string',
2827
+ title: 'X Axis Hover Format',
2828
+ default: '%H:%M, %d %b'
2644
2829
  }
2645
2830
  }
2646
2831
  },
@@ -2648,6 +2833,10 @@ const panelConfig = {
2648
2833
  title: {
2649
2834
  'ui:help': 'Override the default panel title',
2650
2835
  'ui:placeholder': 'Panel Title'
2836
+ },
2837
+ xAxisHoverFormat: {
2838
+ 'ui:help': 'Format for the x-axis hover tooltip',
2839
+ 'ui:placeholder': 'X Axis Hover Format (e.g., %H:%M, %d %b)'
2651
2840
  }
2652
2841
  }
2653
2842
  };
@@ -2964,6 +3153,7 @@ const InfraDashProvider = ({
2964
3153
 
2965
3154
 
2966
3155
 
3156
+
2967
3157
  /******/ return __webpack_exports__;
2968
3158
  /******/ })()
2969
3159
  ;