perf: update gather account

This commit is contained in:
ibuler
2024-10-29 19:23:29 +08:00
parent c0b4029917
commit 0e7c682f72
7 changed files with 321 additions and 157 deletions

View File

@@ -1,14 +1,25 @@
<template> <template>
<span class="conform-td"> <span class="conform-td">
<span v-if="!iValue" class="confirm-action"> <span v-if="!iValue" class="confirm-action">
<el-tooltip :content="$tc('Confirm')" :open-delay="400"> <el-tooltip :content="$tc('Add account to asset')" :open-delay="400">
<el-button class="confirm action" icon="el-icon-check" size="mini" type="primary" /> <el-button class="confirm action" size="mini" @click="handleConfirm">
<i class="fa fa-check" />
</el-button>
</el-tooltip> </el-tooltip>
<el-tooltip :content="$tc('Ignore')" :open-delay="400"> <el-tooltip :content="$tc('Ignore')" :open-delay="400">
<el-button class="ignore action" icon="el-icon-close-notification" size="mini" /> <el-button class="ignore action" size="mini" @click="handleIgnore">
<svg-icon icon-class="ignore" />
</el-button>
</el-tooltip> </el-tooltip>
</span> </span>
<span v-else class="platform-status">{{ iLabel }}</span> <el-tooltip v-else :content="iLabel" :open-delay="400" class="platform-status">
<span v-if="iValue === 'confirmed' ">
<i class="fa fa-check color-primary" />
</span>
<span v-else>
<svg-icon icon-class="ignore" />
</span>
</el-tooltip>
</span> </span>
</template> </template>
@@ -22,7 +33,12 @@ export default {
formatterArgsDefault: { formatterArgsDefault: {
type: Object, type: Object,
default() { default() {
return {} return {
confirm: ({ row, cellValue }) => {
},
ignore: ({ row, cellValue }) => {
}
}
} }
} }
}, },
@@ -46,17 +62,33 @@ export default {
return this.cellValue return this.cellValue
} }
} }
},
methods: {
handleConfirm() {
this.formatterArgs.confirm({ row: this.row, cellValue: this.cellValue })
},
handleIgnore() {
this.formatterArgs.ignore({ row: this.row, cellValue: this.cellValue })
}
} }
} }
</script> </script>
<style scoped> <style lang='scss' scoped>
.action.el-button--mini { .action.el-button--mini {
cursor: pointer; cursor: pointer;
padding: 1px 4px; padding: 1px 4px;
&.confirm { &.confirm {
::v-deep i {
color: var(--color-primary);
}
}
&.ignore {
::v-deep svg.svg-icon {
}
} }
} }

5
src/icons/svg/ignore.svg Normal file
View File

@@ -0,0 +1,5 @@
<svg t="1730113499097" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1649"
width="200" height="200">
<path d="M512 0C229.234286 0 0 229.234286 0 512s229.234286 512 512 512 512-229.234286 512-512S794.765714 0 512 0zM109.714286 512a400.514286 400.514286 0 0 1 81.68-243.017143l563.622857 563.622857A400.514286 400.514286 0 0 1 512 914.285714C289.828571 914.285714 109.714286 734.171429 109.714286 512z m722.891428 243.017143L268.982857 191.394286A400.514286 400.514286 0 0 1 512 109.714286c222.171429 0 402.285714 180.114286 402.285714 402.285714a400.514286 400.514286 0 0 1-81.68 243.017143z"
p-id="1650"></path>
</svg>

After

Width:  |  Height:  |  Size: 684 B

View File

