Skip to content

Commit 1f86ba9

Browse files
Load dashboard with specific version passed from FN UI (#68)
1 parent 004023b commit 1f86ba9

File tree

8 files changed

+44
-19
lines changed

8 files changed

+44
-19
lines changed

pkg/api/dashboard.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -745,20 +745,18 @@ func (hs *HTTPServer) GetDashboardVersion(c *models.ReqContext) response.Respons
745745
creator = hs.getUserLogin(c.Req.Context(), res.CreatedBy)
746746
}
747747

748-
dashVersionMeta := &dashver.DashboardVersionMeta{
749-
ID: res.ID,
750-
DashboardID: res.DashboardID,
751-
DashboardUID: dashUID,
752-
Data: res.Data,
753-
ParentVersion: res.ParentVersion,
754-
RestoredFrom: res.RestoredFrom,
755-
Version: res.Version,
756-
Created: res.Created,
757-
Message: res.Message,
758-
CreatedBy: creator,
759-
}
760-
761-
return response.JSON(http.StatusOK, dashVersionMeta)
748+
meta := dtos.DashboardMeta{
749+
Type: models.DashTypeDB,
750+
CreatedBy: creator,
751+
Version: res.Version,
752+
}
753+
754+
dto := dtos.DashboardFullWithMeta{
755+
Dashboard: res.Data,
756+
Meta: meta,
757+
}
758+
759+
return response.JSON(http.StatusOK, dto)
762760
}
763761

764762
// swagger:route POST /dashboards/validate dashboards alpha validateDashboard

