mirror of
https://github.com/jumpserver/lina.git
synced 2025-09-03 07:54:45 +00:00
perf: 基本完成应用正好改造
This commit is contained in:
@@ -15,7 +15,7 @@ import { connectivityMeta } from './const'
|
|||||||
import { openTaskPage } from '@/utils/jms'
|
import { openTaskPage } from '@/utils/jms'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Detail',
|
name: 'AccountListTable',
|
||||||
components: {
|
components: {
|
||||||
ListTable,
|
ListTable,
|
||||||
UpdateSecretInfo,
|
UpdateSecretInfo,
|
||||||
|
81
src/components/AppAccountListTable/ShowSecretInfo.vue
Normal file
81
src/components/AppAccountListTable/ShowSecretInfo.vue
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<MFAVerifyDialog
|
||||||
|
@MFAVerifyDone="getAuthInfo"
|
||||||
|
@MFAVerifyCancel="exit"
|
||||||
|
/>
|
||||||
|
<Dialog
|
||||||
|
:title="dialogTitle"
|
||||||
|
:show-confirm="false"
|
||||||
|
:show-cancel="false"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
:width="'50'"
|
||||||
|
:visible.sync="showAuthInfo"
|
||||||
|
v-bind="$attrs"
|
||||||
|
v-on="$listeners"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<el-form label-position="right" label-width="80px" :model="authInfo">
|
||||||
|
<el-form-item :label="this.$t('applications.appName')">
|
||||||
|
<el-input v-model="account['app_name']" readonly />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="this.$t('assets.Username')">
|
||||||
|
<el-input v-model="account['username']" readonly />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="this.$t('assets.Password')">
|
||||||
|
<el-input v-model="authInfo.password" type="password" show-password />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Dialog from '@/components/Dialog'
|
||||||
|
import MFAVerifyDialog from '@/components/MFAVerifyDialog'
|
||||||
|
export default {
|
||||||
|
name: 'ShowSecretInfo',
|
||||||
|
components: {
|
||||||
|
Dialog,
|
||||||
|
MFAVerifyDialog
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
account: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogTitle: this.$t('common.ViewSecret'),
|
||||||
|
authInfo: {},
|
||||||
|
showAuthInfo: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getAuthInfo()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getAuthInfo() {
|
||||||
|
console.log(this.account)
|
||||||
|
const url = `/api/v1/applications/account-secrets/${this.account.uid}/`
|
||||||
|
this.$axios.get(url, { disableFlashErrorMsg: true }).then(resp => {
|
||||||
|
this.authInfo = resp
|
||||||
|
this.showAuthInfo = true
|
||||||
|
})
|
||||||
|
},
|
||||||
|
exit() {
|
||||||
|
this.$emit('update:visible', false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
31
src/components/AppAccountListTable/const.js
Normal file
31
src/components/AppAccountListTable/const.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { ChoicesFormatter } from '@/components/TableFormatters'
|
||||||
|
import { toSafeLocalDateStr } from '@/utils/common'
|
||||||
|
import i18n from '@/i18n/i18n'
|
||||||
|
|
||||||
|
export const connectivityMeta = {
|
||||||
|
label: i18n.t('assets.Reachable'),
|
||||||
|
formatter: ChoicesFormatter,
|
||||||
|
formatterArgs: {
|
||||||
|
iconChoices: {
|
||||||
|
ok: 'fa-check text-primary',
|
||||||
|
failed: 'fa-times text-danger',
|
||||||
|
unknown: 'fa-circle text-warning'
|
||||||
|
},
|
||||||
|
hasTips: true,
|
||||||
|
getTips: ({ row, cellValue }) => {
|
||||||
|
const mapper = {
|
||||||
|
'ok': i18n.tc('assets.Reachable'),
|
||||||
|
'failed': i18n.tc('assets.Unreachable'),
|
||||||
|
'unknown': i18n.tc('assets.Unknown')
|
||||||
|
}
|
||||||
|
let tips = mapper[cellValue]
|
||||||
|
if (row['date_verified']) {
|
||||||
|
const datetime = toSafeLocalDateStr(row['date_verified'])
|
||||||
|
tips += '<br> ' + datetime
|
||||||
|
}
|
||||||
|
return tips
|
||||||
|
}
|
||||||
|
},
|
||||||
|
width: '90px',
|
||||||
|
align: 'center'
|
||||||
|
}
|
167
src/components/AppAccountListTable/index.vue
Normal file
167
src/components/AppAccountListTable/index.vue
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<ListTable ref="ListTable" :table-config="tableConfig" :header-actions="headerActions" />
|
||||||
|
<ShowSecretInfo v-if="showViewSecretDialog" :visible.sync="showViewSecretDialog" :account="account" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ListTable from '@/components/ListTable/index'
|
||||||
|
import { ActionsFormatter, DetailFormatter } from '@/components/TableFormatters'
|
||||||
|
import ShowSecretInfo from './ShowSecretInfo'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Detail',
|
||||||
|
components: {
|
||||||
|
ListTable,
|
||||||
|
ShowSecretInfo
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
url: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
exportUrl: {
|
||||||
|
type: String,
|
||||||
|
default() {
|
||||||
|
return this.url.replace('/applications/accounts/', '/applications/account-secrets/')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hasLeftActions: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
otherActions: {
|
||||||
|
type: Array,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
hasClone: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
showViewSecretDialog: false,
|
||||||
|
showUpdateSecretDialog: false,
|
||||||
|
account: {},
|
||||||
|
tableConfig: {
|
||||||
|
url: this.url,
|
||||||
|
columns: [
|
||||||
|
'app_name', 'username', 'app_category_display',
|
||||||
|
'app_type_display', 'systemuser', 'actions'
|
||||||
|
],
|
||||||
|
columnsMeta: {
|
||||||
|
app_name: {
|
||||||
|
showOverflowTooltip: true,
|
||||||
|
formatter: DetailFormatter,
|
||||||
|
formatterArgs: {
|
||||||
|
getRoute({ row }) {
|
||||||
|
switch (row['app_category']) {
|
||||||
|
case 'remote_app':
|
||||||
|
return {
|
||||||
|
name: 'RemoteAppDetail',
|
||||||
|
params: { id: row.app }
|
||||||
|
}
|
||||||
|
case 'db':
|
||||||
|
return {
|
||||||
|
name: 'DatabaseAppDetail',
|
||||||
|
params: { id: row.app }
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
name: 'KubernetesAppDetail',
|
||||||
|
params: { id: row.app }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
username: {
|
||||||
|
showOverflowTooltip: true
|
||||||
|
},
|
||||||
|
systemuser: {
|
||||||
|
showOverflowTooltip: true,
|
||||||
|
formatter: DetailFormatter,
|
||||||
|
formatterArgs: {
|
||||||
|
getTitle({ row }) {
|
||||||
|
return row.systemuser_display
|
||||||
|
},
|
||||||
|
getRoute({ row }) {
|
||||||
|
return {
|
||||||
|
name: 'SystemUserDetail',
|
||||||
|
params: { id: row.systemuser }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
formatter: ActionsFormatter,
|
||||||
|
formatterArgs: {
|
||||||
|
hasUpdate: false, // can set function(row, value)
|
||||||
|
hasDelete: false, // can set function(row, value)
|
||||||
|
hasClone: this.hasClone,
|
||||||
|
moreActionsTitle: this.$t('common.More'),
|
||||||
|
extraActions: [
|
||||||
|
{
|
||||||
|
name: 'View',
|
||||||
|
title: this.$t('common.View'),
|
||||||
|
type: 'primary',
|
||||||
|
callback: function({ row }) {
|
||||||
|
this.account = row
|
||||||
|
this.showViewSecretDialog = true
|
||||||
|
}.bind(this)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Update',
|
||||||
|
title: this.$t('common.Update'),
|
||||||
|
can: !this.$store.getters.currentOrgIsRoot,
|
||||||
|
callback: function({ row }) {
|
||||||
|
this.$message.success(this.$tc('applications.updateAccountMsg'))
|
||||||
|
}.bind(this)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
headerActions: {
|
||||||
|
hasLeftActions: this.hasLeftActions,
|
||||||
|
hasMoreActions: false,
|
||||||
|
hasImport: this.hasImport,
|
||||||
|
hasExport: this.hasExport,
|
||||||
|
exportOptions: {
|
||||||
|
url: this.exportUrl,
|
||||||
|
mfaVerifyRequired: true
|
||||||
|
},
|
||||||
|
searchConfig: {
|
||||||
|
exclude: ['systemuser', 'asset']
|
||||||
|
},
|
||||||
|
hasSearch: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
url(iNew) {
|
||||||
|
this.$set(this.tableConfig, 'url', iNew)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.otherActions) {
|
||||||
|
const actionColumn = this.tableConfig.columns[this.tableConfig.columns.length - 1]
|
||||||
|
for (const item of this.otherActions) {
|
||||||
|
actionColumn.formatterArgs.extraActions.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onUpdateAuthDone(account) {
|
||||||
|
Object.assign(this.account, account)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang='less' scoped>
|
||||||
|
|
||||||
|
</style>
|
@@ -29,6 +29,7 @@
|
|||||||
},
|
},
|
||||||
"applications": {
|
"applications": {
|
||||||
"": "",
|
"": "",
|
||||||
|
"updateAccountMsg": "请更新系统用户的账号信息",
|
||||||
"RemoteApp": "远程应用",
|
"RemoteApp": "远程应用",
|
||||||
"Database": "数据库",
|
"Database": "数据库",
|
||||||
"Cloud": "云",
|
"Cloud": "云",
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
},
|
},
|
||||||
"applications": {
|
"applications": {
|
||||||
"": "",
|
"": "",
|
||||||
|
"updateAccountMsg": "Please update system user account info",
|
||||||
"RemoteApp": "Remote app",
|
"RemoteApp": "Remote app",
|
||||||
"Database": "Database",
|
"Database": "Database",
|
||||||
"Cloud": "Cloud",
|
"Cloud": "Cloud",
|
||||||
|
@@ -38,57 +38,73 @@ export default [
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'database-apps',
|
path: 'databases',
|
||||||
name: 'DatabaseAppList',
|
name: 'DatabaseAppList',
|
||||||
component: () => import('@/views/applications/DatabaseApp/DatabaseAppList'),
|
component: empty,
|
||||||
meta: { title: i18n.t('route.DatabaseApp') }
|
meta: { title: i18n.t('route.DatabaseApp') },
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
name: 'DatabaseAppList',
|
||||||
|
component: () => import('@/views/applications/DatabaseApp/DatabaseAppList'),
|
||||||
|
meta: { title: i18n.t('route.DatabaseApp') }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'create',
|
||||||
|
name: 'DatabaseAppCreate',
|
||||||
|
component: () => import('@/views/applications/DatabaseApp/DatabaseAppCreateUpdate'),
|
||||||
|
meta: { title: i18n.t('route.DatabaseAppCreate'), activeMenu: '/applications/databases', action: 'create' },
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':id/update',
|
||||||
|
name: 'DatabaseAppUpdate',
|
||||||
|
component: () => import('@/views/applications/DatabaseApp/DatabaseAppCreateUpdate'),
|
||||||
|
meta: { title: i18n.t('route.DatabaseAppUpdate'), activeMenu: '/applications/databases', action: 'update' },
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':id',
|
||||||
|
name: 'DatabaseAppDetail',
|
||||||
|
component: () => import('@/views/applications/DatabaseApp/DatabaseAppDetail/index'),
|
||||||
|
meta: { title: i18n.t('route.DatabaseAppDetail'), activeMenu: '/applications/databases' },
|
||||||
|
hidden: true
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'database-apps/create',
|
path: 'kubernetes',
|
||||||
name: 'DatabaseAppCreate',
|
|
||||||
component: () => import('@/views/applications/DatabaseApp/DatabaseAppCreateUpdate'),
|
|
||||||
meta: { title: i18n.t('route.DatabaseAppCreate'), activeMenu: '/applications/database-apps', action: 'create' },
|
|
||||||
hidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'database-apps/:id/update',
|
|
||||||
name: 'DatabaseAppUpdate',
|
|
||||||
component: () => import('@/views/applications/DatabaseApp/DatabaseAppCreateUpdate'),
|
|
||||||
meta: { title: i18n.t('route.DatabaseAppUpdate'), activeMenu: '/applications/database-apps', action: 'update' },
|
|
||||||
hidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'database-apps/:id',
|
|
||||||
name: 'DatabaseAppDetail',
|
|
||||||
component: () => import('@/views/applications/DatabaseApp/DatabaseAppDetail/index'),
|
|
||||||
meta: { title: i18n.t('route.DatabaseAppDetail'), activeMenu: '/applications/database-apps' },
|
|
||||||
hidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'kubernetes-apps',
|
|
||||||
name: 'KubernetesAppList',
|
name: 'KubernetesAppList',
|
||||||
component: () => import('@/views/applications/KubernetesApp/KubernetesAppList'),
|
component: empty,
|
||||||
meta: { title: i18n.t('route.KubernetesApp') }
|
meta: { title: i18n.t('route.KubernetesApp') },
|
||||||
},
|
children: [
|
||||||
{
|
{
|
||||||
path: 'kubernetes-apps/create',
|
path: '',
|
||||||
name: 'KubernetesAppCreate',
|
name: 'KubernetesAppList',
|
||||||
component: () => import('@/views/applications/KubernetesApp/KubernetesAppCreateUpdate'),
|
component: () => import('@/views/applications/KubernetesApp/KubernetesAppList'),
|
||||||
meta: { title: i18n.t('route.KubernetesAppCreate'), activeMenu: '/applications/kubernetes-apps', action: 'create' },
|
meta: { title: i18n.t('route.KubernetesApp') }
|
||||||
hidden: true
|
},
|
||||||
},
|
{
|
||||||
{
|
path: 'create',
|
||||||
path: 'kubernetes-apps/:id/update',
|
name: 'KubernetesAppCreate',
|
||||||
name: 'KubernetesAppUpdate',
|
component: () => import('@/views/applications/KubernetesApp/KubernetesAppCreateUpdate'),
|
||||||
component: () => import('@/views/applications/KubernetesApp/KubernetesAppCreateUpdate'),
|
meta: { title: i18n.t('route.KubernetesAppCreate'), activeMenu: '/applications/kubernetes', action: 'create' },
|
||||||
meta: { title: i18n.t('route.KubernetesAppUpdate'), activeMenu: '/applications/kubernetes-apps', action: 'update' },
|
hidden: true
|
||||||
hidden: true
|
},
|
||||||
},
|
{
|
||||||
{
|
path: ':id/update',
|
||||||
path: 'kubernetes-apps/:id',
|
name: 'KubernetesAppUpdate',
|
||||||
name: 'KubernetesAppDetail',
|
component: () => import('@/views/applications/KubernetesApp/KubernetesAppCreateUpdate'),
|
||||||
component: () => import('@/views/applications/KubernetesApp/KubernetesAppDetail/index'),
|
meta: { title: i18n.t('route.KubernetesAppUpdate'), activeMenu: '/applications/kubernetes', action: 'update' },
|
||||||
meta: { title: i18n.t('route.KubernetesAppDetail'), activeMenu: '/applications/kubernetes-apps' },
|
hidden: true
|
||||||
hidden: true
|
},
|
||||||
|
{
|
||||||
|
path: ':id',
|
||||||
|
name: 'KubernetesAppDetail',
|
||||||
|
component: () => import('@/views/applications/KubernetesApp/KubernetesAppDetail/index'),
|
||||||
|
meta: { title: i18n.t('route.KubernetesAppDetail'), activeMenu: '/applications/kubernetes' },
|
||||||
|
hidden: true
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@@ -1,20 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<GenericTreeListPage ref="TreeTablePage" :tree-setting="treeSetting">
|
<GenericTreeListPage ref="TreeTablePage" :tree-setting="treeSetting">
|
||||||
<template #table>
|
<template #table>
|
||||||
<AccountListTable ref="table" :url="accountsUrl" />
|
<AppAccountListTable ref="table" :url="accountsUrl" />
|
||||||
</template>
|
</template>
|
||||||
</GenericTreeListPage>
|
</GenericTreeListPage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import GenericTreeListPage from '@/layout/components/GenericTreeListPage'
|
import GenericTreeListPage from '@/layout/components/GenericTreeListPage'
|
||||||
import AccountListTable from '@/components/AccountListTable'
|
import AppAccountListTable from '@/components/AppAccountListTable'
|
||||||
import { setUrlParam } from '@/utils/common'
|
import { setUrlParam } from '@/utils/common'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AssetAccountList',
|
name: 'AssetAccountList',
|
||||||
components: {
|
components: {
|
||||||
GenericTreeListPage, AccountListTable
|
GenericTreeListPage, AppAccountListTable
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const vm = this
|
const vm = this
|
||||||
@@ -22,25 +22,27 @@ export default {
|
|||||||
isInit: true,
|
isInit: true,
|
||||||
clickedRow: null,
|
clickedRow: null,
|
||||||
iShowTree: true,
|
iShowTree: true,
|
||||||
accountsUrl: '/api/v1/assets/accounts/',
|
accountsUrl: '/api/v1/applications/accounts/',
|
||||||
treeSetting: {
|
treeSetting: {
|
||||||
async: false,
|
async: false,
|
||||||
showMenu: false,
|
showMenu: false,
|
||||||
showRefresh: true,
|
showRefresh: true,
|
||||||
showAssets: false,
|
showAssets: false,
|
||||||
url: '/api/v1/assets/accounts/',
|
treeUrl: '/api/v1/applications/applications/tree/?show_count=0',
|
||||||
treeUrl: '/api/v1/applications/applications/tree/',
|
|
||||||
callback: {
|
callback: {
|
||||||
onSelected: function(event, treeNode) {
|
onSelected: function(event, treeNode) {
|
||||||
let url = '/api/v1/assets/accounts/'
|
let url = '/api/v1/applications/accounts/'
|
||||||
if (treeNode.meta.type === 'node') {
|
const nodeId = treeNode.id
|
||||||
const nodeId = treeNode.meta.node.id
|
if (treeNode.meta.type === 'category') {
|
||||||
url = setUrlParam(url, 'asset', '')
|
url = setUrlParam(url, 'app_category', nodeId)
|
||||||
url = setUrlParam(url, 'node', nodeId)
|
url = setUrlParam(url, 'app_type', '')
|
||||||
} else if (treeNode.meta.type === 'asset') {
|
} else if (treeNode.meta.type === 'type') {
|
||||||
const assetId = treeNode.meta.asset.id
|
url = setUrlParam(url, 'app_category', '')
|
||||||
url = setUrlParam(url, 'node', '')
|
url = setUrlParam(url, 'app_type', nodeId)
|
||||||
url = setUrlParam(url, 'asset', assetId)
|
} else if (treeNode.meta.type === 'application') {
|
||||||
|
url = setUrlParam(url, 'app_category', '')
|
||||||
|
url = setUrlParam(url, 'app_type', '')
|
||||||
|
url = setUrlParam(url, 'app', nodeId)
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
vm.accountsUrl = url
|
vm.accountsUrl = url
|
||||||
|
Reference in New Issue
Block a user