Skip to content

Commit 2305108

Browse files
committed
feat(dashboard): download & import a view
1 parent 96c5ecd commit 2305108

File tree

5 files changed

+93
-17
lines changed

5 files changed

+93
-17
lines changed

dashboard/src/dashboard-editor/model/content/index.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { FiltersModel } from '../filters';
1818
import { QueriesModel } from '../queries';
1919
import { SQLSnippetsModel } from '../sql-snippets';
2020

21+
import { v4 as uuidv4 } from 'uuid';
2122
import { TAdditionalQueryInfo } from '~/api-caller/request';
2223
import {
2324
formatSQLSnippet,
@@ -281,24 +282,45 @@ const _ContentModel = types
281282
self.views.findByID(viewID)?.removePanelID(panelID);
282283
},
283284
addANewPanel(viewID: string) {
284-
const id = new Date().getTime().toString();
285+
const id = uuidv4();
285286
self.panels.append(getNewPanel(id));
286287
self.views.findByID(viewID)?.appendPanelID(id);
287288
},
288289
applyJSONSchema(partialSchema: AnyObject) {
289-
const { panels, filters, definition = {} } = partialSchema;
290+
const { views, panels, filters, definition = {} } = partialSchema;
290291
const { queries, sqlSnippets, mock_context } = definition;
292+
const panelIDMap: Map<string, string> = new Map(); // old -> new
291293

292294
// PANELS
293295
if (Array.isArray(panels)) {
294-
const newPanels = panels.map((p) => ({
295-
...p,
296-
id: new Date().getTime().toString(),
297-
}));
296+
const newPanels = panels.map((p) => {
297+
const newID = uuidv4();
298+
panelIDMap.set(p.id, newID);
299+
return {
300+
...p,
301+
id: newID,
302+
};
303+
});
298304
self.panels.appendMultiple(newPanels);
299305

300-
const panelIDs = newPanels.map((p) => p.id);
301-
self.views.VIE?.appendPanelIDs(panelIDs);
306+
// import panels to current view
307+
if (!Array.isArray(views) || views.length === 0) {
308+
const panelIDs = newPanels.map((p) => p.id);
309+
self.views.VIE?.appendPanelIDs(panelIDs);
310+
}
311+
}
312+
313+
// VIEWS
314+
if (Array.isArray(views)) {
315+
const newViews = views.map((v) => {
316+
const panelIDs = v.panelIDs.map((oldID: string) => panelIDMap.get(oldID) ?? oldID);
317+
return {
318+
...v,
319+
id: uuidv4(),
320+
panelIDs,
321+
};
322+
});
323+
self.views.appendMultiple(newViews);
302324
}
303325

304326
// FILTERS

dashboard/src/dashboard-editor/model/views/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import { IDashboardView } from '~/types';
44
import { PanelsModelInstance } from '../panels';
55

66
import { ViewDivisionConfigSnapshotIn, ViewMetaInstance, ViewModalConfigSnapshotIn } from '~/model';
7+
import { ViewModel, ViewModelInstance } from './view';
78

89
export const ViewsModel = types
910
.compose(
1011
'ViewsModel',
1112
ViewsRenderModel,
1213
types.model({
14+
current: types.optional(types.array(ViewModel), []),
1315
idOfVIE: types.string, // VIE: view in edit
1416
}),
1517
)
@@ -21,7 +23,7 @@ export const ViewsModel = types
2123
return self.current[0].id === self.idOfVIE;
2224
},
2325
get VIE() {
24-
return self.current.find(({ id }) => id === self.idOfVIE);
26+
return self.current.find(({ id }) => id === self.idOfVIE) as ViewModelInstance;
2527
},
2628
get options() {
2729
return self.current.map((v) => ({
@@ -70,6 +72,13 @@ export const ViewsModel = types
7072
append(item: ViewRenderModelInstance) {
7173
self.current.push(item);
7274
},
75+
appendMultiple(items: ViewRenderModelInstance[]) {
76+
if (items.length === 0) {
77+
return;
78+
}
79+
80+
self.current.push(...items);
81+
},
7382
remove(index: number) {
7483
self.current.splice(index, 1);
7584
},
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import _ from 'lodash';
2+
import { Instance, SnapshotIn } from 'mobx-state-tree';
3+
import { EViewComponentType, ViewRenderModel } from '~/model';
4+
import { AnyObject } from '~/types';
5+
import { downloadJSON } from '~/utils/download';
6+
7+
export const ViewModel = ViewRenderModel.actions((self) => ({
8+
getSchema() {
9+
const view = self.json;
10+
const panels: AnyObject[] = [];
11+
const queries: AnyObject[] = [];
12+
self.panels.forEach((p: any) => {
13+
const ps = p.getSchema();
14+
panels.push(ps.panel);
15+
if (ps.queries.length > 0) {
16+
queries.push(...ps.queries);
17+
}
18+
});
19+
20+
const ret = {
21+
views: [view],
22+
panels: panels,
23+
definition: {
24+
queries: _.uniqBy(queries, (q) => q.id),
25+
},
26+
};
27+
return ret;
28+
},
29+
downloadSchema() {
30+
if (self.type === EViewComponentType.Tabs) {
31+
console.error(new Error('Please choose a tab first'));
32+
return;
33+
}
34+
const schema = JSON.stringify(this.getSchema(), null, 2);
35+
const filename = self.name;
36+
downloadJSON(filename, schema);
37+
},
38+
}));
39+
40+
export type ViewModelInstance = Instance<typeof ViewModel>;
41+
export type ViewModelSnapshotIn = SnapshotIn<ViewModelInstance>;

dashboard/src/dashboard-editor/ui/header/download-this-view/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const ButtonSx: Sx = {
1515
export const DownloadThisView = observer(() => {
1616
const contentModel = useEditContentModelContext();
1717
const cant = contentModel.views.VIE?.type === EViewComponentType.Tabs;
18-
const download = () => contentModel.views.VIE.downloadSchema();
18+
const download = () => contentModel.views.VIE?.downloadSchema();
1919
if (cant) {
2020
return (
2121
<Tooltip label="Please choose a tab first">

dashboard/src/model/render-model/dashboard/content/panels/panel.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,22 @@ export const PanelRenderModel = PanelMeta.views((self) => ({
7373
__TRIGGERS: {},
7474
};
7575

76-
const ret = {
76+
return {
77+
panel,
78+
queries: self.queries.map((q) => q.json),
79+
};
80+
},
81+
downloadSchema() {
82+
const { panel, queries } = this.getSchema();
83+
const schema = {
7784
panels: [panel],
7885
definition: {
79-
queries: self.queries.map((q) => q.json),
86+
queries,
8087
},
8188
};
82-
return ret;
83-
},
84-
downloadSchema() {
85-
const schema = JSON.stringify(this.getSchema(), null, 2);
89+
const schemaStr = JSON.stringify(schema, null, 2);
8690
const filename = self.name;
87-
downloadJSON(filename, schema);
91+
downloadJSON(filename, schemaStr);
8892
},
8993
}));
9094

0 commit comments

Comments
 (0)