public/app/core/reducers/fn-slice.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export interface FnGlobalState {
88
FNDashboard: boolean;
99
uid: string;
1010
slug: string;
11+
version: number;
1112
mode: GrafanaThemeType.Light | GrafanaThemeType.Dark;
1213
controlsContainer: string | null;
1314
pageTitle: string;
@@ -20,7 +21,7 @@ export type UpdateFNGlobalStateAction = PayloadAction<Partial<FnGlobalState>>;
2021

2122
export type SetFnStateAction = PayloadAction<Omit<FnGlobalState, 'hiddenVariables'>>;
2223

23-
export type FnPropMappedFromState = Extract<keyof FnGlobalState, 'FNDashboard' | 'hiddenVariables' | 'mode' | 'uid' | 'queryParams' | 'slug'>;
24+
export type FnPropMappedFromState = Extract<keyof FnGlobalState, 'FNDashboard' | 'hiddenVariables' | 'mode' | 'uid' | 'queryParams' | 'slug' | 'version'>;
2425
export type FnStateProp = keyof FnGlobalState;
2526

2627
export type FnPropsMappedFromState = Pick<FnGlobalState, FnPropMappedFromState>;
@@ -34,6 +35,7 @@ export const fnStateProps: FnStateProp[] = [
3435
'queryParams',
3536
'slug',
3637
'uid',
38+
'version',
3739
];
3840

3941
export const fnPropsMappedFromState: readonly FnPropMappedFromState[] = [
@@ -43,6 +45,7 @@ export const fnPropsMappedFromState: readonly FnPropMappedFromState[] = [
4345
'uid',
4446
'queryParams',
4547
'slug',
48+
'version',
4649
] as const;
4750

4851
const INITIAL_MODE = GrafanaThemeType.Light;
@@ -54,6 +57,7 @@ export const INITIAL_FN_STATE: FnGlobalState = {
5457
FNDashboard: false,
5558
uid: '',
5659
slug: '',
60+
version: 1,
5761
mode: INITIAL_MODE,
5862
controlsContainer: null,
5963
pageTitle: '',

public/app/core/services/backend_srv.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,10 @@ export class BackendSrv implements BackendService {
464464
return this.get<DashboardDTO>(`/api/dashboards/uid/${uid}`);
465465
}
466466

467+
getDashboardByUidVersion(uid: string, version: number): Promise<DashboardDTO> {
468+
return this.get<DashboardDTO>(`/api/dashboards/uid/${uid}/versions/${version}`);
469+
}
470+
467471
validateDashboard(dashboard: DashboardModel) {
468472
// We want to send the dashboard as a JSON string (in the JSON body payload) so we can get accurate error line numbers back
469473
const dashboardJson = JSON.stringify(dashboard, replaceJsonNulls, 2);

public/app/features/dashboard/containers/DashboardPage.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ const connector = connect(mapStateToProps, mapDispatchToProps);
102102
type OwnProps = {
103103
isPublic?: boolean;
104104
controlsContainer?: string | null;
105+
version?: FNDashboardProps['version'];
105106
fnLoader?: FNDashboardProps['fnLoader'];
106107
isLoading?: FNDashboardProps['isLoading']
107108
};
@@ -176,6 +177,7 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
176177
urlUid: match.params.uid,
177178
urlType: match.params.type,
178179
urlFolderId: queryParams.folderId,
180+
version: match.params.version,
179181
panelType: queryParams.panelType,
180182
routeName: this.props.route.routeName,
181183
fixUrl: !isPublic && !FNDashboard,
@@ -199,6 +201,7 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
199201

200202
if (
201203
prevProps.match.params.uid !== match.params.uid ||
204+
prevProps.match.params.version !== match.params.version ||
202205
(routeReloadCounter !== undefined && this.forceRouteReloadCounter !== routeReloadCounter)
203206
) {
204207
this.initDashboard();

public/app/features/dashboard/services/DashboardLoaderSrv.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export class DashboardLoaderSrv {
3232
};
3333
}
3434

35-
loadDashboard(type: UrlQueryValue, slug: any, uid: any) {
35+
loadDashboard(type: UrlQueryValue, slug: any, uid: any, version: any) {
3636
let promise;
3737

3838
if (type === 'script') {
@@ -54,6 +54,19 @@ export class DashboardLoaderSrv {
5454
.catch(() => {
5555
return this._dashboardLoadFailed('Public Dashboard Not found', true);
5656
});
57+
} else if (version !== undefined) {
58+
promise = backendSrv
59+
.getDashboardByUidVersion(uid, version)
60+
.then((result: any) => {
61+
if (result.meta.isFolder) {
62+
appEvents.emit(AppEvents.alertError, ['Dashboard with version not found']);
63+
throw new Error('Dashboard with version not found');
64+
}
65+
return result;
66+
})
67+
.catch(() => {
68+
return this._dashboardLoadFailed('Not found', true);
69+
});
5770
} else {
5871
promise = backendSrv
5972
.getDashboardByUid(uid)

public/app/features/dashboard/state/initDashboard.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export interface InitDashboardArgs {
2828
urlSlug?: string;
2929
urlType?: string;
3030
urlFolderId?: string;
31+
version?: number;
3132
panelType?: string;
3233
accessToken?: string;
3334
routeName?: string;
@@ -67,10 +68,10 @@ async function fetchDashboard(
6768
return dashDTO;
6869
}
6970
case DashboardRoutes.Public: {
70-
return await dashboardLoaderSrv.loadDashboard('public', args.urlSlug, args.accessToken);
71+
return await dashboardLoaderSrv.loadDashboard('public', args.urlSlug, args.accessToken, args.version);
7172
}
7273
case DashboardRoutes.Normal: {
73-
const dashDTO: DashboardDTO = await dashboardLoaderSrv.loadDashboard(args.urlType, args.urlSlug, args.urlUid);
74+
const dashDTO: DashboardDTO = await dashboardLoaderSrv.loadDashboard(args.urlType, args.urlSlug, args.urlUid, args.version);
7475

7576
if (args.fixUrl && dashDTO.meta.url && !playlistSrv.isPlaying) {
7677
// check if the current url is correct (might be old slug)
@@ -93,7 +94,7 @@ async function fetchDashboard(
9394
}
9495
case DashboardRoutes.Path: {
9596
const path = args.urlSlug ?? '';
96-
return await dashboardLoaderSrv.loadDashboard(DashboardRoutes.Path, path, path);
97+
return await dashboardLoaderSrv.loadDashboard(DashboardRoutes.Path, path, path, args.version);
9798
}
9899
default:
99100
throw { message: 'Unknown route ' + args.routeName };

public/app/fn-app/create-mfe.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ class createMfe {
292292
uid: other.uid,
293293
hiddenVariables: other.hiddenVariables,
294294
slug: other.slug,
295+
version: other.version,
295296
queryParams: other.queryParams,
296297
})
297298
);

public/app/fn-app/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export interface FNDashboardProps {
2222
name: string;
2323
uid: string;
2424
slug: string;
25+
version: number;
2526
mode: GrafanaThemeType.Dark | GrafanaThemeType.Light;
2627
queryParams: ParsedQuery<string>;
2728
fnError?: ReactNode;

0 commit comments

Comments
 (0)