Merge pull request #1 from pemeraldy/feature/fullview-route

Feature/fullview route
This commit is contained in:
Peter Olu 2022-04-23 14:51:26 +01:00 committed by GitHub
commit a76ff1e1ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 14038 additions and 5 deletions

133
src/components/FullVue.vue Normal file
View File

@ -0,0 +1,133 @@
<!-- 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. -->
<template>
<div class="scroll-snap-container">
<div :id="'item' + item.i" class="item" v-for="item in items" :key="item.i">
<slot v-if="items.length">
<component :is="item.type" :data="item" />
</slot>
</div>
</div>
</template>
<script lang="ts">
import { ref, watch, reactive, defineComponent } from "vue";
import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router";
import { useDashboardStore } from "@/store/modules/dashboard";
// import { useAppStoreWithOut } from "@/store/modules/app";
import Configuration from "../views/dashboard/configuration";
import controls from "../views/dashboard/controls/index";
export default defineComponent({
name: "Dashboard",
props: {
items: {
type: Array,
default: () => [],
},
},
components: { ...Configuration, ...controls },
setup() {
const dashboardStore = useDashboardStore();
const tobewatched = reactive(dashboardStore);
// const appStore = useAppStoreWithOut();
const { t } = useI18n();
const p = useRoute().params;
// const layoutKey = ref<string>(`${p.layerId}_${p.entity}_${p.name}`);
// setTemplate();
const currentItem = ref("");
watch(
() => tobewatched.layout,
() => {
setTimeout(() => {
observeItems();
}, 500);
}
);
// async function setTemplate() {
// await dashboardStore.setDashboards();
// if (!p.entity) {
// if (!dashboardStore.currentDashboard) {
// return;
// }
// const { layer, entity, name } = dashboardStore.currentDashboard;
// layoutKey.value = `${layer}_${entity}_${name}`;
// }
// const c: { configuration: string; id: string } = JSON.parse(
// sessionStorage.getItem(layoutKey.value) || "{}"
// );
// const layout: any = c.configuration || {};
// dashboardStore.setLayout(layout.children || []);
// appStore.setPageTitle(layout.name);
// // observeItems();
// if (p.entity) {
// dashboardStore.setCurrentDashboard({
// layer: p.layerId,
// entity: p.entity,
// name: p.name,
// id: c.id,
// isRoot: layout.isRoot,
// });
// }
// }
function observeItems() {
const observer = new IntersectionObserver((entries) => {
entries.forEach((element) => {
if (element.intersectionRatio > 0) {
currentItem.value = element.target.id;
}
});
});
document.querySelectorAll(".item").forEach((element) => {
observer.observe(element);
});
}
return {
t,
dashboardStore,
currentItem,
};
},
});
</script>
<style lang="scss" scoped>
.scroll-snap-container {
height: 90vh;
display: block;
overflow-y: scroll;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
scroll-snap-points-y: repeat(100%);
scroll-snap-destination: 0 0;
scroll-snap-type: y mandatory;
scroll-snap-type: mandatory;
scroll-behavior: smooth;
}
.scroll-snap-container::-webkit-scrollbar {
display: none;
}
.item {
scroll-snap-align: start;
height: 100%;
padding: 40px;
margin: 40px 0;
// background: orange;
}
</style>

View File

