perf: update pam

This commit is contained in:
ibuler
2024-11-25 17:16:09 +08:00
parent b25d2016a6
commit d21dc57305
32 changed files with 326 additions and 200 deletions

View File

@@ -71,6 +71,7 @@
<el-tooltip v-if="opt.tip" :content="opt.tip" :open-delay="500" placement="top">
<i class="el-icon-warning-outline" />
</el-tooltip>
<span v-if="data.helpText">{{ data.helpText }}</span>
</el-checkbox>
<!-- WARNING: radio label 属性来表示 value 的含义 -->
<!-- FYI: radio value 属性可以在没有 radio-group 时用来关联到同一个 v-model -->
@@ -87,7 +88,7 @@
</el-radio>
</template>
</custom-component>
<div v-if="data.helpText" class="help-block">
<div v-if="data.helpText" :class="data.type" class="help-block">
<el-alert
v-if="data.helpText.startsWith('!')"
:closable="false"
@@ -315,6 +316,10 @@ export default {
::v-deep .el-alert__icon {
font-size: 16px
}
&.checkbox {
//display: inline;
}
}
.help-tip-icon {

View File

@@ -1,15 +1,22 @@
<template>
<DataZTree ref="dataztree" :setting="treeSetting" class="data-z-tree" v-on="$listeners">
<slot v-if="treeSetting.hasRightMenu" slot="rMenu">
<li v-if="treeSetting.showCreate" id="m_create" class="rmenu" tabindex="-1" @click="createTreeNode">
<i class="fa fa-plus-square-o" /> {{ this.$t('CreateNode') }}
</li>
<li v-if="treeSetting.showUpdate" id="m_edit" class="rmenu" tabindex="-1" @click="editTreeNode">
<i class="fa fa-pencil-square-o" /> {{ this.$t('RenameNode') }}
</li>
<li v-if="treeSetting.showDelete" id="m_del" class="rmenu" tabindex="-1" @click="removeTreeNode">
<i class="fa fa-minus-square" /> {{ this.$t('DeleteNode') }}
</li>
<slot slot="rMenu">
<div v-if="menu && menu.length > 0">
<span v-for="item in menu" :key="item.id">
<li
v-if="hasMenuItem(item)"
:id="item.id"
:key="item.id"
:class="{ 'disabled': checkDisabled(item) }"
class="rmenu"
tabindex="-1"
@click="onMenuItemClick(item)"
>
<Icon :icon="item.icon" class="icon" /> {{ item.name }}
</li>
<li v-if="item.divided" class="divider" />
</span>
</div>
<slot name="rMenu" />
</slot>
</DataZTree>
@@ -17,13 +24,15 @@
<script>
import DataZTree from '../DataZTree/index.vue'
import Icon from '@/components/Widgets/Icon'
import $ from '@/utils/jquery-vendor'
import { mapGetters } from 'vuex'
export default {
name: 'AutoDataZTree',
components: {
DataZTree
DataZTree,
Icon
},
props: {
setting: {
@@ -34,7 +43,32 @@ export default {
},
data() {
return {
defaultMenu: [
{
id: 'm_create',
name: this.$t('CreateNode'),
icon: 'fa-plus-square-o',
callback: this.createTreeNode,
has: () => this.setting.showCreate
},
{
id: 'm_edit',
name: this.$t('RenameNode'),
icon: 'fa-pencil-square-o',
callback: this.editTreeNode,
has: () => this.setting.showUpdate
},
{
id: 'm_del',
name: this.$t('DeleteNode'),
icon: 'fa-minus-square',
callback: this.removeTreeNode,
has: () => this.setting.showDelete
}
],
defaultSetting: {
showDefaultMenu: true,
showMenu: false,
showCreate: true,
showDelete: true,
showUpdate: true,
@@ -80,12 +114,49 @@ export default {
},
rMenu() {
return this.$refs.dataztree.rMenu
},
menu() {
let menu = []
if (this.setting.showDefaultMenu) {
menu = menu.concat(this.defaultMenu)
}
if (this.setting.menu && this.setting.menu.length > 0) {
menu = menu.concat(this.setting.menu)
}
return menu
}
},
beforeDestroy() {
$('body').unbind('mousedown')
},
methods: {
checkDisabled(item) {
let disabled = item.disabled
if (typeof disabled === 'function') {
disabled = disabled(this.currentNode)
}
if (typeof disabled === 'undefined') {
disabled = false
}
return disabled
},
hasMenu(node) {
return false
},
hasMenuItem(item) {
let has = item.has
if (typeof has === 'function') {
has = has(this.currentNode)
}
if (typeof has === 'undefined') {
has = true
}
return has
},
onMenuItemClick(item) {
item.callback(this.currentNode)
this.hideRMenu()
},
onAsyncSuccess(event, treeId, treeNode, msg) {
const nodes = JSON.parse(msg)
nodes.forEach((node) => {
@@ -115,7 +186,7 @@ export default {
if (this.rMenu) this.rMenu.css({ 'visibility': 'hidden' })
$('body').unbind('mousedown', this.onBodyMouseDown)
},
// Request URL: http://localhost/api/v1/assets/assets/?node_id=d8212328-538d-41a6-bcfd-1e8cc7e3aed4&show_current_asset=null&draw=2&limit=15&offset=0&_=1587022917769
// Request URL: http://localhost/api/v1/assets/assets/?node_id=ID&show_current_asset=null&draw=2&limit=15&offset=0&_=1587022917769
onSelected: function(event, treeNode) {
const show_current_asset = this.$cookie.get('show_current_asset') || '0'
if (!this.setting.url) {
@@ -191,6 +262,8 @@ export default {
const offset = $(`#${zTreeID}`).offset()
const scrollTop = document.querySelector('.treebox')?.scrollTop
x -= offset.left
x = x < 0 ? 0 : x
// Tmp
y -= (offset.top + scrollTop) / 3 - 10
x += document.body.scrollLeft
@@ -199,15 +272,22 @@ export default {
if (y + $(`#${rMenuID} ul`).height() >= window.innerHeight) {
y -= $(`#${rMenuID} ul`).height()
}
y = y < 0 ? 0 : y
this.rMenu.css({ 'top': y + 'px', 'left': x + 'px', 'visibility': 'visible' })
$(`#${rMenuID} ul`).show()
$('body').bind('mousedown', this.onBodyMouseDown)
},
onRightClick: function(event, treeId, treeNode) {
if (!this.setting.showMenu) {
let showMenu = this.setting.showMenu
if (typeof showMenu === 'function') {
showMenu = showMenu(treeNode)
}
if (!showMenu) {
return
}
this.currentNode = treeNode
this.currentNodeId = treeNode.meta.data.id
// 屏蔽收藏资产
if (treeNode?.id === '-12') {
return
@@ -321,9 +401,14 @@ export default {
background-color: #f5f7fa;
}
.icon {
width: 15px;
display: inline-block;
}
.data-z-tree {
::v-deep {
.fa {
.icon {
width: 10px;
margin-right: 3px;
}

View File

@@ -29,6 +29,7 @@
<a id="tree-refresh"><i class="fa fa-refresh" /></a>
</div>
</div>
<div :id="iRMenuID" class="rMenu">
<ul class="dropdown-menu menu-actions">
<slot name="rMenu" />
@@ -49,8 +50,7 @@ import axiosRetry from 'axios-retry'
const defaultObject = {
type: Object,
default: () => {
}
default: () => ({})
}
export default {
name: 'ZTree',
@@ -90,6 +90,12 @@ export default {
window.removeEventListener('resize', this.updateTreeHeight)
},
methods: {
onMenuClick(menu) {
if (menu.disabled) {
return
}
menu.callback()
},
updateTreeHeight: _.debounce(function() {
const tree = document.getElementById(this.iZTreeID)
if (!tree) {
@@ -106,8 +112,8 @@ export default {
}
}
// 使用 table 的高度
const ztreeRect = tree.getBoundingClientRect()
tree.style.height = `calc(100vh - ${ztreeRect.top}px - 30px - 25px)`
const zTreeRect = tree.getBoundingClientRect()
tree.style.height = `calc(100vh - ${zTreeRect.top}px - 30px - 25px)`
}, 100),
async initTree(refresh = false) {
const vm = this
@@ -156,9 +162,6 @@ export default {
if (this.treeSetting.showMenu) {
this.rMenu = $(`#${this.iRMenuID}`)
}
if (this.treeSetting?.otherMenu) {
$('.menu-actions').append(this.otherMenu)
}
},
onSearch() {
this.showTreeSearch = !this.showTreeSearch
@@ -435,6 +438,24 @@ div.rMenu li {
list-style: none outside none;
}
.menu-item {
font-size: 12px;
padding: 0 16px;
position: relative;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #606266;
height: 24px;
line-height: 24px;
box-sizing: border-box;
cursor: pointer;
i {
width: 15px;
}
}
.dropdown-menu {
border: medium none;
min-width: 160px;
@@ -451,7 +472,8 @@ div.rMenu li {
text-shadow: none;
top: 100%;
z-index: 1000;
height: 300px;
max-height: 320px;
min-height: 150px;
overflow: auto;
}

View File

@@ -1,4 +1,7 @@
import i18n from '@/i18n/i18n'
import CronTab from '@/components/Form/FormFields/CronTab/index.vue'
import InputWithUnit from '@/components/Form/FormFields/InputWithUnit.vue'
import store from '@/store'
export const strMatchValues = ['exact', 'not', 'in', 'contains', 'startswith', 'endswith', 'regex']
export const typeMatchMapper = {
@@ -26,3 +29,49 @@ export const attrMatchOptions = [
{ label: i18n.t('GreatEqualThan'), value: 'gte' },
{ label: i18n.t('LessEqualThan'), value: 'lte' }
]
export const crontab = {
type: 'cronTab',
component: CronTab,
label: i18n.t('Crontab'),
hidden: (formValue) => {
return formValue.is_periodic === false
},
helpText: i18n.t('CrontabHelpText'),
helpTip: i18n.t('CrontabHelpTip')
}
const validatorInterval = (rule, value, callback) => {
if (parseInt(value) < 1) {
return callback(new Error(i18n.t('EnsureThisValueIsGreaterThanOrEqualTo1')))
}
callback()
}
export const interval = {
label: i18n.t('Interval'),
hidden: (formValue) => {
return formValue.is_periodic === false
},
component: InputWithUnit,
el: {
unit: 'hour'
},
rules: [
{ validator: validatorInterval }
]
}
export const is_periodic = {
type: 'checkbox',
hidden: (formValue) => {
return !store.getters.hasValidLicense
}
}
export const periodicMeta = {
is_periodic,
interval,
crontab
}

View File

@@ -30,7 +30,7 @@ export { default as AccountListTable } from './Apps/AccountListTable/AccountList
export { default as AssetRelationCard } from './Apps/AssetRelationCard'
export { default as UserConfirmDialog } from './Apps/UserConfirmDialog'
export { default as Announcement } from './Widgets/Announcement'
export { default as CronTab } from './Form/CronTab'
export { default as CronTab } from './Form/FormFields/CronTab'
export { default as Pagination } from './Table/Pagination'
export { default as Tooltip } from './Widgets/Tooltip'
export { default as ResourceActivity } from './Apps/ResourceActivity'

View File

@@ -62,7 +62,7 @@ export default [
},
{
path: 'executions',
component: () => import('@/views/accounts/AccountDiscover/TaskDetail/TaskExecutionList.vue'),
component: () => import('@/views/accounts/AccountDiscover/TaskExecutionList.vue'),
name: 'AccountDiscoverTaskExecutionList',
hidden: true,
meta: {

View File

@@ -547,8 +547,23 @@ li.rmenu i.fa {
height: 28px;
}
.el-checkbox__input {
padding-right: 5px;
}
.el-checkbox__label {
padding-left: 5px !important;
}
.el-checkbox__inner {
border-radius: 1px !important;
width: 16px !important;
height: 16px !important;
&::after {
left: 5px !important;
height: 8px !important;
}
}
.el-alert.el-alert--info.is-light {

View File

@@ -1,13 +1,28 @@
import { constantRoutes } from '@/router'
import store from '@/store'
import { openWindow } from './common'
let openedTaskWindow = null // 保存已打开的窗口对象
function openOrReuseWindow(url, windowName = 'task', windowFeatures = '', iWidth = 900, iHeight = 600) {
const iTop = (window.screen.height - 30 - iHeight) / 2
const iLeft = (window.screen.width - 10 - iWidth) / 2
// 检查窗口是否已经打开
if (openedTaskWindow && !openedTaskWindow.closed) {
openedTaskWindow.location.href = url // 如果窗口未关闭,更新其地址
openedTaskWindow.focus() // 将窗口置于前台
} else {
// 如果窗口未打开或已关闭,创建新窗口
openedTaskWindow = window.open(url, windowName, 'height=' + iHeight + ',width=' + iWidth + ',top=' + iTop + ',left=' + iLeft)
}
}
export function openTaskPage(taskId, taskType, taskUrl) {
taskType = taskType || 'celery'
if (!taskUrl) {
taskUrl = `/core/ops/${taskType}/task/${taskId}/log/?type=${taskType}`
}
openWindow(taskUrl)
openOrReuseWindow(taskUrl)
}
export function checkPermission(permsRequired, permsAll) {

View File

@@ -6,6 +6,7 @@
import { GenericCreateUpdatePage } from '@/layout/components'
import getChangeSecretFields from '@/views/accounts/AccountBackup/fields'
import { encryptPassword } from '@/utils/crypto'
import { periodicMeta } from '@/components/const'
export default {
name: 'AccountBackupUpdate',
@@ -40,9 +41,7 @@ export default {
categories: []
},
fieldsMeta: {
is_periodic: fields.is_periodic,
crontab: fields.crontab,
interval: fields.interval,
...periodicMeta,
is_password_divided_by_email: fields.is_password_divided_by_email,
zip_encrypt_password: fields.zip_encrypt_password,
is_password_divided_by_obj_storage: fields.is_password_divided_by_obj_storage,

View File

@@ -1,5 +1,5 @@
import i18n from '@/i18n/i18n'
import { crontab, interval, is_periodic } from '../const'
import { periodicMeta } from '@/components/const'
function getAccountBackupFields() {
const recipients_part_one = {
@@ -85,9 +85,7 @@ function getAccountBackupFields() {
}
}
return {
is_periodic: is_periodic,
crontab: crontab,
interval: interval,
...periodicMeta,
is_password_divided_by_email: is_password_divided_by_email,
is_password_divided_by_obj_storage: is_password_divided_by_obj_storage,
recipients_part_one: recipients_part_one,

View File

@@ -1,6 +1,6 @@
import i18n from '@/i18n/i18n'
import { PasswordRule, Select2, TagInput, UpdateToken } from '@/components/Form/FormFields'
import { crontab, interval, is_periodic } from '../../accounts/const'
import { periodicMeta } from '@/components/const'
export const getChangeSecretFields = () => {
return {
@@ -75,9 +75,7 @@ export const getChangeSecretFields = () => {
}
}
},
interval,
crontab,
is_periodic,
...periodicMeta,
accounts: {
label: i18n.t('Accounts'),
component: TagInput

View File

@@ -13,6 +13,7 @@
:table-config="tableConfig"
:tree-setting="treeSetting"
/>
<AccountDiscoverDialog :asset="discoveryDialog.asset" :visible.sync="discoveryDialog.visible" />
</div>
</template>
@@ -20,11 +21,13 @@
import AssetTreeTable from '@/components/Apps/AssetTreeTable/index.vue'
import DeleteDialog from '@/views/accounts/AccountDiscover/DeleteDialog.vue'
import { gatherAccountHeaderActions, gatherAccountTableConfig } from '@/views/accounts/const'
import AccountDiscoverDialog from '@/views/assets/Asset/AssetList/components/AccountDiscoverDialog.vue'
export default {
components: {
AssetTreeTable,
DeleteDialog
DeleteDialog,
AccountDiscoverDialog
},
data() {
return {
@@ -33,9 +36,16 @@ export default {
visible: false,
account: {}
},
discoveryDialog: {
asset: '',
visible: false
},
gatherAccounts: [],
treeSetting: {
showMenu: false,
showDefaultMenu: false,
showMenu: (node) => {
return node.meta.type === 'asset'
},
showRefresh: true,
showSearch: true,
showAssets: true,
@@ -43,7 +53,20 @@ export default {
url: '/api/v1/accounts/gathered-accounts/',
nodeUrl: '/api/v1/assets/nodes/',
// ?assets=0不显示资产. =1显示资产
treeUrl: '/api/v1/assets/nodes/children/tree/?assets=1'
treeUrl: '/api/v1/assets/nodes/children/tree/?assets=1&asset_amount=0',
menu: [
{
id: 'discover',
icon: 'discovery',
name: '发现账号',
callback: (node) => {
console.log('Discovery it: ', node)
this.discoveryDialog.asset = node.id
this.discoveryDialog.visible = true
// this.discoveryDialog.asset = node.data
}
}
]
},
quickSummary: [
{

View File

@@ -5,7 +5,7 @@
<script>
import { GenericCreateUpdatePage } from '@/layout/components'
import i18n from '@/i18n/i18n'
import { crontab, interval, is_periodic } from '@/views/accounts/const'
import { periodicMeta } from '@/components/const'
export default {
components: {
@@ -22,14 +22,12 @@ export default {
url: '/api/v1/accounts/gather-account-automations/',
hasDetailInMsg: false,
fieldsMeta: {
...periodicMeta,
is_sync_account: {
label: this.$t('IsSyncAccountLabel'),
helpText: this.$t('IsSyncAccountHelpText')
},
check_risk: {},
is_periodic,
crontab,
interval,
assets: {
el: {
multiple: true,

View File

@@ -9,7 +9,7 @@
<script>
import { GenericDetailPage, TabPage } from '@/layout/components'
import Detail from './Detail.vue'
import TaskExecutionList from './TaskExecutionList.vue'
import TaskExecutionList from '../TaskExecutionList.vue'
export default {
name: 'AccountDiscoverTaskDetail',

View File

@@ -24,8 +24,8 @@ export default {
tableConfig: {
url: '/api/v1/accounts/gather-account-executions/',
columns: [
'automation', 'account_gather_name', 'status', 'trigger', 'date_start',
'date_finished', 'actions'
'automation', 'account_gather_name', 'status', 'trigger',
'date_start', 'date_finished', 'actions'
],
columnsMeta: {
automation: {
@@ -77,6 +77,15 @@ export default {
callback: function({ row }) {
return this.$router.push({ name: 'AccountDiscoverExecutionDetail', params: { id: row.id }})
}
},
{
name: 'report',
title: this.$t('Report'),
type: 'success',
can: this.$hasPerm('accounts.view_gatheraccountsexecution'),
callback: function({ row }) {
window.open(`/api/v1/accounts/gather-account-executions/${row.id}/report/`)
}
}
]
}

View File

@@ -31,7 +31,7 @@ export default {
title: this.$t('ExecutionList'),
name: 'AccountDiscoverTaskExecutionList',
hidden: !this.$hasPerm('accounts.view_gatheraccountsexecution'),
component: () => import('@/views/accounts/AccountDiscover/TaskDetail/TaskExecutionList.vue')
component: () => import('@/views/accounts/AccountDiscover/TaskExecutionList.vue')
}
]
}

View File

@@ -6,7 +6,7 @@
import { GenericCreateUpdatePage } from '@/layout/components'
import { getChangeSecretFields } from '@/views/accounts/AccountChangeSecret/fields'
import { AssetSelect, AutomationParams } from '@/components'
import { crontab, interval, is_periodic } from '@/views/accounts/const'
import { periodicMeta } from '@/components/const'
export default {
name: 'AccountPushCreateUpdate',
@@ -47,6 +47,7 @@ export default {
[this.$t('Other'), ['is_active', 'comment']]
],
fieldsMeta: {
...periodicMeta,
...getChangeSecretFields(),
assets: {
type: 'assetSelect',
@@ -91,9 +92,6 @@ export default {
readonly: true
}
},
is_periodic,
crontab,
interval,
params: {
component: AutomationParams,
label: this.$t('PushParams'),

View File

@@ -1,49 +1,6 @@
import { CronTab } from '@/components'
import i18n from '@/i18n/i18n'
import InputWithUnit from '@/components/Form/FormFields/InputWithUnit.vue'
import store from '@/store'
import { toSafeLocalDateStr } from '@/utils/time'
import { ActionsFormatter, DiscoverConfirmFormatter } from '@/components/Table/TableFormatters'
const validatorInterval = (rule, value, callback) => {
if (parseInt(value) < 1) {
return callback(new Error(i18n.t('EnsureThisValueIsGreaterThanOrEqualTo1')))
}
callback()
}
export const crontab = {
type: 'cronTab',
component: CronTab,
label: i18n.t('Crontab'),
hidden: (formValue) => {
return formValue.is_periodic === false
},
helpText: i18n.t('CrontabHelpText'),
helpTip: i18n.t('CrontabHelpTip')
}
export const interval = {
label: i18n.t('Interval'),
hidden: (formValue) => {
return formValue.is_periodic === false
},
component: InputWithUnit,
el: {
unit: 'hour'
},
rules: [
{ validator: validatorInterval }
]
}
export const is_periodic = {
type: 'checkbox',
hidden: (formValue) => {
return !store.getters.hasValidLicense
}
}
export const gatherAccountTableConfig = (vm, url) => {
if (!url) {
url = '/api/v1/accounts/gathered-accounts/'
@@ -218,9 +175,3 @@ export const gatherAccountHeaderActions = (vm) => {
}
}
export default {
crontab: crontab,
interval: interval,
is_periodic: is_periodic
}

View File

@@ -44,7 +44,10 @@ export default {
category: 'all',
treeSetting: {
url: '/api/v1/assets/assets/',
showMenu: !this.$store.getters.currentOrgIsRoot
showMenu: !this.$store.getters.currentOrgIsRoot,
showDefaultMenu: true,
menu: [
]
},
tableConfig: {
url: tableUrl,

View File

@@ -10,13 +10,15 @@
top="35vh"
width="80%"
>
<ListTable v-bind="config" />
<!-- <ListTable v-bind="config" />-->
<span v-if="loading" v-loading="loading" class="loading" />
<iframe :src="url" frameborder="0" @load="onIframeLoad" />
</Dialog>
<RemoveAccount
v-if="showDeleteAccountDialog"
:accounts="gatherAccounts"
:visible.sync="showDeleteAccountDialog"
/>
<!-- <RemoveAccount-->
<!-- v-if="showDeleteAccountDialog"-->
<!-- :accounts="gatherAccounts"-->
<!-- :visible.sync="showDeleteAccountDialog"-->
<!-- />-->
</div>
</template>
@@ -24,14 +26,10 @@
<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: {
@@ -47,6 +45,7 @@ export default {
data() {
return {
showDeleteAccountDialog: false,
loading: true,
gatherAccounts: [],
config: {
tableConfig: gatherAccountTableConfig(this, `/api/v1/accounts/gathered-accounts/discover/?asset_id=${this.asset}`),
@@ -62,6 +61,11 @@ export default {
set(val) {
this.$emit('update:visible', val)
}
},
url: {
get() {
return `/api/v1/accounts/gathered-accounts/discover/?asset_id=${this.asset}`
}
}
},
watch: {
@@ -76,6 +80,22 @@ export default {
},
beforeMount() {
},
methods: {}
methods: {
onIframeLoad() {
this.loading = false
}
}
}
</script>
<style lang="scss" scoped>
iframe {
width: 100%;
height: 500px;
}
.loading {
margin-top: 20px;
display: block;
}
</style>

View File

@@ -3,15 +3,15 @@
ref="form"
class="form"
v-bind="settings"
@submitSuccess="handleSubmitSuccess"
@performFinished="handlePerformFinished"
@submitSuccess="handleSubmitSuccess"
/>
</template>
<script>
import { GenericCreateUpdateForm } from '@/layout/components'
import { crontab, interval, is_periodic } from '@/views/accounts/const'
import { periodicMeta } from '@/components/const'
export default {
name: 'ResultPanel',
@@ -21,7 +21,8 @@ export default {
props: {
object: {
type: Object,
default: () => {}
default: () => {
}
}
},
data() {
@@ -33,9 +34,7 @@ export default {
[this.$t('Timer'), ['is_periodic', 'interval', 'crontab']]
],
fieldsMeta: {
is_periodic,
interval,
crontab
...periodicMeta
},
defaultButton: false,
submitMethod: 'put',
@@ -92,6 +91,7 @@ export default {
::v-deep .el-form-item.form-buttons {
text-align: right;
}
.form {
margin-right: 0;
}

View File

@@ -4,9 +4,10 @@
<script>
import { GenericCreateUpdatePage } from '@/layout/components'
import { CronTab, Select2 } from '@/components'
import { Select2 } from '@/components'
import rules from '@/components/Form/DataForm/rules'
import SyncInstanceTaskStrategy from './components/SyncInstanceTaskStrategy/index'
import { periodicMeta } from '@/components/const'
export default {
components: {
@@ -34,6 +35,7 @@ export default {
],
url: '/api/v1/xpack/cloud/sync-instance-tasks/',
fieldsMeta: {
...periodicMeta,
account: {
label: this.$t('xpack.Cloud.Account'),
on: {
@@ -86,24 +88,6 @@ export default {
}
}
},
is_periodic: {
type: 'checkbox'
},
crontab: {
component: CronTab,
label: this.$t('xpack.RegularlyPerform'),
hidden: (formValue) => {
return formValue.is_periodic === false
},
helpText: this.$t('xpack.HelpText.CrontabOfCreateUpdatePage')
},
interval: {
label: this.$t('xpack.CyclePerform'),
hidden: (formValue) => {
return formValue.is_periodic === false
},
helpText: this.$t('xpack.HelpText.IntervalOfCreateUpdatePage')
},
strategy: {
label: this.$t('common.Strategy'),
component: SyncInstanceTaskStrategy,

View File

@@ -4,9 +4,8 @@
<script>
import { GenericCreateUpdatePage } from '@/layout/components'
import { getChangeSecretFields } from '@/views/accounts/AccountChangeSecret/fields'
import { AssetSelect } from '@/components'
import { crontab, interval, is_periodic } from '@/views/accounts/const'
import { periodicMeta } from '@/components/const'
import i18n from '@/i18n/i18n'
export default {
@@ -18,18 +17,11 @@ export default {
return {
nodeIds: [],
assetIds: [],
isAssetType: '',
initial: {
is_periodic: false,
password_rules: {
length: 30
},
interval: 24,
secret_type: 'password',
secret_strategy: 'specific'
interval: 24
},
url: '/api/v1/accounts/check-account-automations/',
encryptedFields: ['secret'],
fields: [
[this.$t('Basic'), ['name']],
[this.$t('Asset'), ['assets', 'nodes']],
@@ -38,7 +30,6 @@ export default {
[this.$t('Other'), ['is_active', 'comment']]
],
fieldsMeta: {
...getChangeSecretFields(),
assets: {
type: 'assetSelect',
component: AssetSelect,
@@ -100,33 +91,10 @@ export default {
}
}
},
username: {
hidden: (formValue) => formValue['dynamic_username']
},
ssh_key_change_strategy: {
hidden: (formValue) => formValue['action'] !== 'create_and_push' ||
formValue['secret_type'] !== 'ssh_key'
},
triggers: {
el: {
readonly: true
}
},
is_periodic,
crontab,
interval
...periodicMeta
},
createSuccessNextRoute: { name: 'AccountCheckList' },
updateSuccessNextRoute: { name: 'AccountCheckList' },
afterGetRemoteMeta: this.handleAfterGetRemoteMeta,
cleanFormValue(data) {
const secretType = data.secret_type || ''
if (secretType !== 'password') {
data.secret = data[secretType]
delete data[secretType]
}
return data
}
updateSuccessNextRoute: { name: 'AccountCheckList' }
}
},
computed: {
@@ -134,20 +102,7 @@ export default {
return this.$route.path.indexOf('/update') > -1
}
},
watch: {
nodeIds: {
handler(val) {
this.fieldsMeta.params.el.nodes = val
},
deep: true
},
assetIds: {
handler(val) {
this.fieldsMeta.params.el.assets = val
},
deep: true
}
},
watch: {},
mounted() {
if (!this.$store.getters.hasValidLicense) {
delete this.fields[3]
@@ -156,15 +111,6 @@ export default {
methods: {
hasType(type) {
return this.isAssetType.indexOf(type) > -1
},
handleAfterGetRemoteMeta(meta) {
const needSetOptionFields = [
'secret_type', 'secret_strategy', 'ssh_key_change_strategy'
]
for (const i of needSetOptionFields) {
const field = this.fieldsMeta[i] || {}
field.options = meta[i]?.choices || []
}
}
}
}

View File

@@ -23,7 +23,7 @@ export default {
return {
gatherAccounts: [],
treeSetting: {
showMenu: false,
showMenu: true,
showRefresh: true,
showSearch: true,
showAssets: true,
@@ -31,7 +31,15 @@ export default {
url: '/api/v1/accounts/account-risks/',
nodeUrl: '/api/v1/assets/nodes/',
// ?assets=0不显示资产. =1显示资产
treeUrl: '/api/v1/assets/nodes/children/tree/?assets=1&asset_amount=0'
treeUrl: '/api/v1/assets/nodes/children/tree/?assets=1&asset_amount=0',
menu: [
{
id: 'check',
name: this.$t('Check'),
icon: 'scan',
callback: () => {}
}
]
},
quickFilters: [
{