update LayoutConfig

This commit is contained in:
Qiuxia Fan 2022-03-30 13:55:38 +08:00
parent cda73845bb
commit 88afe29ebb
10 changed files with 116 additions and 107 deletions

View File

@ -28,6 +28,9 @@ export function useQueryProcessor(config: any) {
if (!(config.metrics && config.metrics[0])) { if (!(config.metrics && config.metrics[0])) {
return; return;
} }
if (!(config.metricTypes && config.metricTypes[0])) {
return;
}
const appStore = useAppStoreWithOut(); const appStore = useAppStoreWithOut();
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore(); const selectorStore = useSelectorStore();
@ -221,6 +224,12 @@ export function useQueryPodsMetrics(
config: { metrics: string[]; metricTypes: string[] }, config: { metrics: string[]; metricTypes: string[] },
scope: string scope: string
) { ) {
if (!(config.metrics && config.metrics[0])) {
return;
}
if (!(config.metricTypes && config.metricTypes[0])) {
return;
}
const appStore = useAppStoreWithOut(); const appStore = useAppStoreWithOut();
const selectorStore = useSelectorStore(); const selectorStore = useSelectorStore();
const conditions: { [key: string]: unknown } = { const conditions: { [key: string]: unknown } = {

View File

@ -21,14 +21,6 @@ export const NewControl = {
h: 12, h: 12,
i: "0", i: "0",
type: "Widget", type: "Widget",
widget: {
title: "",
},
graph: {},
standard: {},
metrics: [""],
metricTypes: [""],
metricConfig: [],
}; };
export const TextConfig = { export const TextConfig = {
fontColor: "white", fontColor: "white",

View File

@ -28,13 +28,12 @@ export interface LayoutConfig {
w: number; w: number;
h: number; h: number;
i: string; i: string;
widget: WidgetConfig; widget?: WidgetConfig;
graph: GraphConfig; graph?: GraphConfig;
standard: StandardConfig; metrics?: string[];
metrics: string[];
type: string; type: string;
metricTypes: string[]; metricTypes?: string[];
children?: any; children?: { name: string; children: LayoutConfig[] }[];
activedTabIndex?: number; activedTabIndex?: number;
metricConfig?: MetricConfigOpt[]; metricConfig?: MetricConfigOpt[];
} }
@ -53,20 +52,6 @@ export interface WidgetConfig {
tips?: string; tips?: string;
} }
export interface StandardConfig {
sortOrder?: string;
unit?: string;
labelsIndex?: string;
metricLabels?: string;
plus?: string;
minus?: string;
multiply?: string;
divide?: string;
milliseconds?: string;
seconds?: string;
maxItemNum?: number;
}
export type GraphConfig = export type GraphConfig =
| BarConfig | BarConfig
| LineConfig | LineConfig

View File

@ -16,20 +16,20 @@ limitations under the License. -->
<div class="widget-config flex-v"> <div class="widget-config flex-v">
<div class="graph" v-loading="loading"> <div class="graph" v-loading="loading">
<div class="header"> <div class="header">
<span>{{ dashboardStore.selectedGrid.widget.title || "" }}</span> <span>{{ widget.title || "" }}</span>
<div class="tips" v-show="dashboardStore.selectedGrid.widget.tips"> <div class="tips" v-show="widget.tips">
<el-tooltip :content="dashboardStore.selectedGrid.widget.tips || ''"> <el-tooltip :content="widget.tips || ''">
<Icon iconName="info_outline" size="sm" /> <Icon iconName="info_outline" size="sm" />
</el-tooltip> </el-tooltip>
</div> </div>
</div> </div>
<div class="render-chart"> <div class="render-chart">
<component <component
:is="dashboardStore.selectedGrid.graph.type" :is="graph.type"
:intervalTime="appStoreWithOut.intervalTime" :intervalTime="appStoreWithOut.intervalTime"
:data="states.source" :data="states.source"
:config="{ :config="{
...dashboardStore.selectedGrid.graph, ...graph,
i: dashboardStore.selectedGrid.i, i: dashboardStore.selectedGrid.i,
metrics: dashboardStore.selectedGrid.metrics, metrics: dashboardStore.selectedGrid.metrics,
metricTypes: dashboardStore.selectedGrid.metricTypes, metricTypes: dashboardStore.selectedGrid.metricTypes,
@ -38,7 +38,7 @@ limitations under the License. -->
:isEdit="isEdit" :isEdit="isEdit"
@changeOpt="setStatus" @changeOpt="setStatus"
/> />
<div v-show="!dashboardStore.selectedGrid.graph.type" class="no-data"> <div v-show="!graph.type" class="no-data">
{{ t("noData") }} {{ t("noData") }}
</div> </div>
</div> </div>
@ -56,7 +56,7 @@ limitations under the License. -->
/> />
</el-collapse-item> </el-collapse-item>
<el-collapse-item :title="t('graphStyles')" name="2"> <el-collapse-item :title="t('graphStyles')" name="2">
<component :is="`${dashboardStore.selectedGrid.graph.type}Config`" /> <component :is="`${graph.type}Config`" />
</el-collapse-item> </el-collapse-item>
<el-collapse-item :title="t('widgetOptions')" name="3"> <el-collapse-item :title="t('widgetOptions')" name="3">
<WidgetOptions /> <WidgetOptions />
@ -74,7 +74,7 @@ limitations under the License. -->
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { reactive, defineComponent, ref } from "vue"; import { reactive, defineComponent, ref, computed } 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 { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
@ -111,6 +111,8 @@ export default defineComponent({
visType: [], visType: [],
}); });
const originConfig = dashboardStore.selectedGrid; const originConfig = dashboardStore.selectedGrid;
const widget = computed(() => dashboardStore.selectedGrid.widget || {});
const graph = computed(() => dashboardStore.selectedGrid.graph || {});
function getSource(source: unknown) { function getSource(source: unknown) {
states.source = source; states.source = source;
@ -148,6 +150,8 @@ export default defineComponent({
setLoading, setLoading,
setStatus, setStatus,
isEdit, isEdit,
widget,
graph,
}; };
}, },
}); });

