feat: set a url parameter to activate tab index (#107)

This commit is contained in:
Fine0830 2022-06-14 17:01:11 +08:00 committed by GitHub
parent 0828f8a7aa
commit b697fe4713
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 270 additions and 32 deletions

View File

@ -28,15 +28,26 @@ export const Languages = [
export const RoutesMap: { [key: string]: string } = { export const RoutesMap: { [key: string]: string } = {
GeneralServices: "GENERAL", GeneralServices: "GENERAL",
GeneralServicesActiveTabIndex: "GENERAL",
Database: "VIRTUAL_DATABASE", Database: "VIRTUAL_DATABASE",
DatabaseActiveTabIndex: "VIRTUAL_DATABASE",
MeshServices: "MESH", MeshServices: "MESH",
MeshServicesActiveTabIndex: "MESH",
ControlPanel: "MESH_CP", ControlPanel: "MESH_CP",
ControlPanelActiveTabIndex: "MESH_CP",
DataPanel: "MESH_DP", DataPanel: "MESH_DP",
DataPanelActiveTabIndex: "MESH_DP",
Linux: "OS_LINUX", Linux: "OS_LINUX",
SkyWalkingServer: "SO11Y_OAP", SkyWalkingServer: "SO11Y_OAP",
SkyWalkingServerActiveTabIndex: "SO11Y_OAP",
SatelliteActiveTabIndex: "SO11Y_SATELLITE",
Satellite: "SO11Y_SATELLITE", Satellite: "SO11Y_SATELLITE",
Functions: "FAAS", Functions: "FAAS",
FunctionsActiveTabIndex: "FAAS",
Browser: "BROWSER", Browser: "BROWSER",
BrowserActiveTabIndex: "BROWSER",
KubernetesCluster: "K8S", KubernetesCluster: "K8S",
KubernetesClusterActiveTabIndex: "K8S",
KubernetesService: "K8S_SERVICE", KubernetesService: "K8S_SERVICE",
KubernetesServiceActiveTabIndex: "K8S_SERVICE",
}; };

View File

@ -55,9 +55,9 @@ limitations under the License. -->
<router-link <router-link
class="items" class="items"
:to="m.path" :to="m.path"
:exact="m.meta.exact || false" :exact="(m.meta && m.meta.exact) || false"
> >
<span class="title">{{ t(m.meta.title) }}</span> <span class="title">{{ m.meta && t(m.meta.title) }}</span>
</router-link> </router-link>
</el-menu-item> </el-menu-item>
</el-menu-item-group> </el-menu-item-group>

View File

@ -33,12 +33,20 @@ export const routesBrowser: Array<RouteRecordRaw> = [
name: "Browser", name: "Browser",
meta: { meta: {
title: "browser", title: "browser",
headPath: "/browser",
exact: true, exact: true,
}, },
component: () => component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
}, },
{
path: "/browser/tab/:activeTabIndex",
name: "BrowserActiveTabIndex",
meta: {
notShow: true,
},
component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
},
], ],
}, },
]; ];

View File

