feat: add list components config

This commit is contained in:
Qiuxia Fan 2022-01-18 15:53:43 +08:00
parent db8338ffa5
commit 2e82d52e71
12 changed files with 318 additions and 37 deletions

View File

@ -73,6 +73,7 @@ const msg = {
showBackground: "Show Background",
areaOpacity: "Area Opacity",
editGraph: "Edit Graph Options",
dashboardName: "Select Dashboard Name",
hourTip: "Select Hour",
minuteTip: "Select Minute",
secondTip: "Select Second",

View File

@ -71,6 +71,7 @@ const msg = {
showBackground: "显示背景",
areaOpacity: "透明度",
editGraph: "编辑图表选项",
dashboardName: "选择仪表板名称",
hourTip: "选择小时",
minuteTip: "选择分钟",
secondTip: "选择秒数",

View File

@ -47,7 +47,14 @@ export interface StandardConfig {
seconds?: string;
}
export type GraphConfig = BarConfig | LineConfig | CardConfig | TableConfig;
export type GraphConfig =
| BarConfig
| LineConfig
| CardConfig
| TableConfig
| EndpointListConfig
| ServiceListConfig
| InstanceListConfig;
export interface BarConfig {
type?: string;
showBackground?: boolean;
@ -81,3 +88,21 @@ export interface TopListConfig {
type?: string;
topN: number;
}
export interface ServiceListConfig {
type?: string;
dashboardName: string;
fontSize: number;
}
export interface InstanceListConfig {
type?: string;
dashboardName: string;
fontSize: number;
}
export interface EndpointListConfig {
type?: string;
dashboardName: string;
fontSize: number;
}

View File

@ -50,8 +50,21 @@ limitations under the License. -->
</span>
</div>
</el-collapse-item>
<el-collapse-item :title="t('metricName')" name="2">
<div>
<el-collapse-item
:title="t(states.isTable ? 'dashboardName' : 'metricName')"
name="2"
>
<div v-if="states.isTable">
<Selector
:value="states.graph.dashboardName"
:options="metricOpts"
size="mini"
placeholder="Select a dashboard"
@change="changeDashboard"
class="selectors"
/>
</div>
<div v-else>
<Selector
:value="states.metrics"
:options="metricOpts"
@ -66,7 +79,6 @@ limitations under the License. -->
:value="states.valueType"
:options="states.valueTypes"
size="mini"
placeholder="Select a metric"
@change="changeValueType"
class="selectors"
v-loading="loading"
@ -117,6 +129,7 @@ import {
ChartTypes,
DefaultGraphConfig,
PodsChartTypes,
TableChartTypes,
} from "../data";
import { Option } from "@/types/app";
import { WidgetConfig, GraphConfig, StandardConfig } from "@/types/dashboard";
@ -148,10 +161,11 @@ export default defineComponent({
activeNames: string;
source: any;
index: string;
graph: GraphConfig;
graph: GraphConfig | any;
widget: WidgetConfig | any;
standard: StandardConfig;
visType: Option[];
isTable: boolean;
}>({
metrics: selectedGrid.metrics || [],
valueTypes: [],
@ -164,17 +178,27 @@ export default defineComponent({
widget: selectedGrid.widget,
standard: selectedGrid.standard,
visType: [],
isTable: false,
});
states.isTable = TableChartTypes.includes(states.graph.type || "");
if (states.metrics[0]) {
queryMetricType(states.metrics[0]);
}
if (params.entity === "service") {
states.visType = ChartTypes;
} else {
states.visType = ChartTypes.filter(
(d: Option) => d.value !== "serviceList"
);
} else if (params.entity === "all") {
states.visType = ChartTypes.filter(
(d: Option) => !PodsChartTypes.includes(d.value)
);
} else {
states.visType = ChartTypes.filter(
(d: Option) => !TableChartTypes.includes(d.value)
);
}
async function changeMetrics(arr: Option[]) {
@ -213,6 +237,11 @@ export default defineComponent({
states.graph = {
...DefaultGraphConfig[item.value],
};
states.isTable = TableChartTypes.includes(states.graph.type || "");
}
function changeDashboard(item: Option[]) {
states.graph.dashboardName = item[0].value;
}
const metricOpts = [
@ -302,6 +331,7 @@ export default defineComponent({
updateGraphOptions,
updateStandardOptions,
applyConfig,
changeDashboard,
loading,
};
},

View File

@ -0,0 +1,63 @@
<!-- 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>
<span class="label">{{ t("fontSize") }}</span>
<el-slider
class="slider"
v-model="fontSize"
show-input
input-size="small"
:min="10"
:max="20"
:step="1"
@change="updateConfig({ fontSize })"
/>
</div>
</template>
<script lang="ts" setup>
import { defineProps, ref, defineEmits } from "vue";
import type { PropType } from "vue";
import { EndpointListConfig } from "@/types/dashboard";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const props = defineProps({
config: {
type: Object as PropType<EndpointListConfig>,
default: () => ({ fontSize: 12 }),
},
});
const emits = defineEmits(["update"]);
const fontSize = ref(props.config.fontSize);
function updateConfig(param: { [key: string]: unknown }) {
emits("update", param);
}
</script>
<style lang="scss" scoped>
.slider {
width: 500px;
margin-top: -13px;
}
.label {
font-size: 13px;
font-weight: 500;
display: block;
margin-bottom: 5px;
}
</style>

View File

@ -0,0 +1,63 @@
<!-- 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>
<span class="label">{{ t("fontSize") }}</span>
<el-slider
class="slider"
v-model="fontSize"
show-input
input-size="small"
:min="10"
:max="20"
:step="1"
@change="updateConfig({ fontSize })"
/>
</div>
</template>
<script lang="ts" setup>
import { defineProps, ref, defineEmits } from "vue";
import type { PropType } from "vue";
import { InstanceListConfig } from "@/types/dashboard";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const props = defineProps({
config: {
type: Object as PropType<InstanceListConfig>,
default: () => ({ fontSize: 12 }),
},
});
const emits = defineEmits(["update"]);
const fontSize = ref(props.config.fontSize);
function updateConfig(param: { [key: string]: unknown }) {
emits("update", param);
}
</script>
<style lang="scss" scoped>
.slider {
width: 500px;
margin-top: -13px;
}
.label {
font-size: 13px;
font-weight: 500;
display: block;
margin-bottom: 5px;
}
</style>

View File

@ -0,0 +1,63 @@
<!-- 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>
<span class="label">{{ t("fontSize") }}</span>
<el-slider
class="slider"
v-model="fontSize"
show-input
input-size="small"
:min="10"
:max="20"
:step="1"
@change="updateConfig({ fontSize })"
/>
</div>
</template>
<script lang="ts" setup>
import { defineProps, ref, defineEmits } from "vue";
import type { PropType } from "vue";
import { ServiceListConfig } from "@/types/dashboard";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const props = defineProps({
config: {
type: Object as PropType<ServiceListConfig>,
default: () => ({ fontSize: 12 }),
},
});
const emits = defineEmits(["update"]);
const fontSize = ref(props.config.fontSize);
function updateConfig(param: { [key: string]: unknown }) {
emits("update", param);
}
</script>
<style lang="scss" scoped>
.slider {
width: 500px;
margin-top: -13px;
}
.label {
font-size: 13px;
font-weight: 500;
display: block;
margin-bottom: 5px;
}
</style>

View File

@ -18,9 +18,15 @@
import AreaConfig from "./Area.vue";
import LineConfig from "./Line.vue";
import BarConfig from "./Bar.vue";
import InstanceListConfig from "./InstanceList.vue";
import EndpointListConfig from "./EndpointList.vue";
import ServiceListConfig from "./ServiceList.vue";
export default {
AreaConfig,
LineConfig,
BarConfig,
InstanceListConfig,
EndpointListConfig,
ServiceListConfig,
};

View File

@ -16,6 +16,8 @@
*/
export const PodsChartTypes = ["EndpointList", "InstanceList"];
export const TableChartTypes = ["EndpointList", "InstanceList", "ServiceList"];
export const ChartTypes = [
{ label: "Bar", value: "Bar" },
{ label: "Line", value: "Line" },
@ -60,9 +62,18 @@ export const DefaultGraphConfig: { [key: string]: any } = {
},
InstanceList: {
type: "InstanceList",
dashboardName: "",
fontSize: 12,
},
EndpointList: {
type: "EndpointList",
dashboardName: "",
fontSize: 12,
},
ServiceList: {
type: "ServiceList",
dashboardName: "",
fontSize: 12,
},
};

View File

@ -14,46 +14,52 @@ See the License for the specific language governing permissions and
limitations under the License. -->
<template>
<el-table
v-loading="chartLoading"
:data="selectorStore.endpoints"
style="width: 100%; height: 100%; overflow: auto"
>
<el-table-column label="Endpoints">
<template #default="scope">
<span class="link" @click="linkInstance(scope.row)">
<router-link
target="_blank"
class="link"
:to="`/dashboard/${scope.row.layer}/endpoint/${selectorStore.currentService}/${scope.row.value}/${config.dashboardName}`"
:style="{ fontSize: `${config.fontSize}px` }"
>
{{ scope.row.label }}
</span>
</router-link>
</template>
</el-table-column>
</el-table>
</template>
<script setup lang="ts">
import { defineProps, onBeforeMount } from "vue";
import { defineProps, onBeforeMount, ref } from "vue";
import { useSelectorStore } from "@/store/modules/selectors";
import { ElMessage } from "element-plus";
import router from "@/router";
import type { PropType } from "vue";
import { EndpointListConfig } from "@/types/dashboard";
defineProps({
data: {
type: Object,
},
config: {
type: Object,
default: () => ({}),
type: Object as PropType<EndpointListConfig>,
default: () => ({ dashboardName: "", fontSize: 12 }),
},
});
const selectorStore = useSelectorStore();
const chartLoading = ref<boolean>(false);
onBeforeMount(async () => {
chartLoading.value = true;
const resp = await selectorStore.getEndpoints();
chartLoading.value = false;
if (resp.errors) {
ElMessage.error(resp.errors);
}
});
function linkInstance(row: any) {
const path = `/dashboard/view/${row.layer}/endpoint/${selectorStore.currentService}/${row.value}`;
router.push(path);
}
</script>
<style lang="scss" scoped>
.link {

View File

@ -14,46 +14,52 @@ See the License for the specific language governing permissions and
limitations under the License. -->
<template>
<el-table
v-loading="chartLoading"
:data="selectorStore.instances"
style="width: 100%; height: 100%; overflow: auto"
>
<el-table-column label="Service Instances">
<template #default="scope">
<span class="link" @click="linkInstance(scope.row)">
<router-link
target="_blank"
class="link"
:to="`/dashboard/${scope.row.layer}/serviceInstance/${selectorStore.currentService}/${scope.row.value}/${config.dashboardName}`"
:style="{ fontSize: `${config.fontSize}px` }"
>
{{ scope.row.label }}
</span>
</router-link>
</template>
</el-table-column>
</el-table>
</template>
<script setup lang="ts">
import { defineProps, onBeforeMount } from "vue";
import { defineProps, onBeforeMount, ref } from "vue";
import { useSelectorStore } from "@/store/modules/selectors";
import { ElMessage } from "element-plus";
import router from "@/router";
import type { PropType } from "vue";
import { InstanceListConfig } from "@/types/dashboard";
defineProps({
data: {
type: Object,
},
config: {
type: Object,
default: () => ({}),
type: Object as PropType<InstanceListConfig>,
default: () => ({ dashboardName: "", fontSize: 12 }),
},
});
const selectorStore = useSelectorStore();
const chartLoading = ref<boolean>(false);
onBeforeMount(async () => {
chartLoading.value = true;
const resp = await selectorStore.getServiceInstances();
chartLoading.value = false;
if (resp.errors) {
ElMessage.error(resp.errors);
}
});
function linkInstance(row: any) {
const path = `/dashboard/${row.layer}/serviceInstance/${selectorStore.currentService}/${row.value}/test`;
router.push(path);
}
</script>
<style lang="scss" scoped>
.link {

View File

@ -14,46 +14,52 @@ See the License for the specific language governing permissions and
limitations under the License. -->
<template>
<el-table
v-loading="chartLoading"
:data="selectorStore.services"
style="width: 100%; height: 100%; overflow: auto"
>
<el-table-column label="Services">
<template #default="scope">
<span class="link" @click="linkService(scope.row)">
<router-link
target="_blank"
class="link"
:to="`/dashboard/${scope.row.layer}/service/${selectorStore.currentService}/${config.dashboardName}`"
:style="{ fontSize: `${config.fontSize}px` }"
>
{{ scope.row.label }}
</span>
</router-link>
</template>
</el-table-column>
</el-table>
</template>
<script setup lang="ts">
import { defineProps, onBeforeMount } from "vue";
import { defineProps, onBeforeMount, ref } from "vue";
import { useSelectorStore } from "@/store/modules/selectors";
import { ElMessage } from "element-plus";
import router from "@/router";
import type { PropType } from "vue";
import { ServiceListConfig } from "@/types/dashboard";
defineProps({
data: {
type: Object,
},
config: {
type: Object,
default: () => ({}),
type: Object as PropType<ServiceListConfig>,
default: () => ({ dashboardName: "", fontSize: 12 }),
},
});
const selectorStore = useSelectorStore();
const chartLoading = ref<boolean>(false);
onBeforeMount(async () => {
chartLoading.value = true;
const resp = await selectorStore.fetchServices();
chartLoading.value = false;
if (resp.errors) {
ElMessage.error(resp.errors);
}
});
function linkService(row: { layer: string }) {
const path = `/dashboard/${row.layer}/service/${selectorStore.currentService}/test`;
router.push(path);
}
</script>
<style lang="scss" scoped>
.link {