Skip to content
Merged
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
12 changes: 6 additions & 6 deletions dashboards/src/components/DownloadButton/serializeDashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@
// 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 { DashboardResource } from '../../model/DashboardResource';

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

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

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

if (shape === 'cr-v1alpha1') {
Expand Down Expand Up @@ -73,7 +73,7 @@ function serializeYaml(
}

export function serializeDashboard(
dashboard: DashboardResource | EphemeralDashboardResource,
dashboard: DashboardResource,
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 { DashboardResource } from '../../model';

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: DashboardResource | undefined;
current: DashboardResource;
}): ReactNode {
const handleIsBlocked: BlockerFunction = (ctx) => {
if (JSON.stringify(original) !== JSON.stringify(current)) {
Expand Down
18 changes: 7 additions & 11 deletions dashboards/src/context/DashboardProvider/DashboardProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,10 @@ 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 { DEFAULT_REFRESH_INTERVAL } from '@perses-dev/core';
import { Display, DurationString, DatasourceSpec } from '@perses-dev/spec';
import { usePlugin, usePluginRegistry } from '@perses-dev/plugin-system';
import { DashboardMetaData, DashboardKind, DashboardResource } from '../../model/DashboardResource';
import { createPanelGroupEditorSlice, PanelGroupEditorSlice } from './panel-group-editor-slice';
import { convertLayoutsToPanelGroups, createPanelGroupSlice, PanelGroupSlice } from './panel-group-slice';
import { createPanelEditorSlice, PanelEditorSlice } from './panel-editor-slice';
Expand Down Expand Up @@ -55,9 +51,9 @@ export interface DashboardStoreState
LinksSlice {
isEditMode: boolean;
setEditMode: (isEditMode: boolean) => void;
setDashboard: (dashboard: DashboardResource | EphemeralDashboardResource) => void;
kind: DashboardResource['kind'] | EphemeralDashboardResource['kind'];
metadata: ProjectMetadata;
setDashboard: (dashboard: DashboardResource) => void;
kind: DashboardKind;
metadata: DashboardMetaData;
duration: DurationString;
refreshInterval: DurationString;
display?: Display;
Expand All @@ -76,7 +72,7 @@ export function useDashboardStore<T>(selector: (state: DashboardStoreState) => T
}

export interface DashboardStoreProps {
dashboardResource: DashboardResource | EphemeralDashboardResource;
dashboardResource: DashboardResource;
isEditMode?: boolean;
viewPanelRef?: VirtualPanelRef;
setViewPanelRef?: (viewPanelRef: VirtualPanelRef | undefined) => void;
Expand Down Expand Up @@ -128,7 +124,7 @@ function initStore(props: DashboardProviderProps): StoreApi<DashboardStoreState>

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 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 { DashboardResource } from '../../model';

export type OnSaveDashboard = (dashboard: DashboardResource | EphemeralDashboardResource) => Promise<unknown>;
export type OnSaveDashboard = (dashboard: DashboardResource) => 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,14 +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 { DashboardResource } from '../../model';
import { DashboardStoreState, useDashboardStore } from './DashboardProvider';
import { DeletePanelGroupDialogState } from './delete-panel-group-slice';
import { PanelGroupEditor } from './panel-group-editor-slice';
Expand All @@ -41,7 +36,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: DashboardResource) => void;
} = ({ setDashboard, openAddPanelGroup, openAddPanel }: DashboardStoreState) => ({
setDashboard,
openAddPanelGroup,
Expand All @@ -53,7 +48,7 @@ const selectDashboardActions: ({ setDashboard, openAddPanelGroup, openAddPanel }
export function useDashboardActions(): {
openAddPanelGroup: () => void;
openAddPanel: () => void;
setDashboard: (dashboard: DashboardResource | EphemeralDashboardResource) => void;
setDashboard: (dashboard: DashboardResource) => void;
} {
const { setDashboard, openAddPanelGroup, openAddPanel } = useDashboardStore(selectDashboardActions);
return {
Expand Down
15 changes: 10 additions & 5 deletions dashboards/src/context/DatasourceStoreProvider.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import {
import { DatasourceStoreProvider } from '@perses-dev/dashboards';
import { PropsWithChildren, ReactElement } from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { DashboardResource, Datasource, GlobalDatasourceResource, DatasourceResource } from '@perses-dev/core'; // TODO Datasource should not be used like that, only the spec should be considered
import { DashboardSpec, DatasourceSpec } from '@perses-dev/spec';
import { Datasource, GlobalDatasourceResource, DatasourceResource } from '@perses-dev/core';
import { DashboardSpec, DatasourceSpec, UnknownSpec } from '@perses-dev/spec';
import { DashboardResource } from '../model/DashboardResource';

const PROJECT = 'perses';
const FAKE_PLUGIN_NAME = 'FakeDatasourcePlugin';
Expand Down Expand Up @@ -494,9 +495,13 @@ describe('DatasourceStoreProvider::useListDatasourceSelectItems', () => {
listGlobalDatasources: jest.fn().mockReturnValue(Promise.resolve(data.input.datasources.global)),
};
const queryClient = new QueryClient();
const dashboard = {
spec: { datasources: data.input.datasources.local } as Partial<DashboardSpec>,
} as DashboardResource;
const dashboard: DashboardResource = {
spec: {
datasources: data.input.datasources.local as Record<string, DatasourceSpec<UnknownSpec>>,
} as DashboardSpec,
kind: 'Dashboard',
metadata: { name: 'test_dashboard', project: 'test_project' },
};
const wrapper = ({ children }: PropsWithChildren): ReactElement => {
return (
<PluginRegistry {...mockPluginRegistry(MOCK_DS_PLUGIN)}>
Expand Down
39 changes: 12 additions & 27 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 { DashboardResource } from '../model/DashboardResource';

export interface DatasourceStoreProviderProps {
dashboardResource?: DashboardResource | EphemeralDashboardResource;
dashboardResource?: DashboardResource;
projectName?: string;
datasourceApi: DatasourceApi;
children?: ReactNode;
Expand Down Expand Up @@ -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
22 changes: 12 additions & 10 deletions dashboards/src/context/useDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import { DashboardResource, EphemeralDashboardResource, PanelGroupDefinition } from '@perses-dev/core'; // TODO
import { createPanelRef, GridDefinition, PanelGroupId } from '@perses-dev/spec';
import { DurationString, PanelGroupDefinition } from '@perses-dev/core';
import { createPanelRef, DashboardSpec, GridDefinition, PanelGroupId } from '@perses-dev/spec';
import { DashboardResource } from '../model';
import { useDashboardStore } from './DashboardProvider';
import { useVariableDefinitionActions, useVariableDefinitions } from './VariableProvider';

type DashboardType = Omit<DashboardResource, 'spec'> & { spec: DashboardSpec & { ttl?: DurationString } };
export function useDashboard(): {
dashboard: DashboardResource | EphemeralDashboardResource;
setDashboard: (dashboardResource: DashboardResource | EphemeralDashboardResource) => void;
dashboard: DashboardType;
setDashboard: (dashboardResource: DashboardResource) => void;
} {
const {
panels,
Expand Down Expand Up @@ -66,9 +68,9 @@ export function useDashboard(): {
const variables = useVariableDefinitions();
const layouts = convertPanelGroupsToLayouts(panelGroups, panelGroupOrder);

const dashboard =
const dashboard: DashboardType =
kind === 'Dashboard'
? ({
? {
kind,
metadata,
spec: {
Expand All @@ -81,8 +83,8 @@ export function useDashboard(): {
datasources,
links,
},
} as DashboardResource)
: ({
}
: {
kind,
metadata,
spec: {
Expand All @@ -96,9 +98,9 @@ export function useDashboard(): {
links,
ttl,
},
} as EphemeralDashboardResource);
};

const setDashboard = (dashboardResource: DashboardResource | EphemeralDashboardResource): void => {
const setDashboard = (dashboardResource: DashboardResource): void => {
setVariableDefinitions(dashboardResource.spec.variables);
setDashboardResource(dashboardResource);
};
Expand Down
1 change: 1 addition & 0 deletions dashboards/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
export * from './components';
export * from './context';
export * from './views';
export * from './model';
35 changes: 35 additions & 0 deletions dashboards/src/model/DashboardResource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright The Perses Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { DashboardSpec } from '@perses-dev/spec';

export type DashboardKind = 'Dashboard' | 'EphemeralDashboard';

/* TODO: As discussed we can keep this intermediary type until we decide on a new location for it. */
export type DashboardMetaData = {
name: string;
project: string;
createdAt?: string;
updatedAt?: string;
version?: number;
};

/* TODO: There is an open and ongoing issue whether the meta-data should be removed or not.
Such a decision would affect DashbaordProvider and buildDatasourceProxyUrl
https://github.com/perses/perses/issues/4016
*/
export interface DashboardResource {
kind: DashboardKind;
spec: DashboardSpec;
metadata: DashboardMetaData;
}
Loading
Loading