refactor: create a component for metric config

This commit is contained in:
Qiuxia Fan 2022-01-19 18:12:16 +08:00
parent 3d6fe887a5
commit 4baa00001a
10 changed files with 201 additions and 226 deletions

View File

@ -34,7 +34,7 @@ export const ConfigData: any = {
h: 12,
i: "0",
metrics: ["service_resp_time"],
queryMetricType: "readMetricsValues",
metricTypes: ["readMetricsValues"],
type: "Widget",
widget: {
title: "Title",

View File

@ -173,10 +173,10 @@ export const dashboardStore = defineStore({
return res.data;
},
async fetchMetricValue(config: LayoutConfig) {
// if (!config.queryMetricType) {
// if (!config.metricTypes) {
// return;
// }
config.queryMetricType = "readMetricsValues";
// config.metricTypes = "readMetricsValues";
const appStoreWithOut = useAppStoreWithOut();
const variable = {
condition: {
@ -190,7 +190,7 @@ export const dashboardStore = defineStore({
duration: appStoreWithOut.durationTime,
};
const res: AxiosResponse = await graph
.query(config.queryMetricType)
.query("readMetricsValues")
.params(variable);
return res.data;

View File

@ -24,7 +24,6 @@ body {
sans-serif;
text-rendering: optimizeLegibility;
text-size-adjust: 100%;
text-size-adjust: 100%;
}
html,
@ -124,89 +123,3 @@ code,
pre {
font-family: Consolas, Menlo, Courier, monospace;
}
/* webkit core */
.scroll_hide::-webkit-scrollbar {
width: 0;
height: 0;
}
.scroll_hide::-webkit-scrollbar-button {
background-color: rgb(0 0 0 / 0%);
}
.scroll_hide::-webkit-scrollbar-track {
background-color: rgb(0 0 0 / 0%);
}
.scroll_hide::-webkit-scrollbar-track-piece {
background-color: rgb(0 0 0 / 0%);
}
.scroll_hide::-webkit-scrollbar-thumb {
background-color: rgb(0 0 0 / 0%);
}
.scroll_hide::-webkit-scrollbar-corner {
background-color: rgb(0 0 0 / 0%);
}
.scroll_hide::-webkit-scrollbar-resizer {
background-color: rgb(0 0 0 / 0%);
}
/* o core */
.scroll_hide .-o-scrollbar {
appearance: none !important;
background: rgb(0 255 0 / 0%) !important;
}
.scroll_hide::-o-scrollbar-button {
background-color: rgb(0 0 0 / 0%);
}
.scroll_hide::-o-scrollbar-track {
background-color: rgb(0 0 0 / 0%);
}
.scroll_hide::-o-scrollbar-track-piece {
background-color: rgb(0 0 0 / 0%);
}
.scroll_hide::-o-scrollbar-thumb {
background-color: rgb(0 0 0 / 0%);
}
.scroll_hide::-o-scrollbar-corner {
background-color: rgb(0 0 0 / 0%);
}
.scroll_hide::-o-scrollbar-resizer {
background-color: rgb(0 0 0 / 0%);
}
/* IE10,IE11,IE12 */
.scroll_hide {
-ms-scroll-chaining: chained;
-ms-overflow-style: none;
-ms-content-zooming: zoom;
-ms-scroll-rails: none;
-ms-content-zoom-limit-min: 100%;
-ms-content-zoom-limit-max: 500%;
scroll-snap-points-x: snaplist(100%, 200%, 300%, 400%, 500%);
overflow: auto;
}
.scroll_bar_style::-webkit-scrollbar {
width: 9px;
height: 6px;
}
.scroll_bar_style::-webkit-scrollbar-track {
background-color: #3d444f;
}
.scroll_bar_style::-webkit-scrollbar-thumb {
border-radius: 5px;
background: rgb(196 200 225 / 20%);
}

View File

@ -25,7 +25,7 @@ export interface LayoutConfig {
standard?: StandardConfig;
metrics?: string[];
type?: string;
queryMetricType?: string;
metricTypes?: string[];
children?: any;
}

View File

@ -39,43 +39,11 @@ limitations under the License. -->
:style="{ '--el-collapse-header-font-size': '15px' }"
>
<el-collapse-item :title="t('metricName')" name="1">
<div v-show="states.isTable" class="ds-name">
<Selector
:value="states.graph.dashboardName"
:options="states.metricList"
size="mini"
placeholder="Select a dashboard"
@change="changeDashboard"
class="selectors"
/>
</div>
<div>
<Selector
:value="states.metrics"
:options="states.metricList"
:multiple="!states.isTable"
size="mini"
placeholder="Select a metric"
@change="changeMetrics"
class="selectors"
/>
<Selector
v-if="states.valueType"
:value="states.valueType"
:options="states.valueTypes"
size="mini"
@change="changeValueType"
class="selectors"
v-loading="loading"
/>
<Icon
iconName="add_circle_outlinecontrol_point"
size="middle"
v-show="states.isTable"
@click="addMetricName"
class="cp"
/>
</div>
<MetricOptions
:graph="states.graph"
@update="getSource"
@apply="getMetricsConfig"
/>
</el-collapse-item>
<el-collapse-item :title="t('selectVisualization')" name="2">
<div class="chart-types">
@ -121,15 +89,12 @@ limitations under the License. -->
</div>
</template>
<script lang="ts">
import { reactive, defineComponent, ref } from "vue";
import { 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 { ElMessage } from "element-plus";
import {
ValuesTypes,
MetricQueryTypes,
ChartTypes,
DefaultGraphConfig,
PodsChartTypes,
@ -141,6 +106,7 @@ import graphs from "../graphs";
import configs from "./graph-styles";
import WidgetOptions from "./WidgetOptions.vue";
import StandardOptions from "./StandardOptions.vue";
import MetricOptions from "./MetricOptions.vue";
export default defineComponent({
name: "ConfigEdit",
@ -149,20 +115,16 @@ export default defineComponent({
...configs,
WidgetOptions,
StandardOptions,
MetricOptions,
},
setup() {
const configHeight = document.documentElement.clientHeight - 520;
const loading = ref<boolean>(false);
const { t } = useI18n();
const dashboardStore = useDashboardStore();
const appStoreWithOut = useAppStoreWithOut();
const { selectedGrid } = dashboardStore;
const params = useRoute().params;
const states = reactive<{
metrics: string[];
valueTypes: Option[];
valueType: string;
metricQueryType: string;
activeNames: string;
source: any;
index: string;
@ -171,12 +133,9 @@ export default defineComponent({
standard: StandardConfig;
visType: Option[];
isTable: boolean;
metricList: (Option & { type: string })[];
metrics: string[];
metricTypes: string[];
}>({
metrics: selectedGrid.metrics || [],
valueTypes: [],
valueType: "",
metricQueryType: "",
activeNames: "1",
source: {},
index: selectedGrid.i,
@ -185,9 +144,9 @@ export default defineComponent({
standard: selectedGrid.standard,
visType: [],
isTable: false,
metricList: [],
metrics: [],
metricTypes: [],
});
states.isTable = TableChartTypes.includes(states.graph.type || "");
if (params.entity === "service") {
@ -204,40 +163,12 @@ export default defineComponent({
);
}
setMetricType(states.metrics[0]);
async function changeMetrics(arr: (Option & { type: string })[]) {
if (!arr.length) {
states.valueTypes = [];
states.valueType = "";
return;
}
states.metrics = arr.map((d: Option) => d.value);
if (arr[0]) {
const typeOfMetrics = arr[0].type;
states.valueTypes = ValuesTypes[typeOfMetrics];
states.valueType = ValuesTypes[typeOfMetrics][0].value;
queryMetrics();
}
}
function changeValueType(val: Option[]) {
states.valueType = String(val[0].value);
states.metricQueryType = (MetricQueryTypes as any)[states.valueType];
queryMetrics();
}
function changeChartType(item: Option) {
states.graph = {
...DefaultGraphConfig[item.value],
};
states.isTable = TableChartTypes.includes(states.graph.type || "");
states.isTable = TableChartTypes.includes(states.graph.type);
}
function changeDashboard(item: Option[]) {
states.graph.dashboardName = item[0].value;
}
function updateWidgetOptions(param: { [key: string]: unknown }) {
states.widget = {
...states.widget,
@ -259,57 +190,26 @@ export default defineComponent({
};
}
async function queryMetrics() {
const json = await dashboardStore.fetchMetricValue(
dashboardStore.selectedGrid
);
if (!json) {
return;
}
if (json.errors) {
ElMessage.error(json.errors);
return;
}
const metricVal = json.data.readMetricsValues.values.values.map(
(d: { value: number }) => d.value
);
const m = states.metrics[0];
if (!m) {
return;
}
states.source = {
[m]: metricVal,
};
function getSource(source: unknown) {
states.source = source;
}
async function setMetricType(regex: string) {
const json = await dashboardStore.fetchMetricList(regex);
if (json.errors) {
ElMessage.error(json.errors);
return;
function getMetricsConfig(opts: {
metrics?: string[];
metricTypes?: string[];
}) {
if (opts.metrics !== undefined) {
states.metrics = opts.metrics;
}
states.metricList = json.data.metrics || [];
const name = states.metrics[0];
if (!name) {
return;
if (opts.metricTypes !== undefined) {
states.metricTypes = opts.metricTypes;
}
const typeOfMetrics: any = states.metricList.filter(
(d: { value: string }) => d.value === name
)[0];
states.valueTypes = ValuesTypes[typeOfMetrics];
states.valueType = ValuesTypes[typeOfMetrics][0].value;
queryMetrics();
}
function addMetricName() {
console.log(states);
}
function applyConfig() {
const opts = {
...dashboardStore.selectedGrid,
metrics: states.metrics,
queryMetricType: states.valueType,
metricTypes: states.metricTypes,
widget: states.widget,
graph: states.graph,
standard: states.standard,
@ -321,19 +221,15 @@ export default defineComponent({
return {
states,
changeChartType,
changeValueType,
changeMetrics,
t,
appStoreWithOut,
ChartTypes,
updateWidgetOptions,
configHeight,
updateGraphOptions,
updateStandardOptions,
applyConfig,
changeDashboard,
addMetricName,
loading,
getSource,
getMetricsConfig,
};
},
});

View File

@ -0,0 +1,166 @@
<!-- 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 v-show="states.isTable" class="ds-name">
<Selector
:value="states.graph.dashboardName"
:options="states.metricList"
size="mini"
placeholder="Select a dashboard"
@change="changeDashboard"
class="selectors"
/>
</div>
<div>
<Selector
:value="states.metrics"
:options="states.metricList"
:multiple="true"
size="mini"
placeholder="Select a metric"
@change="changeMetrics"
class="selectors"
/>
<Selector
:value="states.metricTypes"
:options="states.metricTypeList"
size="mini"
@change="changeMetricType"
class="selectors"
:multiple="true"
/>
</div>
</template>
<script lang="ts" setup>
import { reactive, defineProps, defineEmits } from "vue";
import type { PropType } from "vue";
import { useRoute } from "vue-router";
import { Option } from "@/types/app";
import { GraphConfig } from "@/types/dashboard";
import { useDashboardStore } from "@/store/modules/dashboard";
import { MetricTypes, MetricQueryTypes, TableChartTypes } from "../data";
import { ElMessage } from "element-plus";
const props = defineProps({
graph: {
type: Object as PropType<GraphConfig>,
default: () => ({}),
},
});
const emit = defineEmits(["update", "apply"]);
const dashboardStore = useDashboardStore();
const { selectedGrid } = dashboardStore;
const states = reactive<{
metrics: string[];
metricTypes: string[];
metricTypeList: Option[];
metricQueryType: string;
visType: Option[];
isTable: boolean;
metricList: (Option & { type: string })[];
graph: GraphConfig | any;
}>({
metrics: selectedGrid.metrics || [],
metricTypes: selectedGrid.metricTypes || [],
metricTypeList: [],
metricQueryType: "",
visType: [],
isTable: false,
metricList: [],
graph: props.graph,
});
states.isTable = TableChartTypes.includes(states.graph.type || "");
const params = useRoute().params;
setMetricType();
async function setMetricType() {
const json = await dashboardStore.fetchMetricList();
if (json.errors) {
ElMessage.error(json.errors);
return;
}
states.metricList = (json.data.metrics || []).filter(
(d: { catalog: string }) =>
String(params.entity).toUpperCase() === d.catalog
);
const name = states.metrics[0];
if (!name) {
return;
}
const metrics: any = states.metricList.filter(
(d: { value: string }) => d.value === name
)[0];
states.metricTypeList = MetricTypes[metrics.type];
states.metricTypes = [MetricTypes[metrics.type][0].value];
emit("apply", { metricTypes: states.metricTypes });
queryMetrics();
}
function changeMetrics(arr: (Option & { type: string })[]) {
if (!arr.length) {
states.metricTypeList = [];
states.metricTypes = [];
emit("apply", { metricTypes: states.metricTypes });
return;
}
states.metrics = arr.map((d: Option) => d.value);
if (arr[0]) {
const typeOfMetrics = arr[0].type;
states.metricTypeList = MetricTypes[typeOfMetrics];
states.metricTypes = [MetricTypes[typeOfMetrics][0].value];
emit("apply", { metricTypes: states.metricTypes, metrics: states.metrics });
queryMetrics();
}
}
function changeMetricType(val: Option[]) {
states.metricTypes = [val[0].value];
states.metricQueryType = (MetricQueryTypes as any)[states.metricTypes[0]];
emit("apply", { metricTypes: states.metricTypes });
queryMetrics();
}
async function queryMetrics() {
const json = await dashboardStore.fetchMetricValue(
dashboardStore.selectedGrid
);
if (!json) {
return;
}
if (json.errors) {
ElMessage.error(json.errors);
return;
}
const metricVal = json.data.readMetricsValues.values.values.map(
(d: { value: number }) => d.value
);
const m = states.metrics[0];
if (!m) {
return;
}
emit("update", { [m]: metricVal });
}
function changeDashboard(item: Option[]) {
states.graph.dashboardName = item[0].value;
}
</script>
<style lang="scss" scoped>
.ds-name {
margin-bottom: 10px;
}
.selectors {
width: 500px;
margin-right: 10px;
}
</style>

View File

@ -121,7 +121,7 @@ export default defineComponent({
}
}
watch(
() => [props.data.queryMetricType, props.data.metrics],
() => [props.data.metricTypes, props.data.metrics],
(data, old) => {
if (data[0] === old[0] && data[1] === old[1]) {
return;

View File

@ -92,7 +92,7 @@ export enum MetricsType {
HEATMAP = "HEATMAP",
SAMPLED_RECORD = "SAMPLED_RECORD",
}
export const ValuesTypes: {
export const MetricTypes: {
[key: string]: Array<{ label: string; value: string }>;
} = {
REGULAR_VALUE: [

View File

@ -17,7 +17,7 @@ limitations under the License. -->
<div class="search">
<el-input
v-model="searchText"
placeholder="Please input instance name"
placeholder="Please input endpoint name"
class="input-with-search"
size="small"
@change="searchList"

View File

@ -17,7 +17,7 @@ limitations under the License. -->
<div class="search">
<el-input
v-model="searchText"
placeholder="Please input instance name"
placeholder="Please input service name"
class="input-with-search"
size="small"
@change="searchList"