feat: add selector module

This commit is contained in:
Qiuxia Fan 2021-12-15 15:43:38 +08:00
parent d00e547099
commit 9cb8e2b64d
15 changed files with 238 additions and 14 deletions

View File

@ -18,7 +18,6 @@ limitations under the License. -->
<style> <style>
#app { #app {
text-align: center;
color: #2c3e50; color: #2c3e50;
height: 100%; height: 100%;
} }

View File

@ -492,7 +492,7 @@ watch(
} }
.datepicker-range { .datepicker-range {
min-width: 238px; min-width: 260px;
} }
.datepicker-range .datepicker-popup { .datepicker-range .datepicker-popup {

View File

@ -0,0 +1,32 @@
/**
* 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.
*/
export const Services = {
variable: ["$layer: String!"],
query: `
services: listServices(layer: $layer) {
value: id
label: name
group
layer
}
`,
};
export const Layers = {
query: `
layers: listLayers
`,
};

View File

@ -16,9 +16,10 @@
*/ */
import axios, { AxiosPromise, AxiosResponse } from "axios"; import axios, { AxiosPromise, AxiosResponse } from "axios";
import { cancelToken } from "@/utils/cancelToken"; import { cancelToken } from "@/utils/cancelToken";
import * as global from "./query/global"; import * as app from "./query/app";
import * as selector from "./query/selector";
const query: { [key: string]: string } = { ...global }; const query: { [key: string]: string } = { ...app, ...selector };
class Graph { class Graph {
private queryData = ""; private queryData = "";
public query(queryData: string) { public query(queryData: string) {

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { OAPTimeInfo, OAPVersion } from "../fragments/global"; import { OAPTimeInfo, OAPVersion } from "../fragments/app";
export const queryOAPTimeInfo = `query queryOAPTimeInfo {${OAPTimeInfo.query}}`; export const queryOAPTimeInfo = `query queryOAPTimeInfo {${OAPTimeInfo.query}}`;

View File

@ -0,0 +1,20 @@
/**
* 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.
*/
import { Services, Layers } from "../fragments/selector";
export const queryServices = `query queryServices(${Services.variable}) {${Services.query}}`;
export const queryLayers = `query ${Layers.query}`;

View File

@ -43,6 +43,7 @@ const msg = {
eventList: "Event List", eventList: "Event List",
databasePanel: "Database Panel", databasePanel: "Database Panel",
meshServicePanel: "Service Panel", meshServicePanel: "Service Panel",
newDashboard: "New a dashboard",
hourTip: "Select Hour", hourTip: "Select Hour",
minuteTip: "Select Minute", minuteTip: "Select Minute",
secondTip: "Select Second", secondTip: "Select Second",

View File

@ -43,6 +43,7 @@ const msg = {
eventList: "事件列表", eventList: "事件列表",
databasePanel: "数据库面板", databasePanel: "数据库面板",
meshServicePanel: "服务面板", meshServicePanel: "服务面板",
newDashboard: "新增仪表盘",
hourTip: "选择小时", hourTip: "选择小时",
minuteTip: "选择分钟", minuteTip: "选择分钟",
secondTip: "选择秒数", secondTip: "选择秒数",

View File

@ -0,0 +1,54 @@
/**
* 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.
*/
import { defineStore } from "pinia";
import { Option } from "@/types/app";
import { store } from "@/store";
import graph from "@/graph";
import { AxiosResponse } from "axios";
interface SelectorState {
services: Option[];
}
export const selectorStore = defineStore({
id: "selector",
state: (): SelectorState => ({
services: [],
}),
getters: {},
actions: {
async fetchLayers() {
const res: AxiosResponse = await graph.query("queryLayers").params({});
return res;
},
async fetchServices(layer: string): Promise<AxiosResponse> {
const res: AxiosResponse = await graph
.query("queryServices")
.params({ layer });
if (!res.data.errors) {
this.services = res.data.data.services;
}
return res;
},
},
});
export function useSelectorStore(): any {
return selectorStore(store);
}

View File

@ -18,7 +18,7 @@
body { body {
margin: 0; margin: 0;
line-height: 1.5; line-height: 1.5;
font-size: 13px; font-size: 14px;
color: #3d444f; color: #3d444f;
font-family: 'Helvetica', 'Arial', 'Source Han Sans CN', 'Microsoft YaHei', 'sans-serif'; font-family: 'Helvetica', 'Arial', 'Source Han Sans CN', 'Microsoft YaHei', 'sans-serif';
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;

View File

@ -14,11 +14,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* eslint-disable */
import axios from "axios"; import axios from "axios";
const CancelToken = axios.CancelToken; const CancelToken = axios.CancelToken;
export const cancelToken = () => export const cancelToken = (): any =>
new CancelToken(function executor(c) { new CancelToken(function executor(c) {
const w = window as any; const w = window as any;
w.axiosCancel.push(c); w.axiosCancel.push(c);

View File

@ -28,7 +28,9 @@ limitations under the License. -->
</template> </template>
</el-input> </el-input>
<router-link to="/dashboard/new"> <router-link to="/dashboard/new">
<el-button size="small" type="primary">+ New Dashboard</el-button> <el-button size="small" type="primary">
+ {{ t("newDashboard") }}
</el-button>
</router-link> </router-link>
</div> </div>
<el-table :data="tableData" style="width: 100%" max-height="550"> <el-table :data="tableData" style="width: 100%" max-height="550">
@ -57,6 +59,7 @@ limitations under the License. -->
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from "vue"; import { ref } from "vue";
import { useI18n } from "vue-i18n";
import { ElTable, ElTableColumn, ElButton, ElInput } from "element-plus"; import { ElTable, ElTableColumn, ElButton, ElInput } from "element-plus";
// # - os-linux // # - os-linux
// # - k8s // # - k8s
@ -69,6 +72,7 @@ import { ElTable, ElTableColumn, ElButton, ElInput } from "element-plus";
// # - cache // # - cache
// # - browser // # - browser
// # - skywalking // # - skywalking
const { t } = useI18n();
const searchText = ref<string>(""); const searchText = ref<string>("");
const tableData = [ const tableData = [
{ {

View File

@ -13,11 +13,123 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<div class="new-dashboard">{{ props.msg }}</div> <div class="new-dashboard">
<h4>Create a new dashboard</h4>
<div class="item">
<div class="label">Layer</div>
<el-select
size="small"
v-model="template"
placeholder="Select"
class="selectors"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</div>
<div class="item">
<div class="label">Entity</div>
<el-select
size="small"
v-model="entity"
placeholder="Select"
class="selectors"
>
<el-option
v-for="item in EntityType"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</div>
<div class="item">
<div class="label">Service</div>
<el-select
size="small"
v-model="template"
placeholder="Select"
class="selectors"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</div>
<div class="item">
<div class="label">Service / Endpoint</div>
<el-cascader
v-model="value"
:options="options"
:props="props"
></el-cascader>
</div>
<div class="item">
<div class="label">Destination Service</div>
<el-select
size="small"
v-model="template"
placeholder="Select"
class="selectors"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</div>
<div class="item">
<span class="label">Destination Service / Endpoint</span>
<el-cascader
v-model="value"
:options="options"
:props="props"
></el-cascader>
</div>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { defineProps } from "vue"; import { ref } from "vue";
const props = defineProps({ import { ElSelect, ElOption, ElCascader } from "element-plus";
msg: String, import { useSelectorStore } from "@/store/modules/selectors";
});
const EntityType = [
{ value: "Service", label: "Service" },
{ value: "All", label: "All" },
{ value: "Endpoint", label: "Service Endpoint" },
{ value: "ServiceInstance", label: "Service Instance" },
{ value: "ServiceRelation", label: "Service Relation" },
{ value: "ServiceInstanceRelation", label: "Service Instance Relation" },
{ value: "EndpointRelation", label: "Endpoint Relation" },
];
const selectorStore = useSelectorStore();
const entity = ref("");
const template = ref("");
const options = ref([]);
selectorStore.fetchServices("general");
</script> </script>
<style lang="scss" scoped>
.new-dashboard {
width: 600px;
margin: 0 auto;
}
.item {
margin-top: 20px;
}
.selectors {
width: 600px;
}
</style>