mirror of
https://github.com/jumpserver/lina.git
synced 2025-09-26 15:07:04 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -6,6 +6,15 @@
|
|||||||
:rules="_show && Array.isArray(data.rules) ? data.rules : []"
|
:rules="_show && Array.isArray(data.rules) ? data.rules : []"
|
||||||
v-bind="data.attrs"
|
v-bind="data.attrs"
|
||||||
>
|
>
|
||||||
|
<template v-if="data.helpTips" #label>
|
||||||
|
<el-tooltip placement="top">
|
||||||
|
<div slot="content" v-html="data.helpTips" />
|
||||||
|
<el-button style="padding: 0">
|
||||||
|
<i class="fa fa-info-circle" />
|
||||||
|
</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
{{ data.label }}
|
||||||
|
</template>
|
||||||
<template v-if="readonly && hasReadonlyContent">
|
<template v-if="readonly && hasReadonlyContent">
|
||||||
<div
|
<div
|
||||||
v-if="data.type === 'input'"
|
v-if="data.type === 'input'"
|
||||||
@@ -55,6 +64,7 @@
|
|||||||
>{{ opt.label }}</el-radio>
|
>{{ opt.label }}</el-radio>
|
||||||
</template>
|
</template>
|
||||||
</custom-component>
|
</custom-component>
|
||||||
|
<div v-if="data.helpText" class="help-block" v-html="data.helpText" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
<el-form ref="elForm" v-bind="$attrs" :model="value" class="el-form-renderer">
|
<el-form ref="elForm" v-bind="$attrs" :model="value" class="el-form-renderer">
|
||||||
<template v-for="item in innerContent">
|
<template v-for="item in innerContent">
|
||||||
<slot :name="`id:${item.id}`" />
|
<slot :name="`id:${item.id}`" />
|
||||||
<slot :name="`$id:${item.id}`" />
|
|
||||||
<component
|
<component
|
||||||
:is="item.type === GROUP ? 'render-form-group' : 'render-form-item'"
|
:is="item.type === GROUP ? 'render-form-group' : 'render-form-item'"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@@ -14,6 +13,7 @@
|
|||||||
:options="options[item.id]"
|
:options="options[item.id]"
|
||||||
@updateValue="updateValue"
|
@updateValue="updateValue"
|
||||||
/>
|
/>
|
||||||
|
<slot :name="`$id:${item.id}`" />
|
||||||
</template>
|
</template>
|
||||||
<slot />
|
<slot />
|
||||||
</el-form>
|
</el-form>
|
||||||
|
@@ -91,4 +91,16 @@ export default {
|
|||||||
.el-form /deep/ .form-group-header {
|
.el-form /deep/ .form-group-header {
|
||||||
margin-left: 50px;
|
margin-left: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-form /deep/ .help-block {
|
||||||
|
display: block;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
.el-form /deep/ .help-block a {
|
||||||
|
color: #1c84c6;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<el-button size="mini" type="danger" @click="handleDelete(col, row, cellValue, reload)">
|
||||||
|
<i class="fa fa-minus" />
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BaseFormatter from './base'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'DeleteActionFormatter',
|
||||||
|
extends: BaseFormatter,
|
||||||
|
methods: {
|
||||||
|
handleDelete(col, row, cellValue, reload) {
|
||||||
|
const url = col.deleteUrl + cellValue
|
||||||
|
this.$axios.delete(url).then(res => {
|
||||||
|
this.$message.success(this.$tc('Delete success'))
|
||||||
|
reload()
|
||||||
|
}).catch(error => {
|
||||||
|
this.$message.error(this.$tc('Delete failed' + ' ' + error))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@@ -8,6 +8,7 @@ import RouterFormatter from './RouterFormatter'
|
|||||||
import OutputExpandFormatter from './OutputExpandFormatter'
|
import OutputExpandFormatter from './OutputExpandFormatter'
|
||||||
import ExpandAssetPermissionFormatter from './ExpandAssetPermissionFormatter'
|
import ExpandAssetPermissionFormatter from './ExpandAssetPermissionFormatter'
|
||||||
import CustomActionsFormatter from './CustomActionsFormatter'
|
import CustomActionsFormatter from './CustomActionsFormatter'
|
||||||
|
import DeleteActionFormatter from './DeleteActionFormatter'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
DetailFormatter,
|
DetailFormatter,
|
||||||
@@ -19,7 +20,8 @@ export default {
|
|||||||
RouterFormatter,
|
RouterFormatter,
|
||||||
OutputExpandFormatter,
|
OutputExpandFormatter,
|
||||||
ExpandAssetPermissionFormatter,
|
ExpandAssetPermissionFormatter,
|
||||||
CustomActionsFormatter
|
CustomActionsFormatter,
|
||||||
|
DeleteActionFormatter
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
@@ -32,5 +34,6 @@ export {
|
|||||||
RouterFormatter,
|
RouterFormatter,
|
||||||
OutputExpandFormatter,
|
OutputExpandFormatter,
|
||||||
ExpandAssetPermissionFormatter,
|
ExpandAssetPermissionFormatter,
|
||||||
CustomActionsFormatter
|
CustomActionsFormatter,
|
||||||
|
DeleteActionFormatter
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,14 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr v-if="params.hasMore" class="item">
|
||||||
|
<td colspan="2">
|
||||||
|
<el-button type="primary" size="small" style="width: 100%" @click="loadMore">
|
||||||
|
<i class="fa fa-arrow-down" />
|
||||||
|
{{ $tc('More') }} ( {{ hasObjectLeftLength }} )
|
||||||
|
</el-button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
@@ -73,6 +81,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
iHasObjects: this.hasObjects || [],
|
iHasObjects: this.hasObjects || [],
|
||||||
|
totalHasObjectsLength: 0,
|
||||||
params: {
|
params: {
|
||||||
page: 1,
|
page: 1,
|
||||||
hasMore: false,
|
hasMore: false,
|
||||||
@@ -88,22 +97,25 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
iAjax() {
|
iAjax() {
|
||||||
this.$log.debug('iAjax', this.$refs.select2)
|
|
||||||
return this.$refs.select2.iAjax
|
return this.$refs.select2.iAjax
|
||||||
|
},
|
||||||
|
safeMakeParams() {
|
||||||
|
return this.$refs.select2.safeMakeParams
|
||||||
|
},
|
||||||
|
hasObjectLeftLength() {
|
||||||
|
this.$log.debug('Total', this.totalHasObjectsLength)
|
||||||
|
this.$log.debug(this.iHasObjects.length)
|
||||||
|
return this.totalHasObjectsLength - this.iHasObjects.length
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.hasObjectsId.length !== 0) {
|
if (this.hasObjectsId.length !== 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.getHasObjectsByIds()
|
this.getHasObjectsByIds()
|
||||||
}, 500)
|
}, 50)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
safeMakeParams(params) {
|
|
||||||
this.$log.debug('safeMakeParams', this.$refs.select2)
|
|
||||||
return this.$refs.select2.safeMakeParams(params)
|
|
||||||
},
|
|
||||||
async loadMore() {
|
async loadMore() {
|
||||||
if (this.loading) {
|
if (this.loading) {
|
||||||
return
|
return
|
||||||
@@ -125,14 +137,18 @@ export default {
|
|||||||
let data = await this.$axios.get(this.iAjax.url, { params: params })
|
let data = await this.$axios.get(this.iAjax.url, { params: params })
|
||||||
data = this.iAjax.processResults.bind(this)(data)
|
data = this.iAjax.processResults.bind(this)(data)
|
||||||
data.results.forEach((v) => {
|
data.results.forEach((v) => {
|
||||||
this.hasObjects.push(v)
|
if (!this.hasObjects.find((item) => item.value === v.value)) {
|
||||||
|
this.hasObjects.push(v)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
// 如果还有其它页,继续获取, 如果没有就停止
|
// 如果还有其它页,继续获取, 如果没有就停止
|
||||||
if (!data.pagination) {
|
this.params.hasMore = !!data.pagination
|
||||||
this.params.hasMore = false
|
this.totalHasObjectsLength = data.total
|
||||||
}
|
|
||||||
},
|
},
|
||||||
async getHasObjectsByIds() {
|
async getHasObjectsByIds() {
|
||||||
|
if (!this.$refs.select2 || !this.iAjax || !this.safeMakeParams) {
|
||||||
|
return
|
||||||
|
}
|
||||||
const resp = await createSourceIdCache(this.hasObjectsId)
|
const resp = await createSourceIdCache(this.hasObjectsId)
|
||||||
this.params.spm = resp.spm
|
this.params.spm = resp.spm
|
||||||
await this.loadHasObjects()
|
await this.loadHasObjects()
|
||||||
|
@@ -7,9 +7,12 @@
|
|||||||
:multiple="multiple"
|
:multiple="multiple"
|
||||||
filterable
|
filterable
|
||||||
remote
|
remote
|
||||||
|
:reserve-keyword="true"
|
||||||
popper-append-to-body
|
popper-append-to-body
|
||||||
class="select2"
|
class="select2"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
|
@change="onChange"
|
||||||
|
@visible-change="onVisibleChange"
|
||||||
v-on="$listeners"
|
v-on="$listeners"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
@@ -17,6 +20,7 @@
|
|||||||
:key="item.value"
|
:key="item.value"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
|
:disabled="item.disabled === undefined ? false : item.disabled"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
@@ -42,7 +46,8 @@ const defaultProcessResults = (data) => {
|
|||||||
return { label: item.name, value: item.id }
|
return { label: item.name, value: item.id }
|
||||||
})
|
})
|
||||||
const more = !!data.next
|
const more = !!data.next
|
||||||
return { results: results, pagination: more }
|
const total = data.count
|
||||||
|
return { results: results, pagination: more, total: total }
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultAjax = {
|
export const defaultAjax = {
|
||||||
@@ -86,7 +91,7 @@ export default {
|
|||||||
},
|
},
|
||||||
ajax: {
|
ajax: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => { return defaultAjax }
|
default: () => ({})
|
||||||
},
|
},
|
||||||
// 是否是多选
|
// 是否是多选
|
||||||
multiple: {
|
multiple: {
|
||||||
@@ -99,6 +104,10 @@ export default {
|
|||||||
default() {
|
default() {
|
||||||
return this.multiple ? [] : ''
|
return this.multiple ? [] : ''
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
disabledValues: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -110,10 +119,11 @@ export default {
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
iAjax: Object.assign(defaultAjax, this.ajax, this.url ? { url: this.url } : {}),
|
initialized: false,
|
||||||
|
iAjax: Object.assign(_.cloneDeep(defaultAjax), this.ajax, this.url ? { url: this.url } : {}),
|
||||||
iValue: this.multiple ? [] : '',
|
iValue: this.multiple ? [] : '',
|
||||||
defaultParams: defaultParams,
|
defaultParams: _.cloneDeep(defaultParams),
|
||||||
params: Object.assign({}, defaultParams),
|
params: _.cloneDeep(defaultParams),
|
||||||
iOptions: this.options || [],
|
iOptions: this.options || [],
|
||||||
initialOptions: []
|
initialOptions: []
|
||||||
}
|
}
|
||||||
@@ -124,7 +134,13 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initialSelect()
|
this.$log.debug('Select is: ', this.iAjax.url)
|
||||||
|
this.$log.debug('Select url: ', this.url)
|
||||||
|
this.$log.debug('Default ajax: ', defaultAjax)
|
||||||
|
if (!this.initialized) {
|
||||||
|
this.initialSelect()
|
||||||
|
this.initialized = true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async loadMore(load) {
|
async loadMore(load) {
|
||||||
@@ -160,7 +176,17 @@ export default {
|
|||||||
this.params.search = query
|
this.params.search = query
|
||||||
this.getOptions()
|
this.getOptions()
|
||||||
},
|
},
|
||||||
|
reFresh() {
|
||||||
|
this.resetParams()
|
||||||
|
this.iOptions = []
|
||||||
|
this.getOptions()
|
||||||
|
},
|
||||||
|
addOption(option) {
|
||||||
|
if (this.disabledValues.indexOf(option.value) !== -1) {
|
||||||
|
option.disabled = true
|
||||||
|
}
|
||||||
|
this.iOptions.push(option)
|
||||||
|
},
|
||||||
async getInitialOptions() {
|
async getInitialOptions() {
|
||||||
const params = this.safeMakeParams(this.params)
|
const params = this.safeMakeParams(this.params)
|
||||||
this.$log.debug('Get initial options: ', params)
|
this.$log.debug('Get initial options: ', params)
|
||||||
@@ -169,7 +195,7 @@ export default {
|
|||||||
data.results.forEach((v) => {
|
data.results.forEach((v) => {
|
||||||
this.initialOptions.push(v)
|
this.initialOptions.push(v)
|
||||||
if (this.optionsValues.indexOf(v.value) === -1) {
|
if (this.optionsValues.indexOf(v.value) === -1) {
|
||||||
this.iOptions.push(v)
|
this.addOption(v)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// 如果还有其它页,继续获取, 如果没有就停止
|
// 如果还有其它页,继续获取, 如果没有就停止
|
||||||
@@ -190,7 +216,7 @@ export default {
|
|||||||
}
|
}
|
||||||
data.results.forEach((v) => {
|
data.results.forEach((v) => {
|
||||||
if (this.optionsValues.indexOf(v.value) === -1) {
|
if (this.optionsValues.indexOf(v.value) === -1) {
|
||||||
this.iOptions.push(v)
|
this.addOption(v)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -207,6 +233,28 @@ export default {
|
|||||||
await this.getOptions()
|
await this.getOptions()
|
||||||
}
|
}
|
||||||
this.iValue = this.value
|
this.iValue = this.value
|
||||||
|
},
|
||||||
|
getOptionsByValues(values) {
|
||||||
|
return this.iOptions.filter((v) => {
|
||||||
|
return values.indexOf(v.value) !== -1
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getSelectedOptions() {
|
||||||
|
const values = this.iValue
|
||||||
|
return this.iOptions.filter((v) => {
|
||||||
|
return values.indexOf(v.value) !== -1
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onChange(values) {
|
||||||
|
const options = this.getSelectedOptions()
|
||||||
|
this.$log.debug('Current select options: ', options)
|
||||||
|
this.$emit('changeOptions', options)
|
||||||
|
},
|
||||||
|
onVisibleChange(visible) {
|
||||||
|
if (!visible && this.params.search) {
|
||||||
|
this.reFresh()
|
||||||
|
this.$log.debug('Visible change, refresh select2')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,3 +16,4 @@ export { default as ActiveCard } from './ActiveCard'
|
|||||||
export { default as Select2 } from './Select2'
|
export { default as Select2 } from './Select2'
|
||||||
export { default as SvgIcon } from './SvgIcon'
|
export { default as SvgIcon } from './SvgIcon'
|
||||||
export { default as TreeTable } from './TreeTable'
|
export { default as TreeTable } from './TreeTable'
|
||||||
|
|
||||||
|
@@ -131,7 +131,8 @@ const cn = {
|
|||||||
'PlatformCreate': '创建系统平台',
|
'PlatformCreate': '创建系统平台',
|
||||||
'PlatformUpdate': '更新系统平台',
|
'PlatformUpdate': '更新系统平台',
|
||||||
'CommandFilterCreate': '创建命令过滤器',
|
'CommandFilterCreate': '创建命令过滤器',
|
||||||
'CommandFilterUpdate': '更新命令过滤器'
|
'CommandFilterUpdate': '更新命令过滤器',
|
||||||
|
'CreateReplyStorage': '创建录像存储'
|
||||||
},
|
},
|
||||||
// 用户模块翻译
|
// 用户模块翻译
|
||||||
users: {
|
users: {
|
||||||
@@ -349,6 +350,9 @@ const cn = {
|
|||||||
'RefreshPermissionCache': '刷新授权缓存',
|
'RefreshPermissionCache': '刷新授权缓存',
|
||||||
'ReFreshSuccess': '刷新成功',
|
'ReFreshSuccess': '刷新成功',
|
||||||
'ReFreshFail': '刷新失败',
|
'ReFreshFail': '刷新失败',
|
||||||
|
'IsValid': '有效',
|
||||||
|
'IP': 'IP',
|
||||||
|
'Hostname': '主机名',
|
||||||
'All': '全部',
|
'All': '全部',
|
||||||
'Connect': '连接',
|
'Connect': '连接',
|
||||||
'UpDownload': '上传下载',
|
'UpDownload': '上传下载',
|
||||||
@@ -433,7 +437,18 @@ const cn = {
|
|||||||
'commandStorage': '命令存储',
|
'commandStorage': '命令存储',
|
||||||
'replayStorage': '录像存储',
|
'replayStorage': '录像存储',
|
||||||
'storage': '存储',
|
'storage': '存储',
|
||||||
'test': '测试'
|
'test': '测试',
|
||||||
|
'createReplyStorage': '创建录像存储',
|
||||||
|
'endPoint': '端点',
|
||||||
|
'bucket': '桶名称',
|
||||||
|
'type': '类型',
|
||||||
|
'containerName': '容器名称',
|
||||||
|
'accountName': '账户名称',
|
||||||
|
'accountKey': '账户密钥',
|
||||||
|
'endpointSuffix': '端点后缀',
|
||||||
|
'docType': '文档类型',
|
||||||
|
'index': '索引',
|
||||||
|
'hosts': '主机'
|
||||||
},
|
},
|
||||||
jobcenter: {
|
jobcenter: {
|
||||||
'RunTimes': '执行次数',
|
'RunTimes': '执行次数',
|
||||||
|
@@ -314,7 +314,18 @@ const en = {
|
|||||||
'commandStorage': 'Command storage',
|
'commandStorage': 'Command storage',
|
||||||
'replayStorage': 'Replay Storage',
|
'replayStorage': 'Replay Storage',
|
||||||
'storage': 'Storage',
|
'storage': 'Storage',
|
||||||
'test': 'Test'
|
'test': 'Test',
|
||||||
|
'createReplyStorage': 'Create replay storage',
|
||||||
|
'endPoint': 'Endpoint',
|
||||||
|
'bucket': 'Bucket',
|
||||||
|
'type': 'Type',
|
||||||
|
'containerName': 'Container name',
|
||||||
|
'accountName': 'Account name',
|
||||||
|
'accountKey': 'Account key',
|
||||||
|
'endpointSuffix': 'Endpoint suffix',
|
||||||
|
'docType': 'Doc type',
|
||||||
|
'index': 'Index',
|
||||||
|
'hosts': 'Hosts'
|
||||||
},
|
},
|
||||||
setting: {
|
setting: {
|
||||||
'setting': 'System Setting',
|
'setting': 'System Setting',
|
||||||
|
@@ -41,6 +41,10 @@ export default {
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
},
|
},
|
||||||
|
cleanFormValue: {
|
||||||
|
type: Function,
|
||||||
|
default: (value) => value
|
||||||
|
},
|
||||||
onSubmit: {
|
onSubmit: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: null
|
default: null
|
||||||
@@ -124,6 +128,7 @@ export default {
|
|||||||
handleSubmit(values) {
|
handleSubmit(values) {
|
||||||
let handler = this.onSubmit || this.defaultOnSubmit
|
let handler = this.onSubmit || this.defaultOnSubmit
|
||||||
handler = handler.bind(this)
|
handler = handler.bind(this)
|
||||||
|
values = this.cleanFormValue(values)
|
||||||
return handler(values)
|
return handler(values)
|
||||||
},
|
},
|
||||||
defaultPerformSubmit(validValues) {
|
defaultPerformSubmit(validValues) {
|
||||||
@@ -135,7 +140,6 @@ export default {
|
|||||||
const route = this.method === 'post' ? this.createSuccessNextRoute : this.updateSuccessNextRoute
|
const route = this.method === 'post' ? this.createSuccessNextRoute : this.updateSuccessNextRoute
|
||||||
performSubmit(validValues).then(() => {
|
performSubmit(validValues).then(() => {
|
||||||
this.$message.success(msg)
|
this.$message.success(msg)
|
||||||
console.log(route)
|
|
||||||
this.$router.push(route)
|
this.$router.push(route)
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
const response = error.response
|
const response = error.response
|
||||||
|
@@ -91,7 +91,7 @@ export default {
|
|||||||
detailApiUrl: getApiPath(this)
|
detailApiUrl: getApiPath(this)
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: true,
|
||||||
activeName: this.activeMenu || 'info',
|
activeName: this.activeMenu || 'info',
|
||||||
validActions: Object.assign(defaultActions, this.actions)
|
validActions: Object.assign(defaultActions, this.actions)
|
||||||
}
|
}
|
||||||
@@ -117,8 +117,13 @@ export default {
|
|||||||
return this.title || this.getTitle(this.object)
|
return this.title || this.getTitle(this.object)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
async mounted() {
|
||||||
this.getObject()
|
try {
|
||||||
|
this.loading = true
|
||||||
|
await this.getObject()
|
||||||
|
} finally {
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
defaultDelete() {
|
defaultDelete() {
|
||||||
@@ -157,12 +162,9 @@ export default {
|
|||||||
this.$router.push({ name: routeName, params: { id: id }})
|
this.$router.push({ name: routeName, params: { id: id }})
|
||||||
},
|
},
|
||||||
getObject() {
|
getObject() {
|
||||||
this.loading = true
|
|
||||||
const url = this.validActions.detailApiUrl
|
const url = this.validActions.detailApiUrl
|
||||||
this.$axios.get(url).then(data => {
|
return this.$axios.get(url).then(data => {
|
||||||
this.$emit('update:object', data)
|
this.$emit('update:object', data)
|
||||||
}).finally(() => {
|
|
||||||
this.loading = false
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleTabClick(tab) {
|
handleTabClick(tab) {
|
||||||
|
@@ -416,6 +416,20 @@ export const constantRoutes = [
|
|||||||
name: 'Storage',
|
name: 'Storage',
|
||||||
component: () => import('@/views/sessions/Storage'),
|
component: () => import('@/views/sessions/Storage'),
|
||||||
hidden: true
|
hidden: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'replay-storage/create',
|
||||||
|
name: 'CreateReplyStorage',
|
||||||
|
component: () => import('@/views/sessions/ReplyStorageCreate'),
|
||||||
|
meta: { title: 'CreateReplyStorage' },
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'command-storage/create',
|
||||||
|
name: 'CreateCommandStorage',
|
||||||
|
component: () => import('@/views/sessions/CommandStorageCreate'),
|
||||||
|
meta: { title: 'CreateCommandStorage' },
|
||||||
|
hidden: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import ListTable from '@/components/ListTable'
|
import ListTable from '@/components/ListTable'
|
||||||
import { RelationCard } from '@/components'
|
import { RelationCard } from '@/components'
|
||||||
|
import { DeleteActionFormatter } from '@/components/ListTable/formatters/index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AssetPermissionAsset',
|
name: 'AssetPermissionAsset',
|
||||||
@@ -26,12 +27,24 @@ export default {
|
|||||||
tableConfig: {
|
tableConfig: {
|
||||||
url: `/api/v1/perms/asset-permissions/${this.$route.params.id}/assets/all/`,
|
url: `/api/v1/perms/asset-permissions/${this.$route.params.id}/assets/all/`,
|
||||||
columns: [
|
columns: [
|
||||||
'asset_display'
|
'asset_display', 'delete_action'
|
||||||
],
|
],
|
||||||
columnsMeta: {
|
columnsMeta: {
|
||||||
asset_display: {
|
asset_display: {
|
||||||
label: this.$t('perms.Asset')
|
label: this.$t('perms.Asset'),
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
delete_action: {
|
||||||
|
prop: 'asset',
|
||||||
|
label: this.$tc('Action'),
|
||||||
|
align: 'center',
|
||||||
|
width: 150,
|
||||||
|
formatter: DeleteActionFormatter,
|
||||||
|
deleteUrl: `/api/v1/perms/asset-permissions-assets-relations/?assetpermission=${this.$route.params.id}&asset=`
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
tableAttrs: {
|
||||||
|
border: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
headerActions: {
|
headerActions: {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<GenericDetailPage :object.sync="assetPermissionData" v-bind="config">
|
<GenericDetailPage :object.sync="assetPermissionData" v-bind="config" @tab-click="TabClick">
|
||||||
<template #detail>
|
<template #detail>
|
||||||
<div>
|
<div>
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
@@ -111,7 +111,6 @@ export default {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: this.$t('perms.DateExpired'),
|
key: this.$t('perms.DateExpired'),
|
||||||
// value: toSafeLocalDateStr(this.assetData.date_expired),
|
|
||||||
value: toSafeLocalDateStr(this.assetPermissionData.date_expired)
|
value: toSafeLocalDateStr(this.assetPermissionData.date_expired)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -141,6 +140,13 @@ export default {
|
|||||||
return data.length
|
return data.length
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
},
|
||||||
|
TabClick(tab) {
|
||||||
|
if (tab.name !== 'detail') {
|
||||||
|
this.$set(this.config, 'hasRightSide', false)
|
||||||
|
} else {
|
||||||
|
this.$set(this.config, 'hasRightSide', true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,17 @@ export default {
|
|||||||
url: '/api/v1/perms/asset-permissions/',
|
url: '/api/v1/perms/asset-permissions/',
|
||||||
hasSelection: false,
|
hasSelection: false,
|
||||||
hasTree: true,
|
hasTree: true,
|
||||||
|
tagSearch: [
|
||||||
|
{ label: this.$tc('Name'), key: 'name' },
|
||||||
|
{ label: this.$t('perms.IsValid'), key: 'is_valid' },
|
||||||
|
{ label: this.$tc('username'), key: 'username' },
|
||||||
|
{ label: this.$t('perms.UserGroups'), key: 'user_group' },
|
||||||
|
{ label: this.$t('perms.IP'), key: 'ip' },
|
||||||
|
{ label: this.$t('perms.Hostname'), key: 'hostname' },
|
||||||
|
{ label: this.$t('perms.Node'), key: 'node' },
|
||||||
|
{ label: this.$t('perms.SystemUser'), key: 'system_user' },
|
||||||
|
{ label: '继承(先占位)', key: 'all=0' }
|
||||||
|
],
|
||||||
treeSetting: {
|
treeSetting: {
|
||||||
showMenu: false,
|
showMenu: false,
|
||||||
showRefresh: true,
|
showRefresh: true,
|
||||||
@@ -56,8 +67,12 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
headerActions: {
|
headerActions: {
|
||||||
|
hasExport: false,
|
||||||
|
hasImport: false,
|
||||||
|
hasRefresh: false,
|
||||||
hasBulkDelete: false,
|
hasBulkDelete: false,
|
||||||
extraActions: [
|
hasBulkUpdate: false,
|
||||||
|
extraMoreActions: [
|
||||||
{
|
{
|
||||||
name: 'RefreshPermissionCache',
|
name: 'RefreshPermissionCache',
|
||||||
title: this.$t('perms.RefreshPermissionCache'),
|
title: this.$t('perms.RefreshPermissionCache'),
|
||||||
@@ -73,9 +88,9 @@ export default {
|
|||||||
HandleRefreshPermissionCache() {
|
HandleRefreshPermissionCache() {
|
||||||
const url = '/api/v1/perms/asset-permissions/cache/refresh/'
|
const url = '/api/v1/perms/asset-permissions/cache/refresh/'
|
||||||
this.$axios.get(url).then(res => {
|
this.$axios.get(url).then(res => {
|
||||||
this.$message(this.$t('perms.ReFreshSuccess'))
|
this.$message.success(this.$t('perms.ReFreshSuccess'))
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
this.$message(this.$t('perms.ReFreshFail') + ':' + err)
|
this.$message.error(this.$t('perms.ReFreshFail') + ':' + err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import ListTable from '@/components/ListTable'
|
import ListTable from '@/components/ListTable'
|
||||||
import { RelationCard } from '@/components'
|
import { RelationCard } from '@/components'
|
||||||
|
import { DeleteActionFormatter } from '@/components/ListTable/formatters/index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AssetPermissionUser',
|
name: 'AssetPermissionUser',
|
||||||
@@ -25,12 +26,24 @@ export default {
|
|||||||
tableConfig: {
|
tableConfig: {
|
||||||
url: `/api/v1/perms/asset-permissions/${this.$route.params.id}/users/all/`,
|
url: `/api/v1/perms/asset-permissions/${this.$route.params.id}/users/all/`,
|
||||||
columns: [
|
columns: [
|
||||||
'user_display'
|
'user_display', 'delete_action'
|
||||||
],
|
],
|
||||||
columnsMeta: {
|
columnsMeta: {
|
||||||
user_display: {
|
user_display: {
|
||||||
label: this.$t('perms.User')
|
label: this.$t('perms.User'),
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
delete_action: {
|
||||||
|
prop: 'user',
|
||||||
|
label: this.$tc('Action'),
|
||||||
|
align: 'center',
|
||||||
|
width: 150,
|
||||||
|
formatter: DeleteActionFormatter,
|
||||||
|
deleteUrl: `/api/v1/perms/asset-permissions-users-relations/?assetpermission=${this.$route.params.id}&user=`
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
tableAttrs: {
|
||||||
|
border: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
headerActions: {
|
headerActions: {
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import ListTable from '@/components/ListTable'
|
import ListTable from '@/components/ListTable'
|
||||||
import { RelationCard } from '@/components'
|
import { RelationCard } from '@/components'
|
||||||
|
import { DeleteActionFormatter } from '@/components/ListTable/formatters/index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DatabaseAppPermissionDatabaseApp',
|
name: 'DatabaseAppPermissionDatabaseApp',
|
||||||
@@ -25,11 +26,20 @@ export default {
|
|||||||
tableConfig: {
|
tableConfig: {
|
||||||
url: `/api/v1/perms/database-app-permissions/${this.$route.params.id}/database-apps/all/`,
|
url: `/api/v1/perms/database-app-permissions/${this.$route.params.id}/database-apps/all/`,
|
||||||
columns: [
|
columns: [
|
||||||
'databaseapp_display'
|
'databaseapp_display', 'delete_action'
|
||||||
],
|
],
|
||||||
columnsMeta: {
|
columnsMeta: {
|
||||||
databaseapp_display: {
|
databaseapp_display: {
|
||||||
label: this.$t('perms.DatabaseApp')
|
label: this.$t('perms.DatabaseApp'),
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
delete_action: {
|
||||||
|
prop: 'databaseapp',
|
||||||
|
label: this.$tc('Action'),
|
||||||
|
align: 'center',
|
||||||
|
width: 150,
|
||||||
|
formatter: DeleteActionFormatter,
|
||||||
|
deleteUrl: `/api/v1/perms/database-app-permissions-database-apps-relations/?databaseapppermission=${this.$route.params.id}&databaseapp=`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<GenericDetailPage :object.sync="databaseAppData" v-bind="config">
|
<GenericDetailPage :object.sync="databaseAppData" v-bind="config" @tab-click="TabClick">
|
||||||
<div slot="detail">
|
<div slot="detail">
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :md="14" :sm="24">
|
<el-col :md="14" :sm="24">
|
||||||
@@ -130,6 +130,13 @@ export default {
|
|||||||
return data.length
|
return data.length
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
},
|
||||||
|
TabClick(tab) {
|
||||||
|
if (tab.name !== 'detail') {
|
||||||
|
this.$set(this.config, 'hasRightSide', false)
|
||||||
|
} else {
|
||||||
|
this.$set(this.config, 'hasRightSide', true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import ListTable from '@/components/ListTable'
|
import ListTable from '@/components/ListTable'
|
||||||
import { RelationCard } from '@/components'
|
import { RelationCard } from '@/components'
|
||||||
|
import { DeleteActionFormatter } from '@/components/ListTable/formatters/index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DatabaseAppPermissionUser',
|
name: 'DatabaseAppPermissionUser',
|
||||||
components: {
|
components: {
|
||||||
@@ -25,11 +27,20 @@ export default {
|
|||||||
tableConfig: {
|
tableConfig: {
|
||||||
url: `/api/v1/perms/database-app-permissions/${this.$route.params.id}/users/all/`,
|
url: `/api/v1/perms/database-app-permissions/${this.$route.params.id}/users/all/`,
|
||||||
columns: [
|
columns: [
|
||||||
'user_display'
|
'user_display', 'delete_action'
|
||||||
],
|
],
|
||||||
columnsMeta: {
|
columnsMeta: {
|
||||||
user_display: {
|
user_display: {
|
||||||
label: this.$t('perms.User')
|
label: this.$t('perms.User'),
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
delete_action: {
|
||||||
|
prop: 'user',
|
||||||
|
label: this.$tc('Action'),
|
||||||
|
align: 'center',
|
||||||
|
width: 150,
|
||||||
|
formatter: DeleteActionFormatter,
|
||||||
|
deleteUrl: `/api/v1/perms/database-app-permissions-users-relations/?databaseapppermission=${this.$route.params.id}&user=`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<GenericDetailPage :object.sync="remoteAppData" v-bind="config">
|
<GenericDetailPage :object.sync="remoteAppData" v-bind="config" @tab-click="TabClick">
|
||||||
<div slot="detail">
|
<div slot="detail">
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="14">
|
<el-col :span="14">
|
||||||
@@ -130,6 +130,13 @@ export default {
|
|||||||
return data.length
|
return data.length
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
},
|
||||||
|
TabClick(tab) {
|
||||||
|
if (tab.name !== 'detail') {
|
||||||
|
this.$set(this.config, 'hasRightSide', false)
|
||||||
|
} else {
|
||||||
|
this.$set(this.config, 'hasRightSide', true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
121
src/views/sessions/CommandStorageCreate.vue
Normal file
121
src/views/sessions/CommandStorageCreate.vue
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<template>
|
||||||
|
<GenericCreateUpdatePage
|
||||||
|
:create-success-next-route="createSuccessUrl"
|
||||||
|
:clean-form-value="cleanFormValue"
|
||||||
|
:fields="selectFields"
|
||||||
|
:initial="selectInitial"
|
||||||
|
:fields-meta="selectFieldsMeta"
|
||||||
|
:url="url"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CommandStorageCreate',
|
||||||
|
components: {
|
||||||
|
GenericCreateUpdatePage
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
createSuccessUrl: { name: 'Storage' },
|
||||||
|
es: {
|
||||||
|
initial: {
|
||||||
|
type: 'es'
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
['', ['name', 'type', 'hosts', 'index', 'doc_type', 'comment']]
|
||||||
|
],
|
||||||
|
fieldsMeta: {
|
||||||
|
name: {
|
||||||
|
label: this.$t('sessions.name')
|
||||||
|
},
|
||||||
|
comment: {
|
||||||
|
label: this.$t('sessions.comment')
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: 'select',
|
||||||
|
label: this.$t('sessions.type'),
|
||||||
|
disabled: true,
|
||||||
|
rules: [
|
||||||
|
{ required: true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
hosts: {
|
||||||
|
label: this.$t('sessions.hosts'),
|
||||||
|
rules: [
|
||||||
|
{ required: true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
index: {
|
||||||
|
label: this.$t('sessions.index'),
|
||||||
|
rules: [
|
||||||
|
{ required: true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
doc_type: {
|
||||||
|
label: this.$t('sessions.docType'),
|
||||||
|
rules: [
|
||||||
|
{ required: true }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
url: '/api/v1/terminal/command-storages/'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
postUrl() {
|
||||||
|
return this.url
|
||||||
|
},
|
||||||
|
selectInitial() {
|
||||||
|
return this.renderFieldObject.initial
|
||||||
|
},
|
||||||
|
selectFields() {
|
||||||
|
return this.renderFieldObject.fields
|
||||||
|
},
|
||||||
|
selectFieldsMeta() {
|
||||||
|
return this.renderFieldObject.fieldsMeta
|
||||||
|
},
|
||||||
|
renderFieldObject() {
|
||||||
|
const storageType = this.$route.query.type
|
||||||
|
if (typeof storageType !== 'string') {
|
||||||
|
return this.es
|
||||||
|
}
|
||||||
|
switch (storageType.toLowerCase()) {
|
||||||
|
case 'es':
|
||||||
|
return this.es
|
||||||
|
default:
|
||||||
|
return this.es
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
cleanFormValue(value) {
|
||||||
|
switch (value.type.toLowerCase()) {
|
||||||
|
case 'es':
|
||||||
|
return this.createEsMeta(value)
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
},
|
||||||
|
createEsMeta(value) {
|
||||||
|
const host_array = value.hosts.split(',')
|
||||||
|
return {
|
||||||
|
name: value.name,
|
||||||
|
type: 'es',
|
||||||
|
comment: value.comment,
|
||||||
|
meta: {
|
||||||
|
es_hosts: host_array,
|
||||||
|
es_index: value.index,
|
||||||
|
es_doc_type: value.doc_type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
338
src/views/sessions/ReplyStorageCreate.vue
Normal file
338
src/views/sessions/ReplyStorageCreate.vue
Normal file
@@ -0,0 +1,338 @@
|
|||||||
|
<template>
|
||||||
|
<GenericCreateUpdatePage :create-success-next-route="createSuccessUrl" :clean-form-value="cleanFormValue" :fields="selectFields" :initial="selectInitial" :fields-meta="selectFieldsMeta" :url="url" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
||||||
|
export default {
|
||||||
|
name: 'ReplyStorageCreate',
|
||||||
|
components: {
|
||||||
|
GenericCreateUpdatePage
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
createSuccessUrl: { name: 'Storage' },
|
||||||
|
s3: {
|
||||||
|
initial: {
|
||||||
|
type: 's3'
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
['', ['name', 'type', 'bucket', 'access_key', 'secret_key', 'endpoint', 'comment']]
|
||||||
|
],
|
||||||
|
fieldsMeta: {
|
||||||
|
name: {
|
||||||
|
label: this.$t('sessions.name')
|
||||||
|
},
|
||||||
|
comment: {
|
||||||
|
label: this.$t('sessions.comment')
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
label: this.$t('sessions.type'),
|
||||||
|
disabled: true,
|
||||||
|
rules: [
|
||||||
|
{ required: true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
bucket: {
|
||||||
|
label: this.$t('sessions.bucket')
|
||||||
|
},
|
||||||
|
access_key: {
|
||||||
|
label: 'Access key'
|
||||||
|
},
|
||||||
|
secret_key: {
|
||||||
|
label: 'Secret key'
|
||||||
|
},
|
||||||
|
endpoint: {
|
||||||
|
label: this.$t('sessions.endPoint')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ceph: {
|
||||||
|
initial: {
|
||||||
|
type: 'ceph'
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
['', ['name', 'type', 'bucket', 'access_key', 'secret_key', 'endpoint', 'comment']]
|
||||||
|
],
|
||||||
|
fieldsMeta: {
|
||||||
|
name: {
|
||||||
|
label: this.$t('sessions.name')
|
||||||
|
},
|
||||||
|
comment: {
|
||||||
|
label: this.$t('sessions.comment')
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
label: this.$t('sessions.type'),
|
||||||
|
disabled: true,
|
||||||
|
rules: [
|
||||||
|
{ required: true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
bucket: {
|
||||||
|
label: this.$t('sessions.bucket')
|
||||||
|
},
|
||||||
|
access_key: {
|
||||||
|
label: 'Access key'
|
||||||
|
},
|
||||||
|
secret_key: {
|
||||||
|
label: 'Secret key'
|
||||||
|
},
|
||||||
|
endpoint: {
|
||||||
|
label: this.$t('sessions.endPoint')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
swift: {
|
||||||
|
initial: {
|
||||||
|
type: 'swift',
|
||||||
|
protocol: 'http'
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
['', ['name', 'type', 'bucket', 'access_key', 'secret_key', 'region', 'endpoint', 'protocol', 'comment']]
|
||||||
|
],
|
||||||
|
fieldsMeta: {
|
||||||
|
name: {
|
||||||
|
label: this.$t('sessions.name')
|
||||||
|
},
|
||||||
|
comment: {
|
||||||
|
label: this.$t('sessions.comment')
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
label: this.$t('sessions.type'),
|
||||||
|
disabled: true,
|
||||||
|
rules: [
|
||||||
|
{ required: true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
bucket: {
|
||||||
|
label: this.$t('sessions.bucket')
|
||||||
|
},
|
||||||
|
access_key: {
|
||||||
|
label: 'Access key'
|
||||||
|
},
|
||||||
|
secret_key: {
|
||||||
|
label: 'Secret key'
|
||||||
|
},
|
||||||
|
region: {
|
||||||
|
label: this.$t('sessions.region')
|
||||||
|
},
|
||||||
|
endpoint: {
|
||||||
|
label: this.$t('sessions.endPoint')
|
||||||
|
},
|
||||||
|
protocol: {
|
||||||
|
label: this.$t('sessions.protocol'),
|
||||||
|
type: 'select',
|
||||||
|
options: [
|
||||||
|
{ label: 'http', value: 'http' },
|
||||||
|
{ label: 'https', value: 'https' }
|
||||||
|
],
|
||||||
|
rules: [
|
||||||
|
{ required: true }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
oss: {
|
||||||
|
initial: {
|
||||||
|
type: 'oss'
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
['', ['name', 'type', 'bucket', 'access_key', 'secret_key', 'endpoint', 'comment']]
|
||||||
|
],
|
||||||
|
fieldsMeta: {
|
||||||
|
name: {
|
||||||
|
label: this.$t('sessions.name')
|
||||||
|
},
|
||||||
|
comment: {
|
||||||
|
label: this.$t('sessions.comment')
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
label: this.$t('sessions.type'),
|
||||||
|
disabled: true,
|
||||||
|
rules: [
|
||||||
|
{ required: true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
bucket: {
|
||||||
|
label: this.$t('sessions.bucket')
|
||||||
|
},
|
||||||
|
access_key: {
|
||||||
|
label: 'Access key'
|
||||||
|
},
|
||||||
|
secret_key: {
|
||||||
|
label: 'Secret key'
|
||||||
|
},
|
||||||
|
endpoint: {
|
||||||
|
label: this.$t('sessions.endPoint')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
azure: {
|
||||||
|
initial: {
|
||||||
|
type: 'azure',
|
||||||
|
endpoint_suffix: 'core.chinacloudapi.cn'
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
[this.$t('sessions.createReplyStorage'),
|
||||||
|
['name', 'type', 'container_name', 'account_name', 'account_key', 'endpoint_suffix', 'comment']]
|
||||||
|
],
|
||||||
|
fieldsMeta: {
|
||||||
|
name: {
|
||||||
|
label: this.$t('sessions.name')
|
||||||
|
},
|
||||||
|
comment: {
|
||||||
|
label: this.$t('sessions.comment')
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
label: this.$t('sessions.type'),
|
||||||
|
disabled: true,
|
||||||
|
rules: [
|
||||||
|
{ required: true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
container_name: {
|
||||||
|
label: this.$t('sessions.containerName')
|
||||||
|
},
|
||||||
|
account_name: {
|
||||||
|
label: this.$t('sessions.accountName')
|
||||||
|
},
|
||||||
|
account_key: {
|
||||||
|
label: this.$t('sessions.accountKey')
|
||||||
|
},
|
||||||
|
endpoint_suffix: {
|
||||||
|
label: this.$t('sessions.endpointSuffix'),
|
||||||
|
type: 'select',
|
||||||
|
options: [
|
||||||
|
{ label: 'core.chinacloudapi.cn', value: 'core.chinacloudapi.cn' },
|
||||||
|
{ label: 'core.windows.net', value: 'core.windows.net' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
url: '/api/v1/terminal/replay-storages/'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
postUrl() {
|
||||||
|
return this.url
|
||||||
|
},
|
||||||
|
selectInitial() {
|
||||||
|
return this.renderFieldObject.initial
|
||||||
|
},
|
||||||
|
selectFields() {
|
||||||
|
return this.renderFieldObject.fields
|
||||||
|
},
|
||||||
|
selectFieldsMeta() {
|
||||||
|
return this.renderFieldObject.fieldsMeta
|
||||||
|
},
|
||||||
|
renderFieldObject() {
|
||||||
|
const storageType = this.$route.query.type
|
||||||
|
if (typeof storageType !== 'string') {
|
||||||
|
return this.s3
|
||||||
|
}
|
||||||
|
switch (storageType.toLowerCase()) {
|
||||||
|
case 's3':
|
||||||
|
return this.s3
|
||||||
|
case 'ceph':
|
||||||
|
return this.ceph
|
||||||
|
case 'swift':
|
||||||
|
return this.swift
|
||||||
|
case 'oss':
|
||||||
|
return this.oss
|
||||||
|
case 'azure':
|
||||||
|
return this.azure
|
||||||
|
default:
|
||||||
|
return this.s3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
cleanFormValue(value) {
|
||||||
|
switch (value.type.toLowerCase()) {
|
||||||
|
case 's3':
|
||||||
|
return this.createS3Meta(value)
|
||||||
|
case 'ceph':
|
||||||
|
return this.createCephMeta(value)
|
||||||
|
case 'swift':
|
||||||
|
return this.createSwiftMeta(value)
|
||||||
|
case 'oss':
|
||||||
|
return this.createOSSMeta(value)
|
||||||
|
case 'azure':
|
||||||
|
return this.createAzureMeta(value)
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
},
|
||||||
|
createS3Meta(value) {
|
||||||
|
return {
|
||||||
|
name: value.name,
|
||||||
|
type: 's3',
|
||||||
|
comment: value.comment,
|
||||||
|
meta: {
|
||||||
|
s3_bucket: value.bucket,
|
||||||
|
s3_access_key: value.access_key,
|
||||||
|
s3_secret_key: value.secret_key,
|
||||||
|
s3_endpoint: value.endpoint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createCephMeta(value) {
|
||||||
|
return {
|
||||||
|
name: value.name,
|
||||||
|
type: 'ceph',
|
||||||
|
comment: value.comment,
|
||||||
|
meta: {
|
||||||
|
ceph_bucket: value.bucket,
|
||||||
|
ceph_access_key: value.access_key,
|
||||||
|
ceph_secret_key: value.secret_key,
|
||||||
|
ceph_endpoint: value.endpoint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createSwiftMeta(value) {
|
||||||
|
return {
|
||||||
|
name: value.name,
|
||||||
|
type: 'swift',
|
||||||
|
comment: value.comment,
|
||||||
|
meta: {
|
||||||
|
swift_bucket: value.bucket,
|
||||||
|
swift_access_key: value.access_key,
|
||||||
|
swift_secret_key: value.secret_key,
|
||||||
|
swift_region: value.region,
|
||||||
|
swift_endpoint: value.endpoint,
|
||||||
|
swift_protocol: value.protocol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createOSSMeta(value) {
|
||||||
|
return {
|
||||||
|
name: value.name,
|
||||||
|
type: 'oss',
|
||||||
|
comment: value.comment,
|
||||||
|
meta: {
|
||||||
|
oss_bucket: value.bucket,
|
||||||
|
oss_access_key: value.access_key,
|
||||||
|
oss_secret_key: value.secret_key,
|
||||||
|
oss_endpoint: value.endpoint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createAzureMeta(value) {
|
||||||
|
return {
|
||||||
|
name: value.name,
|
||||||
|
type: 'azure',
|
||||||
|
comment: value.comment,
|
||||||
|
meta: {
|
||||||
|
azure_container_name: value.container_name,
|
||||||
|
azure_account_name: value.account_name,
|
||||||
|
azure_account_key: value.account_key,
|
||||||
|
azure_endpoint_suffix: value.endpoint_suffix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@@ -16,7 +16,6 @@
|
|||||||
import { TabPage } from '@/layout/components'
|
import { TabPage } from '@/layout/components'
|
||||||
import { ListTable } from '@/components'
|
import { ListTable } from '@/components'
|
||||||
import { TestCommandStorage, TestReplayStorage } from '@/api/sessions'
|
import { TestCommandStorage, TestReplayStorage } from '@/api/sessions'
|
||||||
import { CustomActionsFormatter } from '@/components/ListTable/formatters'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Storage',
|
name: 'Storage',
|
||||||
@@ -49,48 +48,38 @@ export default {
|
|||||||
name: 'S3',
|
name: 'S3',
|
||||||
title: 'S3',
|
title: 'S3',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
callback: function() {
|
callback: this.createS3.bind(this)
|
||||||
console.log('S3===')
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Ceph',
|
name: 'Ceph',
|
||||||
title: 'Ceph',
|
title: 'Ceph',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
callback: function() {
|
callback: this.createCeph.bind(this)
|
||||||
console.log('Ceph===')
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Swift',
|
name: 'Swift',
|
||||||
title: 'Swift',
|
title: 'Swift',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
callback: function() {
|
callback: this.createSwift.bind(this)
|
||||||
console.log('Swift===')
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'OSS',
|
name: 'OSS',
|
||||||
title: 'OSS',
|
title: 'OSS',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
callback: function() {
|
callback: this.createOSS.bind(this)
|
||||||
console.log('OSS===')
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Azure',
|
name: 'Azure',
|
||||||
title: 'Azure',
|
title: 'Azure',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
callback: function() {
|
callback: this.createAzure.bind(this)
|
||||||
console.log('Azure===')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
replayTableConfig: {
|
replayTableConfig: {
|
||||||
url: '/api/v1/terminal/replay-storages/',
|
url: '/api/v1/terminal/replay-storages/',
|
||||||
columns: ['name', 'type', 'comment', 'cusActions'],
|
columns: ['name', 'type', 'comment', 'actions'],
|
||||||
columnsMeta: {
|
columnsMeta: {
|
||||||
name: {
|
name: {
|
||||||
formatter: function(row) {
|
formatter: function(row) {
|
||||||
@@ -105,36 +94,16 @@ export default {
|
|||||||
comment: {
|
comment: {
|
||||||
sortable: 'custom'
|
sortable: 'custom'
|
||||||
},
|
},
|
||||||
cusActions: {
|
actions: {
|
||||||
prop: 'id',
|
prop: 'id',
|
||||||
formatter: CustomActionsFormatter,
|
|
||||||
actions: {
|
actions: {
|
||||||
actions: [
|
canUpdate: function(row, cellValue) {
|
||||||
{
|
return (row.name !== 'default' && row.name !== 'null')
|
||||||
name: 'update',
|
},
|
||||||
title: this.$tc('Update'),
|
canDelete: function(row, cellValue) {
|
||||||
type: 'primary',
|
return (row.name !== 'default' && row.name !== 'null')
|
||||||
can: function(row, cellValue,) {
|
},
|
||||||
return row.name !== 'null' && row.name !== 'default'
|
extraActions: [
|
||||||
},
|
|
||||||
callback: function({ row, col, cellValue, reload }) {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'delete',
|
|
||||||
title: this.$tc('Delete'),
|
|
||||||
type: 'danger',
|
|
||||||
can: function(row, cellValue) {
|
|
||||||
return row.name !== 'null' && row.name !== 'default'
|
|
||||||
},
|
|
||||||
callback: function({ row, col, cellValue, reload }) {
|
|
||||||
const id = row.id
|
|
||||||
const url = `${this.url}${id}/`
|
|
||||||
this.$axios.delete(url).then(data => {
|
|
||||||
reload()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'test',
|
name: 'test',
|
||||||
title: this.$t('sessions.test'),
|
title: this.$t('sessions.test'),
|
||||||
@@ -170,16 +139,14 @@ export default {
|
|||||||
name: 'Elasticsearch',
|
name: 'Elasticsearch',
|
||||||
title: 'Elasticsearch',
|
title: 'Elasticsearch',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
callback: function() {
|
callback: this.createEs.bind(this)
|
||||||
console.log('Elasticsearch====')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
commandTableConfig: {
|
commandTableConfig: {
|
||||||
title: 'command',
|
title: 'command',
|
||||||
url: '/api/v1/terminal/command-storages/',
|
url: '/api/v1/terminal/command-storages/',
|
||||||
columns: ['name', 'type', 'comment', 'cusActions'],
|
columns: ['name', 'type', 'comment', 'actions'],
|
||||||
columnsMeta: {
|
columnsMeta: {
|
||||||
comment: {
|
comment: {
|
||||||
sortable: 'custom'
|
sortable: 'custom'
|
||||||
@@ -194,36 +161,15 @@ export default {
|
|||||||
return row.type
|
return row.type
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
cusActions: {
|
actions: {
|
||||||
prop: 'id',
|
|
||||||
formatter: CustomActionsFormatter,
|
|
||||||
actions: {
|
actions: {
|
||||||
actions: [
|
canUpdate: function(row, cellValue) {
|
||||||
{
|
return (row.name !== 'default' && row.name !== 'null')
|
||||||
name: 'update',
|
},
|
||||||
title: this.$tc('Update'),
|
canDelete: function(row, cellValue) {
|
||||||
type: 'primary',
|
return (row.name !== 'default' && row.name !== 'null')
|
||||||
can: function(row, cellValue,) {
|
},
|
||||||
return row.name !== 'null' && row.name !== 'default'
|
extraActions: [
|
||||||
},
|
|
||||||
callback: function({ row, col, cellValue, reload }) {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'delete',
|
|
||||||
title: this.$tc('Delete'),
|
|
||||||
type: 'danger',
|
|
||||||
can: function(row, cellValue) {
|
|
||||||
return row.name !== 'null' && row.name !== 'default'
|
|
||||||
},
|
|
||||||
callback: function({ row, col, cellValue, reload }) {
|
|
||||||
const id = row.id
|
|
||||||
const url = `${this.url}${id}/`
|
|
||||||
this.$axios.delete(url).then(data => {
|
|
||||||
reload()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'test',
|
name: 'test',
|
||||||
title: this.$t('sessions.test'),
|
title: this.$t('sessions.test'),
|
||||||
@@ -253,6 +199,26 @@ export default {
|
|||||||
Title() {
|
Title() {
|
||||||
return this.$t('sessions.storage')
|
return this.$t('sessions.storage')
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
createS3() {
|
||||||
|
this.$router.push({ name: 'CreateReplyStorage', query: { type: 's3' }})
|
||||||
|
},
|
||||||
|
createCeph() {
|
||||||
|
this.$router.push({ name: 'CreateReplyStorage', query: { type: 'ceph' }})
|
||||||
|
},
|
||||||
|
createSwift() {
|
||||||
|
this.$router.push({ name: 'CreateReplyStorage', query: { type: 'swift' }})
|
||||||
|
},
|
||||||
|
createOSS() {
|
||||||
|
this.$router.push({ name: 'CreateReplyStorage', query: { type: 'oss' }})
|
||||||
|
},
|
||||||
|
createAzure() {
|
||||||
|
this.$router.push({ name: 'CreateReplyStorage', query: { type: 'azure' }})
|
||||||
|
},
|
||||||
|
createEs() {
|
||||||
|
this.$router.push({ name: 'CreateCommandStorage', query: { type: 'es' }})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@@ -50,9 +50,66 @@ export default {
|
|||||||
icon: 'fa-user',
|
icon: 'fa-user',
|
||||||
title: this.$tc('Members'),
|
title: this.$tc('Members'),
|
||||||
objectsAjax: {
|
objectsAjax: {
|
||||||
url: '/api/v1/users/users/?fields_size=mini'
|
url: '/api/v1/users/users/?fields_size=mini&order=name',
|
||||||
|
processResults(data) {
|
||||||
|
let results = data.results
|
||||||
|
results = results.map((item) => {
|
||||||
|
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||||
|
})
|
||||||
|
const more = !!data.next
|
||||||
|
return { results: results, pagination: more, total: data.count }
|
||||||
|
}
|
||||||
},
|
},
|
||||||
hasObjectsId: ['938b47a3-db34-40be-b732-ee0125a4857c', '3e3b75a9-11fd-4b97-ad04-17a50a72507c'],
|
hasObjectsId: ['ff0d0dc8-ef71-415f-9b83-60978c1971a8',
|
||||||
|
'9cb0e440-0340-408d-89d6-ce60eb5ab364',
|
||||||
|
'1ed4fb15-c526-45c9-83a8-0527f47b44f3',
|
||||||
|
'2c56fd37-db65-40ed-b787-b65a98635f12',
|
||||||
|
'938b47a3-db34-40be-b732-ee0125a4857c',
|
||||||
|
'6ece7c09-452f-4eac-ab20-9ccb1608680f',
|
||||||
|
'e7f63eb0-1277-4dd9-87b2-0e347851bebc',
|
||||||
|
'af84f59a-d70d-41ae-a30f-e92ceb4d84a1',
|
||||||
|
'ce589bf7-f5ef-4eb1-b8ed-33c19a44566d',
|
||||||
|
'2a7359fc-1a8b-4f49-9bd0-e4b84c94428a',
|
||||||
|
'3e3b75a9-11fd-4b97-ad04-17a50a72507c',
|
||||||
|
'fc175594-2895-4749-a350-0e9c3c89227a',
|
||||||
|
'e34f1f38-eaf8-49ba-9229-44117833e9bb',
|
||||||
|
'87dc36ae-ad17-4f04-ae32-c884312f64e0',
|
||||||
|
'b61768fa-3dfb-41cf-be1c-198402da881e',
|
||||||
|
'c0c75f51-a78f-4623-89bc-7e4906d9eee6',
|
||||||
|
'e48fb72e-ca52-441a-b6cc-d4aa5772d5c8',
|
||||||
|
'49aac9b3-4ff7-4ca1-a2fa-d8c577692f80',
|
||||||
|
'38f4d901-8283-499a-8b7e-f3d1377159a4',
|
||||||
|
'9c2e9073-5fa3-4a56-a5c5-3ef7b9e01fdb',
|
||||||
|
'88174bec-1ce7-40ef-a222-f8496a374812',
|
||||||
|
'12e835fc-978a-4229-b597-30a49232ee72',
|
||||||
|
'91fe7fad-706f-4fd4-b108-14373ff1b86c',
|
||||||
|
'8b63c190-0e3c-4a0c-9b7a-586a108f3239',
|
||||||
|
'a442bfd9-117d-4604-b079-3ead15ebb4fd',
|
||||||
|
'445c998b-35f8-4345-b2d3-0c4eb947ea5b',
|
||||||
|
'55d09c56-09db-411a-93c4-eeeb080cf3c0',
|
||||||
|
'3d11bc66-ed17-402a-b32e-ae912e65999e',
|
||||||
|
'8a6387f0-0d8e-467d-8a57-957e2918e70e',
|
||||||
|
'0dd63aa5-2dfb-4499-ba01-042a4ef40189',
|
||||||
|
'47d63b4d-6a82-45ea-8194-744218b2c54f',
|
||||||
|
'26fd4116-4de7-4628-84ab-c158262e8782',
|
||||||
|
'c335b2f9-ffd1-4b5c-aea6-1e534263b28f',
|
||||||
|
'fb072f99-c352-414c-9deb-10480a9e943e',
|
||||||
|
'ae441f3a-f53b-4232-9f14-88ce47fa37b7',
|
||||||
|
'579d21f7-ac3b-402b-87cd-258f788f95ef',
|
||||||
|
'db20db9b-2d36-4db8-98c3-287e43a3454b',
|
||||||
|
'9add3233-8535-488c-82c8-bb1c5845c87e',
|
||||||
|
'647e467b-50da-4af3-bd71-6b8bca0ed4d6',
|
||||||
|
'21b7cb6f-bbf3-449c-8e91-a461a2b459b8',
|
||||||
|
'74c021e8-ae00-4433-9e48-99f76e975aa5',
|
||||||
|
'204b13b5-d0db-404b-8987-fe0953315c67',
|
||||||
|
'3a3728c0-5afb-43e3-a632-9338e1a7d591',
|
||||||
|
'6e91f74a-0558-48d6-ae47-ccc5afb97c84',
|
||||||
|
'e3cb895f-3a07-4985-b6fb-7bfb23b4834e',
|
||||||
|
'e9a5c087-9f29-4ff9-859f-6c36f87ee67a',
|
||||||
|
'ada94cda-cf3b-4a93-ad4b-97b982dda627',
|
||||||
|
'b2b449d0-f7bf-4874-a463-68f51ec98212',
|
||||||
|
'17dc5bc6-84b4-4814-9b96-d41bd12b5578',
|
||||||
|
'05ed8bfe-e8cb-49aa-86e3-756779ff7fac'],
|
||||||
hasObjects: [
|
hasObjects: [
|
||||||
// {
|
// {
|
||||||
// id: '1',
|
// id: '1',
|
||||||
|
Reference in New Issue
Block a user