-
+ {dashboardsLoading &&
}
+ {dashboardsError &&
{dashboardsError}}
+ {!dashboardsSettings.length &&
Dashboards not found}
+ {dashboards.length > 1 && (
+
+ {dashboards.map(tab => (
+
+ {tab.label}
+
+ ))}
)}
{validDashboardRows && (
rows.map((r,i) =>
)
)}
- {!!dashboards.length && !validDashboardRows && (
+ {!!dashboardsSettings.length && !validDashboardRows && (
"rows"
not found. Check the configuration file {filename}.
@@ -63,4 +70,4 @@ const Index: FC = () => {
;
};
-export default Index;
+export default DashboardsLayout;
diff --git a/app/vmui/packages/vmui/src/pages/PredefinedPanels/style.scss b/app/vmui/packages/vmui/src/pages/PredefinedPanels/style.scss
index 3006ac883..d8e62465c 100644
--- a/app/vmui/packages/vmui/src/pages/PredefinedPanels/style.scss
+++ b/app/vmui/packages/vmui/src/pages/PredefinedPanels/style.scss
@@ -5,22 +5,37 @@
gap: $padding-global;
align-items: flex-start;
+ &-tabs.vm-block {
+ padding: $padding-global;
+ }
+
&-tabs {
display: flex;
+ flex-wrap: wrap;
align-items: center;
justify-content: flex-start;
font-size: $font-size-small;
+ gap: $padding-small;
+ white-space: nowrap;
overflow: hidden;
&__tab {
- padding: $padding-global;
+ padding: $padding-small $padding-global;
+ border-radius: $border-radius-medium;
cursor: pointer;
- transition: opacity 200ms ease-in-out, color 150ms ease-in;
- border-right: $border-divider;
+ transition: background 200ms ease-in-out, color 150ms ease-in;
+ background: $color-white;
text-transform: uppercase;
+ color: rgba($color-black, 0.2);
+ border: 1px solid rgba($color-black, 0.2);
&:hover {
- opacity: 1;
+ color: $color-primary;
+ }
+
+ &_active {
+ border-color: $color-primary;
+ color: $color-primary;
}
}
}
diff --git a/app/vmui/packages/vmui/src/state/dashboards/DashboardsStateContext.tsx b/app/vmui/packages/vmui/src/state/dashboards/DashboardsStateContext.tsx
new file mode 100644
index 000000000..2b9ab235b
--- /dev/null
+++ b/app/vmui/packages/vmui/src/state/dashboards/DashboardsStateContext.tsx
@@ -0,0 +1,24 @@
+import React, { createContext, FC, useContext, useMemo, useReducer } from "preact/compat";
+import { DashboardsAction, DashboardsState, initialDashboardsState, reducer } from "./reducer";
+
+import { Dispatch } from "react";
+
+type DashboardsStateContextType = { state: DashboardsState, dispatch: Dispatch
};
+
+export const DashboardsStateContext = createContext({} as DashboardsStateContextType);
+
+export const useDashboardsState = (): DashboardsState => useContext(DashboardsStateContext).state;
+export const useDashboardsDispatch = (): Dispatch => useContext(DashboardsStateContext).dispatch;
+export const DashboardsStateProvider: FC = ({ children }) => {
+ const [state, dispatch] = useReducer(reducer, initialDashboardsState);
+
+ const contextValue = useMemo(() => {
+ return { state, dispatch };
+ }, [state, dispatch]);
+
+ return
+ {children}
+ ;
+};
+
+
diff --git a/app/vmui/packages/vmui/src/state/dashboards/reducer.ts b/app/vmui/packages/vmui/src/state/dashboards/reducer.ts
new file mode 100644
index 000000000..34a4ae451
--- /dev/null
+++ b/app/vmui/packages/vmui/src/state/dashboards/reducer.ts
@@ -0,0 +1,41 @@
+import { DashboardSettings } from "../../types";
+
+export interface DashboardsState {
+ dashboardsSettings: DashboardSettings[];
+ dashboardsLoading: boolean,
+ dashboardsError: string
+}
+
+export type DashboardsAction =
+ | { type: "SET_DASHBOARDS_SETTINGS", payload: DashboardSettings[] }
+ | { type: "SET_DASHBOARDS_LOADING", payload: boolean }
+ | { type: "SET_DASHBOARDS_ERROR", payload: string }
+
+
+export const initialDashboardsState: DashboardsState = {
+ dashboardsSettings: [],
+ dashboardsLoading: false,
+ dashboardsError: "",
+};
+
+export function reducer(state: DashboardsState, action: DashboardsAction): DashboardsState {
+ switch (action.type) {
+ case "SET_DASHBOARDS_SETTINGS":
+ return {
+ ...state,
+ dashboardsSettings: action.payload
+ };
+ case "SET_DASHBOARDS_LOADING":
+ return {
+ ...state,
+ dashboardsLoading: action.payload
+ };
+ case "SET_DASHBOARDS_ERROR":
+ return {
+ ...state,
+ dashboardsError: action.payload
+ };
+ default:
+ throw new Error();
+ }
+}
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index d83f267e5..1b4745401 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -54,6 +54,7 @@ Released at 2023-01-10
- `vm_vmselect_concurrent_requests_current` - the current number of concurrently executed requests
- `vm_vmselect_concurrent_requests_limit_reached_total` - the total number of requests, which were put in the wait queue when `-search.maxConcurrentRequests` concurrent requests are being executed
- `vm_vmselect_concurrent_requests_limit_timeout_total` - the total number of canceled requests because they were sitting in the wait queue for more than `-search.maxQueueDuration`
+* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add ability to define path to custom dashboards via `vmui.customDashboardsPath` flag. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3322).
* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): properly update the `step` value in url after the `step` input field has been manually changed. This allows preserving the proper `step` when copy-n-pasting the url to another instance of web browser. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3513).
* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): properly update tooltip when quickly hovering multiple lines on the graph. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3530).