mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-07-16 21:55:24 +00:00
import/export templates
This commit is contained in:
parent
1af4adcb96
commit
3ffdc0cf08
@ -100,6 +100,8 @@ const msg = {
|
|||||||
id: "ID",
|
id: "ID",
|
||||||
setRoot: "Set this to root",
|
setRoot: "Set this to root",
|
||||||
setNormal: "Set this to normal",
|
setNormal: "Set this to normal",
|
||||||
|
export: "Export Dashboard Templates",
|
||||||
|
import: "Import Dashboard Templates",
|
||||||
hourTip: "Select Hour",
|
hourTip: "Select Hour",
|
||||||
minuteTip: "Select Minute",
|
minuteTip: "Select Minute",
|
||||||
secondTip: "Select Second",
|
secondTip: "Select Second",
|
||||||
|
@ -100,6 +100,8 @@ const msg = {
|
|||||||
id: "编号",
|
id: "编号",
|
||||||
setRoot: "设置成为根",
|
setRoot: "设置成为根",
|
||||||
setNormal: "设置成为普通",
|
setNormal: "设置成为普通",
|
||||||
|
export: "导出仪表板模板",
|
||||||
|
import: "导入仪表板模板",
|
||||||
hourTip: "选择小时",
|
hourTip: "选择小时",
|
||||||
minuteTip: "选择分钟",
|
minuteTip: "选择分钟",
|
||||||
secondTip: "选择秒数",
|
secondTip: "选择秒数",
|
||||||
|
@ -413,8 +413,8 @@ export const dashboardStore = defineStore({
|
|||||||
this.dashboards.push({
|
this.dashboards.push({
|
||||||
id: json.id,
|
id: json.id,
|
||||||
name: this.currentDashboard.name,
|
name: this.currentDashboard.name,
|
||||||
layer: this.layerId,
|
layer: this.currentDashboard.layer,
|
||||||
entity: this.entity,
|
entity: this.currentDashboard.entity,
|
||||||
isRoot: true,
|
isRoot: true,
|
||||||
});
|
});
|
||||||
const key = [
|
const key = [
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export type DashboardItem = {
|
export type DashboardItem = {
|
||||||
id: string;
|
id?: string;
|
||||||
entity: string;
|
entity: string;
|
||||||
layer: string;
|
layer: string;
|
||||||
isRoot: string;
|
isRoot: string;
|
||||||
|
44
src/utils/file.ts
Normal file
44
src/utils/file.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const readFile = (event: any) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const { files } = event.target;
|
||||||
|
if (files.length < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const file = files[0];
|
||||||
|
const reader: FileReader = new FileReader();
|
||||||
|
reader.readAsText(file);
|
||||||
|
reader.onload = function () {
|
||||||
|
if (typeof this.result === "string") {
|
||||||
|
resolve(JSON.parse(this.result));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const saveFile = (data: any, name: string) => {
|
||||||
|
const newData = JSON.stringify(data);
|
||||||
|
const tagA = document.createElement("a");
|
||||||
|
tagA.download = name;
|
||||||
|
tagA.style.display = "none";
|
||||||
|
const blob = new Blob([newData]);
|
||||||
|
tagA.href = URL.createObjectURL(blob);
|
||||||
|
document.body.appendChild(tagA);
|
||||||
|
tagA.click();
|
||||||
|
document.body.removeChild(tagA);
|
||||||
|
};
|
@ -36,12 +36,13 @@ limitations under the License. -->
|
|||||||
</div>
|
</div>
|
||||||
<div class="table">
|
<div class="table">
|
||||||
<el-table
|
<el-table
|
||||||
:border="true"
|
|
||||||
:data="dashboards"
|
:data="dashboards"
|
||||||
:style="{ width: '100%', fontSize: '13px' }"
|
:style="{ width: '100%', fontSize: '13px' }"
|
||||||
max-height="550"
|
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
|
ref="multipleTableRef"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
>
|
>
|
||||||
|
<el-table-column type="selection" width="35" />
|
||||||
<el-table-column fixed prop="name" label="Name" />
|
<el-table-column fixed prop="name" label="Name" />
|
||||||
<el-table-column prop="layer" label="Layer" width="200" />
|
<el-table-column prop="layer" label="Layer" width="200" />
|
||||||
<el-table-column prop="entity" label="Entity" width="200" />
|
<el-table-column prop="entity" label="Entity" width="200" />
|
||||||
@ -59,7 +60,7 @@ limitations under the License. -->
|
|||||||
@confirm="setRoot(scope.row)"
|
@confirm="setRoot(scope.row)"
|
||||||
>
|
>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-button size="small">
|
<el-button size="small" style="width: 120px">
|
||||||
{{ scope.row.isRoot ? t("setNormal") : t("setRoot") }}
|
{{ scope.row.isRoot ? t("setNormal") : t("setRoot") }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
@ -77,6 +78,27 @@ limitations under the License. -->
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
<div class="toggle-selection">
|
||||||
|
<el-button size="default" class="btn" @click="exportTemplates">
|
||||||
|
<Icon class="mr-5" iconName="save_alt" />
|
||||||
|
{{ t("export") }}
|
||||||
|
</el-button>
|
||||||
|
<el-button class="ml-10 btn" size="default">
|
||||||
|
<input
|
||||||
|
id="dashboard-file"
|
||||||
|
class="import-template"
|
||||||
|
type="file"
|
||||||
|
name="file"
|
||||||
|
title=""
|
||||||
|
accept=".json"
|
||||||
|
@change="importTemplates"
|
||||||
|
/>
|
||||||
|
<label for="dashboard-file" class="input-label">
|
||||||
|
<Icon class="mr-5" iconName="folder_open" />
|
||||||
|
{{ t("import") }}
|
||||||
|
</label>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -89,6 +111,7 @@ import { useAppStoreWithOut } from "@/store/modules/app";
|
|||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import { DashboardItem } from "@/types/dashboard";
|
import { DashboardItem } from "@/types/dashboard";
|
||||||
|
import { saveFile, readFile } from "@/utils/file";
|
||||||
|
|
||||||
const appStore = useAppStoreWithOut();
|
const appStore = useAppStoreWithOut();
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
@ -109,19 +132,58 @@ const dashboards = ref<DashboardItem[]>([]);
|
|||||||
const searchText = ref<string>("");
|
const searchText = ref<string>("");
|
||||||
const loading = ref<boolean>(false);
|
const loading = ref<boolean>(false);
|
||||||
const multipleTableRef = ref<InstanceType<typeof ElTable>>();
|
const multipleTableRef = ref<InstanceType<typeof ElTable>>();
|
||||||
|
const multipleSelection = ref<DashboardItem[]>([]);
|
||||||
|
|
||||||
|
const handleSelectionChange = (val: DashboardItem[]) => {
|
||||||
|
multipleSelection.value = val;
|
||||||
|
};
|
||||||
setList();
|
setList();
|
||||||
|
|
||||||
async function setList() {
|
async function setList() {
|
||||||
await dashboardStore.setDashboards();
|
await dashboardStore.setDashboards();
|
||||||
dashboards.value = dashboardStore.dashboards;
|
dashboards.value = dashboardStore.dashboards;
|
||||||
}
|
}
|
||||||
const handleView = (row: DashboardItem) => {
|
async function importTemplates(event: any) {
|
||||||
|
const arr: any = await readFile(event);
|
||||||
|
loading.value = true;
|
||||||
|
for (const item of arr) {
|
||||||
|
const { layer, name, entity, isRoot, children } = item.configuration;
|
||||||
|
const index = dashboardStore.dashboards.findIndex(
|
||||||
|
(d: DashboardItem) => d.id === item.id
|
||||||
|
);
|
||||||
|
const p: DashboardItem = {
|
||||||
|
name: name,
|
||||||
|
layer: layer,
|
||||||
|
entity: entity,
|
||||||
|
isRoot: isRoot,
|
||||||
|
};
|
||||||
|
if (index > -1) {
|
||||||
|
p.id = item.id;
|
||||||
|
}
|
||||||
|
dashboardStore.setCurrentDashboard(p);
|
||||||
|
dashboardStore.setLayout(children);
|
||||||
|
await dashboardStore.saveDashboard();
|
||||||
|
}
|
||||||
|
dashboards.value = dashboardStore.dashboards;
|
||||||
|
loading.value = false;
|
||||||
|
const el: any = document.getElementById("dashboard-file");
|
||||||
|
el!.value = "";
|
||||||
|
}
|
||||||
|
function exportTemplates() {
|
||||||
|
const templates = multipleSelection.value.map((d: DashboardItem) => {
|
||||||
|
const key = [d.layer, d.entity, d.name.split(" ").join("-")].join("_");
|
||||||
|
const layout = JSON.parse(sessionStorage.getItem(key) || "{}");
|
||||||
|
return layout;
|
||||||
|
});
|
||||||
|
const name = `dashboards.json`;
|
||||||
|
saveFile(templates, name);
|
||||||
|
}
|
||||||
|
function handleView(row: DashboardItem) {
|
||||||
dashboardStore.setCurrentDashboard(row);
|
dashboardStore.setCurrentDashboard(row);
|
||||||
router.push(
|
router.push(
|
||||||
`/dashboard/${row.layer}/${row.entity}/${row.name.split(" ").join("-")}`
|
`/dashboard/${row.layer}/${row.entity}/${row.name.split(" ").join("-")}`
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
async function setRoot(row: DashboardItem) {
|
async function setRoot(row: DashboardItem) {
|
||||||
const items: any[] = [];
|
const items: any[] = [];
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
@ -285,4 +347,24 @@ function searchDashboards() {
|
|||||||
box-shadow: 0px 1px 4px 0px #00000029;
|
box-shadow: 0px 1px 4px 0px #00000029;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toggle-selection {
|
||||||
|
margin-top: 20px;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: 220px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.import-template {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-label {
|
||||||
|
display: inline;
|
||||||
|
line-height: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user