Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 7 additions & 18 deletions dashboards/src/components/Datasources/EditDatasourcesButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { ReactElement, useState } from 'react';
import { Button } from '@mui/material';
import PencilIcon from 'mdi-material-ui/PencilOutline';
import { Drawer, InfoTooltip } from '@perses-dev/components';
import { DashboardResource, EphemeralDashboardResource } from '@perses-dev/core'; // TODO weird that ephemeral dashboard is required here
import { DatasourceSpec } from '@perses-dev/spec';
import { useDatasourceStore } from '@perses-dev/plugin-system';
import { TOOLTIP_TEXT, editButtonStyle } from '../../constants';
Expand Down Expand Up @@ -60,23 +59,13 @@ export function EditDatasourcesButton(): ReactElement {
{} as Record<string, DatasourceSpec>
);

setDashboard(
dashboard.kind === 'Dashboard'
? ({
...dashboard,
spec: {
...dashboard.spec,
datasources: datasources,
},
} as DashboardResource)
: ({
...dashboard,
spec: {
...dashboard.spec,
datasources: datasources,
},
} as EphemeralDashboardResource)
);
setDashboard({
...dashboard,
spec: {
...dashboard.spec,
datasources: datasources,
},
});
setSavedDatasources(newSavedDatasources);
setLocalDatasources(datasources);
setIsDatasourceEditorOpen(false);
Expand Down
13 changes: 8 additions & 5 deletions dashboards/src/components/DownloadButton/serializeDashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,25 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import { DashboardResource, EphemeralDashboardResource } from '@perses-dev/core'; // TODO metadata should not be used, same for ephemeral dashboard
import { stringify } from 'yaml';
import { DashboardMinimalResource } from '../../context';

//TODO: Although the previous comment suggests the metadata not should not be used, I keep them
// Check git history to find prev comment

type SerializedDashboard = {
contentType: string;
content: string;
};

