[KYUUBI #3646][UI] Init Session Statistic Page
### _Why are the changes needed?_ Init Session Statistic Page Close #3646 ### _How was this patch tested?_ - [ ] Add some test cases that check the changes thoroughly including negative and positive cases if possible - [ ] Add screenshots for manual tests if appropriate - [ ] [Run test](https://kyuubi.readthedocs.io/en/master/develop_tools/testing.html#running-tests) locally before make a pull request  Closes #4564 from zwangsheng/KYUUBI_3646. Closes #3646 cbe0842ba [zwangsheng] [KYUUBI #3646] fix style 930cbb12a [zwangsheng] [KYUUBI #3646] bracket same line d2ab1d5fd [zwangsheng] [KYUUBI #3646] Fix i18n about status 7f059e2df [zwangsheng] [KYUUBI #3646] Fix i18n about status 452c3ee5a [zwangsheng] [KYUUBI #3646] Remove unused style class 8967652bc [zwangsheng] [KYUUBI #3646] Add date fns license 70f2472c2 [zwangsheng] [KYUUBI #3646] install date-fns 8a3e845ff [zwangsheng] [KYUUBI #3646][UI] Init Session Statistic Page Lead-authored-by: He Zhao <hezhao2@cisco.com> Co-authored-by: zwangsheng <2213335496@qq.com> Signed-off-by: Cheng Pan <chengpan@apache.org>
This commit is contained in:
parent
6f803c0015
commit
0d5eaa2d0b
@ -456,6 +456,8 @@ is auto-generated by `pnpm licenses list --prod`.
|
||||
├────────────────────────────────────┼──────────────┤
|
||||
│ csstype │ MIT │
|
||||
├────────────────────────────────────┼──────────────┤
|
||||
│ date-fns │ MIT │
|
||||
├────────────────────────────────────┼──────────────┤
|
||||
│ dayjs │ MIT │
|
||||
├────────────────────────────────────┼──────────────┤
|
||||
│ delayed-stream │ MIT │
|
||||
|
||||
@ -69,6 +69,9 @@
|
||||
"exports": "never",
|
||||
"functions": "never"
|
||||
}],
|
||||
"prettier/prettier": ["error", {
|
||||
"bracketSameLine": true
|
||||
}],
|
||||
"vue/multi-word-component-names": "off",
|
||||
"vue/component-definition-name-casing": "off",
|
||||
"vue/require-valid-default-prop": "off",
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.0.9",
|
||||
"axios": "^0.27.2",
|
||||
"date-fns": "^2.29.3",
|
||||
"element-plus": "^2.2.12",
|
||||
"pinia": "^2.0.18",
|
||||
"pinia-plugin-persistedstate": "^2.1.1",
|
||||
|
||||
@ -12,6 +12,7 @@ specifiers:
|
||||
'@vue/eslint-config-typescript': ^11.0.0
|
||||
'@vue/test-utils': ^2.0.2
|
||||
axios: ^0.27.2
|
||||
date-fns: ^2.29.3
|
||||
element-plus: ^2.2.12
|
||||
eslint: ^8.21.0
|
||||
eslint-plugin-prettier: ^4.2.1
|
||||
@ -32,6 +33,7 @@ specifiers:
|
||||
dependencies:
|
||||
'@element-plus/icons-vue': 2.0.9_vue@3.2.37
|
||||
axios: 0.27.2
|
||||
date-fns: 2.29.3
|
||||
element-plus: 2.2.13_vue@3.2.37
|
||||
pinia: 2.0.18_j6bzmzd4ujpabbp5objtwxyjp4
|
||||
pinia-plugin-persistedstate: 2.1.1_pinia@2.0.18
|
||||
@ -907,6 +909,11 @@ packages:
|
||||
whatwg-url: 11.0.0
|
||||
dev: true
|
||||
|
||||
/date-fns/2.29.3:
|
||||
resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==}
|
||||
engines: {node: '>=0.11'}
|
||||
dev: false
|
||||
|
||||
/dayjs/1.11.5:
|
||||
resolution: {integrity: sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA==}
|
||||
dev: false
|
||||
|
||||
32
kyuubi-server/web-ui/src/api/session/index.ts
Normal file
32
kyuubi-server/web-ui/src/api/session/index.ts
Normal 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.
|
||||
*/
|
||||
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getAllSessions() {
|
||||
return request({
|
||||
url: 'api/v1/sessions',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteSession(sessionId: string) {
|
||||
return request({
|
||||
url: `api/v1/sessions/${sessionId}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
@ -16,5 +16,16 @@
|
||||
*/
|
||||
|
||||
export default {
|
||||
test: 'test'
|
||||
test: 'test',
|
||||
user: 'User',
|
||||
client_ip: 'Client IP',
|
||||
kyuubi_instance: 'Kyuubi Instance',
|
||||
session_id: 'Session ID',
|
||||
create_time: 'Create Time',
|
||||
operation: 'Operation',
|
||||
delete_confirm: 'Delete Confirm',
|
||||
message: {
|
||||
delete_succeeded: 'Delete {name} Succeeded',
|
||||
delete_failed: 'Delete {name} Failed'
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,5 +16,16 @@
|
||||
*/
|
||||
|
||||
export default {
|
||||
test: '测试'
|
||||
test: '测试',
|
||||
user: '用户',
|
||||
client_ip: '客户端地址',
|
||||
kyuubi_instance: '服务端地址',
|
||||
session_id: 'Session ID',
|
||||
create_time: '创建时间',
|
||||
operation: '操作',
|
||||
delete_confirm: '确认删除',
|
||||
message: {
|
||||
delete_succeeded: '删除 {name} 成功',
|
||||
delete_failed: '删除 {name} 失败'
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import overviewRoutes from './overview'
|
||||
import workloadRoutes from './workload'
|
||||
import operationRoutes from './operation'
|
||||
import contactRoutes from './contact'
|
||||
import sessionRoutes from './session'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
@ -36,6 +37,7 @@ const routes = [
|
||||
redirect: 'overview',
|
||||
children: [
|
||||
...overviewRoutes,
|
||||
...sessionRoutes,
|
||||
...workloadRoutes,
|
||||
...operationRoutes,
|
||||
...contactRoutes
|
||||
|
||||
26
kyuubi-server/web-ui/src/router/session/index.ts
Normal file
26
kyuubi-server/web-ui/src/router/session/index.ts
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/session/session-statistics',
|
||||
name: 'session-statistics',
|
||||
component: () => import('@/views/session/session-statistics/index.vue')
|
||||
}
|
||||
]
|
||||
|
||||
export default routes
|
||||
78
kyuubi-server/web-ui/src/views/common/use-table.ts
Normal file
78
kyuubi-server/web-ui/src/views/common/use-table.ts
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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 { ref, Ref } from 'vue'
|
||||
|
||||
export function useTable() {
|
||||
const list: Ref<any[]> = ref([])
|
||||
const tableData: Ref<any[]> = ref([])
|
||||
const loading = ref(false)
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const totalPage = ref(1)
|
||||
|
||||
const handleSizeChange = (val: number) => {
|
||||
if (
|
||||
currentPage.value === 1 ||
|
||||
(currentPage.value > 1 && totalPage.value > (currentPage.value - 1) * val)
|
||||
) {
|
||||
loading.value = true
|
||||
setTimeout(() => {
|
||||
setTableData()
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
|
||||
const handleCurrentChange = () => {
|
||||
loading.value = true
|
||||
setTimeout(() => {
|
||||
setTableData()
|
||||
}, 200)
|
||||
}
|
||||
|
||||
const setTableData = () => {
|
||||
tableData.value = [...list.value].splice(
|
||||
(currentPage.value - 1) * pageSize.value,
|
||||
pageSize.value
|
||||
)
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
const getList = (func: Function, data?: any) => {
|
||||
loading.value = true
|
||||
func(data)
|
||||
.then((res: any[]) => (list.value = res || []))
|
||||
.catch(() => (list.value = []))
|
||||
.finally(() => {
|
||||
currentPage.value = 1
|
||||
pageSize.value = 10
|
||||
totalPage.value = list.value.length
|
||||
setTableData()
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
tableData,
|
||||
loading,
|
||||
currentPage,
|
||||
pageSize,
|
||||
totalPage,
|
||||
handleSizeChange,
|
||||
handleCurrentChange,
|
||||
getList
|
||||
}
|
||||
}
|
||||
@ -21,6 +21,16 @@ export const MENUS = [
|
||||
icon: 'Odometer',
|
||||
router: '/overview'
|
||||
},
|
||||
{
|
||||
label: 'Session Management',
|
||||
icon: 'List',
|
||||
children: [
|
||||
{
|
||||
label: 'Session Statistics',
|
||||
router: '/session/session-statistics'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Workload',
|
||||
icon: 'List',
|
||||
|
||||
@ -0,0 +1,104 @@
|
||||
<!--
|
||||
* 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>
|
||||
<!-- TODO we need search here -->
|
||||
<el-card>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="tableData"
|
||||
max-height="500px"
|
||||
style="width: 100%">
|
||||
<el-table-column prop="user" :label="$t('user')" width="160px" />
|
||||
<!-- TODO need jump to engine page -->
|
||||
<el-table-column prop="engineId" :label="$t('engine_ip')" width="160px" />
|
||||
<el-table-column prop="ipAddr" :label="$t('client_ip')" width="160px" />
|
||||
<el-table-column
|
||||
prop="kyuubiInstance"
|
||||
:label="$t('kyuubi_instance')"
|
||||
width="180px" />
|
||||
<!-- TODO need jump to session page -->
|
||||
<el-table-column
|
||||
prop="identifier"
|
||||
:label="$t('session_id')"
|
||||
width="300px" />
|
||||
<el-table-column :label="$t('create_time')" width="200">
|
||||
<template #default="scope">
|
||||
{{
|
||||
scope.row.createTime != null && scope.row.createTime > -1
|
||||
? format(scope.row.createTime, 'yyyy-MM-dd HH:mm:ss')
|
||||
: '-'
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column fixed="right" :label="$t('operation')">
|
||||
<template #default="scope">
|
||||
<el-popconfirm
|
||||
:title="$t('delete_confirm')"
|
||||
@confirm="handleDeleteSession(scope.row.identifier)">
|
||||
<template #reference>
|
||||
<span>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('delete')"
|
||||
placement="top">
|
||||
<template #default>
|
||||
<el-button type="danger" icon="Delete" circle />
|
||||
</template>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { format } from 'date-fns'
|
||||
import { getAllSessions, deleteSession } from '@/api/session'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useTable } from '@/views/common/use-table'
|
||||
const { t } = useI18n()
|
||||
const { tableData, loading, getList: _getList } = useTable()
|
||||
const handleDeleteSession = (sessionId: string) => {
|
||||
deleteSession(sessionId)
|
||||
.then(() => {
|
||||
// need add delete success or failed logic after api support
|
||||
ElMessage({
|
||||
message: t('message.delete_succeeded', { name: 'session' }),
|
||||
type: 'success'
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
message: t('message.delete_failed', { name: 'session' }),
|
||||
type: 'error'
|
||||
})
|
||||
})
|
||||
.finally(() => {
|
||||
getList()
|
||||
})
|
||||
}
|
||||
const getList = () => {
|
||||
_getList(getAllSessions)
|
||||
}
|
||||
getList()
|
||||
</script>
|
||||
Loading…
Reference in New Issue
Block a user