@ -34,6 +34,7 @@ export const RoutesMap: { [key: string]: string } = {
Linux: "OS_LINUX", Linux: "OS_LINUX",
SkyWalkingServer: "SO11Y_OAP", SkyWalkingServer: "SO11Y_OAP",
Satellite: "SO11Y_SATELLITE", Satellite: "SO11Y_SATELLITE",
FullScroll: "SO11Y_SATELLITE",
Functions: "FAAS", Functions: "FAAS",
Browser: "BROWSER", Browser: "BROWSER",
KubernetesCluster: "K8S", KubernetesCluster: "K8S",

View File

@ -66,6 +66,19 @@ export const routesDashboard: Array<RouteRecordRaw> = [
notShow: true, notShow: true,
}, },
}, },
{
path: "/fullview/:layerId/:entity/:name",
component: () =>
import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
),
name: "FullViewCreate",
meta: {
title: "dashboardEdit",
exact: false,
notShow: true,
},
},
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:name", path: "/dashboard/:layerId/:entity/:serviceId/:name",
component: () => component: () =>
@ -79,6 +92,19 @@ export const routesDashboard: Array<RouteRecordRaw> = [
notShow: true, notShow: true,
}, },
}, },
{
path: "/fullview/:layerId/:entity/:serviceId/:name",
component: () =>
import(
/* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
),
name: "FullViewView",
meta: {
title: "dashboardEdit",
exact: false,
notShow: true,
},
},
{ {
path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name", path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name",
component: () => component: () =>
@ -92,6 +118,19 @@ export const routesDashboard: Array<RouteRecordRaw> = [
notShow: true, notShow: true,
}, },
}, },
{
path: "/fullview/related/:layerId/:entity/:serviceId/:destServiceId/:name",
component: () =>
import(
/* webpackChunkName: "FullViewdashboards" */ "@/views/dashboard/Edit.vue"
),
name: "FullViewViewServiceRelation",
meta: {
title: "dashboardEdit",
exact: false,
notShow: true,
},
},
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name", path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name",
component: () => component: () =>
@ -105,6 +144,19 @@ export const routesDashboard: Array<RouteRecordRaw> = [
notShow: true, notShow: true,
}, },
}, },
{
path: "/fullview/:layerId/:entity/:serviceId/:podId/:name",
component: () =>
import(
/* webpackChunkName: "FullViewdashboards" */ "@/views/dashboard/Edit.vue"
),
name: "FullViewViewPod",
meta: {
title: "dashboardEdit",
exact: false,
notShow: true,
},
},
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name", path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
component: () => component: () =>
@ -118,6 +170,19 @@ export const routesDashboard: Array<RouteRecordRaw> = [
notShow: true, notShow: true,
}, },
}, },
{
path: "/fullview/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
component: () =>
import(
/* webpackChunkName: "FullViewdashboards" */ "@/views/dashboard/Edit.vue"
),
name: "FullViewViewPodRelation",
meta: {
title: "dashboardEdit",
exact: true,
notShow: true,
},
},
], ],
}, },
]; ];

View File

@ -49,6 +49,16 @@ export const routesSelf: Array<RouteRecordRaw> = [
component: () => component: () =>
import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
}, },
{
path: "/self/fullScroll",
name: "FullScroll",
meta: {
title: "fullscreen-sample",
headPath: "/mesh/controlPanel",
},
component: () =>
import(/* webpackChunkName: "layer" */ "@/views/FullScroll.vue"),
},
], ],
}, },
]; ];

View File

