mirror of https://github.com/apache/cloudstack.git
new instance component and several other fixes
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
parent
e16e5f635b
commit
7bd84c96ed
|
|
@ -10,7 +10,7 @@
|
|||
<font-awesome-icon icon="coffee" />
|
||||
-->
|
||||
|
||||
<a-breadcrumb class="breadcrumb" v-if="device === 'mobile'">
|
||||
<a-breadcrumb class="breadcrumb">
|
||||
<a-breadcrumb-item v-for="(item, index) in breadList" :key="index">
|
||||
<router-link
|
||||
v-if="item.name"
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
<a-row>
|
||||
<a-col :span="16">
|
||||
<a-tooltip placement="bottom" v-for="(action, actionIndex) in actions" :key="actionIndex" v-if="(!dataView && action.listView) || (dataView && action.dataView)">
|
||||
<a-tooltip placement="bottom" v-for="(action, actionIndex) in actions" :key="actionIndex" v-if="(!dataView && (action.listView || action.groupAction && selectedRowKeys.length > 0)) || (dataView && action.dataView)">
|
||||
<template slot="title">
|
||||
{{ action.label }}
|
||||
</template>
|
||||
|
|
@ -36,26 +36,64 @@
|
|||
shape="circle"
|
||||
style="margin-right: 5px"
|
||||
@click="execAction(action)"
|
||||
:disabled="'hidden' in action ? dataView && action.hidden(resource) : false"
|
||||
>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip placement="bottom">
|
||||
<span v-if="!dataView" style="float: right; padding-right: 8px">
|
||||
<a-tooltip placement="bottom">
|
||||
<template slot="title">
|
||||
{{ "Auto-Refresh" }}
|
||||
</template>
|
||||
<a-switch
|
||||
style="margin: 8px;"
|
||||
:loading="loading"
|
||||
:checked="autoRefresh"
|
||||
@change="toggleAutoRefresh"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip placement="bottom">
|
||||
<template slot="title">
|
||||
{{ "Refresh" }}
|
||||
</template>
|
||||
<a-button
|
||||
@click="fetchData()"
|
||||
:loading="loading"
|
||||
shape="circle"
|
||||
icon="reload"
|
||||
/>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-tooltip placement="bottom" v-if="dataView">
|
||||
<template slot="title">
|
||||
{{ "Refresh" }}
|
||||
</template>
|
||||
<a-button
|
||||
style="float: right"
|
||||
@click="fetchData()"
|
||||
:loading="loading"
|
||||
shape="circle"
|
||||
icon="reload"
|
||||
/>
|
||||
</a-tooltip>
|
||||
</a-col>
|
||||
<a-col :span="8" v-if="!$route.params || !$route.params.id">
|
||||
<a-tooltip placement="bottom" v-if="dataView">
|
||||
<template slot="title">
|
||||
{{ "Auto-Refresh" }}
|
||||
</template>
|
||||
<a-switch v-if="dataView"
|
||||
style="float: right; margin: 5px;"
|
||||
:loading="loading"
|
||||
:checked="autoRefresh"
|
||||
@change="toggleAutoRefresh"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-input-search
|
||||
size="default"
|
||||
placeholder="Search"
|
||||
@search="onSearch"
|
||||
v-if="!dataView"
|
||||
>
|
||||
<a-icon slot="prefix" type="search" />
|
||||
</a-input-search>
|
||||
|
|
@ -81,7 +119,9 @@
|
|||
v-for="(field, fieldIndex) in currentAction.params"
|
||||
:key="fieldIndex"
|
||||
:label="field.name"
|
||||
:v-bind="field.name">
|
||||
:v-bind="field.name"
|
||||
v-if="field.name !== 'id'"
|
||||
>
|
||||
|
||||
<span v-if="field.type==='boolean'">
|
||||
<a-switch
|
||||
|
|
@ -128,26 +168,8 @@
|
|||
</a-modal>
|
||||
|
||||
<div v-if="dataView">
|
||||
<a-row :gutter="12">
|
||||
<a-col :xl="12">
|
||||
<chart-card class="info-card" v-if="resource.name">
|
||||
<h4>Name</h4>
|
||||
<template slot="footer"><span>{{ resource.name }}</span></template>
|
||||
</chart-card>
|
||||
</a-col>
|
||||
<a-col :xl="12">
|
||||
<chart-card class="info-card" v-if="resource.id">
|
||||
<h4>ID</h4>
|
||||
<template slot="footer"><span>{{ resource.id }}</span></template>
|
||||
</chart-card>
|
||||
</a-col>
|
||||
<a-col :xl="6" v-for="(value, key) in resource" :key="key">
|
||||
<chart-card class="info-card" v-if="key !== 'id' && key !== 'name'">
|
||||
<h4>{{ key }}</h4>
|
||||
<template slot="footer"><span>{{ value }}</span></template>
|
||||
</chart-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<instance-view :vm="resource" v-if="routeName == 'vm'" />
|
||||
<data-view :resource="resource" v-else />
|
||||
</div>
|
||||
<div style="margin-top: 12px" v-else>
|
||||
<a-table
|
||||
|
|
@ -217,16 +239,21 @@
|
|||
import { api } from '@/api'
|
||||
import store from '@/store'
|
||||
import ChartCard from '@/components/chart/ChartCard'
|
||||
import DataView from '@/components/widgets/DataView'
|
||||
import InstanceView from '@/components/widgets/InstanceView'
|
||||
|
||||
export default {
|
||||
name: 'Resource',
|
||||
components: {
|
||||
ChartCard
|
||||
ChartCard,
|
||||
DataView,
|
||||
InstanceView
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
apiName: '',
|
||||
loading: false,
|
||||
autoRefresh: false,
|
||||
columns: [],
|
||||
items: [],
|
||||
resource: {},
|
||||
|
|
@ -291,6 +318,8 @@ export default {
|
|||
} else {
|
||||
this.dataView = false
|
||||
}
|
||||
console.log(this.$route)
|
||||
console.log(this.routeName)
|
||||
if (this.$route && this.$route.meta && this.$route.meta.permission) {
|
||||
this.apiName = this.$route.meta.permission[0]
|
||||
if (this.$route.meta.columns) {
|
||||
|
|
@ -366,6 +395,21 @@ export default {
|
|||
onSearch (value) {
|
||||
this.fetchData(value)
|
||||
},
|
||||
toggleAutoRefresh () {
|
||||
this.autoRefresh = !this.autoRefresh
|
||||
this.doRefresh()
|
||||
},
|
||||
doRefresh () {
|
||||
if (!this.autoRefresh) {
|
||||
return
|
||||
}
|
||||
const doRefresh = this.doRefresh
|
||||
const fetchData = this.fetchData
|
||||
setTimeout(function() {
|
||||
fetchData()
|
||||
doRefresh()
|
||||
}, 5000)
|
||||
},
|
||||
closeAction () {
|
||||
this.currentAction.loading = false
|
||||
this.showAction = false
|
||||
|
|
@ -460,6 +504,10 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
if ('id' in this.resource) {
|
||||
params['id'] = this.resource['id']
|
||||
}
|
||||
|
||||
const closeAction = this.closeAction
|
||||
const showError = this.$notification['error']
|
||||
api(this.currentAction.api, params).then(json => {
|
||||
|
|
@ -470,8 +518,12 @@ export default {
|
|||
message: 'Request Failed',
|
||||
description: error.response.headers['x-description']
|
||||
})
|
||||
}).then(function () {
|
||||
})
|
||||
|
||||
const fetchData = this.fetchData
|
||||
setTimeout(function() {
|
||||
fetchData()
|
||||
}, 2500)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
|
@ -550,7 +602,7 @@ export default {
|
|||
|
||||
.ant-breadcrumb {
|
||||
vertical-align: text-bottom;
|
||||
margin-bottom: 6px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ant-breadcrumb .anticon {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
:type="collapsed ? 'menu-unfold' : 'menu-fold'"
|
||||
@click="toggle"/>
|
||||
|
||||
<!--
|
||||
<a-breadcrumb class="breadcrumb" v-if="device !== 'mobile'">
|
||||
<a-breadcrumb-item v-for="(item, index) in breadList" :key="index">
|
||||
<router-link
|
||||
|
|
@ -25,6 +26,7 @@
|
|||
<span v-else>{{ item.meta.title }}</span>
|
||||
</a-breadcrumb-item>
|
||||
</a-breadcrumb>
|
||||
-->
|
||||
<user-menu></user-menu>
|
||||
</div>
|
||||
<div v-else :class="['top-nav-header-index', theme]">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
<template>
|
||||
<a-row :gutter="12">
|
||||
<a-col :xl="12">
|
||||
<chart-card class="info-card" v-if="resource.name">
|
||||
<h4>Name</h4>
|
||||
<template slot="footer"><span>{{ resource.name }}</span></template>
|
||||
</chart-card>
|
||||
</a-col>
|
||||
<a-col :xl="12">
|
||||
<chart-card class="info-card" v-if="resource.id">
|
||||
<h4>ID</h4>
|
||||
<template slot="footer"><span>{{ resource.id }}</span></template>
|
||||
</chart-card>
|
||||
</a-col>
|
||||
<a-col :xl="6" v-for="(value, key) in resource" :key="key">
|
||||
<chart-card class="info-card" v-if="key !== 'id' && key !== 'name'">
|
||||
<h4>{{ key }}</h4>
|
||||
<template slot="footer"><span>{{ value }}</span></template>
|
||||
</chart-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import ChartCard from '@/components/chart/ChartCard'
|
||||
|
||||
export default {
|
||||
name: 'DataView',
|
||||
components: {
|
||||
ChartCard
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
<template>
|
||||
<div style="padding-top: 12px">
|
||||
<a-row>
|
||||
<a-col :span="24">
|
||||
<h2>{{ vm.displayname }} ({{ vm.name }})</h2>
|
||||
</a-col>
|
||||
<a-col :span="5">
|
||||
<a :href="'/client/console?cmd=access&vm=' + vm.id" target="_blank">
|
||||
<a-avatar shape="square" :size="200"
|
||||
style="color: #fff; backgroundColor: #333; width: 175px; height: 120px;">
|
||||
<span style="text-align: bottom">
|
||||
<a-icon type="right-square"/>
|
||||
{{ vm.instancename }}
|
||||
</span>
|
||||
</a-avatar>
|
||||
</a>
|
||||
</a-col>
|
||||
<a-col :span="15">
|
||||
<p>
|
||||
ID: {{ vm.id }} <br/>
|
||||
State: {{ vm.state }} <br/>
|
||||
Guest OS: {{ vm.ostypeid }} <br/>
|
||||
Guest Template: {{ vm.templatename }} <br/>
|
||||
Compute Offering: {{ vm.serviceofferingname }} <br/>
|
||||
Host: {{ vm.hostname }} ({{ vm.hypervisor }}) <br/>
|
||||
Zone: {{ vm.zonename }} <br/>
|
||||
IP Addresses: <ul>
|
||||
<li v-for="eth in vm.nic">{{ eth.ipaddress }}</li>
|
||||
</ul>
|
||||
</p>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<p>
|
||||
<font-awesome-icon :icon="['fas', 'microchip']" />
|
||||
CPU: {{ vm.cpunumber }} x {{ vm.cpuspeed }} Mhz <br/>
|
||||
<font-awesome-icon :icon="['fas', 'memory']" />
|
||||
Memory: {{ vm.memory }} MiB <br/>
|
||||
<font-awesome-icon :icon="['fas', 'database']" />
|
||||
Storage: {{ (totalStorage / (1024 * 1024 * 1024.0)).toFixed(2) }} GiB <br/>
|
||||
</p>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="16">
|
||||
<a-card title="VM Hardware">
|
||||
<a-collapse>
|
||||
<a-collapse-panel :header="'CPU: ' + vm.cpunumber">
|
||||
<p>{{ vm.cpunumber }} CPU(s) x {{ vm.cpuspeed }} Mhz</p>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel :header="'Memory: ' + vm.memory + ' MB'">
|
||||
<p>Total Memory: {{ vm.memory }} MiB<br/>Free Memory: {{ vm.memoryintfreekbs }} kBs</p>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel :header="'Storage: ' + volumes.length" >
|
||||
<a-list
|
||||
itemLayout="horizontal"
|
||||
:dataSource="volumes"
|
||||
>
|
||||
<a-list-item slot="renderItem" slot-scope="item, index">
|
||||
<a-list-item-meta :description="item.id">
|
||||
<a slot="title" href="">{{item.name}} ({{ item.type }})</span></a>
|
||||
<a-avatar slot="avatar">
|
||||
<font-awesome-icon :icon="['fas', 'database']" />
|
||||
</a-avatar>
|
||||
</a-list-item-meta>
|
||||
<p>
|
||||
State: {{ item.state }}<br/>
|
||||
Size: {{ (item.size / (1024 * 1024 * 1024.0)).toFixed(4) }} GB<br/>
|
||||
Physical Size: {{ (item.physicalsize / (1024 * 1024 * 1024.0)).toFixed(4) }} GB<br/>
|
||||
Provisioning: {{ item.provisioningtype }}<br/>
|
||||
Storage Pool: {{ item.storage }} ({{ item.storagetype }})<br/>
|
||||
</p>
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
|
||||
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel :header="'Network Adapter(s): ' + vm.nic.length" >
|
||||
<a-list
|
||||
itemLayout="horizontal"
|
||||
:dataSource="vm.nic"
|
||||
>
|
||||
<a-list-item slot="renderItem" slot-scope="item, index">
|
||||
<a-list-item-meta :description="item.id">
|
||||
<a slot="title" href="https://vue.ant.design/">{{item.ipaddress}} <span v-show="item.isdefault">(Default)</span></a>
|
||||
<a-avatar slot="avatar">
|
||||
<font-awesome-icon :icon="['fas', 'ethernet']" />
|
||||
</a-avatar>
|
||||
</a-list-item-meta>
|
||||
<p>
|
||||
Network: {{ item.networkname }}<br/>
|
||||
Mac Address: {{ item.macaddress }}<br/>
|
||||
Netmask: {{ item.netmask }}<br/>
|
||||
Gateway: {{ item.gateway }}<br/>
|
||||
Broadcast URI: {{ item.broadcasturi }}<br/>
|
||||
Isolation URI: {{ item.isolationuri }}<br/>
|
||||
</p>
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
</a-card>
|
||||
</a-col>
|
||||
|
||||
|
||||
</a-row>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { api } from '@/api'
|
||||
|
||||
export default {
|
||||
name: 'InstanceView',
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
vm: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: {}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
volumes: [],
|
||||
totalStorage: 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
vm: function (newVm, oldVm) {
|
||||
this.fetchData()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
this.listVolumes()
|
||||
},
|
||||
listVolumes() {
|
||||
api('listVolumes', { 'listall': true, 'virtualmachineid': this.vm.id }).then(json => {
|
||||
this.volumes = json.listvolumesresponse.volume
|
||||
for (var volume of this.volumes) {
|
||||
this.totalStorage += volume.size
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
|
|
@ -10,7 +10,8 @@ export default {
|
|||
permission: [ 'listVirtualMachinesMetrics', 'listVirtualMachines' ],
|
||||
component: () => import('@/components/CloudMonkey/Resource.vue'),
|
||||
columns: [
|
||||
'displayname', 'state', 'instancename', { 'ipaddress': (record) => { return record.nic[0].ipaddress } }, 'account', 'zonename',
|
||||
{ 'name': (record) => { return record.displayname } }, 'state', 'instancename',
|
||||
{ 'ipaddress': (record) => { return record.nic[0].ipaddress } }, 'account', 'zonename',
|
||||
'cpunumber', 'cpuused', 'cputotal', 'memoryintfreekbs', 'memorytotal',
|
||||
'networkread', 'networkwrite', 'diskkbsread', 'diskkbswrite', 'diskiopstotal'
|
||||
],
|
||||
|
|
@ -24,33 +25,56 @@ export default {
|
|||
listView: true
|
||||
},
|
||||
{
|
||||
api: 'startVirtualMachine',
|
||||
icon: 'right-square',
|
||||
label: 'View Console',
|
||||
api: 'updateVirtualMachine',
|
||||
icon: 'edit',
|
||||
label: 'Update VM',
|
||||
dataView: true
|
||||
},
|
||||
|
||||
{
|
||||
api: 'startVirtualMachine',
|
||||
icon: 'caret-right',
|
||||
label: 'Start VM',
|
||||
params: ['name', 'zoneid', 'diskofferingid'],
|
||||
listView: true,
|
||||
dataView: true
|
||||
dataView: true,
|
||||
groupAction: true,
|
||||
hidden: (record) => { return record.state !== 'Stopped' },
|
||||
options: ['podid', 'clusterid', 'hostid']
|
||||
},
|
||||
{
|
||||
api: 'stopVirtualMachine',
|
||||
icon: 'stop',
|
||||
label: 'Stop VM',
|
||||
params: ['name', 'zoneid', 'diskofferingid'],
|
||||
listView: true,
|
||||
dataView: true
|
||||
dataView: true,
|
||||
groupAction: true,
|
||||
options: ['podid', 'clusterid', 'hostid'],
|
||||
hidden: (record) => { return record.state !== 'Running' }
|
||||
},
|
||||
{
|
||||
api: 'rebootVirtualMachine',
|
||||
icon: 'sync',
|
||||
label: 'Reboot VM',
|
||||
dataView: true
|
||||
dataView: true,
|
||||
hidden: (record) => { return record.state !== 'Running' },
|
||||
},
|
||||
{
|
||||
api: 'restoreVirtualMachine',
|
||||
icon: 'usb',
|
||||
label: 'Reinstall Instance',
|
||||
dataView: true,
|
||||
params: ['virtualmachineid']
|
||||
},
|
||||
{
|
||||
api: 'updateVMAffinityGroup',
|
||||
icon: 'swap',
|
||||
label: 'Update Affinity Group',
|
||||
dataView: true,
|
||||
params: ['id', 'serviceofferingid']
|
||||
},
|
||||
{
|
||||
api: 'changeServiceForVirtualMachine',
|
||||
icon: 'sliders',
|
||||
label: 'Change Service Offering',
|
||||
dataView: true,
|
||||
params: ['id', 'serviceofferingid']
|
||||
},
|
||||
{
|
||||
api: 'createVMSnapshot',
|
||||
|
|
@ -58,17 +82,17 @@ export default {
|
|||
label: 'Create VM Snapshot',
|
||||
dataView: true
|
||||
},
|
||||
{
|
||||
api: 'restoreVirtualMachine',
|
||||
icon: 'to-top',
|
||||
label: 'Reinstall Instance',
|
||||
dataView: true,
|
||||
params: ['virtualmachineid']
|
||||
},
|
||||
{
|
||||
api: 'attachIso',
|
||||
icon: 'paper-clip',
|
||||
label: 'Attach ISO to Instance',
|
||||
label: 'Attach ISO',
|
||||
dataView: true,
|
||||
params: ['id', 'virtualmachineid']
|
||||
},
|
||||
{
|
||||
api: 'detachIso',
|
||||
icon: 'link',
|
||||
label: 'Detach ISO',
|
||||
dataView: true,
|
||||
params: ['id', 'virtualmachineid']
|
||||
},
|
||||
|
|
@ -76,7 +100,8 @@ export default {
|
|||
api: 'migrateVirtualMachine',
|
||||
icon: 'drag',
|
||||
label: 'Migrate VM',
|
||||
dataView: true
|
||||
dataView: true,
|
||||
hidden: (record) => { return record.state !== 'Running' }
|
||||
},
|
||||
{
|
||||
api: 'resetPasswordForVirtualMachine',
|
||||
|
|
@ -91,20 +116,13 @@ export default {
|
|||
label: 'Reset SSH Key',
|
||||
dataView: true
|
||||
},
|
||||
{
|
||||
api: 'changeServiceForVirtualMachine',
|
||||
icon: 'swap',
|
||||
label: 'Change Service Offering',
|
||||
dataView: true,
|
||||
params: ['id', 'serviceofferingid']
|
||||
},
|
||||
{
|
||||
api: 'destroyVirtualMachine',
|
||||
icon: 'delete',
|
||||
label: 'Destroy VM',
|
||||
params: ['id'],
|
||||
listView: true,
|
||||
dataView: true
|
||||
dataView: true,
|
||||
groupAction: true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -33,6 +33,22 @@ export default {
|
|||
params: ['@file', 'name', 'zoneid', 'format', 'checksum'],
|
||||
listView: true
|
||||
},
|
||||
{
|
||||
api: 'attachVolume',
|
||||
icon: 'paper-clip',
|
||||
label: 'Attach Volume',
|
||||
params: ['id', 'virtualmachineid'],
|
||||
dataView: true,
|
||||
hidden: (record) => { return record.virtualmachineid }
|
||||
},
|
||||
{
|
||||
api: 'detachVolume',
|
||||
icon: 'link',
|
||||
label: 'Detach Volume',
|
||||
params: ['id', 'virtualmachineid'],
|
||||
dataView: true,
|
||||
hidden: (record) => { return !record.virtualmachineid }
|
||||
},
|
||||
{
|
||||
api: 'migrateVolume',
|
||||
icon: 'drag',
|
||||
|
|
@ -47,19 +63,8 @@ export default {
|
|||
type: 'main',
|
||||
params: ['id', 'virtualmachineid'],
|
||||
dataView: true
|
||||
}, {
|
||||
api: 'attachVolume',
|
||||
icon: 'paper-clip',
|
||||
label: 'Attach Volume',
|
||||
params: ['id', 'virtualmachineid'],
|
||||
dataView: true
|
||||
}, {
|
||||
api: 'detachVolume',
|
||||
icon: 'link',
|
||||
label: 'Detach Volume',
|
||||
params: ['id', 'virtualmachineid'],
|
||||
dataView: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
api: 'extractVolume',
|
||||
icon: 'cloud-download',
|
||||
label: 'Download Volume',
|
||||
|
|
@ -76,8 +81,8 @@ export default {
|
|||
icon: 'delete',
|
||||
label: 'Delete Volume',
|
||||
params: ['id'],
|
||||
listView: true,
|
||||
dataView: true
|
||||
dataView: true,
|
||||
groupAction: true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue