Skip to content

Commit 715308d

Browse files
authored
Merge pull request #1236 from merico-dev/1231-able-to-download-panel-schema-and-import-a-panel-with-its-schema
1231 able to download panel schema and import a panel with its schema
2 parents 554edcf + c06917a commit 715308d

File tree

41 files changed

+1183
-198
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1183
-198
lines changed

api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devtable/api",
3-
"version": "10.44.4",
3+
"version": "10.45.1",
44
"description": "",
55
"main": "index.js",
66
"scripts": {

dashboard/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devtable/dashboard",
3-
"version": "10.44.4",
3+
"version": "10.45.1",
44
"license": "Apache-2.0",
55
"publishConfig": {
66
"access": "public",

dashboard/src/components/filter/filter-settings/filter-setting.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,22 @@ const editors = {
2020
'date-range': FilterEditorDateRange,
2121
};
2222

23+
export const filterTypeNames = {
24+
select: 'Select',
25+
'multi-select': 'Multi Select',
26+
'tree-select': 'Tree Select',
27+
'text-input': 'Text Input',
28+
checkbox: 'Checkbox',
29+
'date-range': 'Date Range',
30+
};
31+
2332
const filterTypeOptions = [
24-
{ label: 'Select', value: 'select' },
25-
{ label: 'Multi Select', value: 'multi-select' },
26-
{ label: 'Tree Select', value: 'tree-select' },
27-
{ label: 'Text Input', value: 'text-input' },
28-
{ label: 'Checkbox', value: 'checkbox' },
29-
{ label: 'Date Range', value: 'date-range' },
33+
{ label: filterTypeNames['select'], value: 'select' },
34+
{ label: filterTypeNames['multi-select'], value: 'multi-select' },
35+
{ label: filterTypeNames['tree-select'], value: 'tree-select' },
36+
{ label: filterTypeNames['text-input'], value: 'text-input' },
37+
{ label: filterTypeNames['checkbox'], value: 'checkbox' },
38+
{ label: filterTypeNames['date-range'], value: 'date-range' },
3039
];
3140

3241
interface IFilterSetting {

dashboard/src/components/panel/panel-editor/dropdown-menu/index.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Box, Divider, Menu } from '@mantine/core';
22
import { useModals } from '@mantine/modals';
3-
import { IconCamera } from '@tabler/icons-react';
3+
import { IconCamera, IconCode } from '@tabler/icons-react';
44
import { observer } from 'mobx-react-lite';
55
import React from 'react';
66
import { ArrowsMaximize, Copy, Download, Refresh, Settings, Trash } from 'tabler-icons-react';
@@ -54,6 +54,9 @@ export const PanelDropdownMenu = observer(({ view }: { view: ViewMetaInstance })
5454
<Menu.Item onClick={panel.downloadData} icon={<Download size={14} />}>
5555
Download Data
5656
</Menu.Item>
57+
<Menu.Item onClick={panel.downloadSchema} icon={<IconCode size={14} />}>
58+
Download Schema
59+
</Menu.Item>
5760
<Menu.Item onClick={downloadPanelScreenshot} icon={<IconCamera size={14} />}>
5861
Screenshot
5962
</Menu.Item>

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

Lines changed: 41 additions & 5 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 { TAdditionalQueryInfo } from '~/api-caller/request';
2122
import {
2223
formatSQLSnippet,
2324
getInitialFiltersConfig,
@@ -29,10 +30,10 @@ import {
2930
TPayloadForSQL,
3031
TPayloadForViz,
3132
} from '~/model';
32-
import { PanelModelInstance, PanelsModel } from '../panels';
33-
import { getInitialDashboardViewsModel, ViewsModel } from '../views';
3433
import { payloadToDashboardState } from '~/utils/dashboard-state';
35-
import { TAdditionalQueryInfo } from '~/api-caller/request';
34+
import { UsageRegs } from '~/utils/usage';
35+
import { PanelsModel } from '../panels';
36+
import { getInitialDashboardViewsModel, ViewsModel } from '../views';
3637

3738
const _ContentModel = types
3839
.model({
@@ -233,12 +234,11 @@ const _ContentModel = types
233234
},
234235
get sqlSnippetsUsage() {
235236
const usages: SQLSnippetUsageType[] = [];
236-
const reg = /(?<=sql_snippets\.)([^}.]+)/gm;
237237
self.queries.current.forEach((q) => {
238238
if (!q.typedAsSQL) {
239239
return;
240240
}
241-
const keys = _.uniq(q.sql.match(reg));
241+
const keys = _.uniq(q.sql.match(UsageRegs.sqlSnippet));
242242
keys.forEach((k) => {
243243
usages.push({
244244
queryID: q.id,
@@ -285,6 +285,42 @@ const _ContentModel = types
285285
self.panels.append(getNewPanel(id));
286286
self.views.findByID(viewID)?.appendPanelID(id);
287287
},
288+
applyJSONSchema(partialSchema: AnyObject) {
289+
const { panels, filters, definition = {} } = partialSchema;
290+
const { queries, sqlSnippets, mock_context } = definition;
291+
292+
// PANELS
293+
if (Array.isArray(panels)) {
294+
const newPanels = panels.map((p) => ({
295+
...p,
296+
id: new Date().getTime().toString(),
297+
}));
298+
self.panels.appendMultiple(newPanels);
299+
300+
const panelIDs = newPanels.map((p) => p.id);
301+
self.views.VIE?.appendPanelIDs(panelIDs);
302+
}
303+
304+
// FILTERS
305+
if (Array.isArray(filters)) {
306+
self.filters.appendMultiple(filters);
307+
}
308+
309+
// QUERIES
310+
if (Array.isArray(queries)) {
311+
self.queries.appendMultiple(queries);
312+
}
313+
314+
// SQL SNIPPETS
315+
if (Array.isArray(sqlSnippets)) {
316+
self.sqlSnippets.appendMultiple(sqlSnippets);
317+
}
318+
319+
// MOCK_CONTEXT
320+
if (mock_context && Object.keys(mock_context).length > 0) {
321+
self.mock_context.defaults(mock_context);
322+
}
323+
},
288324
}))
289325
.actions((self) => {
290326
function setupAutoSave() {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export type NavActionType = {
2424
| '_Add_A_QUERY_'
2525
| '_Add_A_VIEW_'
2626
| '_Add_A_PANEL_'
27+
| '_FILTERS_SETTINGS_'
2728
| '_SQL_SNIPPETS_SETTINGS_'
2829
| '_QUERIES_SETTINGS_';
2930
parentID?: string; // for panel only
@@ -47,6 +48,7 @@ function getActionOption(_action_type: NavActionType['_action_type']): NavAction
4748
export type ValidEditorPathType =
4849
| ['_QUERY_VARS_']
4950
| ['_MOCK_CONTEXT_']
51+
| ['_FILTERS_']
5052
| ['_FILTERS_', string]
5153
| ['_SQL_SNIPPETS_']
5254
| ['_SQL_SNIPPETS_', string]
@@ -108,7 +110,7 @@ export const EditorModel = types
108110
label: 'Filters',
109111
value: '_FILTERS_',
110112
Icon: IconFilter,
111-
children: [...filters.options, getActionOption('_Add_A_Filter_')],
113+
children: [getActionOption('_FILTERS_SETTINGS_'), ...filters.options, getActionOption('_Add_A_Filter_')],
112114
_type: 'GROUP',
113115
},
114116
{

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import _ from 'lodash';
12
import {
23
addDisposer,
34
addMiddleware,
@@ -40,6 +41,12 @@ export const FiltersModel = types
4041
}),
4142
)
4243
.views((self) => ({
44+
get idSet() {
45+
return new Set(self.current.map((f) => f.id));
46+
},
47+
get keySet() {
48+
return new Set(self.current.map((f) => f.key));
49+
},
4350
get options() {
4451
return self.current.map(
4552
(f) =>
@@ -67,6 +74,9 @@ export const FiltersModel = types
6774
value: f.key,
6875
}));
6976
},
77+
get sortedList() {
78+
return _.sortBy(self.current, (o) => o.label.toLowerCase());
79+
},
7080
}))
7181
.actions((self) => {
7282
return {
@@ -76,6 +86,14 @@ export const FiltersModel = types
7686
append(item: FilterMetaInstance) {
7787
self.current.push(item);
7888
},
89+
appendMultiple(items: FilterMetaInstance[]) {
90+
if (items.length === 0) {
91+
return;
92+
}
93+
94+
const newItems = items.filter((item) => !self.idSet.has(item.id));
95+
self.current.push(...newItems);
96+
},
7997
remove(index: number) {
8098
self.current.splice(index, 1);
8199
},

dashboard/src/dashboard-editor/model/panels/panels.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ export const PanelsModel = types
4747
append(item: PanelModelSnapshotIn) {
4848
self.list.push(item);
4949
},
50+
appendMultiple(items: PanelModelSnapshotIn[]) {
51+
if (items.length === 0) {
52+
return;
53+
}
54+
55+
self.list.push(...items);
56+
},
5057
remove(index: number) {
5158
self.list.splice(index, 1);
5259
},

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ export const QueriesModel = QueriesRenderModel.views((self) => ({
2424
append(item: QueryRenderModelInstance) {
2525
self.current.push(item);
2626
},
27+
appendMultiple(items: QueryRenderModelInstance[]) {
28+
if (items.length === 0) {
29+
return;
30+
}
31+
32+
const newItems = items.filter((item) => !self.idSet.has(item.id));
33+
self.current.push(...newItems);
34+
},
2735
remove(index: number) {
2836
self.current.splice(index, 1);
2937
},

dashboard/src/dashboard-editor/model/sql-snippets/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ export const SQLSnippetsModel = SQLSnippetsRenderModel.views((self) => ({
2525
append(item: SQLSnippetRenderModelSnapshotIn) {
2626
self.current.push(item);
2727
},
28+
29+
appendMultiple(items: SQLSnippetRenderModelSnapshotIn[]) {
30+
if (items.length === 0) {
31+
return;
32+
}
33+
34+
const newItems = items.filter((item) => !self.keySet.has(item.key));
35+
self.current.push(...newItems);
36+
},
2837
remove(index: number) {
2938
self.current.splice(index, 1);
3039
},

0 commit comments

Comments
 (0)