@ -38,6 +38,7 @@ interface DashboardState {
durationTime: Duration; durationTime: Duration;
selectorStore: any; selectorStore: any;
showTopology: boolean; showTopology: boolean;
fullView: boolean;
currentTabItems: LayoutConfig[]; currentTabItems: LayoutConfig[];
dashboards: DashboardItem[]; dashboards: DashboardItem[];
currentDashboard: Nullable<DashboardItem>; currentDashboard: Nullable<DashboardItem>;
@ -56,6 +57,7 @@ export const dashboardStore = defineStore({
durationTime: useAppStoreWithOut().durationTime, durationTime: useAppStoreWithOut().durationTime,
selectorStore: useSelectorStore(), selectorStore: useSelectorStore(),
showTopology: false, showTopology: false,
fullView: false,
currentTabItems: [], currentTabItems: [],
dashboards: [], dashboards: [],
currentDashboard: null, currentDashboard: null,
@ -68,6 +70,9 @@ export const dashboardStore = defineStore({
setMode(mode: boolean) { setMode(mode: boolean) {
this.editMode = mode; this.editMode = mode;
}, },
setViewMode(mode: boolean) {
this.fullView = mode;
},
resetDashboards(list: DashboardItem[]) { resetDashboards(list: DashboardItem[]) {
this.dashboards = list; this.dashboards = list;
sessionStorage.setItem("dashboards", JSON.stringify(list)); sessionStorage.setItem("dashboards", JSON.stringify(list));

View File

@ -1,6 +1,7 @@
// generated by unplugin-vue-components // generated by unplugin-vue-components
// We suggest you to commit this file into source control // We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/vue-next/pull/3399 // Read more: https://github.com/vuejs/vue-next/pull/3399
import '@vue/runtime-core'
declare module '@vue/runtime-core' { declare module '@vue/runtime-core' {
export interface GlobalComponents { export interface GlobalComponents {
@ -32,6 +33,7 @@ declare module '@vue/runtime-core' {
ElTable: typeof import('element-plus/es')['ElTable'] ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTooltip: typeof import('element-plus/es')['ElTooltip'] ElTooltip: typeof import('element-plus/es')['ElTooltip']
FullVue: typeof import('./../components/FullVue.vue')['default']
Graph: typeof import('./../components/Graph.vue')['default'] Graph: typeof import('./../components/Graph.vue')['default']
Icon: typeof import('./../components/Icon.vue')['default'] Icon: typeof import('./../components/Icon.vue')['default']
Loading: typeof import('element-plus/es')['ElLoadingDirective'] Loading: typeof import('element-plus/es')['ElLoadingDirective']
@ -44,4 +46,4 @@ declare module '@vue/runtime-core' {
} }
} }
export { } export {}

67
src/views/FullScroll.vue Normal file
View File

@ -0,0 +1,67 @@
<!-- 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. -->
<template>
<Dashboard v-if="dashboardStore.currentDashboard" />
<div v-else class="no-root">
{{ t("noRoot") }} {{ dashboardStore.layerId }}
</div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { useRoute } from "vue-router";
import { EntityType } from "./dashboard/data";
import { useDashboardStore } from "@/store/modules/dashboard";
import Dashboard from "./dashboard/Scroll.vue";
import { useI18n } from "vue-i18n";
import { useAppStoreWithOut } from "@/store/modules/app";
import { RoutesMap } from "@/constants/data";
const route = useRoute();
const { t } = useI18n();
const appStore = useAppStoreWithOut();
const dashboardStore = useDashboardStore();
const layer = ref<string>("GENERAL");
getDashboard();
async function getDashboard() {
layer.value = RoutesMap[String(route.name)];
dashboardStore.setLayer(layer.value);
dashboardStore.setMode(false);
await dashboardStore.setDashboards();
const item = dashboardStore.dashboards.find(
(d: { name: string; isRoot: boolean; layer: string; entity: string }) =>
d.layer === dashboardStore.layerId &&
[EntityType[0].value, EntityType[1].value].includes(d.entity) &&
d.isRoot
);
if (!item) {
appStore.setPageTitle(dashboardStore.layer);
dashboardStore.setCurrentDashboard(null);
dashboardStore.setEntity(EntityType[1].value);
return;
}
dashboardStore.setEntity(item.entity);
dashboardStore.setCurrentDashboard(item);
}
</script>
<style lang="scss" scoped>
.no-root {
padding: 15px;
width: 100%;
text-align: center;
color: #888;
}
</style>

View File

@ -0,0 +1,102 @@
<!-- 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. -->
<template>
<Tool v-if="dashboardStore.currentDashboard" />
<div
class="ds-main"
v-if="dashboardStore.currentDashboard"
@click="handleClick"
:style="{ height: dashboardStore.editMode ? 'calc(100% - 45px)' : '100%' }"
>
<FullVue :items="dashboardStore.layout"></FullVue>
<el-dialog
v-model="dashboardStore.showConfig"
:title="t('editGraph')"
fullscreen
:destroy-on-close="true"
@closed="dashboardStore.setConfigPanel(false)"
>
<component :is="dashboardStore.selectedGrid.type" />
</el-dialog>
</div>
</template>
<script lang="ts">
import { ref, defineComponent } from "vue";
import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router";
import GridLayout from "./panel/Layout.vue";
import Tool from "./panel/Tool.vue";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app";
import Configuration from "./configuration";
import controls from "./controls/index";
import FullVue from "@/components/FullVue.vue";
export default defineComponent({
name: "Dashboard",
components: { FullVue, ...Configuration, GridLayout, Tool, ...controls },
setup() {
const dashboardStore = useDashboardStore();
const appStore = useAppStoreWithOut();
const { t } = useI18n();
const p = useRoute().params;
const layoutKey = ref<string>(`${p.layerId}_${p.entity}_${p.name}`);
setTemplate();
const currentItem = ref("");
async function setTemplate() {
await dashboardStore.setDashboards();
if (!p.entity) {
if (!dashboardStore.currentDashboard) {
return;
}
const { layer, entity, name } = dashboardStore.currentDashboard;
layoutKey.value = `${layer}_${entity}_${name}`;
}
const c: { configuration: string; id: string } = JSON.parse(
sessionStorage.getItem(layoutKey.value) || "{}"
);
const layout: any = c.configuration || {};
dashboardStore.setLayout(layout.children || []);
appStore.setPageTitle(layout.name);
if (p.entity) {
dashboardStore.setCurrentDashboard({
layer: p.layerId,
entity: p.entity,
name: p.name,
id: c.id,
isRoot: layout.isRoot,
});
}
}
return {
t,
dashboardStore,
currentItem,
};
},
});
</script>
<style lang="scss" scoped>
.ds-main {
overflow: auto;
}
.full-view__scroll {
height: 60vh;
width: 100%;
}
</style>

View File

@ -21,7 +21,9 @@ limitations under the License. -->
:is-resizable="dashboardStore.editMode" :is-resizable="dashboardStore.editMode"
v-if="dashboardStore.layout.length" v-if="dashboardStore.layout.length"
> >
<FullVue v-if="isFullview" :items="dashboardStore.layout"></FullVue>
<grid-item <grid-item
v-else
v-for="item in dashboardStore.layout" v-for="item in dashboardStore.layout"
:x="item.x" :x="item.x"
:y="item.y" :y="item.y"
@ -39,17 +41,23 @@ limitations under the License. -->
<div class="no-data-tips" v-else>{{ t("noWidget") }}</div> <div class="no-data-tips" v-else>{{ t("noWidget") }}</div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, onBeforeUnmount } from "vue"; import { defineComponent, computed, onBeforeUnmount } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { LayoutConfig } from "@/types/dashboard"; import { LayoutConfig } from "@/types/dashboard";
import controls from "../controls/index"; import controls from "../controls/index";
import FullVue from "@/components/FullVue.vue";
import { useRoute } from "vue-router";
export default defineComponent({ export default defineComponent({
name: "Layout", name: "Layout",
components: { ...controls }, components: { ...controls, FullVue },
setup() { setup() {
const { path } = useRoute();
const isFullview = computed(() => {
return path.includes("fullview");
});
const { t } = useI18n(); const { t } = useI18n();
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore(); const selectorStore = useSelectorStore();
@ -69,6 +77,7 @@ export default defineComponent({
dashboardStore.setConfigPanel(false); dashboardStore.setConfigPanel(false);
}); });
return { return {
isFullview,
dashboardStore, dashboardStore,
clickGrid, clickGrid,
t, t,

View File

@ -104,6 +104,20 @@ limitations under the License. -->
</i> </i>
</el-tooltip> </el-tooltip>
</div> </div>
<div class="switch">
<span style="margin-right: 5px">Toggle full view</span>
<el-switch
v-model="dashboardStore.fullView"
active-text="Full view"
inactive-text="FV"
size="small"
inline-prompt
active-color="#409eff"
inactive-color="#999"
@change="toggleFullView"
/>
</div>
<div class="switch"> <div class="switch">
<el-switch <el-switch
v-model="dashboardStore.editMode" v-model="dashboardStore.editMode"
@ -121,7 +135,7 @@ limitations under the License. -->
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref, computed, watch } from "vue"; import { reactive, ref, computed, watch } from "vue";
import { useRoute } from "vue-router"; import { useRoute, useRouter } from "vue-router";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { import {
@ -144,6 +158,13 @@ const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore(); const selectorStore = useSelectorStore();
const appStore = useAppStoreWithOut(); const appStore = useAppStoreWithOut();
const params = useRoute().params; const params = useRoute().params;
const path = useRoute();
const router = useRouter();
if (!path.path.includes("fullview")) {
dashboardStore.setViewMode(false)
}else{
dashboardStore.setViewMode(true)
}
const toolIcons = ref<{ name: string; content: string; id: string }[]>( const toolIcons = ref<{ name: string; content: string; id: string }[]>(
EndpointRelationTools EndpointRelationTools
); );
@ -387,7 +408,16 @@ function changeDestPods(pod: any) {
selectorStore.setCurrentDestPod(null); selectorStore.setCurrentDestPod(null);
} }
} }
function toggleFullView(e) {
dashboardStore.setViewMode(e);
if (dashboardStore.fullView) {
const newPath = path.path.replace("dashboard", "fullview");
router.push(newPath);
} else {
const newPath = path.path.replace("fullview", "dashboard");
router.push(newPath);
}
}
function changeMode() { function changeMode() {
if (dashboardStore.editMode) { if (dashboardStore.editMode) {
ElMessage.warning(t("editWarning")); ElMessage.warning(t("editWarning"));

13609
yarn.lock Normal file

File diff suppressed because it is too large Load Diff