| <!-- 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="rk-chart-edit"> |
| <div class="rk-chart-edit-container"> |
| <div class="flex-h mb-5"> |
| <div class="title grey sm">{{ $t('title') }}:</div> |
| <input |
| type="text" |
| class="rk-chart-edit-input long" |
| :value="itemConfig.title" |
| @change="setItemConfig({ type: 'title', value: $event.target.value })" |
| /> |
| </div> |
| <div class="flex-h mb-5"> |
| <div class="title grey sm">{{ $t('metrics') }}:</div> |
| <input |
| type="text" |
| class="rk-chart-edit-input long" |
| :value="itemConfig.metricName" |
| @change="setItemConfig({ type: 'metricName', value: $event.target.value })" |
| /> |
| <select |
| class="long" |
| v-model="itemConfig.queryMetricType" |
| @change="setItemConfig({ type: 'queryMetricType', value: $event.target.value })" |
| > |
| <option v-for="query in queryMetricTypesList" :value="query.value" :key="query.value" |
| >{{ query.label }} |
| </option> |
| </select> |
| </div> |
| <div class="flex-h mb-5" v-show="isChartType"> |
| <div class="title grey sm">{{ $t('chartType') }}:</div> |
| <select |
| class="long" |
| v-model="itemConfig.chartType" |
| @change="setItemConfig({ type: 'chartType', value: $event.target.value })" |
| > |
| <option v-for="chart in chartTypeOptions" :value="chart.value" :key="chart.value"> |
| {{ chart.label }} |
| </option> |
| </select> |
| </div> |
| <div class="flex-h mb-5" v-show="isLabel"> |
| <div class="title grey sm">{{ $t('labels') }}:</div> |
| <input |
| type="text" |
| class="rk-chart-edit-input long" |
| :value="itemConfig.metricLabels" |
| @change="setItemConfig({ type: 'metricLabels', value: $event.target.value })" |
| /> |
| </div> |
| <div class="flex-h mb-5" v-show="isLabel"> |
| <div class="title grey sm">{{ $t('labelsIndex') }}:</div> |
| <input |
| type="text" |
| class="rk-chart-edit-input long" |
| :value="itemConfig.labelsIndex" |
| @change="setItemConfig({ type: 'labelsIndex', value: $event.target.value })" |
| /> |
| </div> |
| <div class="flex-h mb-5" v-show="!isDatabase && !pageTypes.includes(type)"> |
| <div class="title grey sm">{{ $t('entityType') }}:</div> |
| <select |
| class="long" |
| v-model="itemConfig.entityType" |
| @change="setItemConfig({ type: 'entityType', value: $event.target.value })" |
| > |
| <option v-for="type in EntityType" :value="type.key" :key="type.key">{{ type.label }}</option> |
| </select> |
| </div> |
| <div class="flex-h mb-5" v-show="itemConfig.independentSelector && isDatabase"> |
| <div class="title grey sm">{{ $t('currentDatabase') }}:</div> |
| <select |
| class="long" |
| v-model="itemConfig.currentDatabase" |
| @change="setItemConfig({ type: 'currentDatabase', value: $event.target.value })" |
| > |
| <option v-for="database in stateDashboardOption.databases" :value="database.label" :key="database.key" |
| >{{ database.label }} |
| </option> |
| </select> |
| </div> |
| <div |
| class="flex-h mb-5" |
| v-show=" |
| itemConfig.entityType !== EntityType[1].key && itemConfig.independentSelector && !isDatabase && !isBrowser |
| " |
| > |
| <div class="title grey sm">{{ $t('currentService') }}:</div> |
| <input |
| type="text" |
| class="rk-chart-edit-input long" |
| :value="itemConfig.servicesKey" |
| @change="setItemConfig({ type: 'servicesKey', value: $event.target.value })" |
| /> |
| <select |
| class="long" |
| v-model="itemConfig.currentService" |
| @change="setItemConfig({ type: 'currentService', value: $event.target.value })" |
| > |
| <option v-for="service in services" :value="service.label" :key="service.key"> |
| {{ service.label }} |
| </option> |
| </select> |
| </div> |
| <div |
| class="flex-h mb-5" |
| v-show=" |
| itemConfig.entityType === EntityType[2].key && itemConfig.independentSelector && !isDatabase && !isBrowser |
| " |
| > |
| <div class="title grey sm">{{ $t('currentEndpoint') }}:</div> |
| <input |
| type="text" |
| class="rk-chart-edit-input long" |
| :value="itemConfig.endpointsKey" |
| @change="setItemConfig({ type: 'endpointsKey', value: $event.target.value })" |
| /> |
| <select |
| class="long" |
| v-model="itemConfig.currentEndpoint" |
| @change="setItemConfig({ type: 'currentEndpoint', value: $event.target.value })" |
| > |
| <option v-for="endpoint in endpoints" :value="endpoint.label" :key="endpoint.key" |
| >{{ endpoint.label }} |
| </option> |
| </select> |
| </div> |
| <div |
| class="flex-h mb-5" |
| v-show=" |
| itemConfig.entityType === EntityType[3].key && itemConfig.independentSelector && !isDatabase && !isBrowser |
| " |
| > |
| <div class="title grey sm">{{ $t('currentInstance') }}:</div> |
| <input |
| type="text" |
| class="rk-chart-edit-input long" |
| :value="itemConfig.instancesKey" |
| @change="setItemConfig({ type: 'instancesKey', value: $event.target.value })" |
| /> |
| <select |
| class="long" |
| v-model="itemConfig.currentInstance" |
| @change="setItemConfig({ type: 'currentInstance', value: $event.target.value })" |
| > |
| <option v-for="instance in instances" :value="instance.label" :key="instance.key" |
| >{{ instance.label }} |
| </option> |
| </select> |
| </div> |
| <div class="flex-h mb-5" v-show="!isIndependentSelector && !isBrowser"> |
| <div class="title grey sm">{{ $t('independentSelector') }}:</div> |
| <select |
| class="long" |
| v-model="itemConfig.independentSelector" |
| @change="setItemConfig({ type: 'independentSelector', value: $event.target.value })" |
| > |
| <option v-for="type in IndependentType" :value="type.key" :key="type.key">{{ type.label }}</option> |
| </select> |
| </div> |
| <div class="flex-h mb-5" v-show="nameMetrics.includes(itemConfig.queryMetricType)"> |
| <div class="title grey sm">{{ $t('parentService') }}:</div> |
| <select |
| class="long" |
| v-model="itemConfig.parentService" |
| @change="setItemConfig({ type: 'parentService', value: $event.target.value })" |
| > |
| <option :value="true">{{ $t('isParentService') }}</option> |
| <option :value="false">{{ $t('noneParentService') }}</option> |
| </select> |
| </div> |
| <div class="flex-h mb-5" v-show="nameMetrics.includes(itemConfig.queryMetricType)"> |
| <div class="title grey sm">{{ $t('sortOrder') }}:</div> |
| <select |
| class="long" |
| v-model="itemConfig.sortOrder" |
| @change="setItemConfig({ type: 'sortOrder', value: $event.target.value })" |
| > |
| <option :value="'DES'">{{ $t('descendOrder') }}</option> |
| <option :value="'ASC'">{{ $t('increaseOrder') }}</option> |
| </select> |
| </div> |
| <div class="flex-h mb-5"> |
| <div class="title grey sm">{{ $t('unit') }}:</div> |
| <input |
| type="text" |
| class="rk-chart-edit-input long" |
| :value="itemConfig.unit" |
| @change="setItemConfig({ type: 'unit', value: $event.target.value })" |
| /> |
| </div> |
| <div class="flex-h mb-5"> |
| <div class="title grey sm">{{ $t('width') }}:</div> |
| <input |
| type="number" |
| min="1" |
| max="12" |
| class="rk-chart-edit-input long" |
| :value="itemConfig.width" |
| @change="setItemConfig({ type: 'width', value: $event.target.value })" |
| /> |
| </div> |
| <div class="flex-h mb-5"> |
| <div class="title grey sm">{{ $t('height') }}:</div> |
| <input |
| type="number" |
| min="1" |
| class="rk-chart-edit-input long" |
| :value="itemConfig.height" |
| @change="setItemConfig({ type: 'height', value: $event.target.value })" |
| /> |
| </div> |
| <div class="flex-h mb-5" v-show="!isChartType"> |
| <div class="title grey sm">{{ $t('maxItemNum') }}:</div> |
| <input |
| type="number" |
| min="1" |
| class="rk-chart-edit-input long" |
| :value="itemConfig.maxItemNum" |
| @change="setItemConfig({ type: 'maxItemNum', value: $event.target.value })" |
| /> |
| </div> |
| <div class="flex-h mb-5"> |
| <div class="title grey sm">{{ $t('aggregation') }}:</div> |
| <select |
| class="long" |
| v-model="itemConfig.aggregation" |
| @change="setItemConfig({ type: 'aggregation', value: $event.target.value })" |
| > |
| <option v-for="type in CalculationType" :value="type.value" :key="type.value">{{ type.label }} </option> |
| </select> |
| <input |
| type="text" |
| class="rk-chart-edit-input long" |
| :value="itemConfig.aggregationNum" |
| @change="setItemConfig({ type: 'aggregationNum', value: $event.target.value })" |
| /> |
| </div> |
| <div class="flex-h mb-5" v-show="itemConfig.chartType === ChartTable"> |
| <div class="title grey sm">{{ $t('tableHeader') }}:</div> |
| <input |
| type="text" |
| class="rk-chart-edit-input long" |
| placeholder="col-1" |
| :value="itemConfig.tableHeaderCol1" |
| @change="setItemConfig({ type: 'tableHeaderCol1', value: $event.target.value })" |
| /> |
| <input |
| type="text" |
| class="rk-chart-edit-input long" |
| placeholder="col-2" |
| :value="itemConfig.tableHeaderCol2" |
| @change="setItemConfig({ type: 'tableHeaderCol2', value: $event.target.value })" |
| /> |
| </div> |
| <div class="flex-h mb-5" v-show="itemConfig.chartType === ChartTable"> |
| <div class="title grey sm">{{ $t('tableValues') }}:</div> |
| <select |
| class="long" |
| v-model="itemConfig.showTableValues" |
| @change="setItemConfig({ type: 'showTableValues', value: $event.target.value })" |
| > |
| <option :value="true">{{ $t('show') }}</option> |
| <option :value="false">{{ $t('hide') }}</option> |
| </select> |
| </div> |
| <div class="flex-h mb-5"> |
| <div class="title grey sm">{{ $t('tooltipsContent') }}:</div> |
| <input |
| type="text" |
| class="rk-chart-edit-input long" |
| :value="itemConfig.tips" |
| @change="setItemConfig({ type: 'tips', value: $event.target.value })" |
| /> |
| </div> |
| </div> |
| </div> |
| </template> |
| |
| <script lang="ts"> |
| import Vue from 'vue'; |
| import { State, Getter, Mutation, Action } from 'vuex-class'; |
| import { Component, Prop } from 'vue-property-decorator'; |
| import { TopologyType } from '@/constants/constant'; |
| import { |
| EntityType, |
| BrowserEntityType, |
| IndependentType, |
| MetricsType, |
| QueryMetricTypes, |
| MetricChartType, |
| CalculationType, |
| ChartTypeOptions, |
| ReadValueChartType, |
| } from './constant'; |
| import { DASHBOARDTYPE } from '../constant'; |
| |
| @Component |
| export default class ChartEdit extends Vue { |
| @State('rocketOption') private stateDashboardOption: any; |
| @State('rocketData') private rocketComps!: any; |
| @Mutation('EDIT_COMP_CONFIG') private EDIT_COMP_CONFIG: any; |
| @Mutation('rocketTopo/EDIT_TOPO_INSTANCE_CONFIG') private EDIT_TOPO_INSTANCE_CONFIG: any; |
| @Mutation('rocketTopo/EDIT_TOPO_ENDPOINT_CONFIG') private EDIT_TOPO_ENDPOINT_CONFIG: any; |
| @Action('GET_ITEM_SERVICES') private GET_ITEM_SERVICES: any; |
| @Action('GET_ITEM_ENDPOINTS') private GET_ITEM_ENDPOINTS: any; |
| @Action('GET_ITEM_INSTANCES') private GET_ITEM_INSTANCES: any; |
| @Action('TYPE_METRICS') private TYPE_METRICS: any; |
| @Getter('durationTime') private durationTime: any; |
| @Prop() private item!: any; |
| @Prop() private index!: number; |
| @Prop() private intervalTime!: any; |
| @Prop() private type!: string; |
| private itemConfig: any = {}; |
| private itemConfigDefault: any = { |
| maxItemNum: '10', |
| }; |
| private EntityType = EntityType; |
| private IndependentType = IndependentType; |
| private CalculationType = CalculationType; |
| private chartTypeOptions = ChartTypeOptions; |
| private services: any = []; |
| private endpoints: any = []; |
| private instances: any = []; |
| private queryMetricTypesList: any = []; |
| private isDatabase = false; |
| private isBrowser = false; |
| private isLabel = false; |
| private isIndependentSelector = false; |
| private nameMetrics = ['sortMetrics', 'readSampledRecords']; |
| private pageTypes = [TopologyType.TOPOLOGY_ENDPOINT, TopologyType.TOPOLOGY_INSTANCE] as string[]; |
| private isChartType = false; |
| private ChartTable = 'ChartTable'; |
| |
| private created() { |
| this.setDefaultValue((this.itemConfig = this.item)); |
| this.initConfig(); |
| if (!this.itemConfig.independentSelector || this.pageTypes.includes(this.type)) { |
| return; |
| } |
| this.setItemServices(); |
| } |
| |
| private setDefaultValue(itemConfig: any) { |
| const currentKeys: string[] = Object.keys(itemConfig); |
| const defaultKeys: string[] = Object.keys(this.itemConfigDefault); |
| |
| if (!currentKeys.length || !defaultKeys.length) { |
| return; |
| } |
| |
| defaultKeys.forEach((key: string) => { |
| if (!currentKeys.includes(key)) { |
| itemConfig[key] = this.itemConfigDefault[key]; |
| } |
| }); |
| } |
| |
| private initConfig() { |
| this.isDatabase = this.pageTypes.includes(this.type) |
| ? false |
| : this.rocketComps.tree[this.rocketComps.group].type === DASHBOARDTYPE.DATABASE |
| ? true |
| : false; |
| this.isBrowser = this.rocketComps.tree[this.rocketComps.group].type === DASHBOARDTYPE.BROWSER; |
| if (this.isBrowser) { |
| this.EntityType = BrowserEntityType; |
| } |
| this.queryMetricTypesList = QueryMetricTypes[this.item.metricType] || []; |
| this.isLabel = this.itemConfig.metricType === MetricsType.LABELED_VALUE ? true : false; |
| this.isIndependentSelector = |
| this.rocketComps.tree[this.rocketComps.group].type === 'metric' || this.pageTypes.includes(this.type); |
| this.chartTypeOptions = |
| this.itemConfig.queryMetricType === 'readMetricsValue' ? ReadValueChartType : ChartTypeOptions; |
| } |
| |
| private setItemConfig(params: { type: string; value: string }) { |
| this.itemConfig[params.type] = params.value; |
| const types = ['endpointsKey', 'instancesKey', 'currentService']; |
| const typesUpdate = ['title', 'width', 'height', 'unit', 'tips']; |
| if (params.type === 'servicesKey') { |
| this.setItemServices(true); |
| } |
| if (types.includes(params.type)) { |
| this.getServiceObject(true); |
| } |
| if (typesUpdate.includes(params.type)) { |
| this.$emit('updateStatus', params.type, params.value); |
| } |
| if (params.type === 'entityType') { |
| if (this.itemConfig.currentService) { |
| this.getServiceObject(true); |
| } |
| } |
| if (params.type === 'metricName') { |
| this.updateMetricName(params); |
| return; |
| } |
| if (params.type === 'queryMetricType') { |
| this.chartTypeOptions = |
| this.itemConfig.queryMetricType === 'readMetricsValue' ? ReadValueChartType : ChartTypeOptions; |
| this.updateQueryMetricType(params); |
| return; |
| } |
| if (params.type === 'independentSelector' || params.type === 'parentService') { |
| this.itemConfig[params.type] = params.value === 'true' ? true : false; |
| if (this.type === this.pageTypes[0]) { |
| this.EDIT_TOPO_ENDPOINT_CONFIG({ |
| index: this.index, |
| values: { [params.type]: this.itemConfig[params.type] }, |
| }); |
| } else if (this.type === this.pageTypes[1]) { |
| this.EDIT_TOPO_INSTANCE_CONFIG({ |
| index: this.index, |
| values: { [params.type]: this.itemConfig[params.type] }, |
| }); |
| } else { |
| this.EDIT_COMP_CONFIG({ index: this.index, values: { [params.type]: this.itemConfig[params.type] } }); |
| } |
| return; |
| } |
| if (params.type === 'aggregation' && ['milliseconds', 'seconds'].includes(this.itemConfig.aggregation)) { |
| this.updateAggregation(params); |
| return; |
| } |
| if (this.type === this.pageTypes[0]) { |
| this.EDIT_TOPO_ENDPOINT_CONFIG({ |
| index: this.index, |
| values: { [params.type]: params.value }, |
| }); |
| } else if (this.type === this.pageTypes[1]) { |
| this.EDIT_TOPO_INSTANCE_CONFIG({ |
| index: this.index, |
| values: { [params.type]: params.value }, |
| }); |
| } else { |
| this.EDIT_COMP_CONFIG({ index: this.index, values: { [params.type]: params.value } }); |
| } |
| } |
| |
| private updateMetricName(params: { type: string; value: string }) { |
| this.TYPE_METRICS({ name: params.value }).then((data: Array<{ typeOfMetrics: string }>) => { |
| if (!data.length) { |
| return; |
| } |
| if (data.length > 1) { |
| const length = data.filter((d: { typeOfMetrics: string }) => d.typeOfMetrics !== MetricsType.REGULAR_VALUE) |
| .length; |
| if (length) { |
| this.$emit('updateStatus', 'metricType', MetricsType.UNKNOWN); |
| return; |
| } |
| } |
| const { typeOfMetrics } = data[0]; |
| this.$emit('updateStatus', 'metricType', typeOfMetrics); |
| this.queryMetricTypesList = QueryMetricTypes[typeOfMetrics] || []; |
| this.itemConfig.queryMetricType = this.queryMetricTypesList[0] && this.queryMetricTypesList[0].value; |
| this.hasChartType(); |
| this.isLabel = typeOfMetrics === MetricsType.LABELED_VALUE ? true : false; |
| const values = { |
| metricType: typeOfMetrics, |
| queryMetricType: this.itemConfig.queryMetricType, |
| chartType: MetricChartType[this.itemConfig.queryMetricType], |
| metricName: params.value, |
| }; |
| if (this.type === this.pageTypes[0]) { |
| this.EDIT_TOPO_ENDPOINT_CONFIG({ |
| index: this.index, |
| values, |
| }); |
| } else if (this.type === this.pageTypes[1]) { |
| this.EDIT_TOPO_INSTANCE_CONFIG({ |
| index: this.index, |
| values, |
| }); |
| } else { |
| this.EDIT_COMP_CONFIG({ |
| index: this.index, |
| values, |
| }); |
| } |
| this.itemConfig = { |
| ...this.itemConfig, |
| ...values, |
| }; |
| }); |
| } |
| |
| private updateAggregation(params: { type: string; value: string }) { |
| const values = { |
| aggregationNum: 'YYYY-MM-DD HH:mm:ss', |
| [params.type]: params.value, |
| }; |
| this.itemConfig = { |
| ...this.itemConfig, |
| ...values, |
| }; |
| this.EDIT_COMP_CONFIG({ |
| index: this.index, |
| values, |
| }); |
| } |
| |
| private updateQueryMetricType(params: { type: string; value: string }) { |
| const values = { |
| chartType: MetricChartType[params.value], |
| [params.type]: params.value, |
| }; |
| if (this.type === this.pageTypes[0]) { |
| this.EDIT_TOPO_ENDPOINT_CONFIG({ |
| index: this.index, |
| values, |
| }); |
| } else if (this.type === this.pageTypes[1]) { |
| this.EDIT_TOPO_INSTANCE_CONFIG({ |
| index: this.index, |
| values, |
| }); |
| } else { |
| this.EDIT_COMP_CONFIG({ |
| index: this.index, |
| values, |
| }); |
| } |
| this.itemConfig = { |
| ...this.itemConfig, |
| ...values, |
| }; |
| this.hasChartType(); |
| } |
| |
| private setItemServices(update: boolean = false) { |
| this.GET_ITEM_SERVICES({ keyword: this.itemConfig.servicesKey || '', duration: this.durationTime }).then( |
| (result: Array<{ label: string; key: string }>) => { |
| this.services = result; |
| if (update) { |
| if (result.length) { |
| this.itemConfig.currentService = result[0].key; |
| } else { |
| this.itemConfig.currentService = ''; |
| } |
| } |
| if (this.itemConfig.currentService) { |
| this.getServiceObject(); |
| } |
| }, |
| ); |
| } |
| |
| private getServiceObject(update: boolean = false) { |
| const service = |
| this.services.filter((d: { key: string; label: string }) => d.label === this.itemConfig.currentService)[0] || |
| {}; |
| const serviceId = service.key; |
| |
| if (!serviceId) { |
| return; |
| } |
| if (this.itemConfig.entityType === EntityType[2].key) { |
| this.GET_ITEM_ENDPOINTS({ |
| serviceId, |
| keyword: this.itemConfig.endpointsKey || '', |
| duration: this.durationTime, |
| }).then((data: Array<{ key: string; label: string }>) => { |
| this.endpoints = data; |
| if (update) { |
| if (data.length) { |
| this.itemConfig.currentEndpoint = data[0].key; |
| } else { |
| this.itemConfig.currentEndpoint = ''; |
| } |
| this.EDIT_COMP_CONFIG({ index: this.index, values: { currentEndpoint: this.itemConfig.currentEndpoint } }); |
| } |
| }); |
| } else if (this.itemConfig.entityType === EntityType[3].key) { |
| this.GET_ITEM_INSTANCES({ |
| serviceId, |
| keyword: this.itemConfig.instancesKey || '', |
| duration: this.durationTime, |
| }).then((data: Array<{ key: string; label: string }>) => { |
| this.instances = data; |
| if (update) { |
| if (data.length) { |
| this.itemConfig.currentInstance = data[0].key; |
| } else { |
| this.itemConfig.currentInstance = ''; |
| } |
| this.EDIT_COMP_CONFIG({ index: this.index, values: { currentInstance: this.itemConfig.currentInstance } }); |
| } |
| }); |
| } |
| } |
| |
| private hasChartType() { |
| this.isChartType = ['readMetricsValue', 'readMetricsValues', 'readLabeledMetricsValues'].includes( |
| this.itemConfig.queryMetricType, |
| ); |
| } |
| } |
| </script> |
| <style lang="scss" scoped> |
| .rk-chart-edit { |
| margin: 0 -10px; |
| height: 100%; |
| border: 1px dashed rgba(196, 200, 225, 0.5); |
| |
| select { |
| margin: 0; |
| height: 30px; |
| border: 1px solid #ddd; |
| background-color: #fff; |
| outline: none; |
| } |
| } |
| |
| .rk-chart-edit-container { |
| padding: 7px 5px; |
| border-radius: 4px; |
| height: 100%; |
| overflow: auto; |
| .title { |
| width: 120px; |
| flex-shrink: 0; |
| } |
| } |
| |
| .rk-chart-edit-input { |
| border: 0; |
| outline: 0; |
| padding: 4px 10px; |
| border-radius: 3px; |
| border: 1px solid #ddd; |
| } |
| </style> |