mirror of
https://github.com/jumpserver/lina.git
synced 2025-08-31 14:38:02 +00:00
perf: 基本完成应用正好改造
This commit is contained in:
@@ -15,7 +15,7 @@ import { connectivityMeta } from './const'
|
||||
import { openTaskPage } from '@/utils/jms'
|
||||
|
||||
export default {
|
||||
name: 'Detail',
|
||||
name: 'AccountListTable',
|
||||
components: {
|
||||
ListTable,
|
||||
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": {
|
||||
"": "",
|
||||
"updateAccountMsg": "请更新系统用户的账号信息",
|
||||
"RemoteApp": "远程应用",
|
||||
"Database": "数据库",
|
||||
"Cloud": "云",
|
||||
|
@@ -28,6 +28,7 @@
|
||||
},
|
||||
"applications": {
|
||||
"": "",
|
||||
"updateAccountMsg": "Please update system user account info",
|
||||
"RemoteApp": "Remote app",
|
||||
"Database": "Database",
|
||||
"Cloud": "Cloud",
|
||||
|
@@ -38,57 +38,73 @@ export default [
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'database-apps',
|
||||
path: 'databases',
|
||||
name: 'DatabaseAppList',
|
||||
component: () => import('@/views/applications/DatabaseApp/DatabaseAppList'),
|
||||
meta: { title: i18n.t('route.DatabaseApp') }
|
||||
component: empty,
|
||||
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',
|
||||
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',
|
||||
path: 'kubernetes',
|
||||
name: 'KubernetesAppList',
|
||||
component: () => import('@/views/applications/KubernetesApp/KubernetesAppList'),
|
||||
meta: { title: i18n.t('route.KubernetesApp') }
|
||||
},
|
||||
{
|
||||
path: 'kubernetes-apps/create',
|
||||
name: 'KubernetesAppCreate',
|
||||
component: () => import('@/views/applications/KubernetesApp/KubernetesAppCreateUpdate'),
|
||||
meta: { title: i18n.t('route.KubernetesAppCreate'), activeMenu: '/applications/kubernetes-apps', action: 'create' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'kubernetes-apps/:id/update',
|
||||
name: 'KubernetesAppUpdate',
|
||||
component: () => import('@/views/applications/KubernetesApp/KubernetesAppCreateUpdate'),
|
||||
meta: { title: i18n.t('route.KubernetesAppUpdate'), activeMenu: '/applications/kubernetes-apps', action: 'update' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'kubernetes-apps/:id',
|
||||
name: 'KubernetesAppDetail',
|
||||
component: () => import('@/views/applications/KubernetesApp/KubernetesAppDetail/index'),
|
||||
meta: { title: i18n.t('route.KubernetesAppDetail'), activeMenu: '/applications/kubernetes-apps' },
|
||||
hidden: true
|
||||
component: empty,
|
||||
meta: { title: i18n.t('route.KubernetesApp') },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'KubernetesAppList',
|
||||
component: () => import('@/views/applications/KubernetesApp/KubernetesAppList'),
|
||||
meta: { title: i18n.t('route.KubernetesApp') }
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
name: 'KubernetesAppCreate',
|
||||
component: () => import('@/views/applications/KubernetesApp/KubernetesAppCreateUpdate'),
|
||||
meta: { title: i18n.t('route.KubernetesAppCreate'), activeMenu: '/applications/kubernetes', action: 'create' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: ':id/update',
|
||||
name: 'KubernetesAppUpdate',
|
||||
component: () => import('@/views/applications/KubernetesApp/KubernetesAppCreateUpdate'),
|
||||
meta: { title: i18n.t('route.KubernetesAppUpdate'), activeMenu: '/applications/kubernetes', action: 'update' },
|
||||
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>
|
||||
<GenericTreeListPage ref="TreeTablePage" :tree-setting="treeSetting">
|
||||
<template #table>
|
||||
<AccountListTable ref="table" :url="accountsUrl" />
|
||||
<AppAccountListTable ref="table" :url="accountsUrl" />
|
||||
</template>
|
||||
</GenericTreeListPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericTreeListPage from '@/layout/components/GenericTreeListPage'
|
||||
import AccountListTable from '@/components/AccountListTable'
|
||||
import AppAccountListTable from '@/components/AppAccountListTable'
|
||||
import { setUrlParam } from '@/utils/common'
|
||||
|
||||
export default {
|
||||
name: 'AssetAccountList',
|
||||
components: {
|
||||
GenericTreeListPage, AccountListTable
|
||||
GenericTreeListPage, AppAccountListTable
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
@@ -22,25 +22,27 @@ export default {
|
||||
isInit: true,
|
||||
clickedRow: null,
|
||||
iShowTree: true,
|
||||
accountsUrl: '/api/v1/assets/accounts/',
|
||||
accountsUrl: '/api/v1/applications/accounts/',
|
||||
treeSetting: {
|
||||
async: false,
|
||||
showMenu: false,
|
||||
showRefresh: true,
|
||||
showAssets: false,
|
||||
url: '/api/v1/assets/accounts/',
|
||||
treeUrl: '/api/v1/applications/applications/tree/',
|
||||
treeUrl: '/api/v1/applications/applications/tree/?show_count=0',
|
||||
callback: {
|
||||
onSelected: function(event, treeNode) {
|
||||
let url = '/api/v1/assets/accounts/'
|
||||
if (treeNode.meta.type === 'node') {
|
||||
const nodeId = treeNode.meta.node.id
|
||||
url = setUrlParam(url, 'asset', '')
|
||||
url = setUrlParam(url, 'node', nodeId)
|
||||
} else if (treeNode.meta.type === 'asset') {
|
||||
const assetId = treeNode.meta.asset.id
|
||||
url = setUrlParam(url, 'node', '')
|
||||
url = setUrlParam(url, 'asset', assetId)
|
||||
let url = '/api/v1/applications/accounts/'
|
||||
const nodeId = treeNode.id
|
||||
if (treeNode.meta.type === 'category') {
|
||||
url = setUrlParam(url, 'app_category', nodeId)
|
||||
url = setUrlParam(url, 'app_type', '')
|
||||
} else if (treeNode.meta.type === 'type') {
|
||||
url = setUrlParam(url, 'app_category', '')
|
||||
url = setUrlParam(url, 'app_type', nodeId)
|
||||
} else if (treeNode.meta.type === 'application') {
|
||||
url = setUrlParam(url, 'app_category', '')
|
||||
url = setUrlParam(url, 'app_type', '')
|
||||
url = setUrlParam(url, 'app', nodeId)
|
||||
}
|
||||
setTimeout(() => {
|
||||
vm.accountsUrl = url
|
||||
|
Reference in New Issue
Block a user