@ -54,69 +54,156 @@ export const routesDashboard: Array<RouteRecordRaw> = [
}, },
}, },
{ {
path: "/dashboard/:layerId/:entity/:name", path: "",
redirect: "/dashboard/:layerId/:entity/:name",
name: "Create",
component: () => component: () =>
import( import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
), ),
name: "Create",
meta: { meta: {
title: "dashboardEdit",
exact: false,
notShow: true, notShow: true,
}, },
children: [
{
path: "/dashboard/:layerId/:entity/:name",
component: () =>
import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
),
name: "CreateChild",
},
{
path: "/dashboard/:layerId/:entity/:name/tab/:activeTabIndex",
component: () =>
import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
),
name: "CreateActiveTabIndex",
},
],
}, },
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:name", path: "",
component: () => component: () =>
import( import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
), ),
name: "View", name: "View",
redirect: "/dashboard/:layerId/:entity/:serviceId/:name",
meta: { meta: {
title: "dashboardEdit",
exact: false,
notShow: true, notShow: true,
}, },
children: [
{
path: "/dashboard/:layerId/:entity/:serviceId/:name",
component: () =>
import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
),
name: "ViewChild",
},
{
path: "/dashboard/:layerId/:entity/:serviceId/:name/tab/:activeTabIndex",
component: () =>
import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
),
name: "ViewActiveTabIndex",
},
],
}, },
{ {
path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name", path: "",
redirect:
"/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name",
component: () => component: () =>
import( import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
), ),
name: "ViewServiceRelation", name: "ViewServiceRelation",
meta: { meta: {
title: "dashboardEdit",
exact: false,
notShow: true, notShow: true,
}, },
children: [
{
path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name",
component: () =>
import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
),
name: "ViewServiceRelation",
},
{
path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name/tab/:activeTabIndex",
component: () =>
import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
),
name: "ViewServiceRelationActiveTabIndex",
},
],
}, },
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name", path: "",
redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:name",
component: () => component: () =>
import( import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
), ),
name: "ViewPod", name: "ViewPod",
meta: { meta: {
title: "dashboardEdit",
exact: false,
notShow: true, notShow: true,
}, },
children: [
{
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name",
component: () =>
import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
),
name: "ViewPod",
},
{
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name/tab/:activeTabIndex",
component: () =>
import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
),
name: "ViewPodActiveTabIndex",
},
],
}, },
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name", path: "",
redirect:
"/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
component: () => component: () =>
import( import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
), ),
name: "ViewPodRelation", name: "ViewPodRelation",
meta: { meta: {
title: "dashboardEdit",
exact: true,
notShow: true, notShow: true,
}, },
children: [
{
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
component: () =>
import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
),
name: "ViewPodRelation",
},
{
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name/tab/:activeTabIndex",
component: () =>
import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
),
name: "ViewPodRelationActiveTabIndex",
},
],
}, },
], ],
}, },

View File

@ -34,12 +34,20 @@ export const routesDatabase: Array<RouteRecordRaw> = [
name: "Database", name: "Database",
meta: { meta: {
title: "virtualDatabase", title: "virtualDatabase",
headPath: "/database",
exact: true, exact: true,
}, },
component: () => component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
}, },
{
path: "/database/tab/:activeTabIndex",
name: "DatabaseActiveTabIndex",
meta: {
notShow: true,
},
component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
},
], ],
}, },
]; ];

View File

@ -32,13 +32,17 @@ export const routesFunctions: Array<RouteRecordRaw> = [
path: "/functions", path: "/functions",
name: "Functions", name: "Functions",
meta: { meta: {
title: "functions",
headPath: "/functions",
exact: true, exact: true,
}, },
component: () => component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
}, },
{
path: "/functions/tab/:activeTabIndex",
name: "FunctionsActiveTabIndex",
component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
},
], ],
}, },
]; ];

View File

@ -33,8 +33,15 @@ export const routesGen: Array<RouteRecordRaw> = [
path: "/general", path: "/general",
name: "GeneralServices", name: "GeneralServices",
meta: { meta: {
title: "services", exact: true,
headPath: "/general/service", },
component: () =>
import(/* webpackChunkName: "layers" */ "@/views/Layer.vue"),
},
{
path: "/general/tab/:activeTabIndex",
name: "GeneralServicesActiveTabIndex",
meta: {
exact: true, exact: true,
}, },
component: () => component: () =>

View File

@ -39,6 +39,15 @@ export const routesInfra: Array<RouteRecordRaw> = [
component: () => component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
}, },
{
path: "/linux/tab/:activeTabIndex",
name: "LinuxActiveTabIndex",
meta: {
title: "linux",
},
component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
},
// { // {
// path: "/infrastructure/vm", // path: "/infrastructure/vm",
// name: "VirtualMachine", // name: "VirtualMachine",

View File

