mirror of https://github.com/veops/cmdb.git
242 lines
7.3 KiB
Python
242 lines
7.3 KiB
Python
<template>
|
|
<a-modal v-model="visible" :title="`${$t('acl.memberManage')}${editRecord.name}`" @ok="handleSubmit" :width="690">
|
|
<!-- <CustomTransfer
|
|
ref="customTransfer"
|
|
:show-search="true"
|
|
:data-source="resources"
|
|
:filter-option="filterOption"
|
|
:target-keys="targetKeys"
|
|
:render="(item) => item.title"
|
|
@change="handleChange"
|
|
@search="handleSearch"
|
|
@selectChange="selectChange"
|
|
>
|
|
</CustomTransfer> -->
|
|
<a-transfer
|
|
:dataSource="resources"
|
|
:showSearch="true"
|
|
:listStyle="{
|
|
width: '300px',
|
|
height: '450px',
|
|
}"
|
|
:titles="[]"
|
|
:render="(item) => item.title"
|
|
:targetKeys="targetKeys"
|
|
@change="handleChange"
|
|
@selectChange="selectChange"
|
|
:selectedKeys="selectedKeys"
|
|
>
|
|
<span slot="notFoundContent">{{ $t('noData') }}</span>
|
|
<template slot="children" slot-scope="{ props: { direction, filteredItems } }">
|
|
<div class="ant-transfer-list-content" v-if="direction === 'right'">
|
|
<div
|
|
@dblclick="(e) => changeSingleItem(e, item)"
|
|
v-for="item in filteredItems"
|
|
:key="item.key"
|
|
:style="{ height: '32px' }"
|
|
>
|
|
<li
|
|
:class="
|
|
`ant-transfer-list-content-item ${
|
|
selectedKeys.includes(item.key) ? 'ant-transfer-list-content-item-selected' : ''
|
|
}`
|
|
"
|
|
style="padding:0 12px 0 12px;position:relative"
|
|
@click="setSelectedKeys(item)"
|
|
>
|
|
<div :class="`ant-transfer-list-content-item-text`" style="display:inline">
|
|
{{ item.title }}
|
|
<div class="ant-transfer-list-icon" @click="(e) => changeSingleItem(e, item)">
|
|
<a-icon type="left" />
|
|
</div>
|
|
</div>
|
|
</li>
|
|
</div>
|
|
</div>
|
|
<div v-if="direction === 'left'" class="ant-transfer-list-content">
|
|
<div
|
|
@dblclick="(e) => changeSingleItem(e, item)"
|
|
v-for="item in filteredItems"
|
|
:key="item.key"
|
|
:style="{ height: '32px' }"
|
|
>
|
|
<li
|
|
:class="
|
|
`ant-transfer-list-content-item ${
|
|
selectedKeys.includes(item.key) ? 'ant-transfer-list-content-item-selected' : ''
|
|
}`
|
|
"
|
|
style="padding:0 12px 0 12px;position:relative"
|
|
@click="setSelectedKeys(item)"
|
|
>
|
|
<div class="ant-transfer-list-content-item-text" style="display:inline">
|
|
{{ item.title }}
|
|
<div @click="(e) => changeSingleItem(e, item)" class="ant-transfer-list-icon">
|
|
<a-icon type="right" />
|
|
</div>
|
|
</div>
|
|
</li>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</a-transfer>
|
|
</a-modal>
|
|
</template>
|
|
<script>
|
|
import _ from 'lodash'
|
|
import { updateResourceGroup, searchResource, getResourceGroupItems } from '@/modules/acl/api/resource'
|
|
|
|
export default {
|
|
name: 'ResourceGroupModal',
|
|
data() {
|
|
return {
|
|
visible: false,
|
|
editRecord: {},
|
|
resources: [],
|
|
targetKeys: [],
|
|
selectedKeys: [],
|
|
}
|
|
},
|
|
methods: {
|
|
handleSubmit() {
|
|
const items = this.targetKeys.map((key) => {
|
|
return this.resources.filter((item) => item.name === key)[0]['id']
|
|
})
|
|
updateResourceGroup(this.editRecord['id'], { items: items.join(',') }).then(() => {
|
|
this.visible = false
|
|
this.$message.success(this.$t('updateSuccess'))
|
|
})
|
|
// .catch(err => this.$httpError(err))
|
|
},
|
|
// filterOption(inputValue, option) {
|
|
// return option.description.indexOf(inputValue) > -1
|
|
// },
|
|
// handleChange(targetKeys, direction, moveKeys) {
|
|
// console.log(JSON.parse(JSON.stringify(targetKeys)))
|
|
// this.targetKeys = targetKeys
|
|
// },
|
|
// handleSearch(dir, value) {
|
|
// console.log('search:', dir, value)
|
|
// },
|
|
async handleEdit(record) {
|
|
this.editRecord = record
|
|
this.visible = true
|
|
this.selectedKeys = []
|
|
await this.loadChildren(record.id)
|
|
await this.loadResource()
|
|
},
|
|
loadChildren(_id) {
|
|
getResourceGroupItems(_id).then((res) => {
|
|
this.targetKeys = res.map((item) => item.name)
|
|
})
|
|
// .catch(err => this.$httpError(err))
|
|
},
|
|
loadResource() {
|
|
const params = {
|
|
app_id: this.editRecord['app_id'],
|
|
resource_type_id: this.editRecord['resource_type_id'],
|
|
page_size: 9999,
|
|
}
|
|
searchResource(params).then((res) => {
|
|
this.resources = res['resources'].map((item) => {
|
|
return {
|
|
id: item.id,
|
|
name: item.name,
|
|
key: item.name,
|
|
description: item.name,
|
|
title: item.name,
|
|
}
|
|
})
|
|
})
|
|
// .catch(err => this.$httpError(err))
|
|
},
|
|
setSelectedKeys(item) {
|
|
const idx = this.selectedKeys.findIndex((key) => key === item.key)
|
|
if (idx > -1) {
|
|
this.selectedKeys.splice(idx, 1)
|
|
} else {
|
|
this.selectedKeys.push(item.key)
|
|
}
|
|
},
|
|
changeSingleItem(e, item) {
|
|
e.stopPropagation()
|
|
e.preventDefault()
|
|
const idx = this.targetKeys.findIndex((key) => key === item.key)
|
|
if (idx > -1) {
|
|
this.targetKeys.splice(idx, 1)
|
|
} else {
|
|
this.targetKeys.push(item.key)
|
|
}
|
|
},
|
|
handleChange(targetKeys, direction, moveKeys) {
|
|
const _selectedKeys = _.cloneDeep(this.selectedKeys)
|
|
moveKeys.forEach((key) => {
|
|
const idx = _selectedKeys.findIndex((selected) => selected === key)
|
|
if (idx > -1) {
|
|
_selectedKeys.splice(idx, 1)
|
|
}
|
|
})
|
|
this.selectedKeys = _.cloneDeep(_selectedKeys)
|
|
this.targetKeys = targetKeys
|
|
},
|
|
selectChange(sourceSelectedKeys, targetSelectedKeys) {
|
|
const _selectedKeys = _.cloneDeep(this.selectedKeys)
|
|
const list = [
|
|
{ data: sourceSelectedKeys, name: 'source' },
|
|
{ data: targetSelectedKeys, name: 'target' },
|
|
]
|
|
list.forEach((item) => {
|
|
if (!item.data.__ob__) {
|
|
if (item.data.length) {
|
|
item.data.forEach((key) => {
|
|
const idx = _selectedKeys.findIndex((selected) => selected === key)
|
|
if (idx > -1) {
|
|
} else {
|
|
_selectedKeys.push(key)
|
|
}
|
|
})
|
|
this.selectedKeys = _.cloneDeep(_selectedKeys)
|
|
} else {
|
|
let _list = []
|
|
if (item.name === 'source') {
|
|
_list = _selectedKeys.filter((key) => this.targetKeys.includes(key))
|
|
} else {
|
|
_list = _selectedKeys.filter((key) => !this.targetKeys.includes(key))
|
|
}
|
|
this.selectedKeys = _list
|
|
}
|
|
}
|
|
})
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style lang="less">
|
|
.ant-transfer-list-body-customize-wrapper {
|
|
padding: 0 !important;
|
|
height: 100%;
|
|
max-height: calc(100% - 44px);
|
|
}
|
|
.ant-transfer-list-content-item {
|
|
transition: all 0.3s;
|
|
.ant-transfer-list-icon {
|
|
position: absolute;
|
|
top: 4px;
|
|
right: 4px;
|
|
display: none;
|
|
&:hover {
|
|
color: @primary-color;
|
|
}
|
|
}
|
|
&:hover .ant-transfer-list-icon {
|
|
display: inline;
|
|
background-color: @primary-color_4;
|
|
border-radius: 4px;
|
|
}
|
|
}
|
|
.ant-transfer-list-content-item-selected {
|
|
background-color: ~'@{primary-color_8}35';
|
|
}
|
|
</style>
|