function serializeYaml(
dashboard: DashboardResource | EphemeralDashboardResource,
dashboard: DashboardMinimalResource,
shape?: 'cr-v1alpha1' | 'cr-v1alpha2'
): SerializedDashboard {
let content: string;

if (shape === 'cr-v1alpha1') {
const name = dashboard.metadata.name.toLowerCase().replace(/[^a-z0-9-]/g, '-');
const name = (dashboard.metadata.name as string)?.toLowerCase().replace(/[^a-z0-9-]/g, '-');
content = stringify(
{
apiVersion: 'perses.dev/v1alpha1',
Expand All @@ -45,7 +48,7 @@ function serializeYaml(
{ schema: 'yaml-1.1' }
);
} else if (shape === 'cr-v1alpha2') {
const name = dashboard.metadata.name.toLowerCase().replace(/[^a-z0-9-]/g, '-');
const name = (dashboard.metadata.name as string).toLowerCase().replace(/[^a-z0-9-]/g, '-');
content = stringify(
{
apiVersion: 'perses.dev/v1alpha2',
Expand Down Expand Up @@ -73,7 +76,7 @@ function serializeYaml(
}

export function serializeDashboard(
dashboard: DashboardResource | EphemeralDashboardResource,
dashboard: DashboardMinimalResource,
format: 'json' | 'yaml',
shape?: 'cr-v1alpha1' | 'cr-v1alpha2'
): SerializedDashboard {
Expand Down
6 changes: 3 additions & 3 deletions dashboards/src/components/LeaveDialog/LeaveDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import { DashboardResource, EphemeralDashboardResource } from '@perses-dev/core'; // TODO only dashboard spec should be used
import { ReactElement, ReactNode, useEffect } from 'react';
import { useBlocker } from 'react-router-dom';
import { DiscardChangesConfirmationDialog } from '@perses-dev/components';
import type { BlockerFunction } from '@remix-run/router';
import { DashboardMinimalResource } from '../../context';

const handleRouteChange = (event: BeforeUnloadEvent): string => {
event.preventDefault();
Expand Down Expand Up @@ -69,8 +69,8 @@ export function LeaveDialog({
original,
current,
}: {
original: DashboardResource | EphemeralDashboardResource | undefined;
current: DashboardResource | EphemeralDashboardResource;
original: DashboardMinimalResource | undefined;
current: DashboardMinimalResource;
}): ReactNode {
const handleIsBlocked: BlockerFunction = (ctx) => {
if (JSON.stringify(original) !== JSON.stringify(current)) {
Expand Down
34 changes: 22 additions & 12 deletions dashboards/src/context/DashboardProvider/DashboardProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,8 @@ import { devtools } from 'zustand/middleware';
import { immer } from 'zustand/middleware/immer';
import { shallow } from 'zustand/shallow';
import { createContext, ReactElement, ReactNode, useCallback, useContext, useEffect, useState } from 'react';
import {
ProjectMetadata,
DashboardResource,
DEFAULT_REFRESH_INTERVAL,
EphemeralDashboardResource,
} from '@perses-dev/core';
import { Display, DurationString, DatasourceSpec } from '@perses-dev/spec';
import { DEFAULT_REFRESH_INTERVAL } from '@perses-dev/core';
import { Display, DurationString, DatasourceSpec, DashboardSpec } from '@perses-dev/spec';
import { usePlugin, usePluginRegistry } from '@perses-dev/plugin-system';
import { createPanelGroupEditorSlice, PanelGroupEditorSlice } from './panel-group-editor-slice';
import { convertLayoutsToPanelGroups, createPanelGroupSlice, PanelGroupSlice } from './panel-group-slice';
Expand All @@ -40,6 +35,16 @@ import { createPanelDefinition } from './common';
import { createViewPanelSlice, ViewPanelSlice, VirtualPanelRef } from './view-panel-slice';
import { createLinksSlice, LinksSlice } from './links-slice';

export type DashboardKind = 'Dashboard' | 'EphemeralDashboard';
export type DashboardGenericMetaData = Record<string, string | number | string[] | undefined>;

export interface DashboardMinimalResource {
kind: DashboardKind;
name: string;
spec: DashboardSpec;
metadata: DashboardGenericMetaData;
}

export interface DashboardStoreState
extends PanelGroupSlice,
PanelSlice,
Expand All @@ -55,9 +60,10 @@ export interface DashboardStoreState
LinksSlice {
isEditMode: boolean;
setEditMode: (isEditMode: boolean) => void;
setDashboard: (dashboard: DashboardResource | EphemeralDashboardResource) => void;
kind: DashboardResource['kind'] | EphemeralDashboardResource['kind'];
metadata: ProjectMetadata;
setDashboard: (dashboard: DashboardMinimalResource) => void;
dashboardName: string;
kind: DashboardKind;
metadata: DashboardGenericMetaData;
duration: DurationString;
refreshInterval: DurationString;
display?: Display;
Expand All @@ -76,7 +82,7 @@ export function useDashboardStore<T>(selector: (state: DashboardStoreState) => T
}

export interface DashboardStoreProps {
dashboardResource: DashboardResource | EphemeralDashboardResource;
dashboardResource: DashboardMinimalResource;
isEditMode?: boolean;
viewPanelRef?: VirtualPanelRef;
setViewPanelRef?: (viewPanelRef: VirtualPanelRef | undefined) => void;
Expand Down Expand Up @@ -124,11 +130,12 @@ function initStore(props: DashboardProviderProps): StoreApi<DashboardStoreState>
kind,
metadata,
spec: { display, duration, refreshInterval = DEFAULT_REFRESH_INTERVAL, datasources, layouts = [], panels = {} },
name,
} = dashboardResource;

const links = dashboardResource.spec.links ?? [];

const ttl = 'ttl' in dashboardResource.spec ? dashboardResource.spec.ttl : undefined;
const ttl = 'ttl' in dashboardResource.spec ? (dashboardResource.spec.ttl as DurationString) : undefined;

const store = createStore<DashboardStoreState>()(
immer(
Expand All @@ -151,6 +158,7 @@ function initStore(props: DashboardProviderProps): StoreApi<DashboardStoreState>
...createDiscardChangesDialogSlice(...args),
...createEditJsonDialogSlice(...args),
...createSaveChangesDialogSlice(...args),
dashboardName: name,
kind,
metadata,
display,
Expand All @@ -163,12 +171,14 @@ function initStore(props: DashboardProviderProps): StoreApi<DashboardStoreState>
set({ isEditMode });
},
setDashboard: ({
name,
kind,
metadata,
spec: { display, panels = {}, layouts = [], duration, refreshInterval, datasources = {}, links = [] },
}): void => {
set((state) => {
state.kind = kind;
state.dashboardName = name;
state.metadata = metadata;
state.display = display;
state.panels = panels;
Expand Down
4 changes: 2 additions & 2 deletions dashboards/src/context/DashboardProvider/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import { DashboardResource, EphemeralDashboardResource } from '@perses-dev/core'; // TODO
import { PanelDefinition, UnknownSpec } from '@perses-dev/spec';
import { DashboardMinimalResource } from './DashboardProvider';

export type OnSaveDashboard = (dashboard: DashboardResource | EphemeralDashboardResource) => Promise<unknown>;
export type OnSaveDashboard = (dashboard: DashboardMinimalResource) => Promise<unknown>;

/**
* The middleware applied to the DashboardStore (can be used as generic argument in StateCreator).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,9 @@
// limitations under the License.

import { useCallback, useMemo } from 'react';
import {
DashboardResource,
EphemeralDashboardResource,
PanelGroupItemLayout,
PanelGroupDefinition,
PanelGroupItemId,
} from '@perses-dev/core'; // TODO
import { PanelGroupItemLayout, PanelGroupDefinition, PanelGroupItemId } from '@perses-dev/core'; // TODO
import { DurationString, Link, PanelDefinition, PanelGroupId } from '@perses-dev/spec';
import { DashboardStoreState, useDashboardStore } from './DashboardProvider';
import { DashboardMinimalResource, DashboardStoreState, useDashboardStore } from './DashboardProvider';
import { DeletePanelGroupDialogState } from './delete-panel-group-slice';
import { PanelGroupEditor } from './panel-group-editor-slice';
import { PanelEditorState } from './panel-editor-slice';
Expand All @@ -41,7 +35,7 @@ export function useEditMode(): { setEditMode: (isEditMode: boolean) => void; isE
const selectDashboardActions: ({ setDashboard, openAddPanelGroup, openAddPanel }: DashboardStoreState) => {
openAddPanelGroup: () => void;
openAddPanel: (panelGroupId?: PanelGroupId) => void;
setDashboard: (dashboard: DashboardResource | EphemeralDashboardResource) => void;
setDashboard: (dashboard: DashboardMinimalResource) => void;
} = ({ setDashboard, openAddPanelGroup, openAddPanel }: DashboardStoreState) => ({
setDashboard,
openAddPanelGroup,
Expand All @@ -53,7 +47,7 @@ const selectDashboardActions: ({ setDashboard, openAddPanelGroup, openAddPanel }
export function useDashboardActions(): {
openAddPanelGroup: () => void;
openAddPanel: () => void;
setDashboard: (dashboard: DashboardResource | EphemeralDashboardResource) => void;
setDashboard: (dashboard: DashboardMinimalResource) => void;
} {
const { setDashboard, openAddPanelGroup, openAddPanel } = useDashboardStore(selectDashboardActions);
return {
Expand Down
43 changes: 14 additions & 29 deletions dashboards/src/context/DatasourceStoreProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,7 @@
// limitations under the License.

import { ReactElement, ReactNode, useCallback, useMemo, useState } from 'react';
import {
DashboardResource,
EphemeralDashboardResource,
DatasourceDefinition,
BuildDatasourceProxyUrlParams,
DatasourceApi,
} from '@perses-dev/core'; // TODO
import { DatasourceDefinition, BuildDatasourceProxyUrlParams, DatasourceApi } from '@perses-dev/core'; // TODO
import { DashboardSpec, DatasourceSelector, DatasourceSpec } from '@perses-dev/spec';
import {
DatasourceStoreContext,
Expand All @@ -29,9 +23,10 @@ import {
DatasourceClient,
DatasourceSelectItem,
} from '@perses-dev/plugin-system';
import { DashboardMinimalResource } from './DashboardProvider';

export interface DatasourceStoreProviderProps {
dashboardResource?: DashboardResource | EphemeralDashboardResource;
dashboardResource?: DashboardMinimalResource;
projectName?: string;
datasourceApi: DatasourceApi;
children?: ReactNode;
Expand Down Expand Up @@ -61,8 +56,8 @@ export function DatasourceStoreProvider(props: DatasourceStoreProviderProps): Re
return {
spec: dashboardDatasource.spec,
proxyUrl: buildDatasourceProxyUrl(datasourceApi, {
project: dashboardResource.metadata.project,
dashboard: dashboardResource.metadata.name,
project: dashboardResource.metadata.project as string,
dashboard: dashboardResource.metadata.name as string,
name: dashboardDatasource.name,
}),
};
Expand All @@ -71,7 +66,7 @@ export function DatasourceStoreProvider(props: DatasourceStoreProviderProps): Re

if (project) {
// Try to find it at the project level as a Datasource resource
const datasource = await datasourceApi.getDatasource(project, selector);
const datasource = await datasourceApi.getDatasource(String(project), selector);
if (datasource !== undefined) {
return {
spec: datasource.spec,
Expand Down Expand Up @@ -126,7 +121,7 @@ export function DatasourceStoreProvider(props: DatasourceStoreProviderProps): Re
async (datasourcePluginName: string): Promise<DatasourceSelectItemGroup[]> => {
const [pluginMetadata, datasources, globalDatasources] = await Promise.all([
listPluginMetadata(['Datasource']),
project ? datasourceApi.listDatasources(project, datasourcePluginName) : [],
project ? datasourceApi.listDatasources(String(project), datasourcePluginName) : [],
datasourceApi.listGlobalDatasources(datasourcePluginName),
]);

Expand Down Expand Up @@ -182,23 +177,13 @@ export function DatasourceStoreProvider(props: DatasourceStoreProviderProps): Re
const setLocalDatasources = useCallback(
(datasources: Record<string, DatasourceSpec>) => {
if (dashboardResource) {
setDashboardResource(
dashboardResource.kind === 'Dashboard'
? ({
...dashboardResource,
spec: {
...dashboardResource.spec,
datasources: datasources,
},
} as DashboardResource)
: ({
...dashboardResource,
spec: {
...dashboardResource.spec,
datasources: datasources,
},
} as EphemeralDashboardResource)
);
setDashboardResource({
...dashboardResource,
spec: {
...dashboardResource.spec,
datasources: datasources,
},
});
}
},
[dashboardResource]
Expand Down
Loading
Loading