This is an automated email from the ASF dual-hosted git repository.
robocanic pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-admin.git
The following commit(s) were added to refs/heads/develop by this push:
new 0ed6d1c4 refactor: :art: Optimize UI styles and search functionality
(#1379)
0ed6d1c4 is described below
commit 0ed6d1c4496ed3105e4826c819011439082f4adb
Author: LGgbond <[email protected]>
AuthorDate: Sun Dec 28 22:23:53 2025 +0800
refactor: :art: Optimize UI styles and search functionality (#1379)
* feat: enhance error handling for unauthorized access and improve toast
messages
* feat: enhance error handling for unauthorized access and improve toast
messages
* fix: correct syntax error in response interceptor for redirect handling
* Update ui-vue3/src/base/http/request.ts
Co-authored-by: Copilot <[email protected]>
* feat: add YAML and XML editor components, update index references, and
enhance error logging
- Introduced new JavaScript files for YAML and XML syntax highlighting and
editing capabilities.
- Added a new component for updating YAML configurations with a structured
editor interface.
- Updated the index.html to reference the new JavaScript bundle for
improved functionality.
- Enhanced the HTTP request module to log errors during redirection on 401
responses for better debugging.
* docs: Only supports exact matching; remove the "prefix search" function
from the placeholder (background word)
* docs: All sorting indicators for lists are initially hidden, including
but not limited to the list pages for applications, instances, services, and
traffic management
* refactor: :art: Optimize the styles of some tables and adapt to backend
changes
* docs: api baseurl
---------
Co-authored-by: Copilot <[email protected]>
---
ui-vue3/src/Login.vue | 21 +-
ui-vue3/src/base/i18n/en.ts | 19 +-
ui-vue3/src/base/i18n/zh.ts | 13 +-
ui-vue3/src/layout/header/layout_header.vue | 2 +-
ui-vue3/src/utils/SearchUtil.ts | 5 +-
ui-vue3/src/views/resources/applications/index.vue | 12 +-
.../views/resources/applications/tabs/instance.vue | 18 +-
.../views/resources/applications/tabs/service.vue | 67 +++---
ui-vue3/src/views/resources/instances/index.vue | 24 +-
ui-vue3/src/views/resources/services/search.vue | 115 +++-------
.../views/resources/services/tabs/distribution.vue | 248 ++++++---------------
.../src/views/traffic/destinationRule/index.vue | 13 +-
ui-vue3/src/views/traffic/dynamicConfig/index.vue | 34 +--
ui-vue3/src/views/traffic/routingRule/index.vue | 24 +-
ui-vue3/src/views/traffic/tagRule/index.vue | 24 +-
ui-vue3/src/views/traffic/virtualService/index.vue | 17 +-
16 files changed, 233 insertions(+), 423 deletions(-)
diff --git a/ui-vue3/src/Login.vue b/ui-vue3/src/Login.vue
index 1988b7ed..6a67a5aa 100644
--- a/ui-vue3/src/Login.vue
+++ b/ui-vue3/src/Login.vue
@@ -44,8 +44,8 @@ function loginHandle() {
updateAuthState(true, userinfo.username)
const { data } = await meshesSearch()
// if mesh is not set or old mesh is expired
- if (!meshStore.mesh || !data.some((x: any) => x.name ===
meshStore.mesh)) {
- meshStore.mesh = data[0]?.name
+ if (!meshStore.mesh || !data.some((x: any) => x.id === meshStore.mesh)) {
+ meshStore.mesh = data[0]?.id
}
router.replace(redirect)
})
@@ -63,25 +63,14 @@ function loginHandle() {
</a-row>
<a-row>
<a-form layout="vertical" :model="userinfo" ref="login-form-ref">
- <a-form-item
- class="item"
- :label="$t('loginDomain.username')"
- name="username"
- :rules="[{ required: true }]"
- >
+ <a-form-item class="item" :label="$t('loginDomain.username')"
name="username" :rules="[{ required: true }]">
<a-input type="" v-model:value="userinfo.username"></a-input>
</a-form-item>
- <a-form-item
- class="item"
- :label="$t('loginDomain.password')"
- name="password"
- :rules="[{ required: true }]"
- >
+ <a-form-item class="item" :label="$t('loginDomain.password')"
name="password" :rules="[{ required: true }]">
<a-input type="password"
v-model:value="userinfo.password"></a-input>
</a-form-item>
<a-form-item class="item" label="">
- <a-button @click="loginHandle" size="large" type="primary"
class="login-btn"
- >{{ $t('loginDomain.login') }}
+ <a-button @click="loginHandle" size="large" type="primary"
class="login-btn">{{ $t('loginDomain.login') }}
</a-button>
</a-form-item>
</a-form>
diff --git a/ui-vue3/src/base/i18n/en.ts b/ui-vue3/src/base/i18n/en.ts
index 6b52d88d..503346f9 100644
--- a/ui-vue3/src/base/i18n/en.ts
+++ b/ui-vue3/src/base/i18n/en.ts
@@ -158,6 +158,12 @@ const words: I18nType = {
opened: 'Opened',
paramRoute: 'Param Route'
},
+ servicesDomain: {
+ appName: 'Application Name',
+ instanceCount: 'Instance Count',
+ deployClusters: 'Deploy Clusters',
+ registryClusters: 'Registry Clusters'
+ },
appServiceTimeout: 'Adjusting the timeout for application service provision',
enableAppInstanceLogs: 'Enable access logs for all instances of this
application',
appServiceLoadBalance: 'Adjusting the load balancing strategy for
application service provision',
@@ -198,6 +204,8 @@ const words: I18nType = {
service: 'Service',
versionGroup: 'Version & Group',
avgQPS: 'last 1min QPS',
+ provider: 'Provider',
+ subset: 'Group',
avgRT: 'last 1min RT',
requestTotal: 'last 1min request total',
serviceSearch: 'Search Service',
@@ -368,6 +376,13 @@ const words: I18nType = {
placeholders: {
searchService: 'Search by service name'
},
+ placeholder: {
+ searchService: 'Search by service name',
+ typeAppName: 'Enter application name',
+ typeDefault: 'Please enter',
+ typeRoutingRules: 'Search routing rules',
+ searchAppNameOrIP: 'Search application, IP'
+ },
methods: 'Methods',
testModule: {
searchServiceHint:
@@ -490,10 +505,6 @@ const words: I18nType = {
backHome: 'Back Home',
noPageTip: 'Sorry, the page you visited does not exist.',
globalSearchTip: 'Search ip, application, instance, service',
- placeholder: {
- typeAppName: 'please type appName, support for prefix',
- typeDefault: 'please type '
- },
none: 'No Select',
debug: 'Debug',
distribution: 'Distribution',
diff --git a/ui-vue3/src/base/i18n/zh.ts b/ui-vue3/src/base/i18n/zh.ts
index b5968662..70af37dd 100644
--- a/ui-vue3/src/base/i18n/zh.ts
+++ b/ui-vue3/src/base/i18n/zh.ts
@@ -175,9 +175,17 @@ const words: I18nType = {
opened: '开启',
paramRoute: '参数路由'
},
+ servicesDomain: {
+ appName: '应用名',
+ instanceCount: '实例数量',
+ deployClusters: '部署集群',
+ registryClusters: '注册集群'
+ },
service: '服务',
versionGroup: '版本&分组',
avgQPS: 'QPS',
+ provider: '提供者',
+ subset: '分组',
avgRT: 'RT',
requestTotal: '近1min请求总量',
serviceSearch: '服务查询',
@@ -478,9 +486,10 @@ const words: I18nType = {
globalSearchTip: '搜索ip,应用,实例,服务',
placeholder: {
- typeAppName: '请输入应用名,支持前缀搜索',
+ typeAppName: '请输入应用名',
typeDefault: '请输入',
- typeRoutingRules: '搜索路由规则,支持前缀过滤'
+ typeRoutingRules: '搜索路由规则',
+ searchAppNameOrIP: '搜索应用,ip'
},
none: '无',
details: '详情',
diff --git a/ui-vue3/src/layout/header/layout_header.vue
b/ui-vue3/src/layout/header/layout_header.vue
index b3ea6fe5..98c32be4 100644
--- a/ui-vue3/src/layout/header/layout_header.vue
+++ b/ui-vue3/src/layout/header/layout_header.vue
@@ -56,7 +56,7 @@
:options="
meshes.map((x: any) => {
return {
- value: x.name,
+ value: x.id,
label: x.name
}
})
diff --git a/ui-vue3/src/utils/SearchUtil.ts b/ui-vue3/src/utils/SearchUtil.ts
index a9915be5..980d45c6 100644
--- a/ui-vue3/src/utils/SearchUtil.ts
+++ b/ui-vue3/src/utils/SearchUtil.ts
@@ -98,9 +98,10 @@ export class SearchDomain {
this.searchApi(queryParams)
.then((res: any) => {
+
const {
- data: { list, pageInfo }
- } = res
+ data: { list = [], pageInfo }
+ } = res || {}
this.result = handleResult ? handleResult(list) : list
if (!this.noPaged) {
diff --git a/ui-vue3/src/views/resources/applications/index.vue
b/ui-vue3/src/views/resources/applications/index.vue
index 091a2d76..37d97749 100644
--- a/ui-vue3/src/views/resources/applications/index.vue
+++ b/ui-vue3/src/views/resources/applications/index.vue
@@ -30,10 +30,7 @@
</a-tag>
</template>
<template v-else-if="column.dataIndex === 'appName'">
- <span
- class="app-link"
-
@click="router.push(`/resources/applications/detail/${record[column.key]}`)"
- >
+ <span class="app-link"
@click="router.push(`/resources/applications/detail/${record[column.key]}`)">
<b>
<Icon style="margin-bottom: -2px"
icon="material-symbols:attach-file-rounded"></Icon>
{{ text }}
@@ -70,7 +67,7 @@ let columns = [
title: 'appName',
key: 'appName',
dataIndex: 'appName',
- sorter: (a: any, b: any) => sortString(a.appName, b.appName),
+ // sorter: (a: any, b: any) => sortString(a.appName, b.appName),
width: 140,
ellipsis: true
},
@@ -79,9 +76,8 @@ let columns = [
key: 'instanceCount',
dataIndex: 'instanceCount',
width: 100,
- sorter: (a: any, b: any) => sortString(a.instanceCount, b.instanceCount)
+ // sorter: (a: any, b: any) => sortString(a.instanceCount, b.instanceCount)
},
-
{
title: 'applicationDomain.deployClusters',
key: 'deployClusters',
@@ -131,11 +127,13 @@ watch(route, (a, b) => {
<style lang="less" scoped>
.search-table-container {
min-height: 60vh;
+
//max-height: 70vh; //overflow: auto;
.app-link {
padding: 4px 10px 4px 4px;
border-radius: 4px;
color: v-bind('PRIMARY_COLOR');
+
&:hover {
cursor: pointer;
background: rgba(133, 131, 131, 0.13);
diff --git a/ui-vue3/src/views/resources/applications/tabs/instance.vue
b/ui-vue3/src/views/resources/applications/tabs/instance.vue
index cb7e0faa..e976de95 100644
--- a/ui-vue3/src/views/resources/applications/tabs/instance.vue
+++ b/ui-vue3/src/views/resources/applications/tabs/instance.vue
@@ -113,7 +113,7 @@ const columns = [
title: 'instanceDomain.ip',
dataIndex: 'ip',
key: 'ip',
- sorter: true,
+ // sorter: true,
width: 150,
fixed: 'left'
},
@@ -121,56 +121,56 @@ const columns = [
title: 'instanceDomain.name',
dataIndex: 'name',
key: 'name',
- sorter: true,
+ // sorter: true,
width: 180
},
{
title: 'instanceDomain.deployState',
dataIndex: 'deployState',
key: 'deployState',
- sorter: true,
+ // sorter: true,
width: 150
},
{
title: 'instanceDomain.deployCluster',
dataIndex: 'deployClusters',
key: 'deployClusters',
- sorter: true,
+ // sorter: true,
width: 180
},
{
title: 'instanceDomain.registerState',
dataIndex: 'registerState',
key: 'registerState',
- sorter: true,
+ // sorter: true,
width: 150
},
{
title: 'instanceDomain.registerClusters',
dataIndex: 'registerCluster',
key: 'registerCluster',
- sorter: true,
+ // sorter: true,
width: 200
},
{
title: 'instanceDomain.cpu',
dataIndex: 'cpu',
key: 'cpu',
- sorter: true,
+ // sorter: true,
width: 120
},
{
title: 'instanceDomain.memory',
dataIndex: 'memory',
key: 'memory',
- sorter: true,
+ // sorter: true,
width: 120
},
{
title: 'instanceDomain.startTime',
dataIndex: 'startTime',
key: 'startTime',
- sorter: true,
+ // sorter: true,
width: 150
}
// {
diff --git a/ui-vue3/src/views/resources/applications/tabs/service.vue
b/ui-vue3/src/views/resources/applications/tabs/service.vue
index d0c029a7..821c6833 100644
--- a/ui-vue3/src/views/resources/applications/tabs/service.vue
+++ b/ui-vue3/src/views/resources/applications/tabs/service.vue
@@ -36,17 +36,6 @@
<template v-if="column.dataIndex === 'serviceName'">
<a-button type="link" @click="viewDetail(text)">{{ text }}</a-button>
</template>
- <template v-else-if="column.dataIndex === 'versionGroupSelect'">
- <a-select :value="text?.versionGroupValue" :bordered="false"
style="width: 80%">
- <a-select-option
- v-for="(item, index) in text?.versionGroupArr"
- :value="item"
- :key="index"
- >
- {{ item }}
- </a-select-option>
- </a-select>
- </template>
</template>
</search-table>
</div>
@@ -108,37 +97,40 @@ const columns = [
{
title: 'provideServiceName',
key: 'service',
- dataIndex: 'serviceName',
- sorter: true,
- width: '30%'
- },
- {
- title: 'versionGroup',
- key: 'versionGroup',
- dataIndex: 'versionGroupSelect',
- width: '25%'
+ dataIndex: 'serviceName'
+ // sorter: true,
},
{
- title: 'avgQPS',
- key: 'avgQPS',
- dataIndex: 'avgQPS',
- sorter: true,
- width: '15%'
+ title: 'version',
+ key: 'version',
+ dataIndex: 'version'
},
{
- title: 'avgRT',
- key: 'avgRT',
- dataIndex: 'avgRT',
- sorter: true,
- width: '15%'
- },
- {
- title: 'requestTotal',
- key: 'requestTotal',
- dataIndex: 'requestTotal',
- sorter: true,
- width: '15%'
+ title: 'subset',
+ key: 'group',
+ dataIndex: 'group'
}
+ // {
+ // title: 'avgQPS',
+ // key: 'avgQPS',
+ // dataIndex: 'avgQPS',
+ // // sorter: true,
+ // width: '15%'
+ // },
+ // {
+ // title: 'avgRT',
+ // key: 'avgRT',
+ // dataIndex: 'avgRT',
+ // // sorter: true,
+ // width: '15%'
+ // },
+ // {
+ // title: 'requestTotal',
+ // key: 'requestTotal',
+ // dataIndex: 'requestTotal',
+ // // sorter: true,
+ // width: '15%'
+ // }
]
const appName = computed(() => {
@@ -213,6 +205,7 @@ provide(PROVIDE_INJECT_KEY.SEARCH_DOMAIN, searchDomain)
.statistic {
width: 8vw;
}
+
:deep(.ant-card-body) {
padding: 12px;
}
diff --git a/ui-vue3/src/views/resources/instances/index.vue
b/ui-vue3/src/views/resources/instances/index.vue
index 4bb9d7b0..9ed8aed3 100644
--- a/ui-vue3/src/views/resources/instances/index.vue
+++ b/ui-vue3/src/views/resources/instances/index.vue
@@ -19,10 +19,8 @@
<search-table :search-domain="searchDomain">
<template #bodyCell="{ text, record, index, column }">
<template v-if="column.dataIndex === 'ip'">
- <span
- class="app-link"
-
@click="router.push(`/resources/instances/detail/${record.name}/${record[column.key]}`)"
- >
+ <span class="app-link"
+
@click="router.push(`/resources/instances/detail/${record.name}/${record[column.key]}`)">
<b>
<Icon style="margin-bottom: -2px"
icon="material-symbols:attach-file-rounded"></Icon>
{{ text }}
@@ -87,14 +85,14 @@ let columns = [
title: 'instanceDomain.instanceIP',
key: 'ip',
dataIndex: 'ip',
- sorter: (a: any, b: any) => sortString(a.ip, b.ip),
+ // sorter: (a: any, b: any) => sortString(a.ip, b.ip),
width: 200
},
{
title: 'instanceDomain.instanceName',
key: 'name',
dataIndex: 'name',
- sorter: (a: any, b: any) => sortString(a.name, b.name),
+ // sorter: (a: any, b: any) => sortString(a.name, b.name),
width: 140
},
{
@@ -102,49 +100,49 @@ let columns = [
key: 'deployState',
dataIndex: 'deployState',
width: 120,
- sorter: (a: any, b: any) => sortString(a.deployState, b.deployState)
+ // sorter: (a: any, b: any) => sortString(a.deployState, b.deployState)
},
{
title: 'instanceDomain.deployCluster',
key: 'deployCluster',
dataIndex: 'deployCluster',
- sorter: (a: any, b: any) => sortString(a.deployCluster, b.deployCluster),
+ // sorter: (a: any, b: any) => sortString(a.deployCluster,
b.deployCluster),
width: 120
},
{
title: 'instanceDomain.registerState',
key: 'registerState',
dataIndex: 'registerState',
- sorter: (a: any, b: any) => sortString(a.registerState, b.registerState),
+ // sorter: (a: any, b: any) => sortString(a.registerState,
b.registerState),
width: 120
},
{
title: 'instanceDomain.registerCluster',
key: 'registerClusters',
dataIndex: 'registerClusters',
- sorter: (a: any, b: any) => sortString(a.registerClusters,
b.registerClusters),
+ // sorter: (a: any, b: any) => sortString(a.registerClusters,
b.registerClusters),
width: 140
},
{
title: 'instanceDomain.CPU',
key: 'cpu',
dataIndex: 'cpu',
- sorter: (a: any, b: any) => sortString(a.cpu, b.cpu),
+ // sorter: (a: any, b: any) => sortString(a.cpu, b.cpu),
width: 140
},
{
title: 'instanceDomain.memory',
key: 'memory',
dataIndex: 'memory',
- sorter: (a: any, b: any) => sortString(a.memory, b.memory),
+ // sorter: (a: any, b: any) => sortString(a.memory, b.memory),
width: 100
},
{
title: 'instanceDomain.startTime_k8s',
key: 'startTime_k8s',
dataIndex: 'startTime',
- sorter: (a: any, b: any) => sortString(a.startTime, b.startTime),
+ // sorter: (a: any, b: any) => sortString(a.startTime, b.startTime),
width: 200
}
// {
diff --git a/ui-vue3/src/views/resources/services/search.vue
b/ui-vue3/src/views/resources/services/search.vue
index 19dda2d1..96e64832 100644
--- a/ui-vue3/src/views/resources/services/search.vue
+++ b/ui-vue3/src/views/resources/services/search.vue
@@ -17,29 +17,15 @@
<template>
<div class="__container_services_index">
<search-table :search-domain="searchDomain">
- <template #bodyCell="{ column, record, text, index: tableRowIndex }">
+ <template #bodyCell="{ column, record, text }">
<template v-if="column.dataIndex === 'serviceName'">
- {{ record.versionGroup }}
- <span class="service-link" @click="viewDistribution(text,
tableRowIndex)">
+ <span class="service-link" @click="viewDistribution(text,
record.group, record.version)">
<b>
<Icon style="margin-bottom: -2px"
icon="material-symbols:attach-file-rounded"></Icon>
{{ text }}
</b>
</span>
</template>
-
- <template v-else-if="column.dataIndex === 'versionGroupSelect'">
- <a-select :value="text?.versionGroupValue" :bordered="false"
style="width: 80%">
- <a-select-option
- v-for="(item, index) in text?.versionGroupArr"
- :value="item"
- @click="selectedVersionAndGroup(tableRowIndex, index, item)"
- :key="index"
- >
- {{ item }}
- </a-select-option>
- </a-select>
- </template>
</template>
</search-table>
</div>
@@ -66,62 +52,49 @@ const columns = [
title: 'service',
key: 'service',
dataIndex: 'serviceName',
- sorter: true,
- width: '30%',
+ // sorter: true,
ellipsis: true
},
{
- title: 'versionGroup',
- key: 'versionGroup',
- dataIndex: 'versionGroupSelect',
- width: '25%'
- },
- {
- title: 'avgQPS',
- key: 'avgQPS',
- dataIndex: 'avgQPS',
- sorter: true,
- width: '15%'
+ title: 'version',
+ key: 'version',
+ dataIndex: 'version'
},
{
- title: 'avgRT',
- key: 'avgRT',
- dataIndex: 'avgRT',
- sorter: true,
- width: '15%'
+ title: 'subset',
+ key: 'group',
+ dataIndex: 'group'
},
{
- title: 'requestTotal',
- key: 'requestTotal',
- dataIndex: 'requestTotal',
- sorter: true,
- width: '15%'
+ title: 'provider',
+ key: 'provider',
+ dataIndex: 'providerAppName'
}
+ // {
+ // title: 'avgQPS',
+ // key: 'avgQPS',
+ // dataIndex: 'avgQPS',
+ // // sorter: true,
+ // width: '15%'
+ // },
+ // {
+ // title: 'avgRT',
+ // key: 'avgRT',
+ // dataIndex: 'avgRT',
+ // // sorter: true,
+ // width: '15%'
+ // },
+ // {
+ // title: 'requestTotal',
+ // key: 'requestTotal',
+ // dataIndex: 'requestTotal',
+ // // sorter: true,
+ // width: '15%'
+ // }
]
-const tempServiceList = ref([])
-
-const handleResult = (result: any) => {
- return result.map((service: any) => {
- service.versionGroupSelect = {}
- service.versionGroupSelect.versionGroupArr =
service.versionGroups.map((item: any) => {
- return (item.versionGroup =
- (item.version ? 'version: ' + item.version + ', ' : '') +
- (item.group ? 'group: ' + item.group : '') || '无')
- })
- service.versionGroupSelect.versionGroupValue =
service.versionGroupSelect.versionGroupArr[0]
- return service
- })
-}
-
function serviceInfo(params: any, table: any) {
return searchService(params).then(async (res) => {
- tempServiceList.value = res.data?.list
- tempServiceList.value.forEach((service: any) => {
- service.selectedIndex = -1
- })
-
- console.log(tempServiceList.value)
return promQueryList(res, ['avgQPS', 'avgRT', 'requestTotal'], async
(service: any) => {
service.avgQPS = await queryMetrics(
`sum (dubbo_provider_qps_total{interface='${service.serviceName}'}) by
(interface)`
@@ -152,33 +125,17 @@ const searchDomain = reactive(
serviceInfo,
columns,
undefined,
- undefined,
- handleResult
+ undefined
)
)
-searchDomain.onSearch(handleResult)
+searchDomain.onSearch()
searchDomain.tableStyle = {
scrollX: '100',
scrollY: '367px'
}
-const selectedVersionAndGroup = (
- tableRowIndex: number,
- versionAndGroupIndex: number,
- versionAndGroupText: string
-) => {
- if (versionAndGroupText === '无') {
- tempServiceList.value[tableRowIndex].selectedIndex = -1
- } else {
- tempServiceList.value[tableRowIndex].selectedIndex = versionAndGroupIndex
- }
-}
-
-const viewDistribution = (serviceName: string, tableRowIndex: number) => {
- const selectedIndex = tempServiceList.value[tableRowIndex]?.selectedIndex
- const group =
tempServiceList.value[tableRowIndex].versionGroups[selectedIndex]?.group || ''
- const version =
tempServiceList.value[tableRowIndex].versionGroups[selectedIndex]?.version || ''
+const viewDistribution = (serviceName: string, group: string, version: string)
=> {
router.push({ name: 'distribution', params: { pathId: serviceName, group,
version } })
}
diff --git a/ui-vue3/src/views/resources/services/tabs/distribution.vue
b/ui-vue3/src/views/resources/services/tabs/distribution.vue
index 0d10a015..96f3adee 100644
--- a/ui-vue3/src/views/resources/services/tabs/distribution.vue
+++ b/ui-vue3/src/views/resources/services/tabs/distribution.vue
@@ -16,219 +16,113 @@
-->
<template>
<div class="__container_services_tabs_distribution">
- <a-flex vertical>
- <a-flex class="service-filter">
- <a-radio-group v-model:value="type" button-style="solid"
@click="debounceSearch">
- <a-radio-button value="provider">生产者</a-radio-button>
- <a-radio-button value="consumer">消费者</a-radio-button>
- </a-radio-group>
- <a-input-search
- v-model:value="searchValue"
- placeholder="搜索应用,ip,支持前缀搜索"
- class="service-filter-input"
- @search="debounceSearch"
- enter-button
- />
- </a-flex>
- <a-table
- :columns="tableColumns"
- :data-source="tableData"
- :scroll="{ y: '45vh' }"
- :pagination="pagination"
- @change="onTablePageChange"
- >
- <template #bodyCell="{ column, text }">
- <template v-if="column.dataIndex === 'appName'">
- <span class="link"
@click="router.push('/resources/applications/detail/' + text)">
- <b>
- <Icon
- style="margin-bottom: -2px"
- icon="material-symbols:attach-file-rounded"
- ></Icon>
- {{ text }}
- </b>
- </span>
- </template>
+ <search-table :search-domain="searchDomain">
+ <template #bodyCell="{ column, text }">
+ <template v-if="column.dataIndex === 'appName'">
+ <span class="link"
@click="router.push('/resources/applications/detail/' + text)">
+ <b>
+ <Icon style="margin-bottom: -2px"
icon="material-symbols:attach-file-rounded"></Icon>
+ {{ text }}
+ </b>
+ </span>
+ </template>
- <template v-if="column.dataIndex === 'instanceName'">
- <span class="link"
@click="router.push('/resources/instances/detail/' + text)">
- <b>
- <Icon
- style="margin-bottom: -2px"
- icon="material-symbols:attach-file-rounded"
- ></Icon>
- {{ text }}
- </b>
- </span>
- </template>
+ <template v-if="column.dataIndex === 'instanceName'">
+ <span class="link"
@click="router.push('/resources/instances/detail/' + text)">
+ <b>
+ <Icon style="margin-bottom: -2px"
icon="material-symbols:attach-file-rounded"></Icon>
+ {{ text }}
+ </b>
+ </span>
+ </template>
- <template v-if="column.dataIndex === 'timeOut'">
- {{ formattedDate(text) }}
- </template>
- <template v-if="column.dataIndex === 'label'">
- <a-tag :color="PRIMARY_COLOR">{{ text }}</a-tag>
- </template>
+ <template v-if="column.dataIndex === 'timeOut'">
+ {{ formattedDate(text) }}
</template>
- </a-table>
- </a-flex>
+ <template v-if="column.dataIndex === 'label'">
+ <a-tag :color="PRIMARY_COLOR">{{ text }}</a-tag>
+ </template>
+ </template>
+ </search-table>
</div>
</template>
<script setup lang="ts">
-import type { ComponentInternalInstance } from 'vue'
-import { ref, reactive, getCurrentInstance } from 'vue'
+import { ref, reactive, provide } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { getServiceDistribution } from '@/api/service/service'
-import { debounce } from 'lodash'
import { PRIMARY_COLOR } from '@/base/constants'
import { Icon } from '@iconify/vue'
import { formattedDate } from '@/utils/DateUtil'
+import SearchTable from '@/components/SearchTable.vue'
+import { SearchDomain } from '@/utils/SearchUtil'
+import { PROVIDE_INJECT_KEY } from '@/base/enums/ProvideInject'
let __null = PRIMARY_COLOR
const router = useRouter()
const route = useRoute()
-const {
- appContext: {
- config: { globalProperties }
- }
-} = <ComponentInternalInstance>getCurrentInstance()
-
-const searchValue = ref('')
-const versionAndGroupOptions = reactive([
- {
- label: '不指定',
- value: ''
- },
- {
- label: 'version=1.0.0',
- value: 'version=1.0.0'
- },
- {
- label: 'group=group1',
- value: 'group=group1'
- },
- {
- label: 'version=1.0.0,group=group1',
- value: 'version=1.0.0,group=group1'
- }
-])
-const versionAndGroup = ref(versionAndGroupOptions[0].value)
-const type = ref('provider')
const tableColumns = [
{
- title: '应用名',
+ title: 'servicesDomain.appName',
+ key: 'appName',
dataIndex: 'appName',
- width: '20%',
- customCell: (_, index) => {
- const currentAppName = tableData.value[index].appName
- if (index === 0 || tableData.value[index - 1].appName !==
currentAppName) {
- const sameAppCount = tableData.value.filter(
- (item: any) => item.appName === currentAppName
- ).length
- return {
- rowSpan: sameAppCount
- }
- } else {
- return {
- rowSpan: 0
- }
- }
- }
- },
- {
- title: '实例数',
- dataIndex: 'instanceNum',
- width: '15%',
- customRender: ({ record }) => {
- const appName = record.appName
- const instanceNum = tableData.value.filter((item: any) => item.appName
=== appName).length
- return instanceNum ?? 0
- },
- customCell: (_, index) => {
- const currentAppName = tableData.value[index].appName
- if (index === 0 || tableData.value[index - 1].appName !==
currentAppName) {
- const sameAppCount = tableData.value.filter(
- (item: any) => item.appName === currentAppName
- ).length
- return {
- rowSpan: sameAppCount
- }
- } else {
- return {
- rowSpan: 0
- }
- }
- }
- },
- {
- title: '实例名',
- dataIndex: 'instanceName',
- width: '25%',
+ width: 140,
ellipsis: true
},
{
- title: 'RPC端口',
- dataIndex: 'rpcPort',
- width: '8%'
+ title: 'servicesDomain.instanceCount',
+ key: 'instanceCount',
+ dataIndex: 'instanceCount',
+ width: 100
},
{
- title: '超时时间',
- dataIndex: 'timeOut',
- width: '10%'
+ title: 'servicesDomain.deployClusters',
+ key: 'deployClusters',
+ dataIndex: 'deployClusters',
+ width: 120
},
{
- title: '重试次数',
- dataIndex: 'retryNum',
- width: '10%'
+ title: 'servicesDomain.registryClusters',
+ key: 'registryClusters',
+ dataIndex: 'registryClusters',
+ width: 200
}
- // {
- // title: '标签',
- // dataIndex: 'label',
- // width: '15%'
- // }
]
-const tableData = ref([])
-
-const pagination = reactive({
- total: 0,
- pageSize: 10,
- current: 1,
- pageOffset: 0,
- showTotal: (v: any) =>
- globalProperties.$t('searchDomain.total') +
- ': ' +
- v +
- ' ' +
- globalProperties.$t('searchDomain.unit')
-})
-
-const onSearch = async () => {
- let params = {
+function getDistribution(params: any) {
+ return getServiceDistribution({
serviceName: route.params?.pathId,
- side: type.value,
+ side: 'consumer',
version: route.params?.version || '',
group: route.params?.group || '',
- pageOffset: pagination.pageOffset,
- pageSize: pagination.pageSize
- }
- const {
- data: { list, pageInfo }
- } = await getServiceDistribution(params)
- tableData.value = list
- pagination.total = pageInfo.Total
+ ...params
+ })
}
-onSearch()
-const debounceSearch = debounce(onSearch, 300)
-
-const onTablePageChange = (pageInfo: any) => {
- pagination.pageSize = pageInfo.pageSize || 10
- pagination.current = pageInfo.current || 1
- pagination.pageOffset = (pagination.current - 1) * pagination.pageSize
- debounceSearch()
+const searchDomain = reactive(
+ new SearchDomain(
+ [
+ {
+ label: 'placeholder.searchAppNameOrIP',
+ param: 'keywords',
+ style: {
+ width: '300px'
+ }
+ }
+ ],
+ getDistribution,
+ tableColumns
+ )
+)
+
+searchDomain.onSearch()
+searchDomain.tableStyle = {
+ scrollX: '100',
+ scrollY: '367px'
}
+
+provide(PROVIDE_INJECT_KEY.SEARCH_DOMAIN, searchDomain)
</script>
<style lang="less" scoped>
diff --git a/ui-vue3/src/views/traffic/destinationRule/index.vue
b/ui-vue3/src/views/traffic/destinationRule/index.vue
index dc1fb101..8af1baa5 100644
--- a/ui-vue3/src/views/traffic/destinationRule/index.vue
+++ b/ui-vue3/src/views/traffic/destinationRule/index.vue
@@ -29,12 +29,7 @@
<template v-if="column.dataIndex === 'operation'">
<a-button type="link">查看</a-button>
<a-button type="link">修改</a-button>
- <a-popconfirm
- title="确认删除该动态配置?"
- ok-text="Yes"
- cancel-text="No"
- @confirm="confirm"
- >
+ <a-popconfirm title="确认删除该动态配置?" ok-text="Yes" cancel-text="No"
@confirm="confirm">
<a-button type="link">删除</a-button>
</a-popconfirm>
</template>
@@ -56,7 +51,7 @@ let columns = [
title: 'ruleName',
key: 'ruleName',
dataIndex: 'ruleName',
- sorter: (a: any, b: any) => sortString(a.appName, b.appName),
+ // sorter: (a: any, b: any) => sortString(a.appName, b.appName),
width: 140
},
{
@@ -64,7 +59,7 @@ let columns = [
key: 'createTime',
dataIndex: 'createTime',
width: 120,
- sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
+ // sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
},
{
title: 'operation',
@@ -94,7 +89,7 @@ onMounted(() => {
searchDomain.onSearch()
})
-const confirm = () => {}
+const confirm = () => { }
provide(PROVIDE_INJECT_KEY.SEARCH_DOMAIN, searchDomain)
</script>
diff --git a/ui-vue3/src/views/traffic/dynamicConfig/index.vue
b/ui-vue3/src/views/traffic/dynamicConfig/index.vue
index c82dc6dc..c530f92c 100644
--- a/ui-vue3/src/views/traffic/dynamicConfig/index.vue
+++ b/ui-vue3/src/views/traffic/dynamicConfig/index.vue
@@ -22,10 +22,7 @@
</template>
<template #bodyCell="{ text, column, record }">
<template v-if="column.dataIndex === 'ruleName'">
- <span
- class="config-link"
-
@click="router.push(`/traffic/dynamicConfig/formview/${record.ruleName}/0`)"
- >
+ <span class="config-link"
@click="router.push(`/traffic/dynamicConfig/formview/${record.ruleName}/0`)">
<b>
<Icon style="margin-bottom: -2px"
icon="material-symbols:attach-file-rounded"></Icon>
{{ text }}
@@ -39,23 +36,12 @@
{{ text ? '启用' : '禁用' }}
</template>
<template v-if="column.dataIndex === 'operation'">
- <a-button
- type="link"
-
@click="router.push(`/traffic/dynamicConfig/formview/${record.ruleName}/0`)"
- >查看</a-button
- >
- <a-button
- type="link"
-
@click="router.push(`/traffic/dynamicConfig/formview/${record.ruleName}/1`)"
- >
+ <a-button type="link"
+
@click="router.push(`/traffic/dynamicConfig/formview/${record.ruleName}/0`)">查看</a-button>
+ <a-button type="link"
@click="router.push(`/traffic/dynamicConfig/formview/${record.ruleName}/1`)">
修改
</a-button>
- <a-popconfirm
- title="确认删除该动态配置?"
- ok-text="Yes"
- cancel-text="No"
- @confirm="delDynamicConfig(record)"
- >
+ <a-popconfirm title="确认删除该动态配置?" ok-text="Yes" cancel-text="No"
@confirm="delDynamicConfig(record)">
<a-button type="link">删除</a-button>
</a-popconfirm>
</template>
@@ -84,7 +70,7 @@ let columns = [
title: 'ruleName',
key: 'ruleName',
dataIndex: 'ruleName',
- sorter: (a: any, b: any) => sortString(a.appName, b.appName),
+ // sorter: (a: any, b: any) => sortString(a.appName, b.appName),
width: 200,
ellipsis: true
},
@@ -94,14 +80,14 @@ let columns = [
dataIndex: 'ruleGranularity',
render: (text, record) => (record.isService ? '服务' : '应用'),
width: 100,
- sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
+ // sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
},
{
title: 'createTime',
key: 'createTime',
dataIndex: 'createTime',
width: 200,
- sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
+ // sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
},
{
title: 'enabled',
@@ -109,7 +95,7 @@ let columns = [
dataIndex: 'enabled',
render: (text, record) => (record.enabled ? '是' : '否'),
width: 120,
- sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
+ // sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
},
{
title: 'operation',
@@ -152,10 +138,12 @@ provide(PROVIDE_INJECT_KEY.SEARCH_DOMAIN, searchDomain)
<style lang="less" scoped>
.__container_traffic_config_index {
min-height: 60vh;
+
.config-link {
padding: 4px 10px 4px 4px;
border-radius: 4px;
color: v-bind('PRIMARY_COLOR');
+
&:hover {
cursor: pointer;
background: rgba(133, 131, 131, 0.13);
diff --git a/ui-vue3/src/views/traffic/routingRule/index.vue
b/ui-vue3/src/views/traffic/routingRule/index.vue
index 4c72c9f6..d5e62c74 100644
--- a/ui-vue3/src/views/traffic/routingRule/index.vue
+++ b/ui-vue3/src/views/traffic/routingRule/index.vue
@@ -18,8 +18,7 @@
<div class="routing-rule-container">
<search-table :search-domain="searchDomain">
<template #customOperation>
- <a-button type="primary"
@click="router.push(`/traffic/addRoutingRule/addByFormView`)"
- >新增条件路由规则
+ <a-button type="primary"
@click="router.push(`/traffic/addRoutingRule/addByFormView`)">新增条件路由规则
</a-button>
</template>
<template #bodyCell="{ text, column, record }">
@@ -45,18 +44,10 @@
<a-button type="link"
@click="router.push(`formview/${record.ruleName}`)">
查看
</a-button>
- <a-button
- type="link"
-
@click="router.push(`/traffic/updateRoutingRule/updateByFormView/${record.ruleName}`)"
- >
+ <a-button type="link"
@click="router.push(`/traffic/updateRoutingRule/updateByFormView/${record.ruleName}`)">
修改
</a-button>
- <a-popconfirm
- title="确认删除该条件路由规则?"
- ok-text="Yes"
- cancel-text="No"
- @confirm="confirm(record.ruleName)"
- >
+ <a-popconfirm title="确认删除该条件路由规则?" ok-text="Yes" cancel-text="No"
@confirm="confirm(record.ruleName)">
<a-button type="link"> 删除</a-button>
</a-popconfirm>
</template>
@@ -81,7 +72,7 @@ let columns = [
title: 'ruleName',
key: 'ruleName',
dataIndex: 'ruleName',
- sorter: (a: any, b: any) => sortString(a.appName, b.appName),
+ // sorter: (a: any, b: any) => sortString(a.appName, b.appName),
width: 140
},
{
@@ -90,21 +81,21 @@ let columns = [
dataIndex: 'ruleGranularity',
render: (text, record) => (record.isService ? '服务' : '应用'),
width: 100,
- sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
+ // sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
},
{
title: 'createTime',
key: 'createTime',
dataIndex: 'createTime',
width: 120,
- sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
+ // sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
},
{
title: 'enabled',
key: 'enabled',
dataIndex: 'enabled',
width: 120,
- sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
+ // sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
},
{
title: 'operation',
@@ -157,6 +148,7 @@ provide(PROVIDE_INJECT_KEY.SEARCH_DOMAIN, searchDomain)
<style lang="less" scoped>
.routing-rule-container {
height: 100%;
+
.search-table-container {
height: 100%;
//min-height: 60vh;
diff --git a/ui-vue3/src/views/traffic/tagRule/index.vue
b/ui-vue3/src/views/traffic/tagRule/index.vue
index fcbe1a56..7e72a337 100644
--- a/ui-vue3/src/views/traffic/tagRule/index.vue
+++ b/ui-vue3/src/views/traffic/tagRule/index.vue
@@ -24,10 +24,7 @@
</template>
<template #bodyCell="{ text, column, record }">
<template v-if="column.dataIndex === 'ruleName'">
- <span
- class="rule-link"
-
@click="router.push(`/traffic/tagRule/formview/${record[column.key]}`)"
- >
+ <span class="rule-link"
@click="router.push(`/traffic/tagRule/formview/${record[column.key]}`)">
<b>
<Icon style="margin-bottom: -2px"
icon="material-symbols:attach-file-rounded"></Icon>
{{ text }}
@@ -44,18 +41,10 @@
<a-button type="link"
@click="router.push(`formview/${record.ruleName}`)">
查看
</a-button>
- <a-button
-
@click="router.push(`/traffic/updateTagRule/updateByFormView/${record.ruleName}`)"
- type="link"
- >
+ <a-button
@click="router.push(`/traffic/updateTagRule/updateByFormView/${record.ruleName}`)"
type="link">
修改
</a-button>
- <a-popconfirm
- title="确认删除该标签路由规则?"
- ok-text="Yes"
- cancel-text="No"
- @confirm="confirm(record.ruleName)"
- >
+ <a-popconfirm title="确认删除该标签路由规则?" ok-text="Yes" cancel-text="No"
@confirm="confirm(record.ruleName)">
<a-button type="link"> 删除 </a-button>
</a-popconfirm>
</template>
@@ -86,7 +75,7 @@ let columns = [
title: 'ruleName',
key: 'ruleName',
dataIndex: 'ruleName',
- sorter: (a: any, b: any) => sortString(a.appName, b.appName),
+ // sorter: (a: any, b: any) => sortString(a.appName, b.appName),
width: 140
},
{
@@ -94,7 +83,7 @@ let columns = [
key: 'createTime',
dataIndex: 'createTime',
width: 120,
- sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
+ // sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
},
{
title: 'enable',
@@ -102,7 +91,7 @@ let columns = [
dataIndex: 'enabled',
// render: (text, record) => (record.enable ? '是' : '否'),
width: 120,
- sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
+ // sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
},
{
title: 'operation',
@@ -153,6 +142,7 @@ provide(PROVIDE_INJECT_KEY.SEARCH_DOMAIN, searchDomain)
<style lang="less" scoped>
.tag-rule-container {
height: 100%;
+
.search-table-container {
min-height: 60vh;
//max-height: 70vh; //overflow: auto;
diff --git a/ui-vue3/src/views/traffic/virtualService/index.vue
b/ui-vue3/src/views/traffic/virtualService/index.vue
index d75a4fc0..f8e5b264 100644
--- a/ui-vue3/src/views/traffic/virtualService/index.vue
+++ b/ui-vue3/src/views/traffic/virtualService/index.vue
@@ -24,17 +24,12 @@
<template v-if="column.dataIndex === 'ruleName'">
<a-button type="link"
@click="router.replace(`formview/${record[column.key]}`)">{{
text
- }}</a-button>
+ }}</a-button>
</template>
<template v-if="column.dataIndex === 'operation'">
<a-button type="link">查看</a-button>
<a-button type="link">修改</a-button>
- <a-popconfirm
- title="确认删除该动态配置?"
- ok-text="Yes"
- cancel-text="No"
- @confirm="confirm"
- >
+ <a-popconfirm title="确认删除该动态配置?" ok-text="Yes" cancel-text="No"
@confirm="confirm">
<a-button type="link">删除</a-button>
</a-popconfirm>
</template>
@@ -56,7 +51,7 @@ let columns = [
title: 'ruleName',
key: 'ruleName',
dataIndex: 'ruleName',
- sorter: (a: any, b: any) => sortString(a.appName, b.appName),
+ // sorter: (a: any, b: any) => sortString(a.appName, b.appName),
width: 140
},
{
@@ -64,14 +59,14 @@ let columns = [
key: 'createTime',
dataIndex: 'createTime',
width: 120,
- sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
+ // sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
},
{
title: 'lastModifiedTime',
key: 'lastModifiedTime',
dataIndex: 'lastModifiedTime',
width: 120,
- sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
+ // sorter: (a: any, b: any) => sortString(a.instanceNum, b.instanceNum)
},
{
title: 'operation',
@@ -101,7 +96,7 @@ onMounted(() => {
searchDomain.onSearch()
})
-const confirm = () => {}
+const confirm = () => { }
provide(PROVIDE_INJECT_KEY.SEARCH_DOMAIN, searchDomain)
</script>