mirror of
https://github.com/jumpserver/lina.git
synced 2026-01-14 03:46:26 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
607eec6c44 | ||
|
|
28daf41fb5 | ||
|
|
e45720af1b |
@@ -1,15 +0,0 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getOrgDetail(oid) {
|
||||
return request({
|
||||
url: `/api/v1/orgs/orgs/current/?oid=${oid}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getCurrentOrg() {
|
||||
return request({
|
||||
url: `/api/v1/orgs/orgs/current/`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
@@ -1,15 +1,40 @@
|
||||
<template>
|
||||
<DataActions :actions="iActions" v-bind="$attrs" />
|
||||
<div :class="grouped ? 'el-button-group' : ''">
|
||||
<el-button v-for="item in iActions" :key="item.name" :size="size" v-bind="item" @click="handleClick(item.name)">
|
||||
<el-tooltip v-if="item.tip" effect="dark" :content="item.tip" placement="top">
|
||||
<i v-if="item.fa" :class="'fa ' + item.fa" />{{ item.title }}
|
||||
</el-tooltip>
|
||||
<span v-else>
|
||||
<i v-if="item.fa" :class="'fa ' + item.fa" />{{ item.title }}
|
||||
</span>
|
||||
</el-button>
|
||||
<el-dropdown v-if="iMoreActions.length > 0" trigger="click" :placement="moreActionsPlacement" @command="handleClick">
|
||||
<el-button :size="size" :type="moreActionsType" class="btn-more-actions">
|
||||
{{ iMoreActionsTitle }}<i class="el-icon-arrow-down el-icon--right" />
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-for="item in iMoreActions" :key="item.name" :command="item.name" v-bind="item" @click="handleClick(item.name)">{{ item.title }} </el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DataActions from '@/components/DataActions'
|
||||
export default {
|
||||
name: 'ActionsGroup',
|
||||
components: {
|
||||
DataActions
|
||||
},
|
||||
props: {
|
||||
grouped: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'small'
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
actions: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
@@ -36,22 +61,79 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
iActions() {
|
||||
const actions = [...this.actions]
|
||||
if (this.iMoreAction && this.iMoreAction.dropdown.length > 0) {
|
||||
actions.push(this.iMoreAction)
|
||||
return this.cleanActions(this.actions)
|
||||
},
|
||||
iMoreActions() {
|
||||
return this.cleanActions(this.moreActions)
|
||||
},
|
||||
totalActions() {
|
||||
return [...this.actions, ...this.moreActions]
|
||||
},
|
||||
totalNamedActions() {
|
||||
const actions = {}
|
||||
for (const action of this.totalActions) {
|
||||
if (!action || !action.hasOwnProperty('name')) {
|
||||
continue
|
||||
}
|
||||
actions[action.name] = action
|
||||
}
|
||||
return actions
|
||||
},
|
||||
iMoreAction() {
|
||||
return {
|
||||
name: 'moreActions',
|
||||
title: this.iMoreActionsTitle,
|
||||
dropdown: this.moreActions || []
|
||||
}
|
||||
},
|
||||
iMoreActionsTitle() {
|
||||
return this.moreActionsTitle || this.$t('common.MoreActions')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClick(item) {
|
||||
const action = this.totalNamedActions[item]
|
||||
if (action && action.callback) {
|
||||
action.callback(action)
|
||||
} else {
|
||||
this.$log.debug('No callback found')
|
||||
}
|
||||
this.$emit('actionClick', item)
|
||||
},
|
||||
checkItem(item, attr, defaults) {
|
||||
if (!item) {
|
||||
return true
|
||||
}
|
||||
let ok = item[attr]
|
||||
if (ok && typeof ok === 'function') {
|
||||
ok = ok(item)
|
||||
} else if (ok == null) {
|
||||
ok = defaults === undefined ? true : defaults
|
||||
}
|
||||
return ok
|
||||
},
|
||||
cleanActions(actions) {
|
||||
const cleanedActions = []
|
||||
const cloneActions = _.cloneDeep(actions)
|
||||
for (const v of cloneActions) {
|
||||
if (!v) {
|
||||
continue
|
||||
}
|
||||
const action = Object.assign({}, v)
|
||||
// 是否拥有这个action
|
||||
const has = this.checkItem(action, 'has')
|
||||
delete action['has']
|
||||
if (!has) {
|
||||
continue
|
||||
}
|
||||
// 是否有分割线
|
||||
const divided = this.checkItem(action, 'divided', false)
|
||||
delete action['divided']
|
||||
action.divided = divided
|
||||
|
||||
// 是否是disabled
|
||||
const can = this.checkItem(action, 'can')
|
||||
delete action['can']
|
||||
action.disabled = !can
|
||||
cleanedActions.push(action)
|
||||
// 删掉callback,避免前台看到
|
||||
delete action['callback']
|
||||
}
|
||||
return cleanedActions
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
<table style="width: 100%">
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<AssetSelect ref="assetSelect" :disabled="disabled" :can-select="canSelect" />
|
||||
<AssetSelect ref="assetSelect" :can-select="canSelect" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<el-button :type="type" size="small" :disabled="disabled" @click="addObjects">{{ $t('common.Add') }}</el-button>
|
||||
<el-button :type="type" size="small" @click="addObjects">{{ $t('common.Add') }}</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -38,10 +38,6 @@ export default {
|
||||
type: String,
|
||||
default: 'primary'
|
||||
},
|
||||
disabled: {
|
||||
type: [Boolean, Function],
|
||||
default: false
|
||||
},
|
||||
value: {
|
||||
type: [Array, Number, String],
|
||||
default: () => []
|
||||
|
||||
@@ -40,10 +40,6 @@ export default {
|
||||
default(row, index) {
|
||||
return true
|
||||
}
|
||||
},
|
||||
disabled: {
|
||||
type: [Boolean, Function],
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
||||
@@ -88,10 +88,6 @@ export default {
|
||||
hasExport: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
hasClone: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -150,7 +146,6 @@ export default {
|
||||
formatterArgs: {
|
||||
hasUpdate: false, // can set function(row, value)
|
||||
hasDelete: false, // can set function(row, value)
|
||||
hasClone: this.hasClone,
|
||||
moreActionsTitle: this.$t('common.More'),
|
||||
extraActions: [
|
||||
{
|
||||
@@ -158,7 +153,7 @@ export default {
|
||||
title: this.$t('common.View'),
|
||||
type: 'primary',
|
||||
callback: function(val) {
|
||||
this.MFAInfo.asset = val.row.id
|
||||
this.MFAInfo.asset = val.cellValue
|
||||
if (!this.needMFAVerify) {
|
||||
this.showMFADialog = true
|
||||
this.MFAConfirmed = true
|
||||
@@ -178,7 +173,7 @@ export default {
|
||||
title: this.$t('common.Delete'),
|
||||
type: 'primary',
|
||||
callback: (val) => {
|
||||
this.$axios.delete(`/api/v1/assets/asset-users/${val.row.id}/`).then(() => {
|
||||
this.$axios.delete(`/api/v1/assets/asset-users/${val.cellValue}/`).then(() => {
|
||||
this.$message.success(this.$t('common.deleteSuccessMsg'))
|
||||
this.$refs.ListTable.reloadTable()
|
||||
})
|
||||
@@ -189,7 +184,7 @@ export default {
|
||||
title: this.$t('common.Test'),
|
||||
callback: (val) => {
|
||||
this.$axios.post(
|
||||
`/api/v1/assets/asset-users/tasks/?id=${val.row.id}`,
|
||||
`/api/v1/assets/asset-users/tasks/?id=${val.cellValue}`,
|
||||
{ action: 'test' }
|
||||
).then(res => {
|
||||
window.open(`/#/ops/celery/task/${res.task}/log/`, '', 'width=900,height=600')
|
||||
@@ -199,7 +194,6 @@ export default {
|
||||
{
|
||||
name: 'Update',
|
||||
title: this.$t('common.Update'),
|
||||
can: !this.$store.getters.currentOrgIsRoot,
|
||||
callback: function(val) {
|
||||
this.showDialog = true
|
||||
this.dialogInfo.asset = val.row.asset
|
||||
@@ -217,7 +211,7 @@ export default {
|
||||
},
|
||||
headerActions: {
|
||||
hasLeftActions: this.hasLeftActions,
|
||||
hasMoreActions: false,
|
||||
hasBulkDelete: false,
|
||||
hasImport: this.hasImport,
|
||||
hasExport: this.hasExport,
|
||||
hasSearch: true,
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
<template>
|
||||
<DataForm
|
||||
:fields="iFields"
|
||||
:form="value"
|
||||
style="margin-left: -26%;margin-right: -6%"
|
||||
v-bind="kwargs"
|
||||
v-on="$listeners"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DataForm } from '@/components'
|
||||
|
||||
export default {
|
||||
name: 'NestedField',
|
||||
components: {
|
||||
DataForm
|
||||
},
|
||||
props: {
|
||||
fields: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
errors: {
|
||||
type: [Object, String],
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
kwargs: {
|
||||
hasReset: false,
|
||||
hasSaveContinue: false,
|
||||
defaultButton: false
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iFields() {
|
||||
const fields = this.fields
|
||||
if (this.errors && typeof this.errors === 'object') {
|
||||
// eslint-disable-next-line prefer-const
|
||||
for (let [name, error] of Object.entries(this.errors)) {
|
||||
const field = fields.find((v) => v.prop === name)
|
||||
if (!field) {
|
||||
continue
|
||||
}
|
||||
this.$log.debug(`${name}: ${error}`)
|
||||
if (typeof error === 'object' && !Array.isArray(error)) {
|
||||
error = this.objectToString(error)
|
||||
}
|
||||
field.attrs.error = error.toString()
|
||||
}
|
||||
}
|
||||
this.$log.debug('Fields change: ', fields, this.errors)
|
||||
return fields
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
objectToString(obj) {
|
||||
let data = ''
|
||||
// eslint-disable-next-line prefer-const
|
||||
for (let [key, value] of Object.entries(obj)) {
|
||||
if (typeof value === 'object') {
|
||||
value = this.objectToString(value)
|
||||
}
|
||||
data += ` ${key}: ${value} `
|
||||
}
|
||||
return data
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,13 +1,15 @@
|
||||
<template>
|
||||
<DataForm ref="dataForm" v-loading="loading" :fields="totalFields" :form="iForm" v-bind="$attrs" v-on="$listeners">
|
||||
<FormGroupHeader v-for="(group, i) in groups" :slot="'id:'+group.name" :key="'group-'+group.name" :title="group.title" :line="i !== 0" />
|
||||
<DataForm ref="dataForm" v-loading="loading" :fields="totalFields" v-bind="$attrs" v-on="$listeners">
|
||||
<FormGroupHeader v-for="(group, i) in groups" :slot="'id:'+group.name" :key="'group-'+group.name" :title="group.title" :line="i != 0" />
|
||||
</DataForm>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DataForm from '../DataForm'
|
||||
import FormGroupHeader from '@/components/FormGroupHeader'
|
||||
import { FormFieldGenerator } from '@/components/AutoDataForm/utils'
|
||||
// import { optionUrlMeta } from '@/api/common'
|
||||
import rules from '@/components/DataForm/rules'
|
||||
import Select2 from '@/components/Select2'
|
||||
export default {
|
||||
name: 'AutoDataForm',
|
||||
components: {
|
||||
@@ -29,10 +31,6 @@ export default {
|
||||
return []
|
||||
}
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
fieldsMeta: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
@@ -40,65 +38,171 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
remoteMeta: {},
|
||||
meta: {},
|
||||
totalFields: [],
|
||||
loading: true,
|
||||
groups: [],
|
||||
iForm: this.form
|
||||
groups: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.optionUrlMetaAndGenerateColumns()
|
||||
this.optionUrlMeta()
|
||||
},
|
||||
methods: {
|
||||
optionUrlMetaAndGenerateColumns() {
|
||||
optionUrlMeta() {
|
||||
this.$store.dispatch('common/getUrlMeta', { url: this.url }).then(data => {
|
||||
this.remoteMeta = data.actions[this.method.toUpperCase()] || {}
|
||||
this.meta = data.actions[this.method.toUpperCase()] || {}
|
||||
this.generateColumns()
|
||||
this.cleanFormValue()
|
||||
}).catch(err => {
|
||||
this.$log.error(err)
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
generateColumns() {
|
||||
const generator = new FormFieldGenerator()
|
||||
this.totalFields = generator.generateFields(this.fields, this.fieldsMeta, this.remoteMeta)
|
||||
this.groups = generator.groups
|
||||
this.$log.debug('Total fields: ', this.totalFields)
|
||||
},
|
||||
_cleanFormValue(form, remoteMeta) {
|
||||
for (const [k, v] of Object.entries(remoteMeta)) {
|
||||
if (v.default === undefined) {
|
||||
continue
|
||||
}
|
||||
const valueSet = form[k]
|
||||
if (valueSet !== undefined) {
|
||||
continue
|
||||
}
|
||||
if (v.type === 'nested object' && typeof valueSet === 'object') {
|
||||
this._cleanFormValue(valueSet, v.children)
|
||||
}
|
||||
form[k] = v.default
|
||||
generateFieldByType(type, field, fieldMeta) {
|
||||
switch (type) {
|
||||
case 'choice':
|
||||
type = 'radio-group'
|
||||
if (!fieldMeta.read_only) {
|
||||
field.options = fieldMeta.choices.map(v => {
|
||||
return { label: v.display_name, value: v.value }
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'datetime':
|
||||
type = 'date-picker'
|
||||
field.el = {
|
||||
type: 'datetime'
|
||||
}
|
||||
break
|
||||
case 'field':
|
||||
type = ''
|
||||
field.component = Select2
|
||||
if (fieldMeta.required) {
|
||||
field.el.clearable = false
|
||||
}
|
||||
break
|
||||
case 'string':
|
||||
type = 'input'
|
||||
if (!fieldMeta.max_length) {
|
||||
field.el.type = 'textarea'
|
||||
field.el.rows = 3
|
||||
}
|
||||
break
|
||||
default:
|
||||
type = 'input'
|
||||
break
|
||||
}
|
||||
if (type === 'radio-group') {
|
||||
if (!fieldMeta.read_only) {
|
||||
const options = fieldMeta.choices.map(v => {
|
||||
return { label: v.display_name, value: v.value }
|
||||
})
|
||||
if (options.length > 4) {
|
||||
type = 'select'
|
||||
field.el.filterable = true
|
||||
}
|
||||
}
|
||||
}
|
||||
field.type = type
|
||||
return field
|
||||
},
|
||||
cleanFormValue() {
|
||||
this._cleanFormValue(this.iForm, this.remoteMeta)
|
||||
generateFieldByName(name, field) {
|
||||
switch (name) {
|
||||
case 'email':
|
||||
field.el.type = 'email'
|
||||
break
|
||||
case 'password':
|
||||
field.el.type = 'password'
|
||||
break
|
||||
case 'comment':
|
||||
field.el.type = 'textarea'
|
||||
break
|
||||
}
|
||||
return field
|
||||
},
|
||||
generateFieldByOther(field, fieldMeta) {
|
||||
const filedRules = field.rules || []
|
||||
if (fieldMeta.required) {
|
||||
if (field.type === 'input') {
|
||||
filedRules.push(rules.Required)
|
||||
} else {
|
||||
filedRules.push(rules.RequiredChange)
|
||||
}
|
||||
}
|
||||
field.rules = filedRules
|
||||
return field
|
||||
},
|
||||
generateField(name) {
|
||||
let field = { id: name, prop: name, el: {}, attrs: {}}
|
||||
// const fieldMeta = this.meta[name] || this.meta['attrs']['children'][name] || {}
|
||||
const fieldMeta = this.meta[name] || ((this.meta['attrs']) ? (this.meta['attrs']['children'][name]) : {})
|
||||
field.label = fieldMeta.label
|
||||
field = this.generateFieldByType(fieldMeta.type, field, fieldMeta)
|
||||
field = this.generateFieldByName(name, field)
|
||||
field = this.generateFieldByOther(field, fieldMeta)
|
||||
field = Object.assign(field, this.fieldsMeta[name] || {})
|
||||
_.set(field, 'attrs.error', '')
|
||||
return field
|
||||
},
|
||||
generateFieldGroup(data) {
|
||||
const [groupTitle, fields] = data
|
||||
this.groups.push({
|
||||
id: groupTitle,
|
||||
title: groupTitle,
|
||||
name: fields[0]
|
||||
})
|
||||
return this.generateFields(fields)
|
||||
},
|
||||
generateFieldAttrs(name) {
|
||||
const fields = []
|
||||
Object.keys(this.meta[name]['children']).forEach((key, i) => {
|
||||
const filed = this.generateField(key)
|
||||
fields.push(filed)
|
||||
})
|
||||
return fields
|
||||
},
|
||||
generateFields(data) {
|
||||
let fields = []
|
||||
for (let field of data) {
|
||||
if (field instanceof Array) {
|
||||
const items = this.generateFieldGroup(field)
|
||||
fields = [...fields, ...items]
|
||||
} else if (field === 'attrs') {
|
||||
const items = this.generateFieldAttrs(field)
|
||||
fields = [...fields, ...items]
|
||||
// 修改title插入ID
|
||||
this.groups[this.groups.length - 1].name = items[0].id
|
||||
} else if (typeof field === 'string') {
|
||||
field = this.generateField(field)
|
||||
fields.push(field)
|
||||
} else if (field instanceof Object) {
|
||||
this.errors[field.prop] = ''
|
||||
_.set(field, 'attrs.error', '')
|
||||
fields.push(field)
|
||||
}
|
||||
}
|
||||
return fields
|
||||
},
|
||||
generateColumns() {
|
||||
this.totalFields = this.generateFields(this.fields)
|
||||
this.$log.debug('Total fields: ', this.totalFields)
|
||||
},
|
||||
setFieldError(name, error) {
|
||||
const field = this.totalFields.find((v) => v.prop === name)
|
||||
if (!field) {
|
||||
return
|
||||
}
|
||||
if (field.attrs.error === error) {
|
||||
error += '.'
|
||||
}
|
||||
if (field.type === 'nestedField') {
|
||||
field.el.errors = error
|
||||
} else {
|
||||
field.attrs.error = error
|
||||
if (typeof error === 'object') {
|
||||
const str = error
|
||||
error = ''
|
||||
Object.keys(str).forEach(key => {
|
||||
error += `${parseInt(key) + 1}.${str[key][0]} `
|
||||
})
|
||||
}
|
||||
// if (field.attrs.error === error) {
|
||||
// error += '.'
|
||||
// }
|
||||
field.attrs.error = error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import Select2 from '@/components/Select2'
|
||||
import NestedField from '@/components/AutoDataForm/components/NestedField'
|
||||
import rules from '@/components/DataForm/rules'
|
||||
|
||||
export class FormFieldGenerator {
|
||||
constructor() {
|
||||
this.groups = []
|
||||
}
|
||||
generateFieldByType(type, field, fieldMeta, fieldRemoteMeta) {
|
||||
switch (type) {
|
||||
case 'choice':
|
||||
type = 'radio-group'
|
||||
if (!fieldRemoteMeta.read_only) {
|
||||
field.options = fieldRemoteMeta.choices.map(v => {
|
||||
return { label: v.display_name, value: v.value }
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'datetime':
|
||||
type = 'date-picker'
|
||||
field.el = {
|
||||
type: 'datetime'
|
||||
}
|
||||
break
|
||||
case 'field':
|
||||
type = ''
|
||||
field.component = Select2
|
||||
if (fieldRemoteMeta.required) {
|
||||
field.el.clearable = false
|
||||
}
|
||||
break
|
||||
case 'string':
|
||||
type = 'input'
|
||||
if (!fieldRemoteMeta.max_length) {
|
||||
field.el.type = 'textarea'
|
||||
field.el.rows = 3
|
||||
}
|
||||
if (fieldRemoteMeta.write_only) {
|
||||
field.el.type = 'password'
|
||||
}
|
||||
break
|
||||
case 'boolean':
|
||||
type = 'checkbox'
|
||||
break
|
||||
case 'nested object':
|
||||
type = 'nestedField'
|
||||
field.component = NestedField
|
||||
field.label = ''
|
||||
field.labelWidth = 0
|
||||
field.el.fields = this.generateNestFields(field, fieldMeta, fieldRemoteMeta)
|
||||
field.el.errors = {}
|
||||
Vue.$log.debug('All fields in generate: ', field.el.allFields)
|
||||
break
|
||||
default:
|
||||
type = 'input'
|
||||
break
|
||||
}
|
||||
if (type === 'radio-group') {
|
||||
if (!fieldRemoteMeta.read_only) {
|
||||
const options = fieldRemoteMeta.choices.map(v => {
|
||||
return { label: v.display_name, value: v.value }
|
||||
})
|
||||
if (options.length > 4) {
|
||||
type = 'select'
|
||||
field.el.filterable = true
|
||||
}
|
||||
}
|
||||
}
|
||||
field.type = type
|
||||
return field
|
||||
}
|
||||
generateNestFields(field, fieldMeta, fieldRemoteMeta) {
|
||||
const fields = []
|
||||
const nestedFields = fieldMeta.fields || []
|
||||
const nestedFieldsMeta = fieldMeta.fieldsMeta || {}
|
||||
const nestedFieldsRemoteMeta = fieldRemoteMeta.children || {}
|
||||
for (const name of nestedFields) {
|
||||
const f = this.generateField(name, nestedFieldsMeta, nestedFieldsRemoteMeta)
|
||||
fields.push(f)
|
||||
}
|
||||
Vue.$log.debug('NestFields: ', fields)
|
||||
return fields
|
||||
}
|
||||
generateFieldByName(name, field) {
|
||||
switch (name) {
|
||||
case 'email':
|
||||
field.el.type = 'email'
|
||||
break
|
||||
case 'password':
|
||||
field.el.type = 'password'
|
||||
break
|
||||
case 'comment':
|
||||
field.el.type = 'textarea'
|
||||
break
|
||||
}
|
||||
return field
|
||||
}
|
||||
generateFieldByOther(field, fieldMeta, fieldRemoteMeta) {
|
||||
const filedRules = field.rules || []
|
||||
if (fieldRemoteMeta.required) {
|
||||
if (field.type === 'input') {
|
||||
filedRules.push(rules.Required)
|
||||
} else {
|
||||
filedRules.push(rules.RequiredChange)
|
||||
}
|
||||
}
|
||||
field.rules = filedRules
|
||||
return field
|
||||
}
|
||||
generateField(name, fieldsMeta, remoteFieldsMeta) {
|
||||
let field = { id: name, prop: name, el: {}, attrs: {}}
|
||||
const remoteFieldMeta = remoteFieldsMeta[name] || {}
|
||||
Vue.$log.debug('FieldsMeta: ', fieldsMeta, name)
|
||||
const fieldMeta = fieldsMeta[name] || {}
|
||||
Vue.$log.debug('FieldMeta is: ', fieldMeta)
|
||||
field.label = remoteFieldMeta.label
|
||||
field.helpText = remoteFieldMeta.help_text
|
||||
field = this.generateFieldByType(remoteFieldMeta.type, field, fieldMeta, remoteFieldMeta)
|
||||
field = this.generateFieldByName(name, field)
|
||||
field = this.generateFieldByOther(field, fieldMeta, remoteFieldMeta)
|
||||
const el = Object.assign(field.el || {}, fieldMeta.el || {})
|
||||
field = Object.assign(field, fieldMeta || {}, { el: el })
|
||||
_.set(field, 'attrs.error', '')
|
||||
return field
|
||||
}
|
||||
generateFieldGroup(field, fieldsMeta, remoteFieldsMeta) {
|
||||
const [groupTitle, fields] = field
|
||||
this.groups.push({
|
||||
id: groupTitle,
|
||||
title: groupTitle,
|
||||
name: fields[0]
|
||||
})
|
||||
return this.generateFields(fields, fieldsMeta, remoteFieldsMeta)
|
||||
}
|
||||
generateFields(_fields, fieldsMeta, remoteFieldsMeta) {
|
||||
let fields = []
|
||||
for (let field of _fields) {
|
||||
if (field instanceof Array) {
|
||||
const items = this.generateFieldGroup(field, fieldsMeta, remoteFieldsMeta)
|
||||
fields = [...fields, ...items]
|
||||
} else if (typeof field === 'string') {
|
||||
field = this.generateField(field, fieldsMeta, remoteFieldsMeta)
|
||||
fields.push(field)
|
||||
} else if (field instanceof Object) {
|
||||
this.errors[field.prop] = ''
|
||||
fields.push(field)
|
||||
}
|
||||
}
|
||||
return fields
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<TagSearch :options="iOption" v-bind="$attrs" v-on="$listeners" />
|
||||
<TagSearch :options="options" v-bind="$attrs" v-on="$listeners" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -23,22 +23,9 @@ export default {
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
internalOptions: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iOption() {
|
||||
return this.options.concat(this.internalOptions)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
options() {
|
||||
// 空函数,方便子组件刷新
|
||||
},
|
||||
url() {
|
||||
this.genericOptions()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -49,7 +36,6 @@ export default {
|
||||
methods: {
|
||||
async genericOptions() {
|
||||
const vm = this // 透传This
|
||||
vm.internalOptions = [] // 重置
|
||||
const data = await this.optionUrlMeta()
|
||||
const meta = data.actions['GET'] || {}
|
||||
for (const [name, field] of Object.entries(meta)) {
|
||||
@@ -63,6 +49,7 @@ export default {
|
||||
label: field.label,
|
||||
type: field.type,
|
||||
value: name
|
||||
|
||||
}
|
||||
if (field.type === 'choice' && field.choices) {
|
||||
option.children = field.choices.map(item => {
|
||||
@@ -82,7 +69,7 @@ export default {
|
||||
{ label: this.$t('common.No'), value: false }
|
||||
]
|
||||
}
|
||||
vm.internalOptions.push(option)
|
||||
vm.options.push(option)
|
||||
}
|
||||
},
|
||||
optionUrlMeta() {
|
||||
@@ -94,4 +81,5 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
<template>
|
||||
<Dialog
|
||||
v-if="showColumnSettingPopover"
|
||||
:title="$t('common.CustomCol')"
|
||||
:visible.sync="showColumnSettingPopover"
|
||||
:destroy-on-close="true"
|
||||
:show-cancel="false"
|
||||
width="35%"
|
||||
top="10%"
|
||||
@confirm="handleColumnConfirm()"
|
||||
>
|
||||
<el-alert type="success">
|
||||
{{ this.$t('common.TableColSettingInfo') }}
|
||||
</el-alert>
|
||||
<el-checkbox-group
|
||||
v-model="iCurrentColumns"
|
||||
>
|
||||
<el-row>
|
||||
<el-col
|
||||
v-for="item in totalColumnsList"
|
||||
:key="item.prop"
|
||||
:span="8"
|
||||
style="margin-top:5px;"
|
||||
>
|
||||
<el-checkbox
|
||||
:label="item.prop"
|
||||
:disabled="
|
||||
item.prop==='id' ||
|
||||
item.prop==='actions' ||
|
||||
minColumns.indexOf(item.prop)!==-1
|
||||
"
|
||||
>
|
||||
{{ item.label }}
|
||||
</el-checkbox>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</el-checkbox-group>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Dialog from '@/components/Dialog/index'
|
||||
export default {
|
||||
name: 'ColumnSettingPopover',
|
||||
components: {
|
||||
Dialog
|
||||
},
|
||||
props: {
|
||||
totalColumnsList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
currentColumns: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
minColumns: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showColumnSettingPopover: false,
|
||||
iCurrentColumns: ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$eventBus.$on('showColumnSettingPopover', () => {
|
||||
this.showColumnSettingPopover = true
|
||||
this.iCurrentColumns = this.currentColumns
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleColumnConfirm() {
|
||||
this.showColumnSettingPopover = false
|
||||
this.$emit('columnsUpdate', this.iCurrentColumns)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
</style>
|
||||
@@ -1,25 +1,15 @@
|
||||
<template>
|
||||
<div>
|
||||
<DataTable v-if="!loading" ref="dataTable" v-loading="loading" :config="iConfig" v-bind="$attrs" v-on="$listeners" @filter-change="filterChange" />
|
||||
<ColumnSettingPopover
|
||||
:current-columns="popoverColumns.currentCols"
|
||||
:total-columns-list="popoverColumns.totalColumnsList"
|
||||
:min-columns="popoverColumns.minCols"
|
||||
@columnsUpdate="handlePopoverColumnsChange"
|
||||
/>
|
||||
</div>
|
||||
<DataTable v-if="!loading" ref="dataTable" v-loading="loading" :config="iConfig" v-bind="$attrs" v-on="$listeners" @filter-change="filterChange" />
|
||||
</template>
|
||||
|
||||
<script type="text/jsx">
|
||||
import DataTable from '../DataTable'
|
||||
import { DateFormatter, DetailFormatter, DisplayFormatter, BooleanFormatter, ActionsFormatter } from '@/components/ListTable/formatters'
|
||||
import i18n from '@/i18n/i18n'
|
||||
import ColumnSettingPopover from './components/ColumnSettingPopover'
|
||||
export default {
|
||||
name: 'AutoDataTable',
|
||||
components: {
|
||||
DataTable,
|
||||
ColumnSettingPopover
|
||||
DataTable
|
||||
},
|
||||
props: {
|
||||
config: {
|
||||
@@ -37,18 +27,8 @@ export default {
|
||||
method: 'get',
|
||||
autoConfig: {},
|
||||
iConfig: {},
|
||||
meta: {},
|
||||
cleanedColumnsShow: {},
|
||||
totalColumns: [],
|
||||
popoverColumns: {
|
||||
totalColumnsList: [],
|
||||
minCols: [],
|
||||
currentCols: []
|
||||
}
|
||||
meta: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
watch: {
|
||||
config: {
|
||||
@@ -64,18 +44,10 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
async optionUrlMetaAndGenCols() {
|
||||
if (this.config.url === '') { return }
|
||||
const url = (this.config.url.indexOf('?') === -1) ? `${this.config.url}?draw=1&display=1` : `${this.config.url}&draw=1&display=1`
|
||||
this.$store.dispatch('common/getUrlMeta', { url: url }).then(data => {
|
||||
const method = this.method.toUpperCase()
|
||||
this.meta = data.actions && data.actions[method] ? data.actions[method] : {}
|
||||
this.generateTotalColumns()
|
||||
}).then(() => {
|
||||
// 根据当前列重新生成最终渲染表格
|
||||
this.filterShowColumns()
|
||||
}).then(() => {
|
||||
// 生成给子组件使用的TotalColList
|
||||
this.generatePopoverColumns()
|
||||
this.meta = data.actions[this.method.toUpperCase()] || {}
|
||||
this.generateColumns()
|
||||
}).catch((error) => {
|
||||
this.$log.error('Error occur: ', error)
|
||||
}).finally(() => {
|
||||
@@ -91,7 +63,7 @@ export default {
|
||||
break
|
||||
case 'actions':
|
||||
col = {
|
||||
prop: 'actions',
|
||||
prop: 'id',
|
||||
label: i18n.t('common.Actions'),
|
||||
align: 'center',
|
||||
width: '150px',
|
||||
@@ -193,7 +165,7 @@ export default {
|
||||
col = this.addFilterIfNeed(col)
|
||||
return col
|
||||
},
|
||||
generateTotalColumns() {
|
||||
generateColumns() {
|
||||
const config = _.cloneDeep(this.config)
|
||||
const columns = []
|
||||
for (let col of config.columns) {
|
||||
@@ -204,78 +176,9 @@ export default {
|
||||
columns.push(col)
|
||||
}
|
||||
}
|
||||
// 第一次初始化时记录 totalColumns
|
||||
this.totalColumns = columns
|
||||
config.columns = columns
|
||||
this.iConfig = config
|
||||
},
|
||||
// 生成给子组件使用的TotalColList
|
||||
cleanColumnsShow() {
|
||||
const totalColumnsNames = this.totalColumns.map(obj => obj.prop)
|
||||
// 默认列
|
||||
let defaultColumnsNames = _.get(this.iConfig, 'columnsShow.default', [])
|
||||
if (defaultColumnsNames.length === 0) {
|
||||
defaultColumnsNames = totalColumnsNames
|
||||
}
|
||||
// Clean it
|
||||
defaultColumnsNames = totalColumnsNames.filter(n => defaultColumnsNames.indexOf(n) > -1)
|
||||
|
||||
// 最小列
|
||||
const minColumnsNames = _.get(this.iConfig, 'columnsShow.min', ['action', 'id'])
|
||||
.filter(n => defaultColumnsNames.indexOf(n) > -1)
|
||||
|
||||
// 应该显示的列
|
||||
const _tableConfig = localStorage.getItem('tableConfig')
|
||||
? JSON.parse(localStorage.getItem('tableConfig'))
|
||||
: {}
|
||||
const configShowColumnsNames = _.get(_tableConfig[this.$route.name], 'showColumns', null)
|
||||
let showColumnsNames = configShowColumnsNames || defaultColumnsNames
|
||||
if (showColumnsNames.length === 0) {
|
||||
showColumnsNames = totalColumnsNames
|
||||
}
|
||||
// 校对显示的列,是不是包含最小列
|
||||
minColumnsNames.forEach((v, i) => {
|
||||
if (showColumnsNames.indexOf(v) === -1) {
|
||||
showColumnsNames.push(v)
|
||||
}
|
||||
})
|
||||
// Clean it
|
||||
showColumnsNames = totalColumnsNames.filter(n => showColumnsNames.indexOf(n) > -1)
|
||||
|
||||
this.cleanedColumnsShow = {
|
||||
default: defaultColumnsNames,
|
||||
show: showColumnsNames,
|
||||
min: minColumnsNames,
|
||||
configShow: configShowColumnsNames
|
||||
}
|
||||
this.$log.debug('Cleaned colums show: ', this.cleanedColumnsShow)
|
||||
},
|
||||
filterShowColumns() {
|
||||
this.cleanColumnsShow()
|
||||
this.iConfig.columns = this.totalColumns.filter(obj => {
|
||||
return this.cleanedColumnsShow.show.indexOf(obj.prop) > -1
|
||||
})
|
||||
},
|
||||
generatePopoverColumns() {
|
||||
this.popoverColumns.totalColumnsList = this.totalColumns.map(obj => {
|
||||
return { prop: obj.prop, label: obj.label }
|
||||
})
|
||||
this.popoverColumns.currentCols = this.cleanedColumnsShow.show
|
||||
this.popoverColumns.minCols = this.cleanedColumnsShow.min
|
||||
this.$log.debug('Popover cols: ', this.popoverColumns)
|
||||
},
|
||||
handlePopoverColumnsChange(columns) {
|
||||
// this.$log.debug('Columns change: ', columns)
|
||||
this.popoverColumns.currentCols = columns
|
||||
const _tableConfig = localStorage.getItem('tableConfig')
|
||||
? JSON.parse(localStorage.getItem('tableConfig'))
|
||||
: {}
|
||||
_tableConfig[this.$route.name] = {
|
||||
'showColumns': columns
|
||||
}
|
||||
localStorage.setItem('tableConfig', JSON.stringify(_tableConfig))
|
||||
this.filterShowColumns()
|
||||
},
|
||||
filterChange(filters) {
|
||||
const key = Object.keys(filters)[0]
|
||||
const attr = {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<DataZTree ref="dataztree" :setting="treeSetting" class="data-z-tree" v-on="$listeners">
|
||||
<slot v-if="treeSetting.hasRightMenu" slot="rMenu">
|
||||
<DataZTree ref="dataztree" :setting="treeSetting">
|
||||
<slot slot="rMenu">
|
||||
<li id="m_create" class="rmenu" tabindex="-1" @click="createTreeNode">
|
||||
<i class="fa fa-plus-square-o" /> {{ this.$t('tree.CreateNode') }}
|
||||
</li>
|
||||
@@ -55,8 +55,7 @@ export default {
|
||||
// beforeDrag
|
||||
// onDrag
|
||||
// beforeAsync: this.defaultCallback.bind(this, 'beforeAsync')
|
||||
},
|
||||
hasRightMenu: true
|
||||
}
|
||||
},
|
||||
currentNode: '',
|
||||
currentNodeId: ''
|
||||
@@ -64,7 +63,6 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
treeSetting() {
|
||||
this.$log.debug('Settings: ', this.setting)
|
||||
return _.merge(this.defaultSetting, this.setting)
|
||||
},
|
||||
zTree() {
|
||||
@@ -122,7 +120,7 @@ export default {
|
||||
this.$message.success(this.$t('common.deleteSuccessMsg'))
|
||||
this.zTree.removeNode(currentNode)
|
||||
}).catch(() => {
|
||||
// this.$message.error(this.$t('common.deleteErrorMsg') + ' ' + error)
|
||||
// this.$message.error(this.$t('common.deleteErrorMsg' + ' ' + error))
|
||||
})
|
||||
},
|
||||
onRename: function(event, treeId, treeNode, isCancel) {
|
||||
@@ -246,18 +244,12 @@ export default {
|
||||
},
|
||||
getSelectedNodes: function() {
|
||||
return this.zTree.getSelectedNodes()
|
||||
},
|
||||
getNodes: function() {
|
||||
return this.zTree.getNodes()
|
||||
},
|
||||
selectNode: function(node) {
|
||||
return this.zTree.selectNode(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang='less' scoped>
|
||||
.rmenu {
|
||||
font-size: 12px;
|
||||
padding: 0 16px;
|
||||
@@ -280,8 +272,4 @@ export default {
|
||||
.rmenu:hover{
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.data-z-tree >>> .fa {
|
||||
width: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
<template>
|
||||
<div :class="grouped ? 'el-button-group' : 'el-button-ungroup'">
|
||||
<template v-for="action in iActions">
|
||||
<el-dropdown
|
||||
v-if="action.dropdown"
|
||||
v-show="action.dropdown.length > 0"
|
||||
:key="action.name"
|
||||
class="action-item"
|
||||
trigger="click"
|
||||
placement="bottom-start"
|
||||
@command="handleDropdownCallback"
|
||||
>
|
||||
<el-button :size="size" v-bind="cleanButtonAction(action)">
|
||||
{{ action.title }}<i class="el-icon-arrow-down el-icon--right" />
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<template v-for="option in action.dropdown">
|
||||
<div v-if="option.group" :key="'group:'+option.name" class="dropdown-menu-title">
|
||||
{{ option.group }}
|
||||
</div>
|
||||
<el-dropdown-item
|
||||
:key="option.name"
|
||||
:command="[option, action]"
|
||||
v-bind="option"
|
||||
>
|
||||
{{ option.title }}
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
||||
<el-button
|
||||
v-else
|
||||
:key="action.name"
|
||||
:size="size"
|
||||
v-bind="cleanButtonAction(action)"
|
||||
class="action-item"
|
||||
@click="handleClick(action)"
|
||||
>
|
||||
<el-tooltip v-if="action.tip" effect="dark" :content="action.tip" placement="top">
|
||||
<i v-if="action.fa" :class="'fa ' + action.fa" />{{ action.title }}
|
||||
</el-tooltip>
|
||||
<span v-else>
|
||||
<i v-if="action.fa" :class="'fa ' + action.fa" />{{ action.title }}
|
||||
</span>
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'DataActions',
|
||||
props: {
|
||||
grouped: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'small'
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
actions: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iActions() {
|
||||
return this.cleanActions(this.actions)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleDropdownCallback(command) {
|
||||
const [option, dropdown] = command
|
||||
const defaultCallback = () => this.$log.debug('No callback found: ', option, dropdown)
|
||||
let callback = option.callback
|
||||
if (!callback) {
|
||||
callback = dropdown.callback
|
||||
}
|
||||
if (!callback) {
|
||||
callback = defaultCallback
|
||||
}
|
||||
return callback(option)
|
||||
},
|
||||
handleClick(action) {
|
||||
if (action && action.callback) {
|
||||
action.callback(action)
|
||||
} else {
|
||||
this.$log.debug('No callback found')
|
||||
}
|
||||
this.$emit('actionClick', action)
|
||||
},
|
||||
checkItem(item, attr, defaults) {
|
||||
if (!item) {
|
||||
return true
|
||||
}
|
||||
let ok = item[attr]
|
||||
if (ok && typeof ok === 'function') {
|
||||
ok = ok(item)
|
||||
} else if (ok == null) {
|
||||
ok = defaults === undefined ? true : defaults
|
||||
}
|
||||
return ok
|
||||
},
|
||||
cleanButtonAction(action) {
|
||||
action = _.cloneDeep(action)
|
||||
delete action['dropdown']
|
||||
delete action['callback']
|
||||
delete action['name']
|
||||
delete action['can']
|
||||
return action
|
||||
},
|
||||
cleanActions(actions) {
|
||||
const cleanedActions = []
|
||||
const cloneActions = _.cloneDeep(actions)
|
||||
for (const v of cloneActions) {
|
||||
if (!v) {
|
||||
continue
|
||||
}
|
||||
const action = Object.assign({}, v)
|
||||
// 是否拥有这个action
|
||||
const has = this.checkItem(action, 'has')
|
||||
delete action['has']
|
||||
if (!has) {
|
||||
continue
|
||||
}
|
||||
// 是否有分割线
|
||||
action.divided = this.checkItem(action, 'divided', false)
|
||||
|
||||
// 是否是disabled
|
||||
const can = this.checkItem(action, 'can')
|
||||
action.disabled = !can
|
||||
|
||||
if (action.dropdown) {
|
||||
// const dropdown = this.cleanActions(action.dropdown)
|
||||
action.dropdown = this.cleanActions(action.dropdown)
|
||||
}
|
||||
cleanedActions.push(action)
|
||||
}
|
||||
return cleanedActions
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dropdown-menu-title {
|
||||
text-align: left;
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
line-height: 30px;
|
||||
padding-left: 10px;
|
||||
padding-top: 10px;
|
||||
border-top: solid 1px #e4e7ed;
|
||||
}
|
||||
|
||||
.dropdown-menu-title:first-child {
|
||||
padding-top: 0;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.el-button-ungroup .action-item {
|
||||
margin-left: 4px
|
||||
}
|
||||
|
||||
.el-button-ungroup .action-item:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -4,7 +4,7 @@
|
||||
:content="fields"
|
||||
:form="basicForm"
|
||||
label-position="right"
|
||||
label-width="20%"
|
||||
label-width="17%"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
@@ -47,7 +47,7 @@ export default {
|
||||
// 初始值
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
default: () => { return {} }
|
||||
},
|
||||
moreButtons: {
|
||||
type: Array,
|
||||
|
||||
@@ -95,8 +95,6 @@ export default {
|
||||
vm.zTree.destroy()
|
||||
}
|
||||
this.zTree = $.fn.zTree.init($(`#${this.iZTreeID}`), this.treeSetting, res)
|
||||
// 手动上报事件, Tree加载完成
|
||||
this.$emit('TreeInitFinish', this.zTree)
|
||||
if (this.treeSetting.showRefresh) {
|
||||
this.rootNodeAddDom(
|
||||
this.zTree,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<ZTree ref="ztree" :setting="treeSetting" v-on="$listeners">
|
||||
<ZTree ref="ztree" :setting="treeSetting">
|
||||
<!--Slot透传-->
|
||||
<div slot="rMenu" slot-scope="{data}">
|
||||
<slot name="rMenu" :data="data" />
|
||||
|
||||
@@ -1,32 +1,24 @@
|
||||
<template>
|
||||
<DataActions
|
||||
v-if="hasLeftActions"
|
||||
:actions="iActions"
|
||||
v-bind="$attrs"
|
||||
class="header-action"
|
||||
/>
|
||||
<ActionsGroup v-if="hasLeftActions" :actions="actions" :more-actions="moreActions" :more-actions-title="moreActionsTitle" v-bind="$attrs" class="header-action" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import i18n from '@/i18n/i18n'
|
||||
import DataActions from '@/components/DataActions'
|
||||
import ActionsGroup from '@/components/ActionsGroup'
|
||||
import { createSourceIdCache } from '@/api/common'
|
||||
import { cleanActions } from './utils'
|
||||
|
||||
const defaultTrue = { type: [Boolean, Function], default: true }
|
||||
const defaultFalse = { type: [Boolean, Function], default: false }
|
||||
const defaultTrue = { type: Boolean, default: true }
|
||||
const defaultFalse = { type: Boolean, default: false }
|
||||
export default {
|
||||
name: 'LeftSide',
|
||||
components: {
|
||||
DataActions
|
||||
ActionsGroup
|
||||
},
|
||||
props: {
|
||||
hasLeftActions: defaultTrue,
|
||||
hasCreate: defaultTrue,
|
||||
canCreate: defaultTrue,
|
||||
hasBulkDelete: defaultTrue,
|
||||
hasBulkUpdate: defaultFalse,
|
||||
hasMoreActions: defaultTrue,
|
||||
hasLeftActions: defaultTrue,
|
||||
tableUrl: {
|
||||
type: String,
|
||||
default: ''
|
||||
@@ -61,41 +53,23 @@ export default {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
moreCreates: {
|
||||
moreActionsButton: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
createTitle: {
|
||||
type: String,
|
||||
default: () => i18n.t('common.Create')
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const defaultActions = [
|
||||
{
|
||||
name: 'actionCreate',
|
||||
title: this.createTitle,
|
||||
type: 'primary',
|
||||
has: this.hasCreate && !this.moreCreates,
|
||||
can: this.canCreate,
|
||||
callback: this.handleCreate
|
||||
}
|
||||
]
|
||||
if (this.moreCreates) {
|
||||
const defaultMoreCreate = {
|
||||
name: 'actionMoreCreate',
|
||||
title: this.createTitle,
|
||||
type: 'primary',
|
||||
has: true,
|
||||
can: this.canCreate,
|
||||
dropdown: [],
|
||||
callback: this.handleCreate
|
||||
}
|
||||
const createCreateAction = Object.assign(defaultMoreCreate, this.moreCreates)
|
||||
defaultActions.push(createCreateAction)
|
||||
}
|
||||
return {
|
||||
defaultActions: defaultActions,
|
||||
defaultActions: [
|
||||
{
|
||||
name: 'actionCreate',
|
||||
title: this.$t('common.Create'),
|
||||
type: 'primary',
|
||||
has: this.hasCreate,
|
||||
can: true,
|
||||
callback: this.handleCreate
|
||||
}
|
||||
],
|
||||
defaultMoreActions: [
|
||||
{
|
||||
title: this.$t('common.deleteSelected'),
|
||||
@@ -118,9 +92,6 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iActions() {
|
||||
return [...this.actions, this.moreAction]
|
||||
},
|
||||
actions() {
|
||||
const actions = [...this.defaultActions, ...this.extraActions]
|
||||
return cleanActions(actions, true, {
|
||||
@@ -128,20 +99,12 @@ export default {
|
||||
reloadTable: this.reloadTable
|
||||
})
|
||||
},
|
||||
moreAction() {
|
||||
if (!this.hasMoreActions) {
|
||||
return
|
||||
}
|
||||
let dropdown = [...this.defaultMoreActions, ...this.extraMoreActions]
|
||||
dropdown = cleanActions(dropdown, true, {
|
||||
moreActions() {
|
||||
const actions = [...this.defaultMoreActions, ...this.extraMoreActions]
|
||||
return cleanActions(actions, true, {
|
||||
selectedRows: this.selectedRows,
|
||||
reloadTable: this.reloadTable
|
||||
})
|
||||
return {
|
||||
name: 'moreActions',
|
||||
title: this.moreActionsTitle || this.$t('common.MoreActions'),
|
||||
dropdown: dropdown
|
||||
}
|
||||
},
|
||||
hasSelectedRows() {
|
||||
return this.selectedRows.length > 0
|
||||
|
||||
@@ -37,13 +37,6 @@ export default {
|
||||
this.$eventBus.$emit('showImportDialog', { selectedRows })
|
||||
}
|
||||
},
|
||||
hasColumnSetting: defaultTrue,
|
||||
handleColumnConfig: {
|
||||
type: Function,
|
||||
default: function() {
|
||||
this.$eventBus.$emit('showColumnSettingPopover')
|
||||
}
|
||||
},
|
||||
hasRefresh: defaultTrue,
|
||||
selectedRows: {
|
||||
type: Array,
|
||||
@@ -61,7 +54,6 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
defaultRightSideActions: [
|
||||
{ name: 'actionColumnSetting', fa: 'fa-cog', tip: this.$t('common.CustomCol'), has: this.hasColumnSetting, callback: this.handleColumnConfig.bind(this) },
|
||||
{ name: 'actionExport', fa: 'fa-download', tip: this.$t('common.Export'), has: this.hasExport, callback: this.handleExport.bind(this) },
|
||||
{ name: 'actionImport', fa: 'fa-upload', tip: this.$t('common.Import'), has: this.hasImport, callback: this.handleImport.bind(this) },
|
||||
{ name: 'actionRefresh', fa: 'fa-refresh', tip: this.$t('common.Refresh'), has: this.hasRefresh, callback: this.handleRefresh }
|
||||
|
||||
@@ -5,9 +5,7 @@ export function cleanActions(actions, canDefaults, { selectedRows, reloadTable }
|
||||
cloneActions.forEach((action) => {
|
||||
action.has = cleanBoolean(action, 'has', true, { selectedRows, reloadTable })
|
||||
action.can = cleanBoolean(action, 'can', true, { selectedRows, reloadTable })
|
||||
if (!action.dropdown) {
|
||||
action.callback = cleanCallback(action, { selectedRows, reloadTable })
|
||||
}
|
||||
action.callback = cleanCallback(action, { selectedRows, reloadTable })
|
||||
cleanedActions.push(action)
|
||||
})
|
||||
return cleanedActions
|
||||
|
||||
@@ -81,15 +81,11 @@ export default {
|
||||
default: function() {
|
||||
return {
|
||||
hasUpdate: true, // can set function(row, value)
|
||||
canUpdate: () => {
|
||||
return !this.$store.getters.currentOrgIsRoot
|
||||
}, // can set function(row, value)
|
||||
canUpdate: true, // can set function(row, value)
|
||||
hasDelete: true, // can set function(row, value)
|
||||
canDelete: true,
|
||||
hasClone: true,
|
||||
canClone: () => {
|
||||
return !this.$store.getters.currentOrgIsRoot
|
||||
},
|
||||
hasClone: false,
|
||||
canClone: true,
|
||||
updateRoute: this.$route.name.replace('List', 'Update'),
|
||||
cloneRoute: this.$route.name.replace('List', 'Create'),
|
||||
performDelete: defaultPerformDelete,
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<template>
|
||||
<span>{{ cellValue.toString() }}</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BaseFormatter from './base'
|
||||
export default {
|
||||
name: 'ArrayFormatter',
|
||||
extends: BaseFormatter
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,42 +0,0 @@
|
||||
<template>
|
||||
<i :class="'fa ' + iconClass" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BaseFormatter from './base'
|
||||
export default {
|
||||
name: 'ChoicesFormatter',
|
||||
extends: BaseFormatter,
|
||||
props: {
|
||||
formatterArgsDefault: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
iconChoices: {
|
||||
true: 'fa-check text-primary',
|
||||
false: 'fa-times text-danger'
|
||||
},
|
||||
typeChange(val) {
|
||||
return !!val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formatterArgs: Object.assign(this.formatterArgsDefault, this.col.formatterArgs)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iconClass() {
|
||||
const key = this.formatterArgs.typeChange(this.cellValue)
|
||||
return this.formatterArgs.iconChoices[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -28,9 +28,6 @@ export default {
|
||||
},
|
||||
hasTips: false,
|
||||
tipStatus(val, vm) {
|
||||
if (!val) {
|
||||
return vm.$t('assets.Unknown')
|
||||
}
|
||||
if (val.status === 0) {
|
||||
return vm.$t('assets.Unreachable')
|
||||
} else if (val.status === 1) {
|
||||
@@ -58,9 +55,6 @@ export default {
|
||||
return this.formatterArgs.tipStatus(this.cellValue, vm)
|
||||
},
|
||||
tipTime() {
|
||||
if (!this.cellValue) {
|
||||
return ''
|
||||
}
|
||||
return toSafeLocalDateStr(this.cellValue.datetime)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<ActionsGroup :size="'mini'" :actions="cleanedActions" :more-actions="cleanMoreActions" v-bind="$attrs" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ActionsGroup from '@/components/ActionsGroup/index'
|
||||
import BaseFormatter from './base'
|
||||
|
||||
export default {
|
||||
name: 'CustomActionsFormatterVue',
|
||||
components: {
|
||||
ActionsGroup
|
||||
},
|
||||
extends: BaseFormatter,
|
||||
computed: {
|
||||
cleanedActions() {
|
||||
if (this.col.actions.actions instanceof Array) {
|
||||
const copy = _.cloneDeep(this.col.actions.actions)
|
||||
let actions = [...copy]
|
||||
actions = actions.map((v) => {
|
||||
v.has = this.checkBool(v, 'has')
|
||||
v.can = this.checkBool(v, 'can')
|
||||
v.callback = this.cleanCallback(v)
|
||||
return v
|
||||
})
|
||||
return actions
|
||||
}
|
||||
return []
|
||||
},
|
||||
cleanMoreActions() {
|
||||
if (this.col.actions.extraActions instanceof Array) {
|
||||
const copy = _.cloneDeep(this.col.actions.extraActions)
|
||||
let actions = [...copy]
|
||||
actions = actions.map((v) => {
|
||||
v.has = this.checkBool(v, 'has')
|
||||
v.can = this.checkBool(v, 'can')
|
||||
v.callback = this.cleanCallback(v)
|
||||
return v
|
||||
})
|
||||
return actions
|
||||
}
|
||||
return []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// console.log(this.col)
|
||||
},
|
||||
methods: {
|
||||
checkBool(item, attr, defaults) {
|
||||
if (!item) {
|
||||
return false
|
||||
}
|
||||
let ok = item[attr]
|
||||
if (ok && typeof ok === 'function') {
|
||||
ok = ok(this.row, this.cellValue)
|
||||
} else if (ok == null) {
|
||||
ok = defaults === undefined ? true : defaults
|
||||
}
|
||||
return ok
|
||||
},
|
||||
cleanCallback(item) {
|
||||
const callback = item.callback
|
||||
const attrs = {
|
||||
reload: this.reload,
|
||||
row: this.row,
|
||||
col: this.col,
|
||||
cellValue: this.cellValue,
|
||||
tableData: this.tableData
|
||||
}
|
||||
return () => { return callback.bind(this)(attrs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-button ref="deleteButton" size="mini" type="danger" :disabled="iDisabled" @click="onDelete(col, row, cellValue, reload)">
|
||||
<el-button ref="deleteButton" size="mini" type="danger" :disabled="canDelete" @click="onDelete(col, row, cellValue, reload)">
|
||||
<i class="fa fa-minus" />
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -11,9 +11,8 @@ export default {
|
||||
name: 'DeleteActionFormatter',
|
||||
extends: BaseFormatter,
|
||||
computed: {
|
||||
iDisabled() {
|
||||
// 禁用
|
||||
return (this.disabled() || this.$store.getters.currentOrgIsRoot)
|
||||
canDelete() {
|
||||
return this.iCanDelete()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -23,7 +22,7 @@ export default {
|
||||
this.$message.success(this.$t('common.deleteSuccessMsg'))
|
||||
reload()
|
||||
}).catch(error => {
|
||||
this.$message.error(this.$t('common.deleteErrorMsg') + ' ' + error)
|
||||
this.$message.error(this.$t('common.deleteErrorMsg' + ' ' + error))
|
||||
})
|
||||
},
|
||||
onDelete(col, row, cellValue, reload) {
|
||||
@@ -33,7 +32,7 @@ export default {
|
||||
this.defaultOnDelete(col, row, cellValue, reload)
|
||||
}
|
||||
},
|
||||
disabled() {
|
||||
iCanDelete() {
|
||||
if (this.col.objects === 'all') {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import DetailFormatter from './DetailFormatter'
|
||||
import ArrayFormatter from './ArrayFormatter'
|
||||
import DisplayFormatter from './DisplayFormatter'
|
||||
import BooleanFormatter from './BooleanFormatter'
|
||||
import ChoicesFormatter from './ChoicesFormatter'
|
||||
import BooleanFormatter from './ChoicesFormatter'
|
||||
import ActionsFormatter from './ActionsFormatter'
|
||||
import CustomActionsFormatter from './CustomActionsFormatter'
|
||||
import DeleteActionFormatter from './DeleteActionFormatter'
|
||||
import DateFormatter from './DateFormatter'
|
||||
import SystemUserFormatter from './GrantedSystemUsersShowFormatter'
|
||||
@@ -15,28 +14,26 @@ export default {
|
||||
DetailFormatter,
|
||||
DisplayFormatter,
|
||||
BooleanFormatter,
|
||||
ChoicesFormatter,
|
||||
ActionsFormatter,
|
||||
CustomActionsFormatter,
|
||||
DeleteActionFormatter,
|
||||
DateFormatter,
|
||||
SystemUserFormatter,
|
||||
ShowKeyFormatter,
|
||||
DialogDetailFormatter,
|
||||
LoadingActionsFormatter,
|
||||
ArrayFormatter
|
||||
LoadingActionsFormatter
|
||||
}
|
||||
|
||||
export {
|
||||
DetailFormatter,
|
||||
DisplayFormatter,
|
||||
BooleanFormatter,
|
||||
ChoicesFormatter,
|
||||
ActionsFormatter,
|
||||
CustomActionsFormatter,
|
||||
DeleteActionFormatter,
|
||||
DateFormatter,
|
||||
SystemUserFormatter,
|
||||
ShowKeyFormatter,
|
||||
DialogDetailFormatter,
|
||||
LoadingActionsFormatter,
|
||||
ArrayFormatter
|
||||
LoadingActionsFormatter
|
||||
}
|
||||
|
||||
@@ -42,20 +42,21 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
dataTable() {
|
||||
return this.$refs.dataTable.$refs.dataTable
|
||||
},
|
||||
// hasCreateAction() {
|
||||
// const hasLeftAction = this.headerActions.hasLeftActions
|
||||
// if (hasLeftAction === false) {
|
||||
// return false
|
||||
// }
|
||||
// const hasCreate = this.headerActions.hasCreate
|
||||
// if (hasCreate === false) {
|
||||
// return false
|
||||
// }
|
||||
// return true
|
||||
// },
|
||||
hasCreateAction() {
|
||||
const hasLeftAction = this.headerActions.hasLeftActions
|
||||
if (hasLeftAction === false) {
|
||||
return false
|
||||
}
|
||||
const hasCreate = this.headerActions.hasCreate
|
||||
if (hasCreate === false) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
iTableConfig() {
|
||||
const config = deepmerge(this.tableConfig, { extraQuery: this.extraQuery })
|
||||
this.$log.debug('Header actions', this.headerActions)
|
||||
@@ -85,11 +86,9 @@ export default {
|
||||
this.dataTable.getList()
|
||||
},
|
||||
search(attrs) {
|
||||
this.$emit('TagSearch', attrs)
|
||||
return this.dataTable.search(attrs, true)
|
||||
},
|
||||
filter(attrs) {
|
||||
this.$emit('TagFilter', attrs)
|
||||
this.$refs.dataTable.$refs.dataTable.search(attrs, true)
|
||||
},
|
||||
handleDateChange(attrs) {
|
||||
@@ -103,7 +102,6 @@ export default {
|
||||
date_from: attrs[0].toISOString(),
|
||||
date_to: attrs[1].toISOString()
|
||||
}
|
||||
this.$emit('TagDateChange', attrs)
|
||||
return this.dataTable.searchDate(query)
|
||||
},
|
||||
toggleRowSelection(row, isSelected) {
|
||||
|
||||
@@ -1,28 +1,22 @@
|
||||
<template>
|
||||
<IBox :fa="icon" :type="type" :title="title" v-bind="$attrs">
|
||||
<table style="width: 100%;table-layout:fixed;" class="CardTable">
|
||||
<table style="width: 100%">
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<Select2 ref="select2" v-model="select2.value" :disabled="iDisabled" v-bind="select2" />
|
||||
<Select2 ref="select2" v-model="select2.value" v-bind="select2" />
|
||||
</td>
|
||||
</tr>
|
||||
<slot />
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<el-button :type="type" size="small" :loading="submitLoading" :disabled="iDisabled" @click="addObjects">
|
||||
{{ $t('common.Add') }}
|
||||
</el-button>
|
||||
<el-button :type="type" size="small" :loading="submitLoading" @click="addObjects">{{ $t('common.Add') }}</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
<template v-if="showHasObjects">
|
||||
<tr v-for="obj of iHasObjects" :key="obj.value" class="item">
|
||||
<td style="width: 100%;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;">
|
||||
<el-tooltip style="margin: 4px;" effect="dark" :content="obj.label" placement="left">
|
||||
<b>{{ obj.label }}</b>
|
||||
</el-tooltip>
|
||||
</td>
|
||||
<tr v-for="obj of iHasObjects" :key="obj.value" style="width: 100%" class="item">
|
||||
<td><b>{{ obj.label }}</b></td>
|
||||
<td>
|
||||
<el-button size="mini" :disabled="iDisabled" type="danger" style="float: right" @click="removeObject(obj)">
|
||||
<el-button size="mini" type="danger" style="float: right" @click="removeObject(obj)">
|
||||
<i class="fa fa-minus" />
|
||||
</el-button>
|
||||
</td>
|
||||
@@ -30,7 +24,7 @@
|
||||
</template>
|
||||
<tr v-if="params.hasMore && showHasMore" class="item">
|
||||
<td colspan="2">
|
||||
<el-button :type="type" :disabled="iDisabled" size="small" style="width: 100%" @click="loadMore">
|
||||
<el-button :type="type" size="small" style="width: 100%" @click="loadMore">
|
||||
<i class="fa fa-arrow-down" />
|
||||
{{ $t('common.More') }}
|
||||
</el-button>
|
||||
@@ -44,7 +38,6 @@
|
||||
import Select2 from '../Select2'
|
||||
import IBox from '../IBox'
|
||||
import { createSourceIdCache } from '@/api/common'
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
name: 'RelationCard',
|
||||
components: {
|
||||
@@ -90,10 +83,6 @@ export default {
|
||||
type: [Array, Number, String],
|
||||
default: () => []
|
||||
},
|
||||
disabled: {
|
||||
type: [Boolean, Function],
|
||||
default: null
|
||||
},
|
||||
showHasMore: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
@@ -145,13 +134,11 @@ export default {
|
||||
ajax: this.objectsAjax,
|
||||
options: this.objects,
|
||||
value: this.value,
|
||||
disabled: this.disabled,
|
||||
disabledValues: []
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['currentOrgIsRoot']),
|
||||
iAjax() {
|
||||
return this.$refs.select2.iAjax
|
||||
},
|
||||
@@ -160,12 +147,6 @@ export default {
|
||||
},
|
||||
hasObjectLeftLength() {
|
||||
return this.totalHasObjectsLength - this.iHasObjects.length
|
||||
},
|
||||
iDisabled() {
|
||||
if (this.disabled !== null) {
|
||||
return this.disabled
|
||||
}
|
||||
return this.currentOrgIsRoot
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
@@ -5,10 +5,8 @@
|
||||
<component
|
||||
:is="component"
|
||||
ref="AutoDataZTree"
|
||||
:key="componentTreeKey"
|
||||
:setting="treeSetting"
|
||||
class="auto-data-ztree"
|
||||
v-on="$listeners"
|
||||
@urlChange="handleUrlChange"
|
||||
>
|
||||
<div slot="rMenu" slot-scope="{data}">
|
||||
@@ -24,7 +22,7 @@
|
||||
</div>
|
||||
<div class="transition-box" style="width: calc(100% - 17px);">
|
||||
<slot name="table">
|
||||
<ListTable ref="ListTable" :key="componentKey" :table-config="iTableConfig" :header-actions="headerActions" v-on="$listeners" />
|
||||
<ListTable ref="ListTable" :key="componentKey" :table-config="iTableConfig" :header-actions="headerActions" />
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,17 +63,10 @@ export default {
|
||||
return {
|
||||
iTableConfig: this.tableConfig,
|
||||
iShowTree: this.showTree,
|
||||
componentKey: 0,
|
||||
componentTreeKey: 0
|
||||
componentKey: 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
treeConfig: {
|
||||
handler(val) {
|
||||
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleUrlChange(_url) {
|
||||
@@ -86,20 +77,11 @@ export default {
|
||||
forceRerender() {
|
||||
this.componentKey += 1
|
||||
},
|
||||
forceRerenderTree() {
|
||||
this.componentTreeKey += 1
|
||||
},
|
||||
hideRMenu() {
|
||||
this.$refs.AutoDataZTree.hideRMenu()
|
||||
},
|
||||
getSelectedNodes: function() {
|
||||
return this.$refs.AutoDataZTree.getSelectedNodes()
|
||||
},
|
||||
getNodes: function() {
|
||||
return this.$refs.AutoDataZTree.getNodes()
|
||||
},
|
||||
selectNode: function(node) {
|
||||
return this.$refs.AutoDataZTree.selectNode(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +1,7 @@
|
||||
{
|
||||
"": "",
|
||||
"acl": {
|
||||
"name": "名称",
|
||||
"username": "用户名",
|
||||
"ip_group": "IP 组",
|
||||
"action": "动作",
|
||||
"priority": "优先级",
|
||||
"date_created": "创建时间",
|
||||
"created_by": "创建者",
|
||||
"asset": "资产信息",
|
||||
"users":"用户信息",
|
||||
"system_user": "系统用户",
|
||||
"username_group":"用户名",
|
||||
"hostname_group":"资产名",
|
||||
"asset_ip_group": "资产IP",
|
||||
"system_users_name_group": "系统用户名称",
|
||||
"system_users_protocol_group": "系统用户协议",
|
||||
"system_users_username_group": "系统用户名",
|
||||
"apply_login_asset": "申请登录资产",
|
||||
"apply_login_system_user": "申请登录系统用户",
|
||||
"apply_login_user": "申请登录用户",
|
||||
"RuleDetail": "规则详情"
|
||||
},
|
||||
"applications": {
|
||||
"": "",
|
||||
"RemoteApp": "远程应用",
|
||||
"Database": "数据库",
|
||||
"Cloud": "云",
|
||||
"applicationsType": {
|
||||
"chrome": "Chrome",
|
||||
"mysql_workbench": "MySQL Workbench",
|
||||
@@ -189,17 +164,13 @@
|
||||
"Version": "版本",
|
||||
"command_filter_list": "命令过滤器列表",
|
||||
"date_joined": "创建日期",
|
||||
"sshKeyFingerprint": "SSH 指纹",
|
||||
"ip": "IP",
|
||||
"sshkey": "sshkey",
|
||||
"GroupsHelpMessage": "请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)",
|
||||
"HomeHelpMessage": "默认家目录 /home/系统用户名: /home/username",
|
||||
"Home": "家目录",
|
||||
"LinuxUserAffiliateGroup": "用户附属组",
|
||||
"ipDomain": "IP(域名)",
|
||||
"HostProtocol": "主机协议",
|
||||
"DatabaseProtocol": "数据库协议",
|
||||
"OtherProtocol": "其它协议"
|
||||
"ipDomain": "IP(域名)"
|
||||
|
||||
},
|
||||
"audits": {
|
||||
@@ -481,7 +452,6 @@
|
||||
"downloadFile": "下载文件",
|
||||
"hostName": "主机名",
|
||||
"isValid": "有效",
|
||||
"isEffective": "起作用的",
|
||||
"nodeCount": "节点数量",
|
||||
"refreshFail": "刷新失败",
|
||||
"refreshPermissionCache": "刷新授权缓存",
|
||||
@@ -551,15 +521,7 @@
|
||||
"KubernetesAppPermissionDetail": "Kubernetes授权详情",
|
||||
"KubernetesAppPermissionUpdate": "更新Kubernetes授权规则",
|
||||
"KubernetesAppUpdate": "更新Kubernetes",
|
||||
"Acl": "访问控制",
|
||||
"UserAclList": "用户登录",
|
||||
"UserAclCreate": "创建用户登录规则",
|
||||
"UserAclUpdate": "更新用户登录规则",
|
||||
"UserAclDetail": "用户登录规则详情",
|
||||
"AssetAclList": "登录资产",
|
||||
"AssetAclCreate": "创建资产登录规则",
|
||||
"AssetAclUpdate": "更新资产登录规则",
|
||||
"AssetAclDetail": "资产登录规则详情",
|
||||
|
||||
"DomainCreate": "创建网域",
|
||||
"DomainDetail": "网域详情",
|
||||
"DomainList": "网域列表",
|
||||
@@ -662,7 +624,6 @@
|
||||
"name": "名称",
|
||||
"protocol": "协议",
|
||||
"region": "地域",
|
||||
"EsDisabled": "节点不可用, 请联系管理员",
|
||||
"sessionActiveCount": "在线会话数量",
|
||||
"systemCpuLoad": "CPU负载",
|
||||
"systemDiskUsedPercent": "硬盘使用率",
|
||||
@@ -691,7 +652,7 @@
|
||||
"sessionMonitor": "监控",
|
||||
"TerminateTaskSendSuccessMsg": "终断任务已下发,请稍后刷新查看",
|
||||
"helpText": {
|
||||
"esUrl": "提示:如果有多台主机,请使用逗号 ( , ) 进行分割。(eg: http://www.jumpserver.a.com:3000,http://www.jumpserver.b.com:3000)",
|
||||
"esUrl": "提示:如果有多台主机,请使用逗号 ( , ) 进行分割。(eg: http://www.jumpserver.a.com,http://www.jumpserver.b.com)",
|
||||
"esIndex": "es提供默认index:jumpserver",
|
||||
"esDocType": "es默认文档类型:command",
|
||||
"s3Endpoint": "S3 格式: http://s3.{REGION_NAME}.amazonaws.com<br>S3(China) 格式: http://s3.{REGION_NAME}.amazonaws.com.cn<br>如: http://s3.cn-north-1.amazonaws.com.cn",
|
||||
@@ -747,11 +708,9 @@
|
||||
"emailTest": "测试连接",
|
||||
"emailUserSSL": "使用SSL",
|
||||
"emailUserTLS": "使用TLS",
|
||||
"InsecureCommandAlert": "危险命令告警",
|
||||
"SecurityInsecureCommand": "危险命令告警",
|
||||
"Insecure_Command_Alert": "危险命令告警",
|
||||
"SecurityInsecureCommandEmailReceiver": "告警接收邮件",
|
||||
"MailSend": "邮件发送",
|
||||
"LDAPServerInfo": "LDAP 服务器",
|
||||
"LDAPUser": "LDAP 用户",
|
||||
"helpText": {
|
||||
"ApiKeyList": "使用api key签名请求头,每个请求的头部是不一样的, 请查阅使用文档",
|
||||
"authLdapSearchFilter": "可能的选项是(cn或uid或sAMAccountName=%(user)s)",
|
||||
@@ -761,7 +720,7 @@
|
||||
"emailCustomUserCreatedHonorific": "提示: 创建用户时,发送设置密码邮件的敬语 (例如: 您好)",
|
||||
"emailCustomUserCreatedSignature": "提示: 邮件的署名 (例如: jumpserver)",
|
||||
"emailCustomUserCreatedSubject": "提示: 创建用户时,发送设置密码邮件的主题 (例如: 创建用户成功)",
|
||||
"emailEmailFrom": "",
|
||||
"emailEmailFrom": "提示:发送邮件账号,默认使用SMTP账号作为发送账号",
|
||||
"emailHostPassword": "提示:一些邮件提供商需要输入的是Token",
|
||||
"emailRecipient": "提示:仅用来作为测试邮件收件人",
|
||||
"emailSubjectPrefix": "提示: 一些关键字可能会被邮件提供商拦截,如 跳板机、JumpServer",
|
||||
@@ -1038,7 +997,6 @@
|
||||
"AWS_Int": "AWS(国际)",
|
||||
"HuaweiCloud": "华为云",
|
||||
"Azure":"Azure(中国)",
|
||||
"Azure_Int": "Azure(国际)",
|
||||
"HostnameStrategy": "用于生成资产主机名。例如:1. 实例名称 (instanceDemo);2. 实例名称和部分IP(后两位) (instanceDemo-250.1)",
|
||||
"IsAlwaysUpdate": "资产信息保持最新",
|
||||
"AccountCreate": "创建账户",
|
||||
|
||||
@@ -1,31 +1,7 @@
|
||||
{
|
||||
"": "",
|
||||
"acl": {
|
||||
"name": "Name",
|
||||
"username": "Username",
|
||||
"ip_group": "IP group",
|
||||
"action": "Action",
|
||||
"priority": "Priority",
|
||||
"date_created": "Date created",
|
||||
"created_by": "Created by",
|
||||
"asset": "Asset",
|
||||
"system_user": "System user",
|
||||
"username_group":"Username group",
|
||||
"hostname_group":"Hostname group",
|
||||
"asset_ip_group": "Asset ip group",
|
||||
"system_users_name_group": "Systemusers name group",
|
||||
"system_users_protocol_group": "Systemusers protocol group",
|
||||
"system_users_username_group": "systemusers username group",
|
||||
"apply_login_asset": "Apply login asset",
|
||||
"apply_login_system_user": "Apply login system user",
|
||||
"apply_login_user": "Apply login user",
|
||||
"RuleDetail": "Rule detail"
|
||||
},
|
||||
"applications": {
|
||||
"": "",
|
||||
"RemoteApp": "Remote app",
|
||||
"Database": "Database",
|
||||
"Cloud": "Cloud",
|
||||
"applicationsType": {
|
||||
"chrome": "Chrome",
|
||||
"mysql_workbench": "MySQL Workbench",
|
||||
@@ -188,17 +164,13 @@
|
||||
"Version": "Version",
|
||||
"command_filter_list": "Command filter list",
|
||||
"date_joined": "Date joined",
|
||||
"sshKeyFingerprint": "SSH fingerprint",
|
||||
"ip": "IP",
|
||||
"sshkey": "sshkey",
|
||||
"GroupsHelpMessage": "Please fill in user groups, separated by commas if there are multiple user groups(Please fill in the existing user groups)",
|
||||
"HomeHelpMessage": "Default home directory: /home/system username",
|
||||
"Home": "Home",
|
||||
"LinuxUserAffiliateGroup": "Linux user affiliate group",
|
||||
"ipDomain": "IP(Domain)",
|
||||
"HostProtocol": "Host Protocol",
|
||||
"DatabaseProtocol": "Database Protocol",
|
||||
"Other Protocol": "Database Protocol"
|
||||
"ipDomain": "IP(Domain)"
|
||||
},
|
||||
"audits": {
|
||||
"Hosts": "Host",
|
||||
@@ -478,7 +450,6 @@
|
||||
"downloadFile": "Download file",
|
||||
"hostName": "Hostname",
|
||||
"isValid": "Validity",
|
||||
"isEffective": "Effective",
|
||||
"nodeCount": "Node count",
|
||||
"refreshFail": "Refresh fail",
|
||||
"refreshPermissionCache": "Refresh permission cache",
|
||||
@@ -548,15 +519,6 @@
|
||||
"KubernetesAppPermissionDetail": "Kubernetes permissions detail",
|
||||
"KubernetesAppPermissionUpdate": "Kubernetes permissions update",
|
||||
"KubernetesAppUpdate": "Kubernetes app update",
|
||||
"Acl": "Access control",
|
||||
"UserAclList": "User acl list",
|
||||
"UserAclCreate": "User acl create",
|
||||
"UserAclUpdate": "User acl update",
|
||||
"UserAclDetail": "User acl detail",
|
||||
"AssetAclList": "Asset acl list",
|
||||
"AssetAclCreate": "Asset acl create",
|
||||
"AssetAclUpdate": "Asset acl update",
|
||||
"AssetAclDetail": "Asset acl detail",
|
||||
"DomainCreate": "Domain create",
|
||||
"DomainDetail": "Domain detail",
|
||||
"DomainList": "Domains",
|
||||
@@ -647,7 +609,6 @@
|
||||
"systemCpuLoad": "cpu load",
|
||||
"systemDiskUsedPercent": "disk used percent",
|
||||
"systemMemoryUsedPercent": "memory used percent",
|
||||
"EsDisabled": "Node is unavailable, please contact administrator",
|
||||
"go": "Go",
|
||||
"goto": "Goto",
|
||||
"hosts": "Hosts",
|
||||
@@ -740,10 +701,6 @@
|
||||
"emailTest": "Test connection",
|
||||
"emailUserSSL": "Use SSL",
|
||||
"emailUserTLS": "Use TLS",
|
||||
"MailSend": "Mail send",
|
||||
"LDAPServerInfo": "LDAP Server",
|
||||
"LDAPUser": "LDAP User",
|
||||
"InsecureCommandAlert": "Insecure command alert",
|
||||
"helpText": {
|
||||
"ApiKeyList": "The API key is used to sign the request header. The header of each request is different. Please refer to the usage documentation",
|
||||
"authLdapSearchFilter": "Choice may be (cn|uid|sAMAccountName)=%(user)s)",
|
||||
@@ -1028,7 +985,6 @@
|
||||
"AWS_Int": "AWS(International)",
|
||||
"HuaweiCloud": "Huawei Cloud",
|
||||
"Azure":"Azure(China)",
|
||||
"Azure_Int": "Azure(International)",
|
||||
"HostnameStrategy": "Used to produce the asset hostname. For example, 1. Instance name (instanceDemo);2. Instance name and Partial IP (instanceDemo-250.1)",
|
||||
"IsAlwaysUpdate": "Asset info is kept up-to-date",
|
||||
"AccountCreate": "Create account",
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import AutoDataForm from '@/components/AutoDataForm'
|
||||
import deepmerge from 'deepmerge'
|
||||
export default {
|
||||
name: 'GenericCreateUpdateForm',
|
||||
components: {
|
||||
@@ -36,10 +37,6 @@ export default {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
afterGetFormValue: {
|
||||
type: Function,
|
||||
default: (value) => value
|
||||
},
|
||||
// 提交前,清理form的值
|
||||
cleanFormValue: {
|
||||
type: Function,
|
||||
@@ -64,14 +61,13 @@ export default {
|
||||
return this.$t('common.createSuccessMsg')
|
||||
}
|
||||
},
|
||||
// 保存成功,继续添加的msg
|
||||
// 更新成功的msg
|
||||
saveSuccessContinueMsg: {
|
||||
type: String,
|
||||
default: function() {
|
||||
return this.$t('common.saveSuccessContinueMsg')
|
||||
}
|
||||
},
|
||||
// 更新成功的msg
|
||||
updateSuccessMsg: {
|
||||
type: String,
|
||||
default: function() {
|
||||
@@ -97,9 +93,7 @@ export default {
|
||||
objectDetailRoute: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
const routeName = this.$route.name
|
||||
.replace('Update', 'Detail')
|
||||
.replace('Create', 'Detail')
|
||||
const routeName = this.$route.name.replace('Update', 'Detail').replace('Create', 'Detail')
|
||||
return { name: routeName }
|
||||
}
|
||||
},
|
||||
@@ -239,8 +233,7 @@ export default {
|
||||
try {
|
||||
const values = await this.getFormValue()
|
||||
this.$log.debug('Final object is: ', values)
|
||||
const formValue = Object.assign(this.form, values)
|
||||
this.form = this.afterGetFormValue(formValue)
|
||||
this.form = Object.assign(this.form, values)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
@@ -280,7 +273,10 @@ export default {
|
||||
}
|
||||
}
|
||||
if (object) {
|
||||
object = _.cloneDeep(object)
|
||||
if (object['attrs']) {
|
||||
object = deepmerge(object, object['attrs'])
|
||||
}
|
||||
this.$log.debug('Object is: ', object)
|
||||
this.$emit('update:object', object)
|
||||
}
|
||||
return object
|
||||
|
||||
@@ -19,7 +19,6 @@ import TabPage from '../TabPage'
|
||||
import { flashErrorMsg } from '@/utils/request'
|
||||
import { getApiPath } from '@/utils/common'
|
||||
import ActionsGroup from '@/components/ActionsGroup'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'GenericDetailPage',
|
||||
@@ -81,27 +80,22 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
const defaultActions = {
|
||||
canDelete: true,
|
||||
deleteCallback: function(item) { this.defaultDelete(item) },
|
||||
deleteApiUrl: getApiPath(this),
|
||||
deleteSuccessRoute: this.$route.name.replace('Detail', 'List'),
|
||||
canUpdate: () => {
|
||||
return !vm.currentOrgIsRoot
|
||||
},
|
||||
canUpdate: true,
|
||||
updateCallback: function(item) { this.defaultUpdate(item) },
|
||||
updateRoute: this.$route.name.replace('Detail', 'Update'),
|
||||
detailApiUrl: getApiPath(this)
|
||||
}
|
||||
return {
|
||||
defaultActions: defaultActions,
|
||||
loading: true,
|
||||
validActions: Object.assign(defaultActions, this.actions)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['currentOrgIsRoot']),
|
||||
pageActions() {
|
||||
return [
|
||||
{
|
||||
@@ -164,7 +158,7 @@ export default {
|
||||
this.$message.success(this.$t('common.deleteSuccessMsg'))
|
||||
this.$router.push({ name: this.validActions.deleteSuccessRoute })
|
||||
} catch (error) {
|
||||
this.$message.error(this.$t('common.deleteErrorMsg') + ' ' + error)
|
||||
this.$message.error(this.$t('common.deleteErrorMsg' + ' ' + error))
|
||||
} finally {
|
||||
instance.confirmButtonLoading = false
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<Page v-bind="$attrs">
|
||||
<GenericListTable ref="ListTable" v-bind="$attrs" />
|
||||
<ListTable ref="ListTable" v-bind="$attrs" />
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Page from '@/layout/components/Page'
|
||||
import GenericListTable from '@/layout/components/GenericListTable'
|
||||
import ListTable from '@/components/ListTable'
|
||||
export default {
|
||||
name: 'GenericListPage',
|
||||
components: {
|
||||
Page, GenericListTable
|
||||
Page, ListTable
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
<template>
|
||||
<ListTable ref="ListTable" v-bind="iAttrs" v-on="$listeners" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ListTable from '@/components/ListTable/index'
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
name: 'GenericListTable',
|
||||
components: {
|
||||
ListTable
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['currentOrgIsRoot']),
|
||||
iAttrs() {
|
||||
const attrs = _.cloneDeep(this.$attrs)
|
||||
const canCreate = _.get(attrs, 'header-actions.canCreate', null)
|
||||
this.$log.debug('Can create: ', canCreate)
|
||||
if (canCreate === null && this.currentOrgIsRoot) {
|
||||
_.set(attrs, 'header-actions.canCreate', false)
|
||||
}
|
||||
this.$log.debug('List table Attrs: ', attrs)
|
||||
return attrs
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,13 +1,7 @@
|
||||
<template>
|
||||
<Page>
|
||||
<el-alert v-if="helpMessage" type="success"> {{ helpMessage }} </el-alert>
|
||||
<TreeTable
|
||||
ref="TreeTable"
|
||||
:table-config="tableConfig"
|
||||
:header-actions="iHeaderActions"
|
||||
:tree-setting="treeSetting"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<TreeTable ref="TreeTable" :table-config="tableConfig" :header-actions="headerActions" :tree-setting="treeSetting">
|
||||
<template #table>
|
||||
<slot name="table" />
|
||||
</template>
|
||||
@@ -21,7 +15,6 @@
|
||||
<script>
|
||||
import Page from '@/layout/components/Page'
|
||||
import TreeTable from '@/components/TreeTable'
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
name: 'GenericTreeListPage',
|
||||
components: {
|
||||
@@ -34,30 +27,12 @@ export default {
|
||||
default: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['currentOrg']),
|
||||
iHeaderActions() {
|
||||
const attrs = _.cloneDeep(this.headerActions)
|
||||
const canCreate = _.get(attrs, 'canCreate', null)
|
||||
// this.$log.debug('Current org: ', this.currentOrg)
|
||||
if (canCreate === null && this.currentOrg && this.currentOrg.is_root) {
|
||||
_.set(attrs, 'canCreate', false)
|
||||
}
|
||||
return attrs
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
hideRMenu() {
|
||||
this.$refs.TreeTable.hideRMenu()
|
||||
},
|
||||
getSelectedNodes: function() {
|
||||
return this.$refs.TreeTable.getSelectedNodes()
|
||||
},
|
||||
getNodes: function() {
|
||||
return this.$refs.TreeTable.getNodes()
|
||||
},
|
||||
selectNode: function(node) {
|
||||
return this.$refs.TreeTable.selectNode(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,10 +48,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
needShow() {
|
||||
const otherOrgs = this.userAdminOrgList.filter(org => {
|
||||
return !org.is_root && !org.is_default
|
||||
})
|
||||
return !this.isCollapse && otherOrgs.length > 0 && this.inAdminPage
|
||||
return !this.isCollapse && this.userAdminOrgList.length > 1 && this.inAdminPage
|
||||
},
|
||||
changeOrg(orgId) {
|
||||
orgUtil.changeOrg(orgId)
|
||||
|
||||
@@ -61,7 +61,7 @@ export default {
|
||||
this.$refs.ListTable.reloadTable()
|
||||
this.$message.success(this.$t('common.deleteSuccessMsg'))
|
||||
}).catch(error => {
|
||||
this.$message.error(this.$t('common.deleteErrorMsg') + ' ' + error)
|
||||
this.$message.error(this.$t('common.deleteErrorMsg' + ' ' + error))
|
||||
})
|
||||
}.bind(this),
|
||||
extraActions: [
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
import i18n from '@/i18n/i18n'
|
||||
import empty from '@/layout/empty'
|
||||
export default [
|
||||
{
|
||||
path: 'asset-acl',
|
||||
component: empty,
|
||||
redirect: '',
|
||||
meta: {
|
||||
title: i18n.t('route.AssetAclList'),
|
||||
licenseRequired: true
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'AssetAclList',
|
||||
component: () => import('@/views/acl/AssetAcl/AssetAclList'),
|
||||
meta: { title: i18n.t('route.AssetAclList'), activeMenu: '/acl/asset-acl' }
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
name: 'AssetAclCreate',
|
||||
component: () => import('@/views/acl/AssetAcl/AssetAclCreateUpdate'),
|
||||
meta: { title: i18n.t('route.AssetAclCreate'), activeMenu: '/acl/asset-acl' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
name: 'AssetAclDetail',
|
||||
component: () => import('@/views/acl/AssetAcl/AssetAclDetail'),
|
||||
meta: { title: i18n.t('route.AssetAclDetail'), activeMenu: '/acl/asset-acl' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: ':id/update',
|
||||
name: 'AssetAclUpdate',
|
||||
component: () => import('@/views/acl/AssetAcl/AssetAclCreateUpdate'),
|
||||
meta: { title: i18n.t('route.AssetAclUpdate'), activeMenu: '/acl/asset-acl' },
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -36,7 +36,6 @@ import OpsRoutes from './ops'
|
||||
import TicketsRoutes from './tickets'
|
||||
import AuditsRoutes from './audits'
|
||||
import commonRoutes from './common'
|
||||
import aclRoutes from './acl'
|
||||
|
||||
/**
|
||||
* constantRoutes
|
||||
@@ -118,17 +117,6 @@ export const allRoleRoutes = [
|
||||
meta: { title: i18n.t('route.Perms'), icon: 'edit' },
|
||||
children: PermsRoute
|
||||
},
|
||||
{
|
||||
path: '/acl/',
|
||||
component: Layout,
|
||||
redirect: '/perms/access-control-list/',
|
||||
name: 'Acl',
|
||||
meta: {
|
||||
licenseRequired: true,
|
||||
title: i18n.t('route.Acl'),
|
||||
icon: 'fort-awesome' },
|
||||
children: aclRoutes
|
||||
},
|
||||
{
|
||||
path: '/terminal/',
|
||||
component: Layout,
|
||||
|
||||
@@ -44,7 +44,7 @@ export default [
|
||||
// meta: { title: i18n.t('route.CeleryTaskLog') }
|
||||
// },
|
||||
{
|
||||
path: `${BASE_URL}/core/flower/?_=${Date.now()}`,
|
||||
path: `${BASE_URL}/core/flower?_=${Date.now()}`,
|
||||
name: 'TaskMonitor',
|
||||
// component: () => window.open(`/core/flower?_=${Date.now()}`),
|
||||
meta: { title: i18n.t('route.TaskMonitor'), permissions: [rolec.PERM_SUPER] }
|
||||
|
||||
@@ -28,13 +28,6 @@ export default [
|
||||
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'tickets/login-asset-confirm/:id',
|
||||
name: 'loginAssetTicketDetail',
|
||||
component: () => import('@/views/tickets/LoginAssetConfirm/Detail/index'),
|
||||
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'tickets/request-application-perm/create',
|
||||
name: 'RequestApplicationPermTicketCreateUpdate',
|
||||
|
||||
@@ -103,13 +103,6 @@ export default [
|
||||
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets', permissions: [rolec.PERM_USE] },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'tickets/login-asset-confirm/:id',
|
||||
name: 'loginAssetTicketDetail',
|
||||
component: () => import('@/views/tickets/LoginAssetConfirm/Detail/index'),
|
||||
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets', permissions: [rolec.PERM_USE] },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'tickets/request-application-perm/create',
|
||||
name: 'RequestApplicationPermTicketCreateUpdate',
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import i18n from '@/i18n/i18n'
|
||||
import empty from '@/layout/empty'
|
||||
export default [
|
||||
{
|
||||
path: 'users',
|
||||
@@ -54,42 +53,5 @@ export default [
|
||||
name: 'UserGroupDetail',
|
||||
hidden: true,
|
||||
meta: { title: i18n.t('route.UserGroupDetail'), activeMenu: '/users/groups' }
|
||||
},
|
||||
{
|
||||
path: 'user-acl',
|
||||
component: empty,
|
||||
redirect: '',
|
||||
meta: { title: i18n.t('route.UserAclList') },
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'UserAclList',
|
||||
component: () => import('@/views/acl/UserAcl/UserAclList'),
|
||||
meta: { title: i18n.t('route.UserAclList'), activeMenu: '/users/users' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
name: 'UserAclCreate',
|
||||
component: () => import('@/views/acl/UserAcl/UserAclCreateUpdate'),
|
||||
meta: { title: i18n.t('route.UserAclCreate'), activeMenu: '/users/users' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
name: 'UserAclDetail',
|
||||
component: () => import('@/views/acl/UserAcl/UserAclDetail'),
|
||||
meta: { title: i18n.t('route.UserAclDetail'), activeMenu: '/users/users' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: ':id/update',
|
||||
name: 'UserAclUpdate',
|
||||
component: () => import('@/views/acl/UserAcl/UserAclCreateUpdate'),
|
||||
meta: { title: i18n.t('route.UserAclUpdate') },
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -3,11 +3,8 @@ const getters = {
|
||||
device: state => state.app.device,
|
||||
token: state => state.users.token,
|
||||
currentOrg: state => state.users.currentOrg,
|
||||
currentOrgIsDefault: state => state.users.currentOrg.is_default,
|
||||
currentOrgIsRoot: state => {
|
||||
return state.users.currentOrg && state.users.currentOrg.is_root
|
||||
},
|
||||
currentRole: state => state.users.currentRole,
|
||||
userAdminOrgList: state => state.users.orgs,
|
||||
currentUser: state => state.users.profile,
|
||||
permission_routes: state => state.permission.routes,
|
||||
visitedViews: state => state.tagsView.visitedViews,
|
||||
@@ -17,17 +14,6 @@ const getters = {
|
||||
currentOrgPerms: state => state.users.perms,
|
||||
MFAVerifyAt: state => state.users.MFAVerifyAt,
|
||||
MFA_TTl: state => state.settings.publicSettings.SECURITY_MFA_VERIFY_TTL,
|
||||
tableConfig: state => state.table.tableConfig,
|
||||
currentUserIsSuperAdmin: state => {
|
||||
return state.users.sysRole === 'Admin'
|
||||
},
|
||||
hasValidLicense: state => state.settings.hasValidLicense,
|
||||
userAdminOrgList: (state, getters) => {
|
||||
let orgs = state.users.orgs
|
||||
if (!getters.hasValidLicense) {
|
||||
orgs = orgs.filter(org => !org.is_root)
|
||||
}
|
||||
return orgs
|
||||
}
|
||||
tableConfig: state => state.table.tableConfig
|
||||
}
|
||||
export default getters
|
||||
|
||||
@@ -19,7 +19,7 @@ function hasPermission(roles, route) {
|
||||
}
|
||||
|
||||
function hasLicense(route, rootState) {
|
||||
const licenseIsValid = rootState.settings.hasValidLicense
|
||||
const licenseIsValid = rootState.settings.publicSettings.XPACK_LICENSE_IS_VALID
|
||||
const licenseRequired = route.meta ? route.meta.licenseRequired : false
|
||||
if (!licenseIsValid && licenseRequired) {
|
||||
return false
|
||||
|
||||
@@ -8,8 +8,7 @@ const state = {
|
||||
fixedHeader: fixedHeader,
|
||||
sidebarLogo: sidebarLogo,
|
||||
tagsView: tagsView,
|
||||
publicSettings: null,
|
||||
hasValidLicense: false
|
||||
publicSettings: null
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
@@ -20,10 +19,6 @@ const mutations = {
|
||||
},
|
||||
SET_PUBLIC_SETTINGS: (state, settings) => {
|
||||
state.publicSettings = settings
|
||||
|
||||
if (settings['XPACK_ENABLED']) {
|
||||
state.hasValidLicense = settings['XPACK_LICENSE_IS_VALID']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
import VueCookie from 'vue-cookie'
|
||||
import Vue from 'vue'
|
||||
|
||||
function getTableConfigfromCookie() {
|
||||
return localStorage.getItem('tableConfig') ? JSON.parse(localStorage.getItem('tableConfig')) : {}
|
||||
return VueCookie.get('tableConfig') ? JSON.parse(VueCookie.get('tableConfig')) : {}
|
||||
}
|
||||
|
||||
const state = {
|
||||
@@ -11,9 +11,8 @@ const state = {
|
||||
|
||||
const mutations = {
|
||||
SET_TABLE_CONFIG: (state, tableConfig) => {
|
||||
const _tableConfig = localStorage.getItem('tableConfig') ? JSON.parse(localStorage.getItem('tableConfig')) : {}
|
||||
Vue.set(_tableConfig, tableConfig.key, tableConfig.value)
|
||||
localStorage.setItem('tableConfig', JSON.stringify(_tableConfig))
|
||||
Vue.set(state.tableConfig, tableConfig.key, tableConfig.value)
|
||||
VueCookie.set('tableConfig', JSON.stringify(state.tableConfig), 14)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,9 @@ const getDefaultState = () => {
|
||||
currentRole: getCurrentRoleFromCookie(),
|
||||
profile: {},
|
||||
roles: {},
|
||||
sysRole: '',
|
||||
orgs: [],
|
||||
perms: 0b00000000,
|
||||
MFAVerifyAt: null,
|
||||
isSuperAdmin: false
|
||||
MFAVerifyAt: null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,9 +52,6 @@ const mutations = {
|
||||
SET_ROLES(state, roles) {
|
||||
state.roles = roles
|
||||
},
|
||||
SET_SYS_ROLE(state, role) {
|
||||
state.sysRole = role
|
||||
},
|
||||
SET_PERMS(state, perms) {
|
||||
state.perms = perms
|
||||
},
|
||||
@@ -116,7 +111,6 @@ const actions = {
|
||||
return dispatch('getProfile').then((profile) => {
|
||||
const { current_org_roles: currentOrgRoles, role } = profile
|
||||
const roles = rolec.parseUserRoles(currentOrgRoles, role)
|
||||
commit('SET_SYS_ROLE', role)
|
||||
commit('SET_ROLES', roles)
|
||||
commit('SET_PERMS', rolec.sumPerms(roles))
|
||||
resolve(roles)
|
||||
|
||||
@@ -454,7 +454,3 @@ a {
|
||||
.el-table {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.el-table-filter__list-item:hover {
|
||||
color: $--color-text-primary;
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@ export default {
|
||||
name: 'connect',
|
||||
fa: 'fa-terminal',
|
||||
type: 'primary',
|
||||
callback: function({ row }) {
|
||||
window.open(`/luna/?type=database_app&login_to=${row.id}`, '_blank')
|
||||
callback: function({ row, col, cellValue, reload }) {
|
||||
window.open(`/luna/?type=database_app&login_to=${cellValue}`, '_blank')
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -59,8 +59,8 @@ export default {
|
||||
name: 'connect',
|
||||
fa: 'fa-terminal',
|
||||
type: 'primary',
|
||||
callback: function({ row }) {
|
||||
window.open(`/luna/?type=k8s_app&login_to=${row.id}`, '_blank')
|
||||
callback: function({ row, col, cellValue, reload }) {
|
||||
window.open(`/luna/?type=k8s_app&login_to=${cellValue}`, '_blank')
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -58,8 +58,8 @@ export default {
|
||||
name: 'connect',
|
||||
fa: 'fa-terminal',
|
||||
type: 'primary',
|
||||
callback: function({ row }) {
|
||||
window.open(`/luna/?type=remote_app&login_to=${row.id}`, '_blank')
|
||||
callback: function({ row, col, cellValue, reload }) {
|
||||
window.open(`/luna/?type=remote_app&login_to=${cellValue}`, '_blank')
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -121,20 +121,20 @@ export default {
|
||||
return row.is_active
|
||||
},
|
||||
callback: function({ row, col, cellValue, reload }) {
|
||||
window.open(`/luna/?login_to=${row.id}`, '_blank')
|
||||
window.open(`/luna/?login_to=${cellValue}`, '_blank')
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'favor',
|
||||
type: 'info',
|
||||
fa: function(row, cellValue) {
|
||||
if (this.checkFavorite(row.id)) {
|
||||
if (this.checkFavorite(cellValue)) {
|
||||
return 'fa-star'
|
||||
}
|
||||
return 'fa-star-o'
|
||||
}.bind(this),
|
||||
callback: function({ row, col, cellValue, reload }) {
|
||||
this.addOrDeleteFavorite(row.id)
|
||||
this.addOrDeleteFavorite(cellValue)
|
||||
}.bind(this)
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { hasUUID, BASE_URL } from '@/utils/common'
|
||||
import { getOrgDetail } from '@/api/orgs'
|
||||
import store from '@/store'
|
||||
|
||||
export const DEFAULT_ORG_ID = '00000000-0000-0000-0000-000000000002'
|
||||
// const ROOT_ORG_ID = '00000000-0000-0000-0000-000000000000'
|
||||
|
||||
function getPropOrg() {
|
||||
const userAdminOrgList = store.getters.userAdminOrgList
|
||||
const defaultOrg = userAdminOrgList.find((item) => item.is_default)
|
||||
let defaultOrg = userAdminOrgList.find((item) => item.id === '')
|
||||
if (defaultOrg) {
|
||||
return defaultOrg
|
||||
}
|
||||
defaultOrg = userAdminOrgList.find((item) => item.id === 'DEFAULT')
|
||||
if (defaultOrg) {
|
||||
return defaultOrg
|
||||
}
|
||||
@@ -19,14 +19,14 @@ function change2PropOrg() {
|
||||
setTimeout(() => changeOrg(org.id), 100)
|
||||
}
|
||||
|
||||
// function getOrgIdMapper() {
|
||||
// const mapper = {}
|
||||
// const userAdminOrgList = store.getters.userAdminOrgList
|
||||
// userAdminOrgList.forEach((v) => {
|
||||
// mapper[v.id] = v
|
||||
// })
|
||||
// return mapper
|
||||
// }
|
||||
function getOrgIdMapper() {
|
||||
const mapper = {}
|
||||
const userAdminOrgList = store.getters.userAdminOrgList
|
||||
userAdminOrgList.forEach((v) => {
|
||||
mapper[v.id] = v
|
||||
})
|
||||
return mapper
|
||||
}
|
||||
|
||||
function hasCurrentOrgPermission() {
|
||||
const currentOrg = store.getters.currentOrg
|
||||
@@ -37,7 +37,7 @@ function hasCurrentOrgPermission() {
|
||||
}
|
||||
|
||||
async function changeOrg(orgId) {
|
||||
const org = await getOrgDetail(orgId)
|
||||
const org = getOrgIdMapper()[orgId]
|
||||
if (!org) {
|
||||
console.debug('Error: org not found')
|
||||
} else {
|
||||
@@ -59,6 +59,5 @@ async function changeOrg(orgId) {
|
||||
export default {
|
||||
hasCurrentOrgPermission,
|
||||
changeOrg,
|
||||
DEFAULT_ORG_ID,
|
||||
change2PropOrg
|
||||
}
|
||||
|
||||
@@ -86,8 +86,8 @@ export function flashErrorMsg({ response, error }) {
|
||||
if (!response.config.disableFlashErrorMsg) {
|
||||
let msg = error.message
|
||||
const data = response.data
|
||||
if (data && (data.error || data.msg || data.detail)) {
|
||||
msg = data.error || data.msg || data.detail
|
||||
if (data && (data.error || data.msg)) {
|
||||
msg = data.error || data.msg
|
||||
}
|
||||
Message({
|
||||
message: msg,
|
||||
|
||||
@@ -6,7 +6,6 @@ import 'nprogress/nprogress.css' // progress bar style
|
||||
import { getTokenFromCookie } from '@/utils/auth'
|
||||
import rolec from '@/utils/role'
|
||||
import orgUtil from '@/utils/org'
|
||||
import { getCurrentOrg } from '@/api/orgs'
|
||||
|
||||
const whiteList = ['/login', process.env.VUE_APP_LOGIN_PATH] // no redirect whitelist
|
||||
let initial = false
|
||||
@@ -35,12 +34,9 @@ async function checkLogin({ to, from, next }) {
|
||||
try {
|
||||
return await store.dispatch('users/getProfile')
|
||||
} catch (e) {
|
||||
const status = e.response.status
|
||||
if (status === 401 || status === 403) {
|
||||
setTimeout(() => {
|
||||
window.location = process.env.VUE_APP_LOGIN_PATH
|
||||
}, 100)
|
||||
}
|
||||
setTimeout(() => {
|
||||
window.location = process.env.VUE_APP_LOGIN_PATH
|
||||
}, 100)
|
||||
return reject('No profile get: ' + e)
|
||||
}
|
||||
}
|
||||
@@ -53,29 +49,22 @@ async function getPublicSetting({ to, from, next }) {
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshCurrentOrg() {
|
||||
getCurrentOrg().then(org => {
|
||||
store.dispatch('users/setCurrentOrg', org)
|
||||
})
|
||||
}
|
||||
|
||||
async function changeCurrentOrgIfNeed({ to, from, next }) {
|
||||
await store.dispatch('users/getInOrgs')
|
||||
const adminOrgs = store.getters.userAdminOrgList
|
||||
if (!adminOrgs || adminOrgs.length === 0) {
|
||||
return
|
||||
}
|
||||
await refreshCurrentOrg()
|
||||
const currentOrg = store.getters.currentOrg
|
||||
if (!currentOrg || typeof currentOrg !== 'object') {
|
||||
// console.log('Not has current org')
|
||||
orgUtil.change2PropOrg()
|
||||
return reject('Change prop org')
|
||||
return reject('change prop org')
|
||||
}
|
||||
if (!orgUtil.hasCurrentOrgPermission()) {
|
||||
console.debug('Not has current org permission')
|
||||
orgUtil.change2PropOrg()
|
||||
return reject('Change prop org')
|
||||
return reject('change prop org')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,11 +133,11 @@ export async function startup({ to, from, next }) {
|
||||
initial = true
|
||||
|
||||
// set page title
|
||||
await getPublicSetting({ to, from, next })
|
||||
await setHeadTitle({ to, from, next })
|
||||
await checkLogin({ to, from, next })
|
||||
await changeCurrentOrgIfNeed({ to, from, next })
|
||||
await changeCurrentRoleIfNeed({ to, from, next })
|
||||
await getPublicSetting({ to, from, next })
|
||||
await generatePageRoutes({ to, from, next })
|
||||
await checkUserFirstLogin({ to, from, next })
|
||||
return true
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
|
||||
<template>
|
||||
<GenericCreateUpdatePage :fields="fields" :initial="initial" :fields-meta="fieldsMeta" :url="url" :perform-submit="performSubmit" :after-get-form-value="afterGetFormValue" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
||||
export default {
|
||||
name: 'AclCreateUpdate',
|
||||
components: {
|
||||
GenericCreateUpdatePage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
initial: {
|
||||
action: 'login_confirm',
|
||||
system_users: {
|
||||
name_group: '*',
|
||||
protocol_group: '*',
|
||||
username_group: '*'
|
||||
},
|
||||
users: {
|
||||
username_group: '*'
|
||||
},
|
||||
assets: {
|
||||
hostname_group: '*',
|
||||
ip_group: '*'
|
||||
}
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'priority']],
|
||||
[this.$t('acl.users'), ['users']],
|
||||
[this.$t('acl.asset'), ['assets']],
|
||||
[this.$t('acl.system_user'), ['system_users']],
|
||||
[this.$t('acl.action'), ['action', 'reviewers']],
|
||||
[this.$t('common.Other'), ['is_active', 'comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
assets: {
|
||||
fields: ['hostname_group', 'ip_group']
|
||||
},
|
||||
users: {
|
||||
fields: ['username_group'],
|
||||
fieldsMeta: {
|
||||
|
||||
}
|
||||
},
|
||||
system_users: {
|
||||
fields: ['name_group', 'username_group', 'protocol_group']
|
||||
},
|
||||
reviewers: {
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/users/users/?fields_size=mini',
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
url: '/api/v1/acls/login-asset-acls/'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getUrl() {
|
||||
const params = this.$route.params
|
||||
let url = `/api/v1/acls/login-asset-acls/`
|
||||
if (params.id) {
|
||||
url = `${url}${params.id}/`
|
||||
} else {
|
||||
url = `${url}`
|
||||
}
|
||||
return url
|
||||
},
|
||||
getMethod() {
|
||||
const params = this.$route.params
|
||||
if (params.id) {
|
||||
return 'put'
|
||||
} else {
|
||||
return 'post'
|
||||
}
|
||||
},
|
||||
afterGetFormValue(validValues) {
|
||||
validValues.assets.ip_group = validValues.assets.ip_group.toString()
|
||||
validValues.assets.hostname_group = validValues.assets.hostname_group.toString()
|
||||
validValues.system_users.name_group = validValues.system_users.name_group.toString()
|
||||
validValues.system_users.protocol_group = validValues.system_users.protocol_group.toString()
|
||||
validValues.system_users.username_group = validValues.system_users.username_group.toString()
|
||||
validValues.users.username_group = validValues.users.username_group.toString()
|
||||
return validValues
|
||||
},
|
||||
performSubmit(validValues) {
|
||||
if (!Array.isArray(validValues.assets.ip_group)) {
|
||||
validValues.assets.ip_group = validValues.assets.ip_group ? validValues.assets.ip_group.split(',') : []
|
||||
}
|
||||
if (!Array.isArray(validValues.assets.hostname_group)) {
|
||||
validValues.assets.hostname_group = validValues.assets.hostname_group ? validValues.assets.hostname_group.split(',') : []
|
||||
}
|
||||
if (!Array.isArray(validValues.system_users.protocol_group)) {
|
||||
validValues.system_users.protocol_group = validValues.system_users.protocol_group ? validValues.system_users.protocol_group.split(',') : []
|
||||
}
|
||||
if (!Array.isArray(validValues.system_users.name_group)) {
|
||||
validValues.system_users.name_group = validValues.system_users.name_group ? validValues.system_users.name_group.split(',') : []
|
||||
}
|
||||
if (!Array.isArray(validValues.system_users.username_group)) {
|
||||
validValues.system_users.username_group = validValues.system_users.username_group ? validValues.system_users.username_group.split(',') : []
|
||||
}
|
||||
if (!Array.isArray(validValues.users.username_group)) {
|
||||
validValues.users.username_group = validValues.users.username_group ? validValues.users.username_group.split(',') : []
|
||||
}
|
||||
const method = this.getMethod()
|
||||
return this.$axios[method](`${this.getUrl()}`, validValues)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -1,113 +0,0 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<!-- <RelationCard ref="RelationCard" type="info" v-bind="nodeRelationConfig" />-->
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DetailCard from '@/components/DetailCard'
|
||||
// import RelationCard from '@/components/RelationCard'
|
||||
import { toSafeLocalDateStr } from '@/utils/common'
|
||||
|
||||
export default {
|
||||
name: 'Detail',
|
||||
components: {
|
||||
DetailCard
|
||||
// RelationCard
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
nodeRelationConfig: {
|
||||
icon: 'fa-info',
|
||||
title: this.$t('assets.ReplaceNodeAssetsAdminUserWithThis'),
|
||||
objectsAjax: {
|
||||
url: '/api/v1/assets/nodes/',
|
||||
transformOption: (item) => {
|
||||
return { label: item.full_value, value: item.id }
|
||||
}
|
||||
},
|
||||
performAdd: (items) => {
|
||||
const data = []
|
||||
const relationUrl = `/api/v1/assets/admin-users/${this.object.id}/nodes/`
|
||||
items.map(v => {
|
||||
data.push(v.value)
|
||||
})
|
||||
return this.$axios.patch(relationUrl, { nodes: data }).then(res => {
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
}).catch(err => {
|
||||
this.$message.error(this.$t('common.updateErrorMsg' + ' ' + err))
|
||||
})
|
||||
},
|
||||
onAddSuccess: () => {
|
||||
this.$refs.RelationCard.$refs.select2.clearSelected()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
detailCardItems() {
|
||||
return [
|
||||
{
|
||||
key: this.$t('acl.name'),
|
||||
value: this.object.name
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.username_group'),
|
||||
value: this.object.users.username_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.hostname_group'),
|
||||
value: this.object.assets.hostname_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.asset_ip_group'),
|
||||
value: this.object.assets.ip_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.system_users_name_group'),
|
||||
value: this.object.system_users.name_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.system_users_protocol_group'),
|
||||
value: this.object.system_users.protocol_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.system_users_username_group'),
|
||||
value: this.object.system_users.username_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.action'),
|
||||
value: this.object.action_display
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.priority'),
|
||||
value: this.object.priority
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.date_created'),
|
||||
value: toSafeLocalDateStr(this.object.date_created)
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.created_by'),
|
||||
value: this.object.created_by
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,41 +0,0 @@
|
||||
<template>
|
||||
<GenericDetailPage :object.sync="TaskDetail" :active-menu.sync="config.activeMenu" v-bind="config" v-on="$listeners">
|
||||
<keep-alive>
|
||||
<component :is="config.activeMenu" :object="TaskDetail" />
|
||||
</keep-alive>
|
||||
</GenericDetailPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericDetailPage } from '@/layout/components'
|
||||
import detail from './detail.vue'
|
||||
export default {
|
||||
components: {
|
||||
GenericDetailPage,
|
||||
detail
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
TaskDetail: {},
|
||||
config: {
|
||||
activeMenu: 'detail',
|
||||
submenu: [
|
||||
{
|
||||
title: this.$t('acl.RuleDetail'),
|
||||
name: 'detail'
|
||||
}
|
||||
],
|
||||
hasRightSide: true,
|
||||
actions: {
|
||||
detailApiUrl: `/api/v1/acls/login-asset-acls/${this.$route.params.id}/`,
|
||||
deleteApiUrl: `/api/v1/acls/login-asset-acls/${this.$route.params.id}/`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,90 +0,0 @@
|
||||
<template>
|
||||
<GenericListPage :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericListPage } from '@/layout/components'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GenericListPage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/acls/login-asset-acls/',
|
||||
columns: ['name', 'user_username_group', 'hostname_group', 'ip_group', 'name_group', 'protocol_group', 'systemuser_username_group', 'reviewers', 'priority', 'is_active', 'comment', 'actions'],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: ['name', 'user_username_group', 'hostname_group', 'ip_group', 'reviewers', 'priority', 'is_active', 'comment', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
user_username_group: {
|
||||
prop: 'users.username_group',
|
||||
showOverflowTooltip: true,
|
||||
formatter: function(row) {
|
||||
return <span> {row.users.username_group.toString()} </span>
|
||||
},
|
||||
label: this.$t('acl.username_group')
|
||||
},
|
||||
reviewers: {
|
||||
prop: 'reviewers_amount'
|
||||
},
|
||||
hostname_group: {
|
||||
prop: 'assets.hostname_group',
|
||||
label: this.$t('acl.hostname_group'),
|
||||
showOverflowTooltip: true,
|
||||
formatter: function(row) {
|
||||
return <span> {row.assets.hostname_group.toString()} </span>
|
||||
}
|
||||
},
|
||||
ip_group: {
|
||||
prop: 'assets.ip_group',
|
||||
label: this.$t('acl.asset_ip_group'),
|
||||
showOverflowTooltip: true,
|
||||
formatter: function(row) {
|
||||
return <span> {row.assets.ip_group.toString()} </span>
|
||||
}
|
||||
},
|
||||
name_group: {
|
||||
prop: 'system_users.name_group',
|
||||
label: this.$t('acl.system_users_name_group'),
|
||||
showOverflowTooltip: true,
|
||||
formatter: function(row) {
|
||||
return <span> {row.system_users.name_group.toString()} </span>
|
||||
}
|
||||
},
|
||||
protocol_group: {
|
||||
prop: 'system_users.protocol_group',
|
||||
label: this.$t('acl.system_users_protocol_group'),
|
||||
showOverflowTooltip: true,
|
||||
formatter: function(row) {
|
||||
return <span> {row.system_users.protocol_group.toString()} </span>
|
||||
}
|
||||
},
|
||||
systemuser_username_group: {
|
||||
prop: 'system_users.username_group',
|
||||
label: this.$t('acl.system_users_username_group'),
|
||||
showOverflowTooltip: true,
|
||||
formatter: function(row) {
|
||||
return <span> {row.system_users.username_group.toString()} </span>
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
updateRoute: 'AssetAclUpdate',
|
||||
headerActions: {
|
||||
createRoute: 'AssetAclCreate',
|
||||
hasRefresh: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasMoreActions: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -1,91 +0,0 @@
|
||||
|
||||
<template>
|
||||
<GenericCreateUpdatePage
|
||||
v-bind="$data"
|
||||
:perform-submit="performSubmit"
|
||||
:after-get-form-value="afterGetFormValue"
|
||||
:get-url="getUrl"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
||||
export default {
|
||||
name: 'AclCreateUpdate',
|
||||
components: {
|
||||
GenericCreateUpdatePage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
initial: {
|
||||
action: 'reject',
|
||||
ip_group: '*',
|
||||
user: this.$route.query.user
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'user', 'ip_group', 'action', 'priority']],
|
||||
[this.$t('common.Other'), ['is_active', 'comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
is_active: {
|
||||
type: 'checkbox'
|
||||
},
|
||||
user: {
|
||||
el: {
|
||||
disabled: true,
|
||||
multiple: false,
|
||||
ajax: {
|
||||
url: '/api/v1/users/users/?fields_size=mini',
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
url: `/api/v1/acls/login-acls/`,
|
||||
updateSuccessNextRoute: { name: 'UserDetail', params: {
|
||||
id: this.$route.query.user
|
||||
}},
|
||||
createSuccessNextRoute: { name: 'UserDetail', params: {
|
||||
id: this.$route.query.user
|
||||
}}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getMethod() {
|
||||
const params = this.$route.params
|
||||
if (params.id) {
|
||||
return 'put'
|
||||
} else {
|
||||
return 'post'
|
||||
}
|
||||
},
|
||||
getUrl() {
|
||||
const params = this.$route.params
|
||||
let url = this.url
|
||||
if (params.id) {
|
||||
url = `${url}${params.id}/?user=${this.$route.query.user}`
|
||||
} else {
|
||||
url = `${url}?user=${this.$route.query.user}`
|
||||
}
|
||||
return url
|
||||
},
|
||||
afterGetFormValue(validValues) {
|
||||
validValues.ip_group = validValues.ip_group.toString()
|
||||
return validValues
|
||||
},
|
||||
performSubmit(validValues) {
|
||||
if (!Array.isArray(validValues.ip_group)) {
|
||||
validValues.ip_group = validValues.ip_group ? validValues.ip_group.split(',') : []
|
||||
}
|
||||
const method = this.getMethod()
|
||||
return this.$axios[method](`${this.getUrl()}`, validValues)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -1,97 +0,0 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<!-- <RelationCard ref="RelationCard" type="info" v-bind="nodeRelationConfig" />-->
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DetailCard from '@/components/DetailCard'
|
||||
// import RelationCard from '@/components/RelationCard'
|
||||
import { toSafeLocalDateStr } from '@/utils/common'
|
||||
|
||||
export default {
|
||||
name: 'Detail',
|
||||
components: {
|
||||
DetailCard
|
||||
// RelationCard
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
nodeRelationConfig: {
|
||||
icon: 'fa-info',
|
||||
title: this.$t('assets.ReplaceNodeAssetsAdminUserWithThis'),
|
||||
objectsAjax: {
|
||||
url: '/api/v1/assets/nodes/',
|
||||
transformOption: (item) => {
|
||||
return { label: item.full_value, value: item.id }
|
||||
}
|
||||
},
|
||||
performAdd: (items) => {
|
||||
const data = []
|
||||
const relationUrl = `/api/v1/assets/admin-users/${this.object.id}/nodes/`
|
||||
items.map(v => {
|
||||
data.push(v.value)
|
||||
})
|
||||
return this.$axios.patch(relationUrl, { nodes: data }).then(res => {
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
}).catch(err => {
|
||||
this.$message.error(this.$t('common.updateErrorMsg' + ' ' + err))
|
||||
})
|
||||
},
|
||||
onAddSuccess: () => {
|
||||
this.$refs.RelationCard.$refs.select2.clearSelected()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
detailCardItems() {
|
||||
return [
|
||||
{
|
||||
key: this.$t('acl.name'),
|
||||
value: this.object.name
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.username'),
|
||||
value: this.object.user_display
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.ip_group'),
|
||||
value: this.object.ip_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.action'),
|
||||
value: this.object.action_display
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.priority'),
|
||||
value: this.object.priority
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.date_created'),
|
||||
value: toSafeLocalDateStr(this.object.date_created)
|
||||
},
|
||||
{
|
||||
key: this.$t('acl.created_by'),
|
||||
value: this.object.created_by
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,41 +0,0 @@
|
||||
<template>
|
||||
<GenericDetailPage :object.sync="TaskDetail" :active-menu.sync="config.activeMenu" v-bind="config" v-on="$listeners">
|
||||
<keep-alive>
|
||||
<component :is="config.activeMenu" :object="TaskDetail" />
|
||||
</keep-alive>
|
||||
</GenericDetailPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericDetailPage } from '@/layout/components'
|
||||
import Detail from './Detail.vue'
|
||||
export default {
|
||||
components: {
|
||||
GenericDetailPage,
|
||||
Detail
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
TaskDetail: {},
|
||||
config: {
|
||||
activeMenu: 'Detail',
|
||||
submenu: [
|
||||
{
|
||||
title: this.$t('acl.RuleDetail'),
|
||||
name: 'Detail'
|
||||
}
|
||||
],
|
||||
hasRightSide: false,
|
||||
actions: {
|
||||
detailApiUrl: `/api/v1/acls/login-acls/${this.$route.params.id}/?user=${this.$route.query.user}`,
|
||||
deleteApiUrl: `/api/v1/acls/login-acls/${this.$route.params.id}/?user=${this.$route.query.user}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,65 +0,0 @@
|
||||
<template>
|
||||
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericListTable from '@/layout/components/GenericListTable'
|
||||
import { ArrayFormatter } from '@/components/ListTable/formatters'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GenericListTable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: `/api/v1/acls/login-acls/?user=${this.$route.params.id}`,
|
||||
columns: ['name', 'ip_group', 'priority', 'action', 'is_active', 'comment', 'actions'],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: ['name', 'ip_group', 'priority', 'action', 'is_active', 'comment', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
name: {
|
||||
formatterArgs: {
|
||||
route: 'UserAclDetail',
|
||||
routeQuery: {
|
||||
user: this.$route.params.id
|
||||
}
|
||||
}
|
||||
},
|
||||
ip_group: {
|
||||
formatter: ArrayFormatter,
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
action: {
|
||||
prop: 'action_display'
|
||||
},
|
||||
actions: {
|
||||
formatterArgs: {
|
||||
hasClone: false,
|
||||
updateRoute: { name: 'UserAclUpdate', query: { user: this.$route.params.id }},
|
||||
performDelete: ({ row, col }) => {
|
||||
const id = row.id
|
||||
const url = `/api/v1/acls/login-acls/${id}/?user=${this.$route.params.id}`
|
||||
return this.$axios.delete(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
createRoute: { name: 'UserAclCreate', query: { user: this.$route.params.id }},
|
||||
hasRefresh: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasMoreActions: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -10,6 +10,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'type', 'domain']],
|
||||
[this.$t('applications.DBInfo'), ['attrs']],
|
||||
@@ -24,6 +25,9 @@ export default {
|
||||
}],
|
||||
disabled: true
|
||||
},
|
||||
host: {
|
||||
type: 'input'
|
||||
},
|
||||
domain: {
|
||||
el: {
|
||||
multiple: false,
|
||||
@@ -32,14 +36,6 @@ export default {
|
||||
url: '/api/v1/assets/domains/'
|
||||
}
|
||||
}
|
||||
},
|
||||
attrs: {
|
||||
fields: ['host', 'port', 'database'],
|
||||
fieldsMeta: {
|
||||
host: {
|
||||
type: 'input'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
url: '/api/v1/applications/applications/',
|
||||
@@ -57,6 +53,11 @@ export default {
|
||||
const baseUrl = `/api/v1/applications/applications/`
|
||||
const url = (params.id) ? `${baseUrl}${params.id}/` : baseUrl
|
||||
const method = this.getMethod()
|
||||
validValues.attrs = {
|
||||
host: validValues.host,
|
||||
port: validValues.port,
|
||||
database: validValues.database
|
||||
}
|
||||
validValues.category = 'db'
|
||||
return this.$axios[method](`${url}?type=${validValues.type}`, validValues)
|
||||
}
|
||||
|
||||
@@ -4,24 +4,19 @@
|
||||
|
||||
<script>
|
||||
import { GenericListPage } from '@/layout/components'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GenericListPage
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/applications/applications/?category=db',
|
||||
columns: [
|
||||
'name', 'type_display', 'attrs.host', 'attrs.port', 'attrs.database',
|
||||
'created_by', 'date_created', 'date_updated', 'comment', 'org_name', 'actions'
|
||||
'name', 'type_display', 'attrs.host', 'attrs.port', 'attrs.database', 'comment', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: ['name', 'type_display', 'attrs.host', 'attrs.port', 'attrs.database', 'comment', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
type_display: {
|
||||
label: this.$t('applications.type'),
|
||||
@@ -40,19 +35,17 @@ export default {
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
actions: {
|
||||
prop: 'actions',
|
||||
prop: '',
|
||||
formatterArgs: {
|
||||
onClone: ({ row }) => {
|
||||
vm.$router.push({ name: 'DatabaseAppCreate', query: { type: row.type, clone_from: row.id }})
|
||||
},
|
||||
hasClone: false,
|
||||
performDelete: function({ row, col, cellValue, reload }) {
|
||||
this.$axios.delete(
|
||||
`/api/v1/applications/applications/${row.id}/`
|
||||
).then(res => {
|
||||
this.$refs.GenericListTable.$refs.ListTable.$refs.ListTable.reloadTable()
|
||||
this.$refs.GenericListTable.$refs.ListTable.reloadTable()
|
||||
// this.$message.success(this.$t('common.deleteSuccessMsg'))
|
||||
}).catch(error => {
|
||||
this.$message.error(this.$t('common.deleteErrorMsg') + ' ' + error)
|
||||
this.$message.error(this.$t('common.deleteErrorMsg' + ' ' + error))
|
||||
})
|
||||
}.bind(this)
|
||||
}
|
||||
@@ -63,38 +56,65 @@ export default {
|
||||
hasCreate: false,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasMoreActions: false,
|
||||
hasBulkDelete: false,
|
||||
createRoute: 'DatabaseAppCreate',
|
||||
moreCreates: {
|
||||
callback: (item) => {
|
||||
vm.$router.push({ name: 'DatabaseAppCreate', query: { type: item.name.toLowerCase() }})
|
||||
moreActionsTitle: this.$t('common.Create'),
|
||||
moreActionsType: 'primary',
|
||||
extraMoreActions: [
|
||||
{
|
||||
name: 'MySQL',
|
||||
title: 'MySQL',
|
||||
type: 'primary',
|
||||
has: true,
|
||||
callback: this.createMysql.bind(this)
|
||||
},
|
||||
dropdown: [
|
||||
{
|
||||
name: 'MySQL',
|
||||
title: 'MySQL',
|
||||
has: true
|
||||
},
|
||||
{
|
||||
name: 'PostgreSQL',
|
||||
title: 'PostgreSQL',
|
||||
has: this.$store.getters.hasValidLicense
|
||||
},
|
||||
{
|
||||
name: 'MariaDB',
|
||||
title: 'MariaDB',
|
||||
type: 'primary',
|
||||
has: this.$store.getters.hasValidLicense
|
||||
},
|
||||
{
|
||||
name: 'Oracle',
|
||||
title: 'Oracle',
|
||||
has: this.$store.getters.hasValidLicense
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
name: 'PostgreSQL',
|
||||
title: 'PostgreSQL',
|
||||
type: 'primary',
|
||||
has: this.isValidateLicense,
|
||||
callback: this.createPostgreSQL.bind(this)
|
||||
},
|
||||
{
|
||||
name: 'MariaDB',
|
||||
title: 'MariaDB',
|
||||
type: 'primary',
|
||||
has: this.isValidateLicense,
|
||||
callback: this.createMariaDB.bind(this)
|
||||
},
|
||||
{
|
||||
name: 'Oracle',
|
||||
title: 'Oracle',
|
||||
type: 'primary',
|
||||
has: this.isValidateLicense,
|
||||
callback: this.createOracle.bind(this)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['publicSettings', 'currentOrg'])
|
||||
},
|
||||
methods: {
|
||||
createMysql() {
|
||||
this.$router.push({ name: 'DatabaseAppCreate', query: { type: 'mysql' }})
|
||||
},
|
||||
createPostgreSQL() {
|
||||
this.$router.push({ name: 'DatabaseAppCreate', query: { type: 'postgresql' }})
|
||||
},
|
||||
createMariaDB() {
|
||||
this.$router.push({ name: 'DatabaseAppCreate', query: { type: 'mariadb' }})
|
||||
},
|
||||
createOracle() {
|
||||
this.$router.push({ name: 'DatabaseAppCreate', query: { type: 'oracle' }})
|
||||
},
|
||||
isValidateLicense() {
|
||||
if (this.publicSettings.XPACK_ENABLED) {
|
||||
return this.publicSettings.XPACK_LICENSE_IS_VALID
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -23,13 +23,8 @@ export default {
|
||||
type: {
|
||||
disabled: true
|
||||
},
|
||||
attrs: {
|
||||
fields: ['cluster'],
|
||||
fieldsMeta: {
|
||||
cluster: {
|
||||
helpText: this.$t('applications.clusterHelpTextMessage')
|
||||
}
|
||||
}
|
||||
cluster: {
|
||||
helpText: this.$t('applications.clusterHelpTextMessage')
|
||||
},
|
||||
domain: {
|
||||
el: {
|
||||
@@ -55,6 +50,9 @@ export default {
|
||||
const baseUrl = `/api/v1/applications/applications/`
|
||||
const url = (params.id) ? `${baseUrl}${params.id}/` : baseUrl
|
||||
const method = this.getMethod()
|
||||
validValues.attrs = {
|
||||
cluster: validValues.cluster
|
||||
}
|
||||
validValues.category = 'cloud'
|
||||
return this.$axios[method](`${url}?type=${validValues.type}`, validValues)
|
||||
}
|
||||
|
||||
@@ -10,18 +10,12 @@ export default {
|
||||
GenericListPage
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/applications/applications/?category=cloud',
|
||||
columns: [
|
||||
'name', 'type', 'attrs.cluster',
|
||||
'created_by', 'date_created', 'date_updated', 'comment', 'org_name', 'actions'
|
||||
'name', 'type', 'attrs.cluster', 'comment', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: ['name', 'type', 'attrs.cluster', 'comment', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
'attrs.cluster': {
|
||||
label: this.$t('applications.cluster')
|
||||
@@ -33,19 +27,17 @@ export default {
|
||||
width: '140px'
|
||||
},
|
||||
actions: {
|
||||
prop: 'actions',
|
||||
prop: '',
|
||||
formatterArgs: {
|
||||
onClone: ({ row }) => {
|
||||
vm.$router.push({ name: 'KubernetesAppCreate', query: { type: row.type, clone_from: row.id }})
|
||||
},
|
||||
hasClone: false,
|
||||
performDelete: function({ row, col, cellValue, reload }) {
|
||||
this.$axios.delete(
|
||||
`/api/v1/applications/applications/${row.id}/`
|
||||
).then(res => {
|
||||
this.$refs.GenericListTable.$refs.ListTable.$refs.ListTable.reloadTable()
|
||||
this.$refs.GenericListTable.$refs.ListTable.reloadTable()
|
||||
// this.$message.success(this.$t('common.deleteSuccessMsg'))
|
||||
}).catch(error => {
|
||||
this.$message.error(this.$t('common.deleteErrorMsg') + ' ' + error)
|
||||
this.$message.error(this.$t('common.deleteErrorMsg' + ' ' + error))
|
||||
})
|
||||
}.bind(this)
|
||||
}
|
||||
@@ -53,7 +45,7 @@ export default {
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasMoreActions: false,
|
||||
hasBulkDelete: false,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
createRoute: 'KubernetesAppCreate'
|
||||
|
||||
@@ -22,32 +22,10 @@ export default {
|
||||
path: pathInitial
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'type']],
|
||||
[this.$t('common.Basic'), ['name', 'type', 'domain']],
|
||||
[appTypeMeta.title, ['attrs']],
|
||||
[this.$t('common.Other'), ['comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
type: {
|
||||
readonly: true
|
||||
},
|
||||
attrs: {
|
||||
fields: fieldsMap,
|
||||
fieldsMeta: {
|
||||
asset: {
|
||||
rules: [{ required: true }],
|
||||
el: {
|
||||
multiple: false,
|
||||
ajax: {
|
||||
url: '/api/v1/assets/assets/?platform__base=Windows',
|
||||
transformOption: (item) => {
|
||||
return { label: item.hostname, value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
url: '/api/v1/applications/applications/',
|
||||
getUrl() {
|
||||
const params = this.$route.params
|
||||
@@ -58,13 +36,96 @@ export default {
|
||||
return `${url}?type=${this.$route.query.type}`
|
||||
},
|
||||
performSubmit(validValues) {
|
||||
this.$log.debug('Validated data: ', validValues)
|
||||
const params = this.$route.params
|
||||
const baseUrl = `/api/v1/applications/applications/`
|
||||
const url = (params.id) ? `${baseUrl}${params.id}/` : baseUrl
|
||||
const method = this.getMethod()
|
||||
switch (validValues.type) {
|
||||
case 'chrome': {
|
||||
validValues.attrs = {
|
||||
chrome_target: validValues.chrome_target,
|
||||
chrome_username: validValues.chrome_username,
|
||||
chrome_password: validValues.chrome_password,
|
||||
asset: validValues.asset,
|
||||
path: validValues.path
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'mysql_workbench': {
|
||||
validValues.attrs = {
|
||||
mysql_workbench_ip: validValues.mysql_workbench_ip,
|
||||
mysql_workbench_port: validValues.mysql_workbench_port,
|
||||
mysql_workbench_name: validValues.mysql_workbench_name,
|
||||
mysql_workbench_username: validValues.mysql_workbench_username,
|
||||
mysql_workbench_password: validValues.mysql_workbench_password,
|
||||
asset: validValues.asset,
|
||||
path: validValues.path
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'vmware_client': {
|
||||
validValues.attrs = {
|
||||
vmware_password: validValues.vmware_password,
|
||||
vmware_username: validValues.vmware_username,
|
||||
vmware_target: validValues.vmware_target,
|
||||
asset: validValues.asset,
|
||||
path: validValues.path
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'custom': {
|
||||
validValues.attrs = {
|
||||
custom_cmdline: validValues.custom_cmdline,
|
||||
custom_target: validValues.custom_target,
|
||||
custom_username: validValues.custom_username,
|
||||
custom_password: validValues.custom_password,
|
||||
asset: validValues.asset,
|
||||
path: validValues.path
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
validValues.category = 'remote_app'
|
||||
console.log(validValues)
|
||||
return this.$axios[method](`${url}?type=${validValues.type}`, validValues)
|
||||
},
|
||||
fieldsMeta: {
|
||||
asset: {
|
||||
rules: [{ required: true }],
|
||||
el: {
|
||||
multiple: false,
|
||||
ajax: {
|
||||
url: '/api/v1/assets/assets/?platform__base=Windows',
|
||||
transformOption: (item) => {
|
||||
return { label: item.hostname, value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
type: {
|
||||
type: 'select',
|
||||
options: [
|
||||
{
|
||||
label: appTypeMeta.title,
|
||||
value: appTypeMeta.name
|
||||
}
|
||||
],
|
||||
disabled: true
|
||||
},
|
||||
asset_info: {
|
||||
type: 'input',
|
||||
hidden: () => true
|
||||
},
|
||||
domain: {
|
||||
el: {
|
||||
multiple: false,
|
||||
clearable: true,
|
||||
ajax: {
|
||||
url: '/api/v1/assets/domains/'
|
||||
}
|
||||
}
|
||||
},
|
||||
...fieldsMap
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -17,13 +17,8 @@ export default {
|
||||
tableConfig: {
|
||||
url: '/api/v1/applications/applications/?category=remote_app',
|
||||
columns: [
|
||||
'name', 'type', 'attrs.asset',
|
||||
'created_by', 'date_created', 'date_updated', 'comment', 'org_name', 'actions'
|
||||
'name', 'type', 'attrs.asset', 'comment', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: ['name', 'type', 'attrs.asset', 'comment', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
type: {
|
||||
displayKey: 'get_type_display',
|
||||
@@ -38,11 +33,8 @@ export default {
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
prop: 'actions',
|
||||
formatterArgs: {
|
||||
onClone: ({ row }) => {
|
||||
vm.$router.push({ name: 'RemoteAppCreate', query: { type: row.type, clone_from: row.id }})
|
||||
},
|
||||
hasClone: false,
|
||||
onUpdate: ({ row }) => {
|
||||
vm.$router.push({ name: 'RemoteAppUpdate', params: { id: row.id }, query: { type: row.type }})
|
||||
},
|
||||
@@ -50,10 +42,10 @@ export default {
|
||||
this.$axios.delete(
|
||||
`/api/v1/applications/applications/${row.id}/`
|
||||
).then(res => {
|
||||
this.$refs.GenericListTable.$refs.ListTable.$refs.ListTable.reloadTable()
|
||||
this.$refs.GenericListTable.$refs.ListTable.reloadTable()
|
||||
// this.$message.success(this.$t('common.deleteSuccessMsg'))
|
||||
}).catch(error => {
|
||||
this.$message.error(this.$t('common.deleteErrorMsg') + ' ' + error)
|
||||
this.$message.error(this.$t('common.deleteErrorMsg' + ' ' + error))
|
||||
})
|
||||
}.bind(this)
|
||||
}
|
||||
@@ -64,24 +56,26 @@ export default {
|
||||
hasCreate: false,
|
||||
hasMoreActions: false,
|
||||
hasBulkDelete: false,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
// createRoute: 'RemoteAppCreate',
|
||||
moreCreates: {
|
||||
dropdown: this.getCreateAppType(),
|
||||
callback: (app) => {
|
||||
console.log('App: ', app)
|
||||
vm.$router.push({ name: 'RemoteAppCreate', query: { type: app.name }})
|
||||
}
|
||||
}
|
||||
moreActionsTitle: this.$t('common.Create'),
|
||||
moreActionsType: 'primary',
|
||||
extraMoreActions: this.genExtraMoreActions()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCreateAppType() {
|
||||
onCallback(type) {
|
||||
this.$router.push({ name: 'RemoteAppCreate', query: { type: type }})
|
||||
},
|
||||
genExtraMoreActions() {
|
||||
const extraMoreActions = []
|
||||
for (const value of ALL_TYPES) {
|
||||
const item = { ...REMOTE_APP_TYPE_META_MAP[value] }
|
||||
item.type = 'primary'
|
||||
item.can = true
|
||||
item.has = true
|
||||
item.callback = this.onCallback.bind(this, value)
|
||||
extraMoreActions.push(item)
|
||||
}
|
||||
return extraMoreActions
|
||||
|
||||
@@ -8,27 +8,73 @@ export const CUSTOM = 'custom'
|
||||
export const ALL_TYPES = [CHROME, MYSQL_WORKBENCH, VMWARE_CLIENT, CUSTOM]
|
||||
|
||||
export const REMOTE_APP_TYPE_FIELDS_MAP = {
|
||||
[CHROME]: ['asset', 'path', 'chrome_target', 'chrome_username', 'chrome_password'],
|
||||
[CHROME]: [
|
||||
{
|
||||
id: 'chrome_target', el: {}, attrs: {}, type: 'input', prop: 'chrome_target',
|
||||
label: i18n.t('applications.chrome_target')
|
||||
},
|
||||
{
|
||||
id: 'chrome_username', el: {}, attrs: {}, type: 'input', prop: 'chrome_username',
|
||||
label: i18n.t('applications.chrome_username')
|
||||
},
|
||||
{
|
||||
id: 'chrome_password', el: { 'show-password': true }, attrs: {}, type: 'password', prop: 'chrome_password',
|
||||
label: i18n.t('applications.chrome_password')
|
||||
}
|
||||
],
|
||||
[MYSQL_WORKBENCH]: [
|
||||
'asset', 'path',
|
||||
'mysql_workbench_ip',
|
||||
'mysql_workbench_port',
|
||||
'mysql_workbench_name',
|
||||
'mysql_workbench_username',
|
||||
'mysql_workbench_password'
|
||||
{
|
||||
id: 'mysql_workbench_ip', el: {}, attrs: {}, type: 'input', prop: 'mysql_workbench_ip',
|
||||
label: i18n.t('applications.mysql_workbench_ip')
|
||||
},
|
||||
{
|
||||
id: 'mysql_workbench_port', el: {}, attrs: {}, type: 'input', prop: 'mysql_workbench_port',
|
||||
label: i18n.t('applications.mysql_workbench_port')
|
||||
},
|
||||
{
|
||||
id: 'mysql_workbench_name', el: {}, attrs: {}, type: 'input', prop: 'mysql_workbench_name',
|
||||
label: i18n.t('applications.mysql_workbench_name')
|
||||
},
|
||||
{
|
||||
id: 'mysql_workbench_username', el: {}, attrs: {}, type: 'input', prop: 'mysql_workbench_username',
|
||||
label: i18n.t('applications.mysql_workbench_username')
|
||||
},
|
||||
{
|
||||
id: 'mysql_workbench_password', el: { 'show-password': true }, attrs: {}, type: 'password', prop: 'mysql_workbench_password',
|
||||
label: i18n.t('applications.mysql_workbench_password')
|
||||
}
|
||||
],
|
||||
[VMWARE_CLIENT]: [
|
||||
'asset', 'path',
|
||||
'vmware_target',
|
||||
'vmware_username',
|
||||
'vmware_password'
|
||||
{
|
||||
id: 'vmware_target', el: {}, attrs: {}, type: 'input', prop: 'vmware_target',
|
||||
label: i18n.t('applications.vmware_target')
|
||||
},
|
||||
{
|
||||
id: 'vmware_username', el: {}, attrs: {}, type: 'input', prop: 'vmware_username',
|
||||
label: i18n.t('applications.vmware_username')
|
||||
},
|
||||
{
|
||||
id: 'vmware_password', el: { 'show-password': true }, attrs: {}, type: 'password', prop: 'vmware_password',
|
||||
label: i18n.t('applications.vmware_password')
|
||||
}
|
||||
],
|
||||
[CUSTOM]: [
|
||||
'asset', 'path',
|
||||
'custom_cmdline',
|
||||
'custom_target',
|
||||
'custom_username',
|
||||
'custom_password'
|
||||
{
|
||||
id: 'custom_cmdline', el: {}, attrs: {}, type: 'input', prop: 'custom_cmdline',
|
||||
label: i18n.t('applications.custom_cmdline')
|
||||
},
|
||||
{
|
||||
id: 'custom_target', el: {}, attrs: {}, type: 'input', prop: 'custom_target',
|
||||
label: i18n.t('applications.custom_target')
|
||||
},
|
||||
{
|
||||
id: 'custom_username', el: {}, attrs: {}, type: 'input', prop: 'custom_username',
|
||||
label: i18n.t('applications.custom_username')
|
||||
},
|
||||
{
|
||||
id: 'custom_password', el: { 'show-password': true }, attrs: {}, type: 'password', prop: 'custom_password',
|
||||
label: i18n.t('applications.custom_password')
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<AssetUserTable :url="assetUserUrl" :has-import="false" :has-clone="false" />
|
||||
<AssetUserTable :url="assetUserUrl" :has-import="false" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import QuickActions from '@/components/QuickActions/index'
|
||||
import ListTable from '@/components/ListTable'
|
||||
import RelationCard from '@/components/RelationCard'
|
||||
import { ChoicesFormatter } from '@/components/ListTable/formatters'
|
||||
import { BooleanFormatter } from '@/components/ListTable/formatters'
|
||||
|
||||
export default {
|
||||
name: 'AssetList',
|
||||
@@ -44,7 +44,7 @@ export default {
|
||||
},
|
||||
connectivity: {
|
||||
label: this.$t('assets.Reachable'),
|
||||
formatter: ChoicesFormatter,
|
||||
formatter: BooleanFormatter,
|
||||
formatterArgs: {
|
||||
iconChoices: {
|
||||
0: 'fa-times text-danger',
|
||||
|
||||
@@ -3,17 +3,22 @@
|
||||
<el-col :span="14">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<RelationCard ref="RelationCard" type="info" v-bind="nodeRelationConfig" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DetailCard from '@/components/DetailCard'
|
||||
import RelationCard from '@/components/RelationCard'
|
||||
import { toSafeLocalDateStr } from '@/utils/common'
|
||||
|
||||
export default {
|
||||
name: 'Detail',
|
||||
components: {
|
||||
DetailCard
|
||||
DetailCard,
|
||||
RelationCard
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
@@ -23,7 +28,31 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
nodeRelationConfig: {
|
||||
icon: 'fa-info',
|
||||
title: this.$t('assets.ReplaceNodeAssetsAdminUserWithThis'),
|
||||
objectsAjax: {
|
||||
url: '/api/v1/assets/nodes/',
|
||||
transformOption: (item) => {
|
||||
return { label: item.full_value, value: item.id }
|
||||
}
|
||||
},
|
||||
performAdd: (items) => {
|
||||
const data = []
|
||||
const relationUrl = `/api/v1/assets/admin-users/${this.object.id}/nodes/`
|
||||
items.map(v => {
|
||||
data.push(v.value)
|
||||
})
|
||||
return this.$axios.patch(relationUrl, { nodes: data }).then(res => {
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
}).catch(err => {
|
||||
this.$message.error(this.$t('common.updateErrorMsg' + ' ' + err))
|
||||
})
|
||||
},
|
||||
onAddSuccess: () => {
|
||||
this.$refs.RelationCard.$refs.select2.clearSelected()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -37,10 +66,6 @@ export default {
|
||||
key: this.$t('assets.Username'),
|
||||
value: this.object.username
|
||||
},
|
||||
{
|
||||
key: this.$t('assets.sshKeyFingerprint'),
|
||||
value: this.object.ssh_key_fingerprint
|
||||
},
|
||||
{
|
||||
key: this.$t('assets.date_joined'),
|
||||
value: toSafeLocalDateStr(this.object.date_created)
|
||||
|
||||
@@ -13,14 +13,7 @@ export default {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/assets/admin-users/',
|
||||
columns: [
|
||||
'name', 'username', 'assets_amount',
|
||||
'created_by', 'date_created', 'date_updated', 'comment', 'org_name', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: ['name', 'username', 'assets_amount', 'comment', 'actions']
|
||||
},
|
||||
columns: ['name', 'username', 'assets_amount', 'comment', 'actions'],
|
||||
columnsMeta: {
|
||||
username: {
|
||||
showOverflowTooltip: true
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="16">
|
||||
<AssetUserTable ref="ListTable" :url="assetUserUrl" :has-import="false" :has-clone="false" />
|
||||
<AssetUserTable ref="ListTable" :url="assetUserUrl" :has-import="false" />
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<QuickActions type="primary" :actions="quickActions" />
|
||||
|
||||
@@ -67,14 +67,13 @@
|
||||
|
||||
<script>
|
||||
import GenericTreeListPage from '@/layout/components/GenericTreeListPage/index'
|
||||
import { DetailFormatter, ActionsFormatter, ChoicesFormatter } from '@/components/ListTable/formatters'
|
||||
import { DetailFormatter, ActionsFormatter, BooleanFormatter } from '@/components/ListTable/formatters'
|
||||
import $ from '@/utils/jquery-vendor'
|
||||
import Dialog from '@/components/Dialog'
|
||||
import TreeTable from '@/components/TreeTable'
|
||||
import { GenericUpdateFormDialog } from '@/layout/components'
|
||||
import rules from '@/components/DataForm/rules'
|
||||
import Protocols from '@/views/assets/Asset/components/Protocols/index'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -90,7 +89,6 @@ export default {
|
||||
showMenu: true,
|
||||
showRefresh: true,
|
||||
showAssets: false,
|
||||
hasRightMenu: this.currentOrgIsRoot,
|
||||
url: '/api/v1/assets/assets/',
|
||||
nodeUrl: '/api/v1/assets/nodes/',
|
||||
// ?assets=0不显示资产. =1显示资产
|
||||
@@ -100,20 +98,8 @@ export default {
|
||||
url: '/api/v1/assets/assets/',
|
||||
hasTree: true,
|
||||
columns: [
|
||||
'hostname', 'ip', 'public_ip', 'admin_user_display',
|
||||
'protocols',
|
||||
'platform', 'hardware_info', 'model',
|
||||
'cpu_model', 'cpu_cores', 'cpu_count', 'cpu_vcpus',
|
||||
'disk_info', 'disk_total', 'memory',
|
||||
'os', 'os_arch', 'os_version',
|
||||
'number', 'vendor', 'sn',
|
||||
'connectivity',
|
||||
'created_by', 'date_created', 'comment', 'org_name', 'actions'
|
||||
'hostname', 'ip', 'hardware_info', 'connectivity', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['hostname', 'ip', 'actions'],
|
||||
default: ['hostname', 'ip', 'hardware_info', 'connectivity', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
hostname: {
|
||||
formatter: DetailFormatter,
|
||||
@@ -129,18 +115,9 @@ export default {
|
||||
hardware_info: {
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
cpu_model: {
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
sn: {
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
comment: {
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
connectivity: {
|
||||
label: this.$t('assets.Reachable'),
|
||||
formatter: ChoicesFormatter,
|
||||
formatter: BooleanFormatter,
|
||||
formatterArgs: {
|
||||
iconChoices: {
|
||||
0: 'fa-times text-danger',
|
||||
@@ -148,9 +125,6 @@ export default {
|
||||
2: 'fa-circle text-warning'
|
||||
},
|
||||
typeChange: function(val) {
|
||||
if (!val) {
|
||||
return 2
|
||||
}
|
||||
return val.status
|
||||
},
|
||||
hasTips: true
|
||||
@@ -161,6 +135,7 @@ export default {
|
||||
actions: {
|
||||
formatter: ActionsFormatter,
|
||||
formatterArgs: {
|
||||
hasClone: true,
|
||||
performDelete: ({ row, col }) => {
|
||||
const id = row.id
|
||||
const url = `/api/v1/assets/assets/${id}/`
|
||||
@@ -171,8 +146,8 @@ export default {
|
||||
name: 'View',
|
||||
title: this.$t(`common.UpdateAssetDetail`),
|
||||
type: 'primary',
|
||||
callback: function({ cellValue, tableData, row }) {
|
||||
return this.$router.push({ name: 'AssetMoreInformationEdit', params: { id: row.id }})
|
||||
callback: function({ cellValue, tableData }) {
|
||||
return this.$router.push({ name: 'AssetMoreInformationEdit', params: { id: cellValue }})
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -181,7 +156,6 @@ export default {
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
// canCreate: false,
|
||||
createRoute: {
|
||||
name: 'AssetCreate',
|
||||
query: this.$route.query
|
||||
@@ -227,7 +201,7 @@ export default {
|
||||
{
|
||||
name: 'updateSelected',
|
||||
title: this.$t('common.updateSelected'),
|
||||
can: ({ selectedRows }) => selectedRows.length > 0 && !this.$store.getters.currentOrgIsRoot,
|
||||
can: ({ selectedRows }) => selectedRows.length > 0,
|
||||
callback: ({ selectedRows, reloadTable }) => {
|
||||
vm.updateSelectedDialogSetting.dialogSetting.dialogVisible = true
|
||||
vm.updateSelectedDialogSetting.selectedRows = selectedRows
|
||||
@@ -240,7 +214,7 @@ export default {
|
||||
if (!this.$route.query.node) {
|
||||
return false
|
||||
}
|
||||
return selectedRows.length > 0 && !this.$store.getters.currentOrgIsRoot
|
||||
return selectedRows.length > 0
|
||||
},
|
||||
callback: function({ selectedRows, reloadTable }) {
|
||||
const assetsId = []
|
||||
@@ -389,12 +363,8 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['currentOrgIsRoot'])
|
||||
},
|
||||
mounted() {
|
||||
this.decorateRMenu()
|
||||
this.treeSetting.hasRightMenu = !this.currentOrgIsRoot
|
||||
},
|
||||
methods: {
|
||||
decorateRMenu() {
|
||||
@@ -495,7 +465,7 @@ export default {
|
||||
},
|
||||
rCheckAssetsAmount: function() {
|
||||
this.$axios.post(
|
||||
`/api/v1/assets/nodes/check_assets_amount_task/`
|
||||
`/api/v1/assets/nodes/launch_check_assets_amount_task/`
|
||||
).then(res => {
|
||||
window.open(`/#/ops/celery/task/${res.task}/log/`, '', 'width=900,height=600')
|
||||
}).catch(error => {
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
|
||||
<ListTable :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericListTable from '@/layout/components/GenericListTable'
|
||||
import ListTable from '@/components/ListTable'
|
||||
|
||||
export default {
|
||||
name: 'Rules',
|
||||
components: {
|
||||
GenericListTable
|
||||
ListTable
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
@@ -50,7 +50,6 @@ export default {
|
||||
headerActions: {
|
||||
hasSearch: true,
|
||||
hasBulkDelete: false,
|
||||
hasMoreActions: false,
|
||||
createRoute: {
|
||||
name: 'CommandFilterRulesCreate',
|
||||
query: {
|
||||
|
||||
@@ -25,6 +25,7 @@ export default {
|
||||
initial: {
|
||||
filter: filterId,
|
||||
type: 'regex',
|
||||
priority: 50,
|
||||
action: 0
|
||||
},
|
||||
fields: [
|
||||
@@ -65,7 +66,7 @@ export default {
|
||||
},
|
||||
priority: {
|
||||
// helpText: '优先级可选范围为1-100,1最低优先级,100最高优先级'
|
||||
// helpText: this.$t('assets.CommandFilterRulePriorityHelpText')
|
||||
helpText: this.$t('assets.CommandFilterRulePriorityHelpText')
|
||||
}
|
||||
},
|
||||
getNextRoute(res, method) {
|
||||
|
||||
@@ -14,14 +14,7 @@ export default {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/assets/cmd-filters/',
|
||||
columns: [
|
||||
'name', 'rules', 'system_users', 'is_active',
|
||||
'created_by', 'date_created', 'comment', 'org_name', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: ['name', 'rules', 'system_users', 'comment', 'actions']
|
||||
},
|
||||
columns: ['name', 'rules', 'system_users', 'comment', 'actions'],
|
||||
columnsMeta: {
|
||||
rules: {
|
||||
label: this.$t('assets.Rules'),
|
||||
@@ -35,9 +28,6 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
date_created: {
|
||||
label: this.$t('users.DateJoined')
|
||||
},
|
||||
system_users: {
|
||||
label: this.$t('assets.SystemUsers'),
|
||||
formatter: DetailFormatter,
|
||||
@@ -51,7 +41,7 @@ export default {
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasRightActions: true,
|
||||
hasRightActions: false,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasRefresh: true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
|
||||
<ListTable :table-config="tableConfig" :header-actions="headerActions" />
|
||||
<Dialog
|
||||
v-if="dialogVisible"
|
||||
:title="this.$t('assets.TestGatewayTestConnection')"
|
||||
@@ -29,12 +29,12 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericListTable from '@/layout/components/GenericListTable/index'
|
||||
import ListTable from '@/components/ListTable/index'
|
||||
import DisplayFormatter from '@/components/ListTable/formatters/DisplayFormatter'
|
||||
import Dialog from '@/components/Dialog'
|
||||
export default {
|
||||
components: {
|
||||
GenericListTable,
|
||||
ListTable,
|
||||
Dialog
|
||||
},
|
||||
props: {
|
||||
@@ -81,7 +81,7 @@ export default {
|
||||
return this.$message.error(this.$t('common.BadRequestErrorMsg'))
|
||||
} else {
|
||||
this.portInput = val.row.port
|
||||
this.cellValue = val.row.id
|
||||
this.cellValue = val.cellValue
|
||||
}
|
||||
}.bind(this)
|
||||
}
|
||||
|
||||
@@ -15,13 +15,8 @@ export default {
|
||||
tableConfig: {
|
||||
url: '/api/v1/assets/domains/',
|
||||
columns: [
|
||||
'name', 'asset_count', 'application_count', 'gateway_count', 'date_created',
|
||||
'comment', 'org_name', 'actions'
|
||||
'name', 'asset_count', 'application_count', 'gateway_count', 'comment', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: ['name', 'asset_count', 'application_count', 'gateway_count', 'comment', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
asset_count: {
|
||||
label: this.$t('assets.Assets')
|
||||
|
||||
@@ -13,10 +13,7 @@ export default {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/assets/labels/',
|
||||
columns: [
|
||||
'name', 'value', 'asset_count',
|
||||
'date_created', 'comment', 'org_name', 'actions'
|
||||
],
|
||||
columns: ['name', 'value', 'asset_count', 'actions'],
|
||||
columnsMeta: {
|
||||
name: {
|
||||
formatter: null
|
||||
@@ -27,6 +24,11 @@ export default {
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasRightActions: false,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasRefresh: true,
|
||||
hasSearch: true,
|
||||
hasMoreActions: false,
|
||||
createRoute: 'LabelCreate'
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
<script>
|
||||
import { GenericListPage } from '@/layout/components'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GenericListPage
|
||||
@@ -13,31 +14,22 @@ export default {
|
||||
tableConfig: {
|
||||
url: '/api/v1/assets/platforms/',
|
||||
columns: [
|
||||
'name', 'base',
|
||||
'comment', 'actions'
|
||||
'name', 'base', 'comment', 'actions'
|
||||
],
|
||||
columnsMeta: {
|
||||
base: {
|
||||
width: '140px'
|
||||
},
|
||||
actions: {
|
||||
formatterArgs: {
|
||||
canClone: true,
|
||||
canDelete: (row, value) => {
|
||||
return !row.internal
|
||||
},
|
||||
canUpdate: (row, value) => {
|
||||
return !row.internal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasRightActions: true,
|
||||
hasRightActions: false,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasRefresh: false,
|
||||
hasSearch: false,
|
||||
hasMoreActions: false,
|
||||
hasBulkDelete: false,
|
||||
canCreate: true,
|
||||
createRoute: 'PlatformCreate'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
<template>
|
||||
<GenericCreateUpdatePage :fields="fields" :initial="initial" :fields-meta="fieldsMeta" :url="url" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
||||
import UploadKey from '@/components/UploadKey'
|
||||
import { Required } from '@/components/DataForm/rules'
|
||||
|
||||
export default {
|
||||
name: 'SystemUserCreateUpdate',
|
||||
components: { GenericCreateUpdatePage },
|
||||
data() {
|
||||
return {
|
||||
initial: {
|
||||
login_mode: 'auto',
|
||||
protocol: this.$route.query.protocol,
|
||||
username_same_with_user: false,
|
||||
auto_generate_key: false,
|
||||
auto_push: false
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'login_mode', 'username', 'username_same_with_user', 'priority', 'protocol']],
|
||||
[this.$t('common.Auth'), ['update_password', 'password']],
|
||||
[this.$t('common.Other'), ['comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
login_mode: {
|
||||
helpText: this.$t('assets.LoginModeHelpMessage'),
|
||||
hidden: (form) => {
|
||||
if (form.protocol === 'k8s') {
|
||||
return true
|
||||
}
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
if (value === 'manual') {
|
||||
updateForm({ auto_push: false })
|
||||
updateForm({ auto_generate_key: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
username: {
|
||||
el: {
|
||||
disabled: false
|
||||
},
|
||||
rules: [Required],
|
||||
hidden: (form) => {
|
||||
if (form.login_mode === 'auto') {
|
||||
this.fieldsMeta.username.rules = [Required]
|
||||
} else {
|
||||
this.fieldsMeta.username.rules[0].required = false
|
||||
}
|
||||
if (!form.username_same_with_user) {
|
||||
this.fieldsMeta.username.rules = [Required]
|
||||
} else {
|
||||
this.fieldsMeta.username.rules[0].required = false
|
||||
}
|
||||
if (['mysql', 'postgresql', 'mariadb', 'oracle'].indexOf(form.protocol) !== -1) {
|
||||
this.fieldsMeta.username.rules = [Required]
|
||||
this.fieldsMeta.username.rules[0].required = true
|
||||
}
|
||||
}
|
||||
},
|
||||
private_key: {
|
||||
component: UploadKey,
|
||||
hidden: (form) => {
|
||||
if (form.login_mode !== 'auto') {
|
||||
return true
|
||||
}
|
||||
if (form.protocol === 'k8s') {
|
||||
return true
|
||||
}
|
||||
return form.auto_generate_key === true
|
||||
}
|
||||
},
|
||||
username_same_with_user: {
|
||||
type: 'switch',
|
||||
helpText: this.$t('assets.UsernameHelpMessage'),
|
||||
hidden: (form) => {
|
||||
this.fieldsMeta.username.el.disabled = form.username_same_with_user
|
||||
return form.protocol === 'k8s'
|
||||
},
|
||||
el: {
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
protocol: {
|
||||
rules: [Required],
|
||||
el: {
|
||||
disabled: true,
|
||||
style: 'width:100%'
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
if (['ssh', 'rdp'].indexOf(value) === -1) {
|
||||
updateForm({ auto_push: false })
|
||||
updateForm({ auto_generate_key: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
update_password: {
|
||||
label: this.$t('users.UpdatePassword'),
|
||||
type: 'checkbox',
|
||||
hidden: (formValue) => {
|
||||
if (formValue.update_password || formValue.protocol === 'k8s') {
|
||||
return true
|
||||
}
|
||||
if (formValue.login_mode === 'manual') {
|
||||
return true
|
||||
}
|
||||
return !this.$route.params.id
|
||||
}
|
||||
},
|
||||
password: {
|
||||
helpText: this.$t('assets.PasswordHelpMessage'),
|
||||
hidden: form => {
|
||||
if (form.login_mode !== 'auto' || form.protocol === 'k8s' || form.auto_generate_key) {
|
||||
return true
|
||||
}
|
||||
if (!this.$route.params.id) {
|
||||
return false
|
||||
}
|
||||
return !form.update_password
|
||||
}
|
||||
}
|
||||
},
|
||||
url: '/api/v1/assets/system-users/',
|
||||
authHiden: false
|
||||
}
|
||||
},
|
||||
method: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
const params = this.$route.params
|
||||
const method = params.id ? 'update' : 'create'
|
||||
if (method === 'update') {
|
||||
this.fieldsMeta.username_same_with_user.el.disabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,62 +0,0 @@
|
||||
<template>
|
||||
<GenericCreateUpdatePage
|
||||
:fields="fields"
|
||||
:initial="initial"
|
||||
:fields-meta="fieldsMeta"
|
||||
:url="url"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
||||
import { Required } from '@/components/DataForm/rules'
|
||||
|
||||
export default {
|
||||
name: 'SystemUserCreateUpdate',
|
||||
components: { GenericCreateUpdatePage },
|
||||
data() {
|
||||
return {
|
||||
initial: {
|
||||
protocol: this.$route.query.protocol
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'priority', 'protocol']],
|
||||
[this.$t('common.Auth'), ['token']],
|
||||
[this.$t('common.Other'), ['comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
token: {
|
||||
rules: [Required],
|
||||
el: {
|
||||
type: 'textarea',
|
||||
autosize: { minRows: 3 }
|
||||
}
|
||||
},
|
||||
protocol: {
|
||||
rules: [Required],
|
||||
el: {
|
||||
disabled: true,
|
||||
style: 'width:100%'
|
||||
}
|
||||
}
|
||||
},
|
||||
url: '/api/v1/assets/system-users/',
|
||||
authHiden: false
|
||||
}
|
||||
},
|
||||
method: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
const params = this.$route.params
|
||||
const method = params.id ? 'update' : 'create'
|
||||
if (method === 'update') {
|
||||
this.fieldsMeta.token.rules[0].required = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,157 +0,0 @@
|
||||
<template>
|
||||
<GenericCreateUpdatePage :fields="fields" :initial="initial" :fields-meta="fieldsMeta" :url="url" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
||||
import { Required } from '@/components/DataForm/rules'
|
||||
|
||||
export default {
|
||||
name: 'SystemUserCreateUpdate',
|
||||
components: { GenericCreateUpdatePage },
|
||||
data() {
|
||||
return {
|
||||
initial: {
|
||||
login_mode: 'auto',
|
||||
protocol: this.$route.query.protocol,
|
||||
username_same_with_user: false,
|
||||
auto_generate_key: false,
|
||||
auto_push: false,
|
||||
sftp_root: 'tmp',
|
||||
sudo: '/bin/whoami',
|
||||
shell: '/bin/bash'
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'login_mode', 'username', 'username_same_with_user', 'priority', 'protocol']],
|
||||
[this.$t('assets.AutoPush'), ['auto_push']],
|
||||
[this.$t('common.Auth'), ['update_password', 'password', 'ad_domain']],
|
||||
[this.$t('common.Other'), ['comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
login_mode: {
|
||||
helpText: this.$t('assets.LoginModeHelpMessage'),
|
||||
hidden: (form) => {
|
||||
if (form.protocol === 'k8s') {
|
||||
return true
|
||||
}
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
if (value === 'manual') {
|
||||
updateForm({ auto_push: false })
|
||||
updateForm({ auto_generate_key: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
username: {
|
||||
el: {
|
||||
disabled: false
|
||||
},
|
||||
rules: [Required],
|
||||
hidden: (form) => {
|
||||
if (form.login_mode === 'auto') {
|
||||
this.fieldsMeta.username.rules = [Required]
|
||||
} else {
|
||||
this.fieldsMeta.username.rules[0].required = false
|
||||
}
|
||||
if (!form.username_same_with_user) {
|
||||
this.fieldsMeta.username.rules = [Required]
|
||||
} else {
|
||||
this.fieldsMeta.username.rules[0].required = false
|
||||
}
|
||||
}
|
||||
},
|
||||
username_same_with_user: {
|
||||
type: 'switch',
|
||||
helpText: this.$t('assets.UsernameHelpMessage'),
|
||||
hidden: (form) => {
|
||||
this.fieldsMeta.username.el.disabled = form.username_same_with_user
|
||||
return form.protocol === 'k8s'
|
||||
},
|
||||
el: {
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
auto_push: {
|
||||
type: 'switch',
|
||||
el: {
|
||||
disabled: false
|
||||
},
|
||||
hidden: form => {
|
||||
if (form.login_mode === 'manual') { this.fieldsMeta.auto_push.el.disabled = true }
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
if (!value) {
|
||||
updateForm({ auto_generate_key: value })
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
protocol: {
|
||||
rules: [Required],
|
||||
el: {
|
||||
style: 'width:100%',
|
||||
disabled: true
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
if (['ssh', 'rdp'].indexOf(value) === -1) {
|
||||
updateForm({ auto_push: false })
|
||||
updateForm({ auto_generate_key: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
ad_domain: {
|
||||
label: this.$t('assets.AdDomain'),
|
||||
hidden: (form) => ['rdp'].indexOf(form.protocol) === -1,
|
||||
helpText: this.$t('assets.AdDomainHelpText')
|
||||
},
|
||||
update_password: {
|
||||
label: this.$t('users.UpdatePassword'),
|
||||
type: 'checkbox',
|
||||
hidden: (formValue) => {
|
||||
if (formValue.update_password || formValue.protocol === 'k8s') {
|
||||
return true
|
||||
}
|
||||
if (formValue.login_mode === 'manual') {
|
||||
return true
|
||||
}
|
||||
return !this.$route.params.id
|
||||
}
|
||||
},
|
||||
password: {
|
||||
helpText: this.$t('assets.PasswordHelpMessage'),
|
||||
hidden: form => {
|
||||
if (form.login_mode !== 'auto' || form.protocol === 'k8s' || form.auto_generate_key) {
|
||||
return true
|
||||
}
|
||||
if (!this.$route.params.id) {
|
||||
return false
|
||||
}
|
||||
return !form.update_password
|
||||
}
|
||||
}
|
||||
},
|
||||
url: '/api/v1/assets/system-users/',
|
||||
authHiden: false
|
||||
}
|
||||
},
|
||||
method: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
const params = this.$route.params
|
||||
const method = params.id ? 'update' : 'create'
|
||||
if (method === 'update') {
|
||||
this.fieldsMeta.username_same_with_user.el.disabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,245 +0,0 @@
|
||||
<template>
|
||||
<GenericCreateUpdatePage :fields="fields" :initial="initial" :fields-meta="fieldsMeta" :url="url" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
||||
import UploadKey from '@/components/UploadKey'
|
||||
import { Select2 } from '@/components'
|
||||
import { Required } from '@/components/DataForm/rules'
|
||||
|
||||
// const asciiProtocols = ['ssh', 'telnet', 'mysql']
|
||||
const graphProtocols = ['vnc', 'rdp', 'k8s']
|
||||
|
||||
export default {
|
||||
name: 'SystemUserCreateUpdate',
|
||||
components: { GenericCreateUpdatePage },
|
||||
data() {
|
||||
return {
|
||||
initial: {
|
||||
login_mode: 'auto',
|
||||
protocol: this.$route.query.protocol,
|
||||
username_same_with_user: false,
|
||||
auto_generate_key: false,
|
||||
auto_push: false,
|
||||
sftp_root: 'tmp',
|
||||
sudo: '/bin/whoami',
|
||||
shell: '/bin/bash'
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'login_mode', 'username', 'username_same_with_user', 'priority', 'protocol']],
|
||||
[this.$t('assets.AutoPush'), ['auto_push', 'sudo', 'shell', 'home', 'system_groups']],
|
||||
[this.$t('common.Auth'), ['auto_generate_key', 'update_password', 'password', 'private_key', 'token', 'ad_domain']],
|
||||
[this.$t('common.Command filter'), ['cmd_filters']],
|
||||
[this.$t('common.Other'), ['sftp_root', 'comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
login_mode: {
|
||||
helpText: this.$t('assets.LoginModeHelpMessage'),
|
||||
hidden: (form) => {
|
||||
if (form.protocol === 'k8s') {
|
||||
return true
|
||||
}
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
if (value === 'manual') {
|
||||
updateForm({ auto_push: false })
|
||||
updateForm({ auto_generate_key: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
username: {
|
||||
el: {
|
||||
disabled: false
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
updateForm({ home: `/home/${value}` })
|
||||
}
|
||||
},
|
||||
rules: [Required],
|
||||
hidden: (form) => {
|
||||
if (form.login_mode === 'auto') {
|
||||
this.fieldsMeta.username.rules = [Required]
|
||||
} else {
|
||||
this.fieldsMeta.username.rules[0].required = false
|
||||
}
|
||||
if (!form.username_same_with_user) {
|
||||
this.fieldsMeta.username.rules = [Required]
|
||||
} else {
|
||||
this.fieldsMeta.username.rules[0].required = false
|
||||
}
|
||||
if (['mysql', 'postgresql', 'mariadb', 'oracle'].indexOf(form.protocol) !== -1) {
|
||||
this.fieldsMeta.username.rules = [Required]
|
||||
this.fieldsMeta.username.rules[0].required = true
|
||||
}
|
||||
}
|
||||
},
|
||||
private_key: {
|
||||
component: UploadKey,
|
||||
hidden: (form) => {
|
||||
if (form.login_mode !== 'auto') {
|
||||
return true
|
||||
}
|
||||
if (form.protocol === 'k8s') {
|
||||
return true
|
||||
}
|
||||
return form.auto_generate_key === true
|
||||
}
|
||||
},
|
||||
username_same_with_user: {
|
||||
type: 'switch',
|
||||
helpText: this.$t('assets.UsernameHelpMessage'),
|
||||
hidden: (form) => {
|
||||
this.fieldsMeta.username.el.disabled = form.username_same_with_user
|
||||
return form.protocol === 'k8s'
|
||||
},
|
||||
el: {
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
auto_generate_key: {
|
||||
type: 'switch',
|
||||
label: this.$t('assets.AutoGenerateKey'),
|
||||
hidden: form => {
|
||||
this.fieldsMeta.auto_generate_key.el.disabled = ['ssh', 'rdp'].indexOf(form.protocol) === -1 || form.login_mode === 'manual'
|
||||
if (JSON.stringify(this.$route.params) !== '{}') {
|
||||
return true
|
||||
}
|
||||
if (form.protocol === 'k8s') {
|
||||
return true
|
||||
}
|
||||
},
|
||||
el: {
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
token: {
|
||||
rules: [Required],
|
||||
el: {
|
||||
type: 'textarea',
|
||||
autosize: { minRows: 3 }
|
||||
},
|
||||
hidden: form => {
|
||||
return form.protocol !== 'k8s'
|
||||
}
|
||||
},
|
||||
protocol: {
|
||||
rules: [Required],
|
||||
el: {
|
||||
style: 'width:100%',
|
||||
disabled: true
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
if (['ssh', 'rdp'].indexOf(value) === -1) {
|
||||
updateForm({ auto_push: false })
|
||||
updateForm({ auto_generate_key: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
ad_domain: {
|
||||
label: this.$t('assets.AdDomain'),
|
||||
hidden: (form) => ['rdp'].indexOf(form.protocol) === -1,
|
||||
helpText: this.$t('assets.AdDomainHelpText')
|
||||
},
|
||||
cmd_filters: {
|
||||
component: Select2,
|
||||
hidden: (form) => graphProtocols.indexOf(form.protocol) !== -1,
|
||||
el: {
|
||||
multiple: true,
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/assets/cmd-filters/'
|
||||
}
|
||||
}
|
||||
},
|
||||
auto_push: {
|
||||
type: 'switch',
|
||||
el: {
|
||||
disabled: false
|
||||
},
|
||||
hidden: form => {
|
||||
this.fieldsMeta.auto_push.el.disabled = ['ssh', 'rdp'].indexOf(form.protocol) === -1 || form.login_mode === 'manual'
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
if (!value) {
|
||||
updateForm({ auto_generate_key: value })
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
sftp_root: {
|
||||
rules: [Required],
|
||||
helpText: this.$t('assets.SFTPHelpMessage'),
|
||||
hidden: (item) => item.protocol !== 'ssh'
|
||||
},
|
||||
sudo: {
|
||||
rules: [Required],
|
||||
helpText: this.$t('assets.SudoHelpMessage'),
|
||||
hidden: (item) => item.protocol !== 'ssh' || !item.auto_push
|
||||
},
|
||||
update_password: {
|
||||
label: this.$t('users.UpdatePassword'),
|
||||
type: 'checkbox',
|
||||
hidden: (formValue) => {
|
||||
if (formValue.update_password || formValue.protocol === 'k8s') {
|
||||
return true
|
||||
}
|
||||
if (formValue.login_mode === 'manual') {
|
||||
return true
|
||||
}
|
||||
return !this.$route.params.id
|
||||
}
|
||||
},
|
||||
password: {
|
||||
helpText: this.$t('assets.PasswordHelpMessage'),
|
||||
hidden: form => {
|
||||
if (form.login_mode !== 'auto' || form.protocol === 'k8s' || form.auto_generate_key) {
|
||||
return true
|
||||
}
|
||||
if (!this.$route.params.id) {
|
||||
return false
|
||||
}
|
||||
return !form.update_password
|
||||
}
|
||||
},
|
||||
shell: {
|
||||
hidden: (item) => item.protocol !== 'ssh' || !item.auto_push,
|
||||
rules: [Required]
|
||||
},
|
||||
home: {
|
||||
label: this.$t('assets.Home'),
|
||||
hidden: (item) => item.protocol !== 'ssh' || !item.auto_push || item.username_same_with_user,
|
||||
helpText: this.$t('assets.HomeHelpMessage')
|
||||
},
|
||||
system_groups: {
|
||||
label: this.$t('assets.LinuxUserAffiliateGroup'),
|
||||
hidden: (item) => ['ssh', 'rdp'].indexOf(item.protocol) === -1 || !item.auto_push || item.username_same_with_user,
|
||||
helpText: this.$t('assets.GroupsHelpMessage')
|
||||
}
|
||||
},
|
||||
url: '/api/v1/assets/system-users/',
|
||||
authHiden: false
|
||||
}
|
||||
},
|
||||
method: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
const params = this.$route.params
|
||||
const method = params.id ? 'update' : 'create'
|
||||
if (method === 'update') {
|
||||
this.fieldsMeta.username_same_with_user.el.disabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,118 +0,0 @@
|
||||
<template>
|
||||
<GenericCreateUpdatePage :fields="fields" :initial="initial" :fields-meta="fieldsMeta" :url="url" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
||||
import { Required } from '@/components/DataForm/rules'
|
||||
|
||||
// const asciiProtocols = ['ssh', 'telnet', 'mysql']
|
||||
|
||||
export default {
|
||||
name: 'SystemUserCreateUpdate',
|
||||
components: { GenericCreateUpdatePage },
|
||||
data() {
|
||||
return {
|
||||
initial: {
|
||||
login_mode: 'auto',
|
||||
protocol: this.$route.query.protocol,
|
||||
username_same_with_user: false
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'login_mode', 'username', 'username_same_with_user', 'priority', 'protocol']],
|
||||
[this.$t('common.Auth'), ['update_password', 'password']],
|
||||
[this.$t('common.Other'), ['comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
login_mode: {
|
||||
helpText: this.$t('assets.LoginModeHelpMessage')
|
||||
},
|
||||
username: {
|
||||
el: {
|
||||
disabled: false
|
||||
},
|
||||
rules: [Required],
|
||||
hidden: (form) => {
|
||||
if (form.login_mode === 'auto') {
|
||||
this.fieldsMeta.username.rules = [Required]
|
||||
} else {
|
||||
this.fieldsMeta.username.rules[0].required = false
|
||||
}
|
||||
if (!form.username_same_with_user) {
|
||||
this.fieldsMeta.username.rules = [Required]
|
||||
} else {
|
||||
this.fieldsMeta.username.rules[0].required = false
|
||||
}
|
||||
}
|
||||
},
|
||||
username_same_with_user: {
|
||||
type: 'switch',
|
||||
helpText: this.$t('assets.UsernameHelpMessage'),
|
||||
hidden: (form) => {
|
||||
this.fieldsMeta.username.el.disabled = form.username_same_with_user
|
||||
},
|
||||
el: {
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
protocol: {
|
||||
rules: [Required],
|
||||
el: {
|
||||
disabled: true,
|
||||
style: 'width:100%'
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
if (['ssh', 'rdp'].indexOf(value) === -1) {
|
||||
updateForm({ auto_push: false })
|
||||
updateForm({ auto_generate_key: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
update_password: {
|
||||
label: this.$t('users.UpdatePassword'),
|
||||
type: 'checkbox',
|
||||
hidden: (formValue) => {
|
||||
if (formValue.update_password || formValue.protocol === 'k8s') {
|
||||
return true
|
||||
}
|
||||
if (formValue.login_mode === 'manual') {
|
||||
return true
|
||||
}
|
||||
return !this.$route.params.id
|
||||
}
|
||||
},
|
||||
password: {
|
||||
helpText: this.$t('assets.PasswordHelpMessage'),
|
||||
hidden: form => {
|
||||
if (form.login_mode !== 'auto' || form.protocol === 'k8s' || form.auto_generate_key) {
|
||||
return true
|
||||
}
|
||||
if (!this.$route.params.id) {
|
||||
return false
|
||||
}
|
||||
return !form.update_password
|
||||
}
|
||||
}
|
||||
},
|
||||
url: '/api/v1/assets/system-users/',
|
||||
authHiden: false
|
||||
}
|
||||
},
|
||||
method: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
const params = this.$route.params
|
||||
const method = params.id ? 'update' : 'create'
|
||||
if (method === 'update') {
|
||||
this.fieldsMeta.username_same_with_user.el.disabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,47 +1,245 @@
|
||||
<template>
|
||||
<component :is="activePage" />
|
||||
<GenericCreateUpdatePage :fields="fields" :initial="initial" :fields-meta="fieldsMeta" :url="url" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SSH from './SystemUserCreate/ssh'
|
||||
import RDP from './SystemUserCreate/rdp'
|
||||
import VncAndTelnet from './SystemUserCreate/vncAndTelnet'
|
||||
import DATABASE from './SystemUserCreate/database'
|
||||
import K8S from './SystemUserCreate/k8s'
|
||||
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
||||
import UploadKey from '@/components/UploadKey'
|
||||
import { Select2 } from '@/components'
|
||||
import { Required } from '@/components/DataForm/rules'
|
||||
|
||||
// const asciiProtocols = ['ssh', 'telnet', 'mysql']
|
||||
const graphProtocols = ['vnc', 'rdp', 'k8s']
|
||||
|
||||
export default {
|
||||
name: 'SystemUserCreateUpdate',
|
||||
components: { SSH, RDP, VncAndTelnet, DATABASE },
|
||||
components: { GenericCreateUpdatePage },
|
||||
data() {
|
||||
return {
|
||||
|
||||
initial: {
|
||||
login_mode: 'auto',
|
||||
priority: '20',
|
||||
protocol: 'ssh',
|
||||
username_same_with_user: false,
|
||||
auto_generate_key: false,
|
||||
auto_push: false,
|
||||
sftp_root: 'tmp',
|
||||
sudo: '/bin/whoami',
|
||||
shell: '/bin/bash'
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'login_mode', 'username', 'username_same_with_user', 'priority', 'protocol']],
|
||||
[this.$t('assets.AutoPush'), ['auto_push', 'sudo', 'shell', 'home', 'system_groups']],
|
||||
[this.$t('common.Auth'), ['auto_generate_key', 'update_password', 'password', 'private_key', 'token', 'ad_domain']],
|
||||
[this.$t('common.Command filter'), ['cmd_filters']],
|
||||
[this.$t('common.Other'), ['sftp_root', 'comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
login_mode: {
|
||||
helpText: this.$t('assets.LoginModeHelpMessage'),
|
||||
hidden: (form) => {
|
||||
if (form.protocol === 'k8s') {
|
||||
return true
|
||||
}
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
if (value === 'manual') {
|
||||
updateForm({ auto_push: false })
|
||||
updateForm({ auto_generate_key: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
username: {
|
||||
el: {
|
||||
disabled: false
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
updateForm({ home: `/home/${value}` })
|
||||
}
|
||||
},
|
||||
rules: [Required],
|
||||
hidden: (form) => {
|
||||
if (form.login_mode === 'auto') {
|
||||
this.fieldsMeta.username.rules = [Required]
|
||||
} else {
|
||||
this.fieldsMeta.username.rules[0].required = false
|
||||
}
|
||||
if (!form.username_same_with_user) {
|
||||
this.fieldsMeta.username.rules = [Required]
|
||||
} else {
|
||||
this.fieldsMeta.username.rules[0].required = false
|
||||
}
|
||||
if (['mysql', 'postgresql', 'mariadb', 'oracle'].indexOf(form.protocol) !== -1) {
|
||||
this.fieldsMeta.username.rules = [Required]
|
||||
this.fieldsMeta.username.rules[0].required = true
|
||||
}
|
||||
}
|
||||
},
|
||||
private_key: {
|
||||
component: UploadKey,
|
||||
hidden: (form) => {
|
||||
if (form.login_mode !== 'auto') {
|
||||
return true
|
||||
}
|
||||
if (form.protocol === 'k8s') {
|
||||
return true
|
||||
}
|
||||
return form.auto_generate_key === true
|
||||
}
|
||||
},
|
||||
username_same_with_user: {
|
||||
type: 'switch',
|
||||
helpText: this.$t('assets.UsernameHelpMessage'),
|
||||
hidden: (form) => {
|
||||
this.fieldsMeta.username.el.disabled = form.username_same_with_user
|
||||
return form.protocol === 'k8s'
|
||||
},
|
||||
el: {
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
auto_generate_key: {
|
||||
type: 'switch',
|
||||
label: this.$t('assets.AutoGenerateKey'),
|
||||
hidden: form => {
|
||||
this.fieldsMeta.auto_generate_key.el.disabled = ['ssh', 'rdp'].indexOf(form.protocol) === -1 || form.login_mode === 'manual'
|
||||
if (JSON.stringify(this.$route.params) !== '{}') {
|
||||
return true
|
||||
}
|
||||
if (form.protocol === 'k8s') {
|
||||
return true
|
||||
}
|
||||
},
|
||||
el: {
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
token: {
|
||||
rules: [Required],
|
||||
el: {
|
||||
type: 'textarea',
|
||||
autosize: { minRows: 3 }
|
||||
},
|
||||
hidden: form => {
|
||||
return form.protocol !== 'k8s'
|
||||
}
|
||||
},
|
||||
protocol: {
|
||||
rules: [Required],
|
||||
el: {
|
||||
style: 'width:100%'
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
if (['ssh', 'rdp'].indexOf(value) === -1) {
|
||||
updateForm({ auto_push: false })
|
||||
updateForm({ auto_generate_key: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
ad_domain: {
|
||||
label: this.$t('assets.AdDomain'),
|
||||
hidden: (form) => ['rdp'].indexOf(form.protocol) === -1,
|
||||
helpText: this.$t('assets.AdDomainHelpText')
|
||||
},
|
||||
cmd_filters: {
|
||||
component: Select2,
|
||||
hidden: (form) => graphProtocols.indexOf(form.protocol) !== -1,
|
||||
el: {
|
||||
multiple: true,
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/assets/cmd-filters/'
|
||||
}
|
||||
}
|
||||
},
|
||||
priority: {
|
||||
rules: [Required],
|
||||
helpText: this.$t('assets.PriorityHelpMessage')
|
||||
},
|
||||
auto_push: {
|
||||
type: 'switch',
|
||||
el: {
|
||||
disabled: false
|
||||
},
|
||||
hidden: form => {
|
||||
this.fieldsMeta.auto_push.el.disabled = ['ssh', 'rdp'].indexOf(form.protocol) === -1 || form.login_mode === 'manual'
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
if (!value) {
|
||||
updateForm({ auto_generate_key: value })
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
sftp_root: {
|
||||
rules: [Required],
|
||||
helpText: this.$t('assets.SFTPHelpMessage'),
|
||||
hidden: (item) => item.protocol !== 'ssh'
|
||||
},
|
||||
sudo: {
|
||||
rules: [Required],
|
||||
helpText: this.$t('assets.SudoHelpMessage'),
|
||||
hidden: (item) => item.protocol !== 'ssh' || !item.auto_push
|
||||
},
|
||||
update_password: {
|
||||
label: this.$t('users.UpdatePassword'),
|
||||
type: 'checkbox',
|
||||
hidden: (formValue) => {
|
||||
if (formValue.update_password || formValue.protocol === 'k8s') {
|
||||
return true
|
||||
}
|
||||
if (formValue.login_mode === 'manual') {
|
||||
return true
|
||||
}
|
||||
return !this.$route.params.id
|
||||
}
|
||||
},
|
||||
password: {
|
||||
helpText: this.$t('assets.PasswordHelpMessage'),
|
||||
hidden: form => {
|
||||
if (form.login_mode !== 'auto' || form.protocol === 'k8s' || form.auto_generate_key) {
|
||||
return true
|
||||
}
|
||||
if (!this.$route.params.id) {
|
||||
return false
|
||||
}
|
||||
return !form.update_password
|
||||
}
|
||||
},
|
||||
shell: {
|
||||
hidden: (item) => item.protocol !== 'ssh' || !item.auto_push,
|
||||
rules: [Required]
|
||||
},
|
||||
home: {
|
||||
label: this.$t('assets.Home'),
|
||||
hidden: (item) => item.protocol !== 'ssh' || !item.auto_push || item.username_same_with_user,
|
||||
helpText: this.$t('assets.HomeHelpMessage')
|
||||
},
|
||||
system_groups: {
|
||||
label: this.$t('assets.LinuxUserAffiliateGroup'),
|
||||
hidden: (item) => ['ssh', 'rdp'].indexOf(item.protocol) === -1 || !item.auto_push || item.username_same_with_user,
|
||||
helpText: this.$t('assets.GroupsHelpMessage')
|
||||
}
|
||||
},
|
||||
url: '/api/v1/assets/system-users/',
|
||||
authHiden: false
|
||||
}
|
||||
},
|
||||
method: {
|
||||
|
||||
},
|
||||
computed: {
|
||||
activePage() {
|
||||
const query = this.$route.query
|
||||
const protocol = query.protocol
|
||||
switch (protocol) {
|
||||
case 'ssh':
|
||||
return SSH
|
||||
case 'rdp':
|
||||
return RDP
|
||||
case 'vnc':
|
||||
case 'telnet':
|
||||
return VncAndTelnet
|
||||
case 'mysql':
|
||||
case 'oracle':
|
||||
case 'postgresql':
|
||||
case 'mariadb':
|
||||
return DATABASE
|
||||
case 'k8s':
|
||||
return K8S
|
||||
default:
|
||||
return SSH
|
||||
}
|
||||
mounted() {
|
||||
const params = this.$route.params
|
||||
const method = params.id ? 'update' : 'create'
|
||||
if (method === 'update') {
|
||||
this.fieldsMeta.token.rules[0].required = false
|
||||
this.fieldsMeta.username_same_with_user.el.disabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<AssetUserTable ref="ListTable" :url="assetUserUrl" :has-import="false" :has-clone="false" />
|
||||
<AssetUserTable ref="ListTable" :url="assetUserUrl" :has-import="false" />
|
||||
</el-col>
|
||||
<el-col :span="8" />
|
||||
</el-row>
|
||||
|
||||
@@ -57,7 +57,6 @@ export default {
|
||||
formatterArgs: {
|
||||
hasUpdate: false, // can set function(row, value)
|
||||
hasDelete: false, // can set function(row, value)
|
||||
hasClone: false,
|
||||
moreActionsTitle: this.$t('common.More'),
|
||||
extraActions: [
|
||||
{
|
||||
@@ -77,9 +76,8 @@ export default {
|
||||
name: 'Delete',
|
||||
title: this.$t('common.Delete'),
|
||||
type: 'danger',
|
||||
can: !this.$store.getters.currentOrgIsRoot,
|
||||
callback: (val) => {
|
||||
this.$axios.delete(`/api/v1/assets/system-users-assets-relations/${val.row.id}/`).then(() => {
|
||||
this.$axios.delete(`/api/v1/assets/system-users-assets-relations/${val.cellValue}/`).then(() => {
|
||||
this.$message.success(this.$t('common.deleteSuccessMsg'))
|
||||
this.$refs.ListTable.reloadTable()
|
||||
})
|
||||
@@ -191,7 +189,6 @@ export default {
|
||||
assetRelationConfig: {
|
||||
icon: 'fa-edit',
|
||||
title: this.$t('xpack.ChangeAuthPlan.AddAsset'),
|
||||
disabled: this.$store.getters.currentOrgIsRoot,
|
||||
performAdd: (items, that) => {
|
||||
const relationUrl = `/api/v1/assets/system-users-assets-relations/`
|
||||
const data = [
|
||||
|
||||
@@ -10,19 +10,10 @@ export default {
|
||||
GenericListPage
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/assets/system-users/',
|
||||
columns: [
|
||||
'name', 'username', 'username_same_with_user', 'protocol', 'login_mode',
|
||||
'assets_amount', 'priority',
|
||||
'created_by', 'date_created', 'date_updated', 'comment', 'org_name', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: ['name', 'username', 'protocol', 'login_mode', 'assets_amount', 'comment', 'actions']
|
||||
},
|
||||
columns: ['name', 'username', 'protocol', 'login_mode', 'assets_amount', 'comment', 'actions'],
|
||||
columnsMeta: {
|
||||
username: {
|
||||
showOverflowTooltip: true
|
||||
@@ -30,9 +21,6 @@ export default {
|
||||
protocol: {
|
||||
width: '100px'
|
||||
},
|
||||
username_same_with_user: {
|
||||
width: '150px'
|
||||
},
|
||||
login_mode: {
|
||||
width: '120px'
|
||||
},
|
||||
@@ -41,85 +29,14 @@ export default {
|
||||
},
|
||||
actions: {
|
||||
formatterArgs: {
|
||||
onUpdate: ({ row }) => {
|
||||
vm.$router.push({ name: 'SystemUserUpdate', params: { id: row.id }, query: { protocol: row.protocol }})
|
||||
},
|
||||
onClone: ({ row }) => {
|
||||
vm.$router.push({ name: 'SystemUserCreate', query: { protocol: row.protocol, clone_from: row.id }})
|
||||
}
|
||||
hasClone: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
headerActions: {
|
||||
hasMoreActions: false,
|
||||
hasCreate: false,
|
||||
createRoute: 'SystemUserCreate',
|
||||
moreCreates: {
|
||||
callback: (option) => {
|
||||
vm.$router.push({ name: 'SystemUserCreate', query: { protocol: option.title.toLowerCase() }})
|
||||
},
|
||||
dropdown: [
|
||||
{
|
||||
title: 'SSH',
|
||||
name: 'SSH',
|
||||
type: 'primary',
|
||||
group: this.$t('assets.HostProtocol'),
|
||||
has: true
|
||||
},
|
||||
{
|
||||
title: 'Telnet',
|
||||
name: 'Telnet',
|
||||
type: 'primary',
|
||||
has: true
|
||||
},
|
||||
{
|
||||
title: 'RDP',
|
||||
name: 'RDP',
|
||||
type: 'primary',
|
||||
has: true
|
||||
},
|
||||
{
|
||||
title: 'VNC',
|
||||
name: 'VNC',
|
||||
type: 'primary',
|
||||
has: true
|
||||
},
|
||||
{
|
||||
name: 'MySQL',
|
||||
title: 'MySQL',
|
||||
type: 'primary',
|
||||
has: true,
|
||||
group: this.$t('assets.DatabaseProtocol')
|
||||
},
|
||||
{
|
||||
name: 'PostgreSQL',
|
||||
title: 'PostgreSQL',
|
||||
type: 'primary',
|
||||
has: this.$store.getters.hasValidLicense
|
||||
},
|
||||
{
|
||||
name: 'MariaDB',
|
||||
title: 'MariaDB',
|
||||
type: 'primary',
|
||||
has: this.$store.getters.hasValidLicense
|
||||
},
|
||||
{
|
||||
name: 'Oracle',
|
||||
title: 'Oracle',
|
||||
type: 'primary',
|
||||
has: this.$store.getters.hasValidLicense
|
||||
},
|
||||
{
|
||||
name: 'K8S',
|
||||
title: 'K8S',
|
||||
type: 'primary',
|
||||
has: this.$store.getters.hasValidLicense,
|
||||
group: this.$t('assets.OtherProtocol')
|
||||
}
|
||||
]
|
||||
}
|
||||
createRoute: 'SystemUserCreate'
|
||||
},
|
||||
helpMessage: this.$t('assets.SystemUserListHelpMessage')
|
||||
}
|
||||
|
||||
@@ -199,9 +199,7 @@ export default {
|
||||
setWsCallback() {
|
||||
this.ws.onmessage = (e) => {
|
||||
const data = JSON.parse(e.data)
|
||||
let message = data.message
|
||||
message = message.replace(/Task ops\.tasks\.run_command_execution.*/, '')
|
||||
this.xterm.write(message)
|
||||
this.xterm.write(data.message)
|
||||
}
|
||||
},
|
||||
wrapperError(msg) {
|
||||
|
||||
@@ -82,8 +82,8 @@ export default {
|
||||
name: 'detail',
|
||||
title: this.$t('ops.detail'),
|
||||
type: 'primary',
|
||||
callback: function({ row, tableData }) {
|
||||
return this.$router.push({ name: 'HistoryExecutionDetail', params: { id: row.id }})
|
||||
callback: function({ cellValue, tableData }) {
|
||||
return this.$router.push({ name: 'HistoryExecutionDetail', params: { id: cellValue }})
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -74,14 +74,13 @@ export default {
|
||||
hasEdit: false,
|
||||
hasDelete: false,
|
||||
hasUpdate: false,
|
||||
hasClone: false,
|
||||
extraActions: [
|
||||
{
|
||||
name: 'detail',
|
||||
title: this.$t('ops.detail'),
|
||||
type: 'primary',
|
||||
callback: function({ row, tableData }) {
|
||||
return this.$router.push({ name: 'AdhocDetail', params: { id: row.id }})
|
||||
callback: function({ cellValue, tableData }) {
|
||||
return this.$router.push({ name: 'AdhocDetail', params: { id: cellValue }})
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -86,14 +86,13 @@ export default {
|
||||
hasEdit: false,
|
||||
hasDelete: false,
|
||||
hasUpdate: false,
|
||||
hasClone: false,
|
||||
extraActions: [
|
||||
{
|
||||
name: 'detail',
|
||||
title: this.$t('ops.detail'),
|
||||
type: 'primary',
|
||||
callback: function({ row, tableData }) {
|
||||
return this.$router.push({ name: 'HistoryExecutionDetail', params: { id: row.id }})
|
||||
callback: function({ cellValue, tableData }) {
|
||||
return this.$router.push({ name: 'HistoryExecutionDetail', params: { id: cellValue }})
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -72,15 +72,14 @@ export default {
|
||||
prop: 'id',
|
||||
formatterArgs: {
|
||||
hasUpdate: false,
|
||||
hasClone: false,
|
||||
extraActions: [
|
||||
{
|
||||
name: 'run',
|
||||
title: this.$t('ops.run'),
|
||||
type: 'primary',
|
||||
callback: function({ row, tableData }) {
|
||||
callback: function({ cellValue, tableData }) {
|
||||
this.$axios.get(
|
||||
`/api/v1/ops/tasks/${row.id}/run/`
|
||||
`/api/v1/ops/tasks/${cellValue}/run/`
|
||||
).then(res => {
|
||||
window.open(`/#/ops/celery/task/${res.task}/log/`, '', 'width=900,height=600')
|
||||
})
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
<template>
|
||||
|
||||
<GenericCreateUpdatePage
|
||||
ref="createUpdatePage"
|
||||
:fields="fields"
|
||||
:initial="initial"
|
||||
:fields-meta="fieldsMeta"
|
||||
:url="url"
|
||||
/>
|
||||
|
||||
<GenericCreateUpdatePage ref="createUpdatePage" :fields="fields" :initial="initial" :fields-meta="fieldsMeta" :url="url" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -117,9 +109,8 @@ export default {
|
||||
},
|
||||
async mounted() {
|
||||
const params = this.$route.params
|
||||
const query = this.$route.query
|
||||
// 更新获取链接
|
||||
if (params.id || query.clone_from) {
|
||||
if (params.id) {
|
||||
const form = await this.$refs.createUpdatePage.$refs.createUpdateForm.getFormValue()
|
||||
this.fieldsMeta.applications.el.ajax.url = `/api/v1/applications/applications/?category=${form.category}&type=${form.type}`
|
||||
this.fieldsMeta.system_users.el.ajax.url = form.category === 'remote_app' ? `/api/v1/assets/system-users/?protocol=rdp` : `/api/v1/assets/system-users/?protocol=${form.type}`
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user