blob: 945a7086865e59c290f1ea1a4571c523b87103da [file] [log] [blame]
<template>
<div>
<div style="margin-bottom: 16px; margin-top: 16px">
<a-button
@click="fetchData"
:loading="loading"
shape="circle"
icon="reload"
/>
<a-button
v-for="(action, index) in actions"
:key="index"
:icon="action.icon"
:type="action.icon == 'delete' ? 'danger' : (action.icon == 'plus' ? 'primary' : 'default')"
shape="circle"
style="margin-left: 5px"
@click="execAction(action)"
>
</a-button>
<a-drawer
:title="action.label"
placement="right"
width="75%"
:closable="true"
@close="closeAction"
:visible="showAction"
>
<a-spin :spinning="action.loading">
<a-form
:form="form"
@submit="handleSubmit"
layout="vertical" >
<a-form-item
v-for="(field, index) in action.params"
:key="index"
:label="field.name"
:v-bind="field.name">
<span v-if="field.type==='boolean'">
<a-switch
v-decorator="[field.name, {
rules: [{ required: field.required, message: 'Please provide input' }]
}]"
:placeholder="field.description"
/>
</span>
<span v-else-if="field.type==='uuid' || field.name==='account'">
<a-select
:loading="field.loading"
v-decorator="[field.name, {
rules: [{ required: field.required, message: 'Please select option' }]
}]"
:placeholder="field.description"
>
<a-select-option v-for="(opt, index) in field.opts" :key="index">
{{ opt.name }}
</a-select-option>
</a-select>
</span>
<span v-else-if="field.type==='long'">
<a-input-number
v-decorator="[field.name, {
rules: [{ required: field.required, message: 'Please enter a number' }]
}]"
:placeholder="field.description"
/>
</span>
<span v-else>
<a-input
v-decorator="[field.name, {
rules: [{ required: field.required, message: 'Please enter input' }]
}]"
:placeholder="field.description"
/>
</span>
</a-form-item>
<a-form-item>
<div
:style="{
bottom: 0,
width: '100%',
borderTop: '1px solid #e8e8e8',
paddingTop: '24px',
textAlign: 'right',
left: 0,
background: '#fff',
borderRadius: '0 0 4px 4px',
}"
>
<a-button
style="marginRight: 8px"
@click="closeAction"
>
Cancel
</a-button>
<a-button
:loading="action.loading"
type="primary"
html-type="submit">
Submit
</a-button>
</div>
</a-form-item>
</a-form>
</a-spin>
</a-drawer>
<span style="margin-left: 8px">
<template v-if="hasSelected">
{{ `Selected ${selectedRowKeys.length} items` }}
</template>
</span>
</div>
<div v-if="$route.params && $route.params.id">
<p v-for="(value, key) in getResource($route.params.id)" :key="key">
<span>{{ key }}: </span>
<span>{{ value }}</span>
</p>
</div>
<div v-else>
<a-table
size="middle"
:rowKey="record => record.id"
:loading="loading"
:columns="columns"
:dataSource="items"
:scroll="{ x: true }"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
>
<a slot="name" slot-scope="text, record" href="javascript:;">
<router-link :to="{ path: $route.name + '/' + record.id }">{{ text }}</router-link>
</a>
<a slot="username" slot-scope="text, record" href="javascript:;">
<router-link :to="{ path: $route.name + '/' + record.id }">{{ text }}</router-link>
</a>
<a slot="vmname" slot-scope="text, record" href="javascript:;">
<router-link :to="{ path: '/vm/' + record.virtualmachineid }">{{ text }}</router-link>
</a>
<a slot="account" slot-scope="text, record" href="javascript:;">
<router-link :to="{ path: '/account/' + record.accountid }">{{ text }}</router-link>
</a>
<a slot="domain" slot-scope="text, record" href="javascript:;">
<router-link :to="{ path: '/domain/' + record.domainid }">{{ text }}</router-link>
</a>
<a slot="zonename" slot-scope="text, record" href="javascript:;">
<router-link :to="{ path: '/zone/' + record.zoneid }">{{ text }}</router-link>
</a>
<a slot="guestnetworkname" slot-scope="text, record" href="javascript:;">
<router-link :to="{ path: '/guestnetwork/' + record.guestnetworkid }">{{ text }}</router-link>
</a>
</a-table>
</div>
</div>
</template>
<script>
import { api } from '@/api'
import { apiConfig } from '@/config/apiConfig'
import store from '@/store'
export default {
name: 'Resource',
data () {
return {
apiName: '',
config: {},
loading: false,
columns: [],
items: [],
selectedRowKeys: [],
action: {},
showAction: false,
actions: []
}
},
computed: {
hasSelected () {
return this.selectedRowKeys.length > 0
}
},
mounted () {
this.fetchData()
},
watch: {
'$route' (to, from) {
if (to.name === this.$route.name) {
this.fetchData()
}
}
},
beforeCreate () {
this.form = this.$form.createForm(this)
},
methods: {
fetchData () {
this.apiName = ''
this.actions = []
this.columns = []
this.columnKeys = []
this.config = apiConfig[this.$route.name]
var params = { listall: true }
if (this.$route.meta.params) {
params = this.$route.meta.params
params['listall'] = 'true'
}
if (this.config) {
this.apiName = this.config.listApi
this.actions = this.config.actions
this.columnKeys = this.config.column
} else {
if (this.$route && this.$route.meta && this.$route.meta.permission) {
this.apiName = this.$route.meta.permission[0]
}
}
if (this.apiName && this.apiName !== '' && !this.columnKeys || this.columnKeys.length == 0) {
for (const field of store.getters.apis[this.apiName]['response']) {
this.columnKeys.push(field.name)
}
this.columnKeys = [...new Set(this.columnKeys)]
this.columnKeys.sort(function (a, b) {
if (a === 'name' && b !== 'name') { return -1 }
if (a < b) { return -1 }
if (a > b) { return 1 }
return 0
})
}
for (const key of this.columnKeys) {
this.columns.push({
title: key,
dataIndex: key,
key: key,
scopedSlots: { customRender: key },
sorter: (a, b) => a[key].length - b[key].length
})
}
this.loading = true
if (this.$route.params && this.$route.params.id) {
params['id'] = this.$route.params.id
}
api(this.apiName, params).then(json => {
this.loading = false
var responseName
var objectName
for (const key in json) {
if (key.includes('response')) {
responseName = key
break
}
}
for (const key in json[responseName]) {
if (key == 'count') continue
objectName = key
break
}
this.items = json[responseName][objectName]
if (!this.items || this.items.length == 0) {
this.items = []
}
for (let idx = 0; idx < this.items.length; idx++) {
this.items[idx]['key'] = idx
}
})
},
getResource (id) {
var res = {}
for (const item of this.items) {
if (item.id == id) {
res = item
break
}
}
return res
},
closeAction () {
this.action.loading = false
this.showAction = false
this.action = {}
},
execAction (action) {
this.action = action
this.action['params'] = store.getters.apis[action.api]['params']
this.action['params'].sort(function (a, b) {
if (a.name === 'name' && b.name !== 'name') { return -1 }
if (a.name !== 'name' && b.name === 'name') { return -1 }
if (a.name === 'id') { return -1 }
if (a.name < b.name) { return -1 }
if (a.name > b.name) { return 1 }
return 0
})
for (var param of this.action['params']) {
if (param.type === 'uuid' || param.name === 'account') {
this.listUuidOpts(param)
}
}
this.showAction = true
this.action.loading = false
},
listUuidOpts (param) {
var paramName = param.name
const possibleName = 'list' + paramName.replace('id', '').toLowerCase() + 's'
var possibleApi = undefined
if (paramName == 'id') {
possibleApi = this.apiName
} else {
for (const api in store.getters.apis) {
if (api.toLowerCase().startsWith(possibleName)) {
possibleApi = api
break
}
}
}
if (!possibleApi) {
return
}
param.loading = true
param.opts = []
var params = { listall: true }
if (possibleApi == 'listTemplates') {
params['templatefilter'] = 'executable'
}
api(possibleApi, params).then(json => {
param.loading = false
for (const obj in json) {
if (obj.includes('response')) {
for (const res in json[obj]) {
if (res == 'count') {
continue
}
param.opts = json[obj][res]
this.$forceUpdate()
break
}
break
}
}
}).catch(function (error) {
param.loading = false
}).then(function () {
})
},
handleSubmit (e) {
e.preventDefault()
this.form.validateFields((err, values) => {
if (!err) {
this.action.loading = true
const params = {}
for (const key in values) {
const input = values[key]
for (const param of this.action['params']) {
if (param.name === key) {
if (input === undefined) {
if (param.type === 'boolean') {
params[key] = false
}
break
}
if (param.type === 'uuid') {
params[key] = param.opts[input]['id']
} else {
params[key] = input
}
break
}
}
}
api(this.action.api, params).then(json => {
console.log(json)
this.closeAction()
}).catch(function (error) {
console.log(error)
this.closeAction()
}).then(function () {
})
}
})
},
start () {
this.loading = true
this.fetchData()
setTimeout(() => {
this.loading = false
this.selectedRowKeys = []
}, 1000)
},
onSelectChange (selectedRowKeys) {
console.log('selectedRowKeys changed: ', selectedRowKeys)
this.selectedRowKeys = selectedRowKeys
}
}
}
</script>
<style scoped>
</style>