View File

@ -42,12 +42,13 @@ import { useDashboardStore } from "@/store/modules/dashboard";
const { t } = useI18n(); const { t } = useI18n();
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const { selectedGrid } = dashboardStore; const { selectedGrid } = dashboardStore;
const title = ref<string>(selectedGrid.widget.title || ""); const widget = dashboardStore.selectedGrid.widget || {};
const tips = ref<string>(selectedGrid.widget.tips || ""); const title = ref<string>(widget.title || "");
const tips = ref<string>(widget.tips || "");
function updateWidgetConfig(param: { [key: string]: unknown }) { function updateWidgetConfig(param: { [key: string]: unknown }) {
const widget = { const widget = {
...selectedGrid.widget, ...dashboardStore.selectedGrid.widget,
...param, ...param,
}; };
dashboardStore.selectWidget({ ...selectedGrid, widget }); dashboardStore.selectWidget({ ...selectedGrid, widget });

View File

@ -43,9 +43,7 @@ limitations under the License. -->
:value="states.metricTypes[index]" :value="states.metricTypes[index]"
:options="states.metricTypeList[index]" :options="states.metricTypeList[index]"
size="small" size="small"
:disabled=" :disabled="graph.type && !states.isList && index !== 0"
dashboardStore.selectedGrid.graph.type && !states.isList && index !== 0
"
@change="changeMetricType(index, $event)" @change="changeMetricType(index, $event)"
class="selectors" class="selectors"
/> />
@ -85,11 +83,11 @@ limitations under the License. -->
<div>{{ t("visualization") }}</div> <div>{{ t("visualization") }}</div>
<div class="chart-types"> <div class="chart-types">
<span <span
v-for="(type, index) in states.visTypes" v-for="(type, index) in setVisTypes"
:key="index" :key="index"
@click="changeChartType(type)" @click="changeChartType(type)"
:class="{ :class="{
active: type.value === dashboardStore.selectedGrid.graph.type, active: type.value === graph.type,
}" }"
> >
{{ type.label }} {{ type.label }}
@ -97,7 +95,7 @@ limitations under the License. -->
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref } from "vue"; import { reactive, ref, computed } from "vue";
import { Option } from "@/types/app"; import { Option } from "@/types/app";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { import {
@ -124,24 +122,26 @@ import Standard from "./Standard.vue";
const { t } = useI18n(); const { t } = useI18n();
const emit = defineEmits(["update", "loading", "changeOpt"]); const emit = defineEmits(["update", "loading", "changeOpt"]);
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const { metrics, metricTypes, graph } = dashboardStore.selectedGrid; const metrics = computed(() => dashboardStore.selectedGrid.metrics || []);
const graph = computed(() => dashboardStore.selectedGrid.graph || {});
const metricTypes = computed(
() => dashboardStore.selectedGrid.metricTypes || []
);
const states = reactive<{ const states = reactive<{
metrics: string[]; metrics: string[];
metricTypes: string[]; metricTypes: string[];
metricTypeList: Option[][]; metricTypeList: Option[][];
visTypes: Option[];
isList: boolean; isList: boolean;
metricList: (Option & { type: string })[]; metricList: (Option & { type: string })[];
dashboardName: string; dashboardName: string;
dashboardList: ((DashboardItem & { label: string; value: string }) | any)[]; dashboardList: ((DashboardItem & { label: string; value: string }) | any)[];
}>({ }>({
metrics: metrics && metrics.length ? metrics : [""], metrics: metrics.value.length ? metrics.value : [""],
metricTypes: metricTypes && metricTypes.length ? metricTypes : [""], metricTypes: metricTypes.value.length ? metricTypes.value : [""],
metricTypeList: [], metricTypeList: [],
visTypes: [],
isList: false, isList: false,
metricList: [], metricList: [],
dashboardName: graph.dashboardName, dashboardName: graph.value.dashboardName,
dashboardList: [{ label: "", value: "" }], dashboardList: [{ label: "", value: "" }],
}); });
const currentMetricConfig = ref<MetricConfigOpt>({ const currentMetricConfig = ref<MetricConfigOpt>({
@ -152,15 +152,33 @@ const currentMetricConfig = ref<MetricConfigOpt>({
sortOrder: "DES", sortOrder: "DES",
}); });
states.isList = ListChartTypes.includes(graph.type); states.isList = ListChartTypes.includes(graph.value.type);
const defaultLen = ref<number>(states.isList ? 5 : 20); const defaultLen = ref<number>(states.isList ? 5 : 20);
states.visTypes = setVisTypes();
setDashboards(); setDashboards();
setMetricType(); setMetricType();
const setVisTypes = computed(() => {
let graphs = [];
if (dashboardStore.entity === EntityType[0].value) {
graphs = ChartTypes.filter(
(d: Option) =>
![ChartTypes[7].value, ChartTypes[8].value].includes(d.value)
);
} else if (dashboardStore.entity === EntityType[1].value) {
graphs = ChartTypes.filter(
(d: Option) => !PodsChartTypes.includes(d.value)
);
} else {
graphs = ChartTypes.filter(
(d: Option) => !ListChartTypes.includes(d.value)
);
}
return graphs;
});
async function setMetricType(chart?: any) { async function setMetricType(chart?: any) {
const graph = chart || dashboardStore.selectedGrid.graph; const g = chart || dashboardStore.selectedGrid.graph || {};
const json = await dashboardStore.fetchMetricList(); const json = await dashboardStore.fetchMetricList();
if (json.errors) { if (json.errors) {
ElMessage.error(json.errors); ElMessage.error(json.errors);
@ -172,7 +190,7 @@ async function setMetricType(chart?: any) {
if (d.type === MetricsType.REGULAR_VALUE) { if (d.type === MetricsType.REGULAR_VALUE) {
return d; return d;
} }
} else if (graph.type === "Table") { } else if (g.type === "Table") {
if ( if (
d.type === MetricsType.LABELED_VALUE || d.type === MetricsType.LABELED_VALUE ||
d.type === MetricsType.REGULAR_VALUE d.type === MetricsType.REGULAR_VALUE
@ -203,7 +221,7 @@ async function setMetricType(chart?: any) {
...dashboardStore.selectedGrid, ...dashboardStore.selectedGrid,
metrics: states.metrics, metrics: states.metrics,
metricTypes: states.metricTypes, metricTypes: states.metricTypes,
graph, graph: g,
}); });
states.metricTypeList = []; states.metricTypeList = [];
for (const metric of metrics) { for (const metric of metrics) {
@ -220,7 +238,7 @@ async function setMetricType(chart?: any) {
} }
function setDashboards(type?: string) { function setDashboards(type?: string) {
const graph = type || dashboardStore.selectedGrid.graph; const chart = type || dashboardStore.selectedGrid.graph || {};
const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]"); const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
const arr = list.reduce( const arr = list.reduce(
( (
@ -229,9 +247,9 @@ function setDashboards(type?: string) {
) => { ) => {
if (d.layer === dashboardStore.layerId) { if (d.layer === dashboardStore.layerId) {
if ( if (
(d.entity === EntityType[0].value && graph.type === "ServiceList") || (d.entity === EntityType[0].value && chart.type === "ServiceList") ||
(d.entity === EntityType[2].value && graph.type === "EndpointList") || (d.entity === EntityType[2].value && chart.type === "EndpointList") ||
(d.entity === EntityType[3].value && graph.type === "InstanceList") (d.entity === EntityType[3].value && chart.type === "InstanceList")
) { ) {
prev.push({ prev.push({
...d, ...d,
@ -248,26 +266,9 @@ function setDashboards(type?: string) {
states.dashboardList = arr.length ? arr : [{ label: "", value: "" }]; states.dashboardList = arr.length ? arr : [{ label: "", value: "" }];
} }
function setVisTypes() {
let graphs = [];
if (dashboardStore.entity === EntityType[0].value) {
graphs = ChartTypes.filter((d: Option) => d.value !== ChartTypes[7].value);
} else if (dashboardStore.entity === EntityType[1].value) {
graphs = ChartTypes.filter(
(d: Option) => !PodsChartTypes.includes(d.value)
);
} else {
graphs = ChartTypes.filter(
(d: Option) => !ListChartTypes.includes(d.value)
);
}
return graphs;
}
function changeChartType(item: Option) { function changeChartType(item: Option) {
const graph = DefaultGraphConfig[item.value]; const chart = DefaultGraphConfig[item.value] || {};
states.isList = ListChartTypes.includes(graph.type); states.isList = ListChartTypes.includes(chart.type);
if (states.isList) { if (states.isList) {
dashboardStore.selectWidget({ dashboardStore.selectWidget({
...dashboardStore.selectedGrid, ...dashboardStore.selectedGrid,
@ -278,8 +279,8 @@ function changeChartType(item: Option) {
states.metricTypes = [""]; states.metricTypes = [""];
defaultLen.value = 5; defaultLen.value = 5;
} }
setMetricType(graph); setMetricType(chart);
setDashboards(graph.type); setDashboards(chart.type);
states.dashboardName = ""; states.dashboardName = "";
defaultLen.value = 10; defaultLen.value = 10;
} }
@ -415,7 +416,7 @@ function setMetricTypeList(type: string) {
if (type !== MetricsType.REGULAR_VALUE) { if (type !== MetricsType.REGULAR_VALUE) {
return MetricTypes[type]; return MetricTypes[type];
} }
if (states.isList || dashboardStore.selectedGrid.graph.type === "Table") { if (states.isList || graph.value.type === "Table") {
return [ return [
{ label: "read all values in the duration", value: "readMetricsValues" }, { label: "read all values in the duration", value: "readMetricsValues" },
{ {

View File

@ -17,17 +17,17 @@ limitations under the License. -->
<div class="header flex-h"> <div class="header flex-h">
<div> <div>
<span> <span>
{{ data.widget?.title || "" }} {{ widget.title || "" }}
</span> </span>
</div> </div>
<div> <div>
<el-tooltip :content="data.widget?.tips"> <el-tooltip :content="widget.tips || ''">
<span> <span>
<Icon <Icon
iconName="info_outline" iconName="info_outline"
size="sm" size="sm"
class="operation" class="operation"
v-show="data.widget?.tips" v-show="widget.tips"
/> />
</span> </span>
</el-tooltip> </el-tooltip>
@ -51,15 +51,15 @@ limitations under the License. -->
</el-popover> </el-popover>
</div> </div>
</div> </div>
<div class="body" v-if="data.graph?.type" v-loading="loading"> <div class="body" v-if="graph.type" v-loading="loading">
<component <component
:is="data.graph.type" :is="graph.type"
:intervalTime="appStore.intervalTime" :intervalTime="appStore.intervalTime"
:data="state.source" :data="state.source"
:config="{ :config="{
...data.graph, ...data.graph,
metrics: data.metrics, metrics: data.metrics || [''],
metricTypes: data.metricTypes, metricTypes: data.metricTypes || [''],
i: data.i, i: data.i,
metricConfig: data.metricConfig, metricConfig: data.metricConfig,
}" }"
@ -70,7 +70,7 @@ limitations under the License. -->
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { toRefs, reactive, defineComponent, ref, watch } from "vue"; import { toRefs, reactive, defineComponent, ref, watch, computed } from "vue";
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";
@ -88,7 +88,7 @@ import { EntityType, ListChartTypes } from "../data";
const props = { const props = {
data: { data: {
type: Object as PropType<LayoutConfig>, type: Object as PropType<LayoutConfig>,
default: () => ({ widget: {} }), default: () => ({ widget: {}, graph: {} }),
}, },
activeIndex: { type: String, default: "" }, activeIndex: { type: String, default: "" },
needQuery: { type: Boolean, default: false }, needQuery: { type: Boolean, default: false },
@ -107,14 +107,19 @@ export default defineComponent({
const appStore = useAppStoreWithOut(); const appStore = useAppStoreWithOut();
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore(); const selectorStore = useSelectorStore();
const isList = ListChartTypes.includes(props.data.graph.type || ""); const graph = computed(() => props.data.graph || {});
const widget = computed(() => props.data.widget || {});
const isList = ListChartTypes.includes(
(props.data.graph && props.data.graph.type) || ""
);
if ((props.needQuery || !dashboardStore.currentDashboard.id) && !isList) { if ((props.needQuery || !dashboardStore.currentDashboard.id) && !isList) {
queryMetrics(); queryMetrics();
} }
async function queryMetrics() { async function queryMetrics() {
const { metricTypes, metrics } = props.data; const metricTypes = props.data.metricTypes || [];
const metrics = props.data.metrics || [];
const catalog = await useGetMetricEntity(metrics[0], metricTypes[0]); const catalog = await useGetMetricEntity(metrics[0], metricTypes[0]);
const params = await useQueryProcessor({ ...props.data, catalog }); const params = await useQueryProcessor({ ...props.data, catalog });
@ -129,8 +134,8 @@ export default defineComponent({
return; return;
} }
const d = { const d = {
metrics: props.data.metrics, metrics: props.data.metrics || [],
metricTypes: props.data.metricTypes, metricTypes: props.data.metricTypes || [],
metricConfig: props.data.metricConfig || [], metricConfig: props.data.metricConfig || [],
}; };
state.source = useSourceProcessor(json, d); state.source = useSourceProcessor(json, d);
@ -149,7 +154,7 @@ export default defineComponent({
} }
} }
watch( watch(
() => [props.data.metricTypes, props.data.metrics, props.data.standard], () => [props.data.metricTypes, props.data.metrics],
() => { () => {
if (!dashboardStore.selectedGrid) { if (!dashboardStore.selectedGrid) {
return; return;
@ -157,7 +162,9 @@ export default defineComponent({
if (props.data.i !== dashboardStore.selectedGrid.i) { if (props.data.i !== dashboardStore.selectedGrid.i) {
return; return;
} }
const isList = ListChartTypes.includes(props.data.graph.type || ""); const isList = ListChartTypes.includes(
(props.data.graph && props.data.graph.type) || ""
);
if ( if (
ListChartTypes.includes(dashboardStore.selectedGrid.graph.type) || ListChartTypes.includes(dashboardStore.selectedGrid.graph.type) ||
isList isList
@ -170,7 +177,9 @@ export default defineComponent({
watch( watch(
() => [selectorStore.currentService, selectorStore.currentDestService], () => [selectorStore.currentService, selectorStore.currentDestService],
() => { () => {
const isList = ListChartTypes.includes(props.data.graph.type || ""); const isList = ListChartTypes.includes(
(props.data.graph && props.data.graph.type) || ""
);
if (isList) { if (isList) {
return; return;
} }
@ -209,6 +218,8 @@ export default defineComponent({
loading, loading,
dashboardStore, dashboardStore,
t, t,
graph,
widget,
}; };
}, },
}); });

View File

@ -96,7 +96,13 @@ const props = defineProps({
metricTypes: string[]; metricTypes: string[];
} & { metricConfig: MetricConfigOpt[] } } & { metricConfig: MetricConfigOpt[] }
>, >,
default: () => ({ dashboardName: "", fontSize: 12, i: "" }), default: () => ({
metrics: [],
metricTypes: [],
dashboardName: "",
fontSize: 12,
i: "",
}),
}, },
intervalTime: { type: Array as PropType<string[]>, default: () => [] }, intervalTime: { type: Array as PropType<string[]>, default: () => [] },
isEdit: { type: Boolean, default: false }, isEdit: { type: Boolean, default: false },
@ -128,9 +134,9 @@ async function queryEndpointMetrics(currentPods: Endpoint[]) {
if (!currentPods.length) { if (!currentPods.length) {
return; return;
} }
const metrics = props.config.metrics.filter((d: string) => d); const metrics = (props.config.metrics || []).filter((d: string) => d);
const metricTypes = props.config.metricTypes || [];
if (metrics.length && metrics[0]) { if (metrics.length && metrics[0] && metricTypes.length && metricTypes[0]) {
const params = await useQueryPodsMetrics( const params = await useQueryPodsMetrics(
currentPods, currentPods,
props.config, props.config,

View File

@ -166,9 +166,9 @@ async function queryInstanceMetrics(currentInstances: Instance[]) {
if (!currentInstances.length) { if (!currentInstances.length) {
return; return;
} }
const { metrics } = props.config; const { metrics, metricTypes } = props.config;
if (metrics.length && metrics[0]) { if (metrics.length && metrics[0] && metricTypes.length && metricTypes[0]) {
const params = await useQueryPodsMetrics( const params = await useQueryPodsMetrics(
currentInstances, currentInstances,
props.config, props.config,

View File

@ -210,9 +210,9 @@ async function queryServiceMetrics(currentServices: Service[]) {
if (!currentServices.length) { if (!currentServices.length) {
return; return;
} }
const { metrics } = props.config; const { metrics, metricTypes } = props.config;
if (metrics.length && metrics[0]) { if (metrics.length && metrics[0] && metricTypes.length && metricTypes[0]) {
const params = await useQueryPodsMetrics( const params = await useQueryPodsMetrics(
currentServices, currentServices,
props.config, props.config,