@@ -193,14 +193,14 @@ export default {
} }
::v-deep .page-content { ::v-deep .page-content {
overflow-y: hidden; overflow-y: hidden !important;
padding: 0; padding: 0;
} }
.tab-page-content { .tab-page-content {
padding: 10px 30px 22px; padding: 10px 30px 22px;
overflow-y: auto; overflow-y: auto;
height: calc(100% - 50px); height: calc(100vh - 130px);
.el-alert { .el-alert {
margin-top: 0; margin-top: 0;

View File

@@ -18,9 +18,8 @@
<script> <script>
import AssetTreeTable from '@/components/Apps/AssetTreeTable/index.vue' import AssetTreeTable from '@/components/Apps/AssetTreeTable/index.vue'
import { toSafeLocalDateStr } from '@/utils/time'
import { ActionsFormatter, ConfirmFormatter } from '@/components/Table/TableFormatters'
import RemoveAccount from '@/components/Apps/AccountListTable/RemoveAccount.vue' import RemoveAccount from '@/components/Apps/AccountListTable/RemoveAccount.vue'
import { gatherAccountHeaderActions, gatherAccountTableConfig } from '@/views/accounts/const'
export default { export default {
components: { components: {
@@ -28,19 +27,9 @@ export default {
RemoveAccount RemoveAccount
}, },
data() { data() {
const vm = this
return { return {
config: {
title: this.$t('RealTimeData'),
tip: this.$t('RealTimeData')
},
counter: {
total_count_online_sessions: '.',
total_count_online_users: '.',
total_count_today_failed_sessions: '.'
},
showDeleteAccountDialog: false, showDeleteAccountDialog: false,
gatherAccounts: {}, gatherAccounts: [],
treeSetting: { treeSetting: {
showMenu: false, showMenu: false,
showRefresh: true, showRefresh: true,
@@ -107,147 +96,16 @@ export default {
] ]
} }
], ],
tableConfig: { tableConfig: gatherAccountTableConfig(this),
url: '/api/v1/accounts/gathered-accounts/', headerActions: gatherAccountHeaderActions(this)
hasTree: true,
columns: [
'asset', 'username', 'date_last_login',
'address_last_login', 'present', 'date_updated', 'status'
],
columnsShow: {
default: [
'asset', 'username', 'address_last_login',
'date_last_login', 'present', 'status'
]
},
columnsMeta: {
asset: {
formatter: function(row) {
const to = {
name: 'AssetDetail',
params: { id: row.asset.id }
}
if (vm.$hasPerm('assets.view_asset')) {
return <router-link to={to}>{row.asset.name}</router-link>
} else {
return <span>{row.asset.name}</span>
}
}
},
username: {
showOverflowTooltip: true
},
present: {
width: '100px'
},
date_updated: {
formatter: function(row, col, cell) {
return toSafeLocalDateStr(row.date_updated)
}
},
status: {
formatter: ConfirmFormatter
},
actions: {
formatter: ActionsFormatter,
formatterArgs: {
hasClone: false,
hasUpdate: false, // can set function(row, value)
moreActionsTitle: this.$t('More'),
extraActions: [
{
name: 'Sync',
title: this.$t('Sync'),
can: this.$hasPerm('accounts.add_gatheredaccount') && !this.$store.getters.currentOrgIsRoot,
type: 'primary',
callback: ({ row }) => {
this.$axios.post(
`/api/v1/accounts/gathered-accounts/sync-accounts/`,
{ gathered_account_ids: [row.id] }
).then(res => {
this.$message.success(this.$tc('SyncSuccessMsg'))
}).catch(() => {
})
}
},
{
name: 'SyncDelete',
title: this.$t('SyncDelete'),
can: this.$hasPerm('accounts.remove_account') && !this.$store.getters.currentOrgIsRoot,
type: 'danger',
callback: ({ row }) => {
vm.gatherAccounts = [row]
vm.showDeleteAccountDialog = false
setTimeout(() => {
vm.showDeleteAccountDialog = true
})
}
}
]
}
}
}
},
headerActions: {
hasCreate: false,
hasImport: false,
hasExport: true,
searchConfig: {
exclude: ['asset'],
options: [
{
label: this.$t('AssetName'),
value: 'asset_name'
}
]
},
extraMoreActions: [
{
name: 'SyncSelected',
title: this.$t('SyncSelected'),
type: 'primary',
icon: 'fa fa-exchange',
can: ({ selectedRows }) => {
return selectedRows.length > 0 && vm.$hasPerm('accounts.add_gatheredaccount')
},
callback: function({ selectedRows }) {
const ids = selectedRows.map(v => {
return v.id
})
this.$axios.post(
`/api/v1/accounts/gathered-accounts/sync-accounts/`,
{ gathered_account_ids: ids }
).then(() => {
this.$message.success(this.$tc('SyncSuccessMsg'))
}).catch(err => {
this.$message.error(this.$tc('SyncErrorMsg' + ' ' + err))
})
}.bind(this)
},
{
name: 'SyncDeleteSelected',
title: this.$t('SyncDeleteSelected'),
type: 'primary',
icon: 'fa fa-exchange',
can: ({ selectedRows }) => {
return selectedRows.length > 0 && vm.$hasPerm('accounts.remove_account')
},
callback: function({ selectedRows }) {
vm.gatherAccounts = selectedRows
vm.showDeleteAccountDialog = false
setTimeout(() => {
vm.showDeleteAccountDialog = true
})
}
}
]
}
} }
}, },
activated() { activated() {
setTimeout(() => { setTimeout(() => {
this.$refs.AssetTreeTable.$refs.TreeList.reloadTable() this.$refs.AssetTreeTable.$refs.TreeList.reloadTable()
}, 300) }, 300)
},
mounted() {
} }
} }
</script> </script>

View File

@@ -2,6 +2,8 @@ import { CronTab } from '@/components'
import i18n from '@/i18n/i18n' import i18n from '@/i18n/i18n'
import InputWithUnit from '@/components/Form/FormFields/InputWithUnit.vue' import InputWithUnit from '@/components/Form/FormFields/InputWithUnit.vue'
import store from '@/store' import store from '@/store'
import { toSafeLocalDateStr } from '@/utils/time'
import { ActionsFormatter, ConfirmFormatter } from '@/components/Table/TableFormatters'
const validatorInterval = (rule, value, callback) => { const validatorInterval = (rule, value, callback) => {
if (parseInt(value) < 1) { if (parseInt(value) < 1) {
@@ -42,6 +44,177 @@ export const is_periodic = {
} }
} }
export const gatherAccountTableConfig = (vm, url) => {
if (!url) {
url = '/api/v1/accounts/gathered-accounts/'
}
const h = vm.$createElement
return {
url: url,
hasTree: true,
columns: [
'asset', 'username', 'date_last_login',
'address_last_login', 'present', 'date_updated', 'status'
],
columnsShow: {
default: [
'username', 'asset', 'address_last_login',
'date_last_login', 'present', 'status'
]
},
columnsMeta: {
asset: {
formatter: function(row) {
const to = {
name: 'AssetDetail',
params: { id: row.asset.id }
}
if (vm.$hasPerm('assets.view_asset')) {
return h('router-link', { props: { to }}, row.asset.name)
} else {
return h('span', row.asset.name)
}
}
},
username: {
showOverflowTooltip: true
},
present: {
width: '160px'
},
date_updated: {
formatter: function(row, col, cell) {
return toSafeLocalDateStr(row.date_updated)
}
},
address_last_login: {
width: '150px'
},
status: {
formatter: ConfirmFormatter,
width: '100px',
formatterArgs: {
confirm: ({ row }) => {
vm.$axios.put(
`/api/v1/accounts/gathered-accounts/${row.id}/status/`,
{ status: 'confirmed' }
).then(res => {
row.status = 'confirmed'
}).catch(() => {
row.status = vm.$t('Error')
})
},
ignore: ({ row }) => {
vm.$axios.put(
`/api/v1/accounts/gathered-accounts/${row.id}/status/`,
{ status: 'ignored' }
).then(res => {
row.status = 'ignored'
}).catch(() => {
row.status = vm.$t('Error')
})
}
}
},
actions: {
formatter: ActionsFormatter,
formatterArgs: {
hasClone: false,
hasUpdate: false, // can set function(row, value)
moreActionsTitle: vm.$t('More'),
extraActions: [
{
name: 'Sync',
title: vm.$t('Sync'),
can: vm.$hasPerm('accounts.add_gatheredaccount') && !vm.$store.getters.currentOrgIsRoot,
type: 'primary',
callback: ({ row }) => {
vm.$axios.post(
`/api/v1/accounts/gathered-accounts/sync-accounts/`,
{ gathered_account_ids: [row.id] }
).then(res => {
vm.$message.success(vm.$tc('SyncSuccessMsg'))
}).catch(() => {
})
}
},
{
name: 'SyncDelete',
title: vm.$t('SyncDelete'),
can: vm.$hasPerm('accounts.remove_account') && !vm.$store.getters.currentOrgIsRoot,
type: 'danger',
callback: ({ row }) => {
vm.gatherAccounts = [row]
vm.showDeleteAccountDialog = false
setTimeout(() => {
vm.showDeleteAccountDialog = true
})
}
}
]
}
}
}
}
}
export const gatherAccountHeaderActions = (vm) => {
return {
hasCreate: false,
hasImport: false,
hasExport: true,
searchConfig: {
exclude: ['asset'],
options: [
{
label: vm.$t('AssetName'),
value: 'asset_name'
}
]
},
extraMoreActions: [
{
name: 'SyncSelected',
title: vm.$t('ConfirmSelected'),
type: 'primary',
icon: 'fa fa-check',
can: ({ selectedRows }) => {
return selectedRows.length > 0 && vm.$hasPerm('accounts.add_account')
},
callback: function({ selectedRows }) {
const ids = selectedRows.map(v => {
return v.id
})
vm.$axios.post(
`/api/v1/accounts/gathered-accounts/sync-accounts/`,
{ gathered_account_ids: ids }
).then(() => {
vm.$message.success(vm.$tc('SyncSuccessMsg'))
}).catch(err => {
vm.$message.error(vm.$tc('SyncErrorMsg' + ' ' + err))
})
}
},
{
name: 'SyncDeleteSelected',
title: vm.$t('SyncDeleteSelected'),
type: 'primary',
icon: 'fa fa-exchange',
can: ({ selectedRows }) => {
return selectedRows.length > 0 && vm.$hasPerm('accounts.remove_account')
},
callback: function({ selectedRows }) {
vm.gatherAccounts = selectedRows
vm.showDeleteAccountDialog = false
setTimeout(() => {
vm.showDeleteAccountDialog = true
})
}
}
]
}
}
export default { export default {
crontab: crontab, crontab: crontab,
interval: interval, interval: interval,

View File

@@ -0,0 +1,81 @@
<template>
<div>
<Dialog
v-if="iVisible"
:destroy-on-close="true"
:show-cancel="false"
:show-confirm="false"
:title="$tc('DiscoverAccountsDialog')"
:visible.sync="iVisible"
top="35vh"
width="80%"
>
<ListTable v-bind="config" />
</Dialog>
<RemoveAccount
v-if="showDeleteAccountDialog"
:accounts="gatherAccounts"
:visible.sync="showDeleteAccountDialog"
/>
</div>
</template>
<script>
import Dialog from '@/components/Dialog/index.vue'
import { gatherAccountHeaderActions, gatherAccountTableConfig } from '@/views/accounts/const'
import ListTable from '@/components/Table/ListTable/index.vue'
import RemoveAccount from '@/components/Apps/AccountListTable/RemoveAccount.vue'
export default {
name: 'AccountDiscoverDialog',
components: {
RemoveAccount,
ListTable,
Dialog
},
props: {
visible: {
type: Boolean,
default: false
},
asset: {
type: String,
default: ''
}
},
data() {
return {
showDeleteAccountDialog: false,
gatherAccounts: [],
config: {
tableConfig: gatherAccountTableConfig(this, `/api/v1/accounts/gathered-accounts/discover/?asset_id=${this.asset}`),
headerActions: gatherAccountHeaderActions(this)
}
}
},
computed: {
iVisible: {
get() {
return this.visible
},
set(val) {
this.$emit('update:visible', val)
}
}
},
watch: {
asset: {
handler(val) {
this.config.tableConfig.url = `/api/v1/accounts/gathered-accounts/discover/?asset_id=${val}`
},
immediate: true
}
},
mounted() {
},
beforeMount() {
},
methods: {}
}
</script>

View File

@@ -17,6 +17,7 @@
:port="gatewayPort" :port="gatewayPort"
:visible.sync="gatewayVisible" :visible.sync="gatewayVisible"
/> />
<AccountDiscoverDialog :asset="discoveryDialog.asset" :visible.sync="discoveryDialog.visible" />
</div> </div>
</template> </template>
@@ -32,12 +33,14 @@ import GatewayDialog from '@/components/Apps/GatewayDialog'
import { openTaskPage } from '@/utils/jms' import { openTaskPage } from '@/utils/jms'
import HostInfoFormatter from '@/components/Table/TableFormatters/HostInfoFormatter' import HostInfoFormatter from '@/components/Table/TableFormatters/HostInfoFormatter'
import AmountFormatter from '@/components/Table/TableFormatters/AmountFormatter.vue' import AmountFormatter from '@/components/Table/TableFormatters/AmountFormatter.vue'
import AccountDiscoverDialog from './AccountDiscoverDialog.vue'
export default { export default {
components: { components: {
ListTable, ListTable,
GatewayDialog, GatewayDialog,
PlatformDialog, PlatformDialog,
AccountDiscoverDialog,
AssetBulkUpdateDialog AssetBulkUpdateDialog
}, },
props: { props: {
@@ -241,7 +244,15 @@ export default {
}, },
{ {
name: 'DiscoverAccounts', name: 'DiscoverAccounts',
title: 'Discover accounts' title: 'Discover accounts',
callback: ({ row }) => {
console.log('Row: ', row)
vm.discoveryDialog.asset = row.id
console.log('vm.discoveryDialog.asset: ', vm.discoveryDialog)
setTimeout(() => {
vm.discoveryDialog.visible = true
}, 200)
}
}, },
...this.addExtraMoreColActions ...this.addExtraMoreColActions
] ]
@@ -342,6 +353,10 @@ export default {
visible: false, visible: false,
category: this.category, category: this.category,
selectedRows: [] selectedRows: []
},
discoveryDialog: {
visible: false,
asset: ''
} }
} }
}, },