mirror of
https://github.com/jumpserver/lina.git
synced 2025-11-08 02:18:44 +00:00
Compare commits
1 Commits
v4.10.2-lt
...
pr@dev@per
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e678a81ea |
162
src/components/Apps/UserSelect/dialog.vue
Normal file
162
src/components/Apps/UserSelect/dialog.vue
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:title="$tc('Users')"
|
||||||
|
custom-class="user-select-dialog"
|
||||||
|
v-bind="$attrs"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
@confirm="handleConfirm"
|
||||||
|
v-on="$listeners"
|
||||||
|
>
|
||||||
|
<ListTable
|
||||||
|
ref="ListPage"
|
||||||
|
:header-actions="headerActions"
|
||||||
|
:sync-select-to-url="false"
|
||||||
|
:table-config="tableConfig"
|
||||||
|
:url="baseUrl"
|
||||||
|
v-bind="$attrs"
|
||||||
|
@loaded="handleTableLoaded"
|
||||||
|
v-on="$listeners"
|
||||||
|
/>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Dialog from '@/components/Dialog'
|
||||||
|
import ListTable from '@/components/Table/ListTable'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
componentName: 'AssetSelectDialog',
|
||||||
|
components: { Dialog, ListTable },
|
||||||
|
props: {
|
||||||
|
baseUrl: {
|
||||||
|
type: String,
|
||||||
|
default: '/api/v1/users/users/?fields_size=small'
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
canSelect: {
|
||||||
|
type: Function,
|
||||||
|
default(row, index) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: [Boolean, Function],
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
const vm = this
|
||||||
|
return {
|
||||||
|
isLoaded: false,
|
||||||
|
dialogVisible: false,
|
||||||
|
rowSelected: _.cloneDeep(this.value) || [],
|
||||||
|
rowsAdd: [],
|
||||||
|
tableConfig: {
|
||||||
|
url: this.baseUrl,
|
||||||
|
canSelect: this.canSelect,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
prop: 'name',
|
||||||
|
label: this.$t('Name'),
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'username',
|
||||||
|
label: this.$t('Username'),
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'email',
|
||||||
|
label: this.$t('Email'),
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'mfa_level.label',
|
||||||
|
label: this.$t('MfaLevel'),
|
||||||
|
sortable: true,
|
||||||
|
formatter: function(row) {
|
||||||
|
return row.mfa_level.label
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'source.label',
|
||||||
|
label: this.$t('Source'),
|
||||||
|
sortable: true,
|
||||||
|
formatter: function(row) {
|
||||||
|
return row.source.label
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'org_roles.display_name',
|
||||||
|
label: this.$t('OrgRoles'),
|
||||||
|
sortable: true,
|
||||||
|
formatter: function(row) {
|
||||||
|
return row.org_roles.map(role => role.display_name).join(', ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
columnsMeta: {
|
||||||
|
actions: {
|
||||||
|
has: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
listeners: {
|
||||||
|
'toggle-row-selection': (isSelected, row) => {
|
||||||
|
if (isSelected) {
|
||||||
|
vm.addRowToSelect(row)
|
||||||
|
} else {
|
||||||
|
vm.removeRowFromSelect(row)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
theRowDefaultIsSelected: (row) => {
|
||||||
|
return this.value.indexOf(row.id) > -1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
headerActions: {
|
||||||
|
hasLeftActions: false,
|
||||||
|
hasImport: false,
|
||||||
|
hasExport: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleTableLoaded() {
|
||||||
|
this.isLoaded = true
|
||||||
|
},
|
||||||
|
handleConfirm() {
|
||||||
|
this.$emit('confirm', this.rowSelected, this.rowsAdd)
|
||||||
|
},
|
||||||
|
handleCancel() {
|
||||||
|
this.$emit('cancel')
|
||||||
|
},
|
||||||
|
addRowToSelect(row) {
|
||||||
|
const selectValueIndex = this.rowSelected.indexOf(row.id)
|
||||||
|
if (selectValueIndex === -1) {
|
||||||
|
this.rowSelected.push(row.id)
|
||||||
|
this.rowsAdd.push(row)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeRowFromSelect(row) {
|
||||||
|
const selectValueIndex = this.rowSelected.indexOf(row.id)
|
||||||
|
if (selectValueIndex > -1) {
|
||||||
|
this.rowSelected.splice(selectValueIndex, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.page ::v-deep .page-heading {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-select-dialog ::v-deep .el-icon-circle-check {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
130
src/components/Apps/UserSelect/index.vue
Normal file
130
src/components/Apps/UserSelect/index.vue
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
<template>
|
||||||
|
<div class="user-select-formatter">
|
||||||
|
<Select2
|
||||||
|
ref="select2"
|
||||||
|
v-model="select2Config.value"
|
||||||
|
v-bind="select2Config"
|
||||||
|
@input="onInputChange"
|
||||||
|
v-on="$listeners"
|
||||||
|
@focus.stop="handleFocus"
|
||||||
|
/>
|
||||||
|
<UserSelectDialog
|
||||||
|
v-if="dialogVisible"
|
||||||
|
ref="dialog"
|
||||||
|
:base-url="baseUrl"
|
||||||
|
:value="value"
|
||||||
|
:visible.sync="dialogVisible"
|
||||||
|
v-bind="$attrs"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
@confirm="handleConfirm"
|
||||||
|
v-on="$listeners"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Select2 from '@/components/Form/FormFields/Select2.vue'
|
||||||
|
import UserSelectDialog from './dialog.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
componentName: 'UserSelect',
|
||||||
|
components: { UserSelectDialog, Select2 },
|
||||||
|
props: {
|
||||||
|
baseUrl: {
|
||||||
|
type: String,
|
||||||
|
default: '/api/v1/users/users/?fields_size=small'
|
||||||
|
},
|
||||||
|
defaultPageSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 10
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: [Boolean, Function],
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
const iValue = []
|
||||||
|
for (const item of this.value) {
|
||||||
|
if (typeof item === 'object') {
|
||||||
|
iValue.push(item.id)
|
||||||
|
} else {
|
||||||
|
iValue.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
initialValue: _.cloneDeep(iValue),
|
||||||
|
select2Config: {
|
||||||
|
disabled: this.disabled,
|
||||||
|
value: iValue,
|
||||||
|
multiple: true,
|
||||||
|
clearable: true,
|
||||||
|
defaultPageSize: this.defaultPageSize,
|
||||||
|
ajax: {
|
||||||
|
url: this.baseUrl,
|
||||||
|
transformOption: (item) => {
|
||||||
|
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleFocus() {
|
||||||
|
this.$refs.select2.selectRef.blur()
|
||||||
|
this.dialogVisible = true
|
||||||
|
},
|
||||||
|
handleConfirm(valueSelected, rowsAdd) {
|
||||||
|
if (valueSelected === undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$refs.select2.iValue = valueSelected
|
||||||
|
this.addRowsToSelect(rowsAdd)
|
||||||
|
this.onInputChange(valueSelected)
|
||||||
|
this.dialogVisible = false
|
||||||
|
},
|
||||||
|
handleCancel() {
|
||||||
|
this.dialogVisible = false
|
||||||
|
},
|
||||||
|
onInputChange(val) {
|
||||||
|
this.$emit('change', val)
|
||||||
|
},
|
||||||
|
addToSelect(options, row) {
|
||||||
|
const selectOptionsHas = options.find(item => item.value === row.id)
|
||||||
|
// 如果select2的options中没有,那么可能无法显示正常的值
|
||||||
|
if (selectOptionsHas === undefined) {
|
||||||
|
const option = {
|
||||||
|
label: `${row.name}(${row.username})`,
|
||||||
|
value: row.id
|
||||||
|
}
|
||||||
|
options.push(option)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addRowsToSelect(rows) {
|
||||||
|
const outSelectOptions = this.$refs.select2.options
|
||||||
|
for (const row of rows) {
|
||||||
|
this.addToSelect(outSelectOptions, row)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.el-select {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page ::v-deep .page-heading {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page ::v-deep .treebox {
|
||||||
|
height: inherit !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { GenericCreateUpdatePage } from '@/layout/components'
|
import { GenericCreateUpdatePage } from '@/layout/components'
|
||||||
|
import UserSelect from '@/components/Apps/UserSelect'
|
||||||
import AssetSelect from '@/components/Apps/AssetSelect'
|
import AssetSelect from '@/components/Apps/AssetSelect'
|
||||||
import AccountFormatter from './components/AccountFormatter'
|
import AccountFormatter from './components/AccountFormatter'
|
||||||
import { AllAccount } from '../const'
|
import { AllAccount } from '../const'
|
||||||
@@ -49,14 +50,15 @@ export default {
|
|||||||
createSuccessNextRoute: { name: 'AssetPermissionDetail' },
|
createSuccessNextRoute: { name: 'AssetPermissionDetail' },
|
||||||
fieldsMeta: {
|
fieldsMeta: {
|
||||||
users: {
|
users: {
|
||||||
|
type: 'userSelect',
|
||||||
|
component: UserSelect,
|
||||||
|
rules: [{
|
||||||
|
required: false
|
||||||
|
}],
|
||||||
el: {
|
el: {
|
||||||
value: [],
|
value: [],
|
||||||
ajax: {
|
defaultPageSize: 300,
|
||||||
url: '/api/v1/users/users/?fields_size=mini',
|
baseUrl: '/api/v1/users/users/?fields_size=small'
|
||||||
transformOption: (item) => {
|
|
||||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
user_groups: {
|
user_groups: {
|
||||||
|
|||||||
Reference in New Issue
Block a user