@ -33,20 +33,42 @@ export const routesK8s: Array<RouteRecordRaw> = [
path: "/kubernetes/cluster", path: "/kubernetes/cluster",
name: "KubernetesCluster", name: "KubernetesCluster",
meta: { meta: {
notShow: false,
title: "kubernetesCluster", title: "kubernetesCluster",
}, },
component: () => component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
}, },
{
path: "/kubernetes/cluster/tab/:activeTabIndex",
name: "KubernetesClusterActiveTabIndex",
meta: {
notShow: true,
title: "kubernetesClusterActiveTabIndex",
},
component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
},
{ {
path: "/kubernetes/service", path: "/kubernetes/service",
name: "KubernetesService", name: "KubernetesService",
meta: { meta: {
notShow: false,
title: "kubernetesService", title: "kubernetesService",
}, },
component: () => component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
}, },
{
path: "/kubernetes/service/tab/:activeTabIndex",
name: "KubernetesServiceActiveTabIndex",
meta: {
notShow: true,
title: "kubernetesServiceActiveTabIndex",
},
component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
},
], ],
}, },
]; ];

View File

@ -34,7 +34,15 @@ export const routesSelf: Array<RouteRecordRaw> = [
name: "SkyWalkingServer", name: "SkyWalkingServer",
meta: { meta: {
title: "skyWalkingServer", title: "skyWalkingServer",
headPath: "/mesh/services", },
component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
},
{
path: "/self/skyWalkingServer/tab/:activeTabIndex",
name: "SkyWalkingServerActiveTabIndex",
meta: {
notShow: true,
}, },
component: () => component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
@ -44,7 +52,15 @@ export const routesSelf: Array<RouteRecordRaw> = [
name: "Satellite", name: "Satellite",
meta: { meta: {
title: "satellite", title: "satellite",
headPath: "/mesh/controlPanel", },
component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
},
{
path: "/self/satellite/tab/:activeTabIndex",
name: "SatelliteActiveTabIndex",
meta: {
notShow: true,
}, },
component: () => component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),

View File

@ -33,8 +33,17 @@ export const routesMesh: Array<RouteRecordRaw> = [
path: "/mesh/services", path: "/mesh/services",
name: "MeshServices", name: "MeshServices",
meta: { meta: {
notShow: false,
title: "services", title: "services",
headPath: "/mesh/services", },
component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
},
{
path: "/mesh/services/tab/:activeTabIndex",
name: "MeshServicesActiveTabIndex",
meta: {
notShow: true,
}, },
component: () => component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
@ -43,8 +52,17 @@ export const routesMesh: Array<RouteRecordRaw> = [
path: "/mesh/controlPanel", path: "/mesh/controlPanel",
name: "ControlPanel", name: "ControlPanel",
meta: { meta: {
notShow: false,
title: "controlPanel", title: "controlPanel",
headPath: "/mesh/controlPanel", },
component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
},
{
path: "/mesh/controlPanel/tab/:activeTabIndex",
name: "ControlPanelActiveTabIndex",
meta: {
notShow: true,
}, },
component: () => component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
@ -53,10 +71,21 @@ export const routesMesh: Array<RouteRecordRaw> = [
path: "/mesh/dataPanel", path: "/mesh/dataPanel",
name: "DataPanel", name: "DataPanel",
meta: { meta: {
notShow: false,
title: "dataPanel", title: "dataPanel",
headPath: "/mesh/dataPanel",
}, },
component: () => import("@/views/Layer.vue"), component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
},
{
path: "/mesh/dataPanel/tab/:activeTabIndex",
name: "DataPanelActiveTabIndex",
meta: {
notShow: true,
title: "dataPanelActiveTabIndex",
},
component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
}, },
], ],
}, },

View File

