diff --git a/package.json b/package.json index adbd196bf..0b6346c42 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "crypto-js": "^4.1.1", "css-color-function": "^1.3.3", "deepmerge": "^4.2.2", - "echarts": "^4.7.0", + "echarts": "4.7.0", "element-ui": "2.13.2", "eslint-plugin-html": "^6.0.0", "highlight.js": "^11.9.0", diff --git a/public/index.html b/public/index.html index 296fc3d9f..5e4975076 100644 --- a/public/index.html +++ b/public/index.html @@ -27,6 +27,9 @@ if(pathname.indexOf('/ui') === -1) { window.location.href = window.location.origin + '/ui/#' + pathname } + if (pathname.startsWith('/ui/#/chat')) { + window.location.href = window.location.origin + pathname + } }
diff --git a/src/components/Apps/AccountCreateUpdateForm/const.js b/src/components/Apps/AccountCreateUpdateForm/const.js new file mode 100644 index 000000000..cb3fac519 --- /dev/null +++ b/src/components/Apps/AccountCreateUpdateForm/const.js @@ -0,0 +1,191 @@ +import { UpdateToken, UploadSecret } from '@/components/Form/FormFields' +import Select2 from '@/components/Form/FormFields/Select2.vue' +import AssetSelect from '@/components/Apps/AssetSelect/index.vue' +import { Required, RequiredChange } from '@/components/Form/DataForm/rules' +import AutomationParamsForm from '@/views/assets/Platform/AutomationParamsSetting.vue' + +export const accountFieldsMeta = (vm) => { + const defaultPrivilegedAccounts = ['root', 'administrator'] + return { + assets: { + rules: [Required], + component: AssetSelect, + label: vm.$t('assets.Asset'), + el: { + multiple: false + }, + hidden: () => { + return vm.platform || vm.asset + } + }, + template: { + component: Select2, + rules: [Required], + el: { + multiple: false, + ajax: { + url: '/api/v1/accounts/account-templates/', + transformOption: (item) => { + return { label: item.name, value: item.id } + } + } + }, + hidden: () => { + return vm.platform || vm.asset || !vm.addTemplate + } + }, + on_invalid: { + rules: [Required], + label: vm.$t('accounts.AccountPolicy'), + helpText: vm.$t('accounts.BulkCreateStrategy'), + hidden: () => { + return vm.platform || vm.asset + } + }, + name: { + label: vm.$t('common.Name'), + rules: [RequiredChange], + on: { + input: ([value], updateForm) => { + if (!vm.usernameChanged) { + if (!vm.account?.name) { + updateForm({ username: value }) + } + const maybePrivileged = defaultPrivilegedAccounts.includes(value) + if (maybePrivileged) { + updateForm({ privileged: true }) + } + } + } + }, + hidden: () => { + return vm.addTemplate + } + }, + username: { + el: { + disabled: !!vm.account?.name + }, + on: { + input: ([value], updateForm) => { + vm.usernameChanged = true + }, + change: ([value], updateForm) => { + const maybePrivileged = defaultPrivilegedAccounts.includes(value) + if (maybePrivileged) { + updateForm({ privileged: true }) + } + } + }, + hidden: () => { + return vm.addTemplate + } + }, + privileged: { + label: vm.$t('assets.Privileged'), + hidden: () => { + return vm.addTemplate + } + }, + su_from: { + component: Select2, + hidden: (formValue) => { + return !vm.asset?.id || !vm.iPlatform.su_enabled + }, + el: { + multiple: false, + clearable: true, + ajax: { + url: `/api/v1/accounts/accounts/su-from-accounts/?account=${vm.account?.id || ''}&asset=${vm.asset?.id || ''}`, + transformOption: (item) => { + return { label: `${item.name}(${item.username})`, value: item.id } + } + } + } + }, + su_from_username: { + label: vm.$t('assets.UserSwitchFrom'), + hidden: (formValue) => { + return vm.platform || vm.asset || vm.addTemplate + } + }, + password: { + label: vm.$t('assets.Password'), + component: UpdateToken, + hidden: (formValue) => { + console.log('formValue: ', formValue) + return formValue.secret_type !== 'password' || vm.addTemplate + } + }, + ssh_key: { + label: vm.$t('assets.PrivateKey'), + component: UploadSecret, + hidden: (formValue) => formValue.secret_type !== 'ssh_key' || vm.addTemplate + }, + passphrase: { + label: vm.$t('assets.Passphrase'), + component: UpdateToken, + hidden: (formValue) => formValue.secret_type !== 'ssh_key' || vm.addTemplate + }, + token: { + label: vm.$t('assets.Token'), + component: UploadSecret, + hidden: (formValue) => formValue.secret_type !== 'token' || vm.addTemplate + }, + access_key: { + id: 'access_key', + label: vm.$t('assets.AccessKey'), + component: UploadSecret, + hidden: (formValue) => formValue.secret_type !== 'access_key' || vm.addTemplate + }, + api_key: { + id: 'api_key', + label: vm.$t('assets.ApiKey'), + component: UploadSecret, + hidden: (formValue) => formValue.secret_type !== 'api_key' || vm.addTemplate + }, + secret_type: { + type: 'radio-group', + options: [], + hidden: () => { + return vm.addTemplate + } + }, + push_now: { + helpText: vm.$t('accounts.AccountPush.WindowsPushHelpText'), + hidden: (formValue) => { + const automation = vm.iPlatform.automation || {} + return !automation.push_account_enabled || + !automation.ansible_enabled || + !vm.$hasPerm('accounts.push_account') || + (formValue.secret_type === 'ssh_key' && vm.iPlatform.type.value === 'windows') || + vm.addTemplate + } + }, + params: { + label: vm.$t('assets.PushParams'), + component: AutomationParamsForm, + el: { + method: vm.asset?.auto_config?.push_account_method + }, + hidden: (formValue) => { + const automation = vm.iPlatform.automation || {} + return !formValue.push_now || + !automation.push_account_enabled || + !automation.ansible_enabled || + (formValue.secret_type === 'ssh_key' && vm.iPlatform.type.value === 'windows') || + !vm.$hasPerm('accounts.push_account') || + vm.addTemplate + } + }, + is_active: { + label: vm.$t('common.IsActive') + }, + comment: { + label: vm.$t('common.Comment'), + hidden: () => { + return vm.addTemplate + } + } + } +} diff --git a/src/components/Apps/AccountCreateUpdateForm/index.vue b/src/components/Apps/AccountCreateUpdateForm/index.vue index 1abd70d02..0bcf2716f 100644 --- a/src/components/Apps/AccountCreateUpdateForm/index.vue +++ b/src/components/Apps/AccountCreateUpdateForm/index.vue @@ -9,12 +9,8 @@ + + diff --git a/src/components/Apps/AccountListTable/AccountList.vue b/src/components/Apps/AccountListTable/AccountList.vue index a64161599..67dc6caaa 100644 --- a/src/components/Apps/AccountListTable/AccountList.vue +++ b/src/components/Apps/AccountListTable/AccountList.vue @@ -37,6 +37,12 @@ :result="createAccountResults" :visible.sync="showResultDialog" /> + @@ -49,10 +55,12 @@ import AccountCreateUpdate from './AccountCreateUpdate.vue' import { connectivityMeta } from './const' import { openTaskPage } from '@/utils/jms' import ResultDialog from './BulkCreateResultDialog.vue' +import AccountBulkUpdateDialog from '@/components/Apps/AccountListTable/AccountBulkUpdateDialog.vue' export default { name: 'AccountListTable', components: { + AccountBulkUpdateDialog, ResultDialog, ListTable, UpdateSecretInfo, @@ -116,6 +124,10 @@ export default { headerExtraActions: { type: Array, default: () => [] + }, + extraQuery: { + type: Object, + default: () => ({}) } }, data() { @@ -137,9 +149,7 @@ export default { app: 'assets', resource: 'account' }, - extraQuery: { - order: '-date_updated' - }, + extraQuery: this.extraQuery, columnsExclude: ['spec_info'], columnsShow: { min: ['name', 'username', 'actions'], @@ -336,6 +346,25 @@ export default { ...this.headerExtraActions ], extraMoreActions: [ + { + name: 'BulkVerify', + title: this.$t('accounts.BulkVerify'), + type: 'primary', + fa: 'fa-handshake-o', + can: ({ selectedRows }) => { + return selectedRows.length > 0 + }, + callback: function({ selectedRows }) { + const ids = selectedRows.map(v => { return v.id }) + this.$axios.post( + '/api/v1/accounts/accounts/tasks/', + { action: 'verify', accounts: ids }).then(res => { + openTaskPage(res['task']) + }).catch(err => { + this.$message.error(this.$tc('common.bulkVerifyErrorMsg' + ' ' + err)) + }) + }.bind(this) + }, { name: 'ClearSecrets', title: this.$t('ClearSecret'), @@ -354,6 +383,21 @@ export default { this.$message.error(this.$tc('BulkClearErrorMsg' + ' ' + err)) }) }.bind(this) + }, + { + name: 'actionUpdateSelected', + title: this.$t('accounts.AccountBatchUpdate'), + fa: 'batch-update', + can: ({ selectedRows }) => { + return selectedRows.length > 0 && + !this.$store.getters.currentOrgIsRoot && + vm.$hasPerm('accounts.change_account') && + selectedRows.every(i => i.secret_type.value === selectedRows[0].secret_type.value) + }, + callback: ({ selectedRows }) => { + vm.updateSelectedDialogSetting.selectedRows = selectedRows + vm.updateSelectedDialogSetting.visible = true + } } ], canBulkDelete: vm.$hasPerm('accounts.delete_account'), @@ -362,6 +406,10 @@ export default { exclude: ['asset'] }, hasSearch: true + }, + updateSelectedDialogSetting: { + visible: false, + selectedRows: [] } } }, @@ -429,6 +477,10 @@ export default { setTimeout(() => { this.showResultDialog = true }, 100) + }, + handleAccountBulkUpdate() { + this.updateSelectedDialogSetting.visible = false + this.$refs.ListTable.reloadTable() } } } diff --git a/src/components/Apps/AssetSelect/dialog.vue b/src/components/Apps/AssetSelect/dialog.vue index 759b9a64c..e54a20043 100644 --- a/src/components/Apps/AssetSelect/dialog.vue +++ b/src/components/Apps/AssetSelect/dialog.vue @@ -1,5 +1,6 @@