@ -40,7 +40,14 @@ limitations under the License. -->
<span class="tab-icons" v-if="dashboardStore.editMode"> <span class="tab-icons" v-if="dashboardStore.editMode">
<el-tooltip content="Add tab items" placement="bottom"> <el-tooltip content="Add tab items" placement="bottom">
<i @click="addTabItem"> <i @click="addTabItem">
<Icon size="middle" iconName="add" /> <Icon size="middle" iconName="add" class="tab-icon" />
</i>
</el-tooltip>
</span>
<span class="tab-icons">
<el-tooltip content="Copy Link" placement="bottom">
<i @click="copyLink">
<Icon size="middle" iconName="review-list" class="tab-icon" />
</i> </i>
</el-tooltip> </el-tooltip>
</span> </span>
@ -99,6 +106,7 @@ limitations under the License. -->
<script lang="ts"> <script lang="ts">
import { ref, watch, defineComponent, toRefs } from "vue"; import { ref, watch, defineComponent, toRefs } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router";
import type { PropType } from "vue"; import type { PropType } from "vue";
import { LayoutConfig } from "@/types/dashboard"; import { LayoutConfig } from "@/types/dashboard";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
@ -111,6 +119,7 @@ import Text from "./Text.vue";
import Ebpf from "./Ebpf.vue"; import Ebpf from "./Ebpf.vue";
import { dragIgnoreFrom } from "../data"; import { dragIgnoreFrom } from "../data";
import DemandLog from "./DemandLog.vue"; import DemandLog from "./DemandLog.vue";
import copy from "@/utils/copy";
const props = { const props = {
data: { data: {
@ -126,11 +135,16 @@ export default defineComponent({
setup(props) { setup(props) {
const { t } = useI18n(); const { t } = useI18n();
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const activeTabIndex = ref<number>(0); const route = useRoute();
const activeTabIndex = ref<number>(
Number(route.params.activeTabIndex) || 0
);
const activeTabWidget = ref<string>(""); const activeTabWidget = ref<string>("");
const editTabIndex = ref<number>(NaN); // edit tab item name const editTabIndex = ref<number>(NaN); // edit tab item name
const canEditTabName = ref<boolean>(false); const canEditTabName = ref<boolean>(false);
const needQuery = ref<boolean>(false); const needQuery = ref<boolean>(false);
dashboardStore.setActiveTabIndex(activeTabIndex);
const l = dashboardStore.layout.findIndex( const l = dashboardStore.layout.findIndex(
(d: LayoutConfig) => d.i === props.data.i (d: LayoutConfig) => d.i === props.data.i
); );
@ -154,6 +168,11 @@ export default defineComponent({
dashboardStore.layout[l].children[activeTabIndex.value].children dashboardStore.layout[l].children[activeTabIndex.value].children
); );
needQuery.value = true; needQuery.value = true;
if (route.params.activeTabIndex) {
let p = location.href.split("/tab/")[0];
p = p + "/tab/" + activeTabIndex.value;
history.replaceState({}, "", p);
}
} }
function removeTab(e: Event) { function removeTab(e: Event) {
e.stopPropagation(); e.stopPropagation();
@ -202,6 +221,16 @@ export default defineComponent({
dashboardStore.layout[l].children[activeTabIndex.value].children dashboardStore.layout[l].children[activeTabIndex.value].children
); );
} }
function copyLink() {
let path = "";
if (route.params.activeTabIndex === undefined) {
path = location.href + "/tab/" + activeTabIndex.value;
} else {
const p = location.href.split("/tab/")[0];
path = p + "/tab/" + activeTabIndex.value;
}
copy(path);
}
document.body.addEventListener("click", handleClick, false); document.body.addEventListener("click", handleClick, false);
watch( watch(
() => dashboardStore.activedGridItem, () => dashboardStore.activedGridItem,
@ -227,6 +256,7 @@ export default defineComponent({
deleteTabItem, deleteTabItem,
removeTab, removeTab,
clickTabs, clickTabs,
copyLink,
...toRefs(props), ...toRefs(props),
activeTabWidget, activeTabWidget,
dashboardStore, dashboardStore,
@ -330,6 +360,10 @@ export default defineComponent({
overflow: auto; overflow: auto;
} }
.tab-icon {
color: #666;
}
.vue-grid-item.active { .vue-grid-item.active {
border: 1px solid #409eff; border: 1px solid #409eff;
} }

View File

@ -538,6 +538,9 @@ function setNodeTools(nodeDashboard: any) {
} }
} }
async function freshNodes() { async function freshNodes() {
if (!svg.value) {
return;
}
svg.value.selectAll(".topo-svg-graph").remove(); svg.value.selectAll(".topo-svg-graph").remove();
await init(); await init();
update(); update();