plugin: Quota plugin (#298)

Fixes #295

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
Hoang Nguyen 2020-07-04 13:32:57 +07:00 committed by Rohit Yadav
parent 30c4e3fae0
commit b61c4ae35d
12 changed files with 882 additions and 12 deletions

View File

@ -30,7 +30,7 @@
</div>
<slot name="name">
<h4 class="name">
{{ resource.displayname || resource.displaytext || resource.name || resource.hostname || resource.username || resource.ipaddress || resource.virtualmachinename }}
{{ resource.displayname || resource.displaytext || resource.name || resource.hostname || resource.username || resource.ipaddress || resource.virtualmachinename || resource.templatetype }}
</h4>
<console style="margin-left: 10px" :resource="resource" size="default" v-if="resource.id" />
</slot>

View File

@ -21,7 +21,7 @@
:loading="loading"
:columns="fetchColumns()"
:dataSource="items"
:rowKey="record => record.id || record.name"
:rowKey="record => record.id || record.name || record.usageType"
:pagination="false"
:rowSelection="['vm', 'event', 'alert'].includes($route.name) ? {selectedRowKeys: selectedRowKeys, onChange: onSelectChange} : null"
:rowClassName="getRowClassName"
@ -75,6 +75,9 @@
</span>
</div>
</span>
<a slot="templatetype" slot-scope="text, record" href="javascript:;">
<router-link :to="{ path: $route.path + '/' + record.templatetype }">{{ text }}</router-link>
</a>
<a slot="displayname" slot-scope="text, record" href="javascript:;">
<router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
</a>
@ -147,11 +150,14 @@
<router-link :to="{ path: '/pod/' + record.podid }">{{ text }}</router-link>
</a>
<a slot="account" slot-scope="text, record" href="javascript:;">
<router-link :to="{ path: '/account/' + record.accountid }" v-if="record.accountid">{{ text }}</router-link>
<router-link
v-if="'quota' in record && $router.resolve(`${$route.path}/${record.account}`) !== '404'"
:to="{ path: `${$route.path}/${record.account}`, query: { account: record.account, domainid: record.domainid, quota: true } }">{{ text }}</router-link>
<router-link :to="{ path: '/account/' + record.accountid }" v-else-if="record.accountid">{{ text }}</router-link>
<router-link :to="{ path: '/account', query: { name: record.account, domainid: record.domainid } }" v-else>{{ text }}</router-link>
</a>
<span slot="domain" slot-scope="text, record" href="javascript:;">
<router-link v-if="record.domainid && !record.domainid.includes(',') && $router.resolve('/domain/' + record.domainid).route.name !== '404'" :to="{ path: '/domain/' + record.domainid }">{{ text }}</router-link>
<router-link v-if="record.domainid && !record.domainid.toString().includes(',') && $router.resolve('/domain/' + record.domainid).route.name !== '404'" :to="{ path: '/domain/' + record.domainid }">{{ text }}</router-link>
<span v-else>{{ text }}</span>
</span>
<span slot="domainpath" slot-scope="text, record" href="javascript:;">
@ -235,6 +241,15 @@
<a-icon type="close-circle" theme="twoTone" twoToneColor="#f5222d" />
</a-button>
</template>
<template slot="tariffActions" slot-scope="text, record">
<a-button
shape="circle"
v-if="editableValueKey !== record.key"
:disabled="!('quotaTariffUpdate' in $store.getters.apis)"
icon="edit"
@click="editTariffValue(record)" />
<slot></slot>
</template>
</a-table>
</template>
@ -267,7 +282,7 @@ export default {
default: false
}
},
inject: ['parentFetchData', 'parentToggleLoading'],
inject: ['parentFetchData', 'parentToggleLoading', 'parentEditTariffAction'],
data () {
return {
selectedRowKeys: [],
@ -329,10 +344,9 @@ export default {
}).catch(error => {
console.error(error)
this.$message.error('There was an error saving this setting.')
}).finally(() => {
this.$emit('refresh')
})
.finally(() => {
this.$emit('refresh')
})
},
editValue (record) {
this.editableValueKey = record.key
@ -428,6 +442,9 @@ export default {
data.forEach((item, index) => {
this.handleUpdateOrder(item.id, index + 1)
})
},
editTariffValue (record) {
this.parentEditTariffAction(true, record)
}
}
}

View File

@ -28,7 +28,39 @@ export default {
icon: 'bars',
permission: ['quotaSummary'],
columns: ['account', 'domain', 'state', 'currency', 'balance', 'quota'],
details: ['account', 'domain', 'state', 'currency', 'balance', 'quota', 'startdate', 'enddate']
details: ['account', 'domain', 'state', 'currency', 'balance', 'quota', 'startdate', 'enddate'],
component: () => import('@/views/plugins/quota/QuotaSummary.vue'),
tabs: [
{
name: 'details',
component: () => import('@/components/view/DetailsTab.vue')
},
{
name: 'quota.statement.quota',
component: () => import('@/views/plugins/quota/QuotaUsage.vue')
},
{
name: 'quota.statement.balance',
component: () => import('@/views/plugins/quota/QuotaBalance.vue')
}
],
actions: [
{
api: 'quotaCredits',
icon: 'plus',
label: 'label.quota.add.credits',
dataView: true,
args: ['value', 'min_balance', 'quota_enforce'],
mapping: {
account: {
value: (record) => { return record.account }
},
domainid: {
value: (record) => { return record.domainid }
}
}
}
]
},
{
name: 'quotatariff',
@ -36,8 +68,9 @@ export default {
icon: 'credit-card',
docHelp: 'plugins/quota.html#quota-tariff',
permission: ['quotaTariffList'],
columns: ['usageName', 'description', 'usageUnit', 'tariffValue'],
details: ['usageName', 'description', 'usageUnit', 'tariffValue']
columns: ['usageName', 'description', 'usageUnit', 'tariffValue', 'tariffActions'],
details: ['usageName', 'description', 'usageUnit', 'tariffValue'],
component: () => import('@/views/plugins/quota/QuotaTariff.vue')
},
{
name: 'quotaemailtemplate',
@ -45,7 +78,11 @@ export default {
icon: 'mail',
permission: ['quotaEmailTemplateList'],
columns: ['templatetype', 'templatesubject', 'templatebody'],
details: ['templatetype', 'templatesubject', 'templatebody']
details: ['templatetype', 'templatesubject', 'templatebody'],
tabs: [{
name: 'details',
component: () => import('@/views/plugins/quota/EmailTemplateDetails.vue')
}]
}
]
}

View File

@ -1260,6 +1260,7 @@
"label.minmemory": "Min Memory (in MB)",
"label.minute.past.hour": "minute(s) past the hour",
"label.minutes.past.hour": "minutes(s) past the hour",
"label.min_balance": "Min Balance",
"label.monday": "Monday",
"label.monitor": "Monitor",
"label.monthly": "Monthly",
@ -1530,12 +1531,14 @@
"label.quiescevm": "Quiesce VM",
"label.quiettime": "Quiet Time (in sec)",
"label.quota": "Quota",
"label.quota_enforce": "Enforce Quota",
"label.quota.add.credits": "Add Credits",
"label.quota.configuration": "Quota Configuration",
"label.quota.configure": "Configure Quota",
"label.quota.credits": "Credits",
"label.quota.dates": "Update Dates",
"label.quota.description": "Quota Description",
"label.quota.email.edit": "Edit Email Template",
"label.quota.enddate": "End Date",
"label.quota.endquota": "End Quota",
"label.quota.enforce": "Enforce Quota",
@ -1552,6 +1555,9 @@
"label.quota.tariff.edit": "Edit Tariff",
"label.quota.tariff.effectivedate": "Effective Date",
"label.quota.totalusage": "Total Usage",
"label.quota.total":"Total",
"label.quota.type.name":"Usage Type",
"label.quota.type.unit":"Usage Unit",
"label.quota.usage": "Quota Consumption",
"label.quota.value": "Quota Value",
"label.rados.monitor": "RADOS Monitor",
@ -1904,6 +1910,7 @@
"label.tagged": "Tagged",
"label.tags": "Tags",
"label.target.iqn": "Target IQN",
"label.tariffactions": "Actions",
"label.tariffvalue": "Tariff Value",
"label.task.completed": "Task completed",
"label.tcp": "TCP",

View File

@ -283,7 +283,9 @@
</div>
<div v-if="dataView">
<slot v-if="$route.path.startsWith('/quotasummary')"></slot>
<resource-view
v-else
:resource="resource"
:loading="loading"
:tabs="$route.meta.tabs" />
@ -342,6 +344,7 @@ export default {
parentToggleLoading: this.toggleLoading,
parentStartLoading: this.startLoading,
parentFinishLoading: this.finishLoading,
parentChangeResource: this.changeResource,
parentPollActionCompletion: this.pollActionCompletion
}
},
@ -446,6 +449,7 @@ export default {
if (this.$route && this.$route.params && this.$route.params.id) {
this.resource = {}
this.dataView = true
this.$emit('change-resource', this.resource)
} else {
this.dataView = false
}
@ -597,6 +601,7 @@ export default {
}
if (this.items.length > 0) {
this.resource = this.items[0]
this.$emit('change-resource', this.resource)
}
}).catch(error => {
this.$notifyError(error)

View File

@ -0,0 +1,136 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
<template>
<a-modal
v-if="showAction"
style="top: 20px;"
centered
:confirmLoading="loading"
:title="$t('label.quota.configuration')"
:closable="true"
:visible="showAction"
@ok="submitTariff"
@cancel="onClose"
>
<a-form
:form="form"
layout="vertical"
@submit="submitTariff">
<a-form-item :label="$t('label.quota.value')">
<a-input
v-decorator="['value', {
rules: [{
required: true,
message: `${$t('message.error.required.input')}`
}]
}]"></a-input>
</a-form-item>
<a-form-item :label="$t('label.quota.tariff.effectivedate')">
<a-date-picker
:disabledDate="disabledDate"
style="width: 100%"
v-decorator="['startdate', {
rules: [{
type: 'object',
required: true,
message: `${$t('message.error.date')}`
}]
}]"></a-date-picker>
</a-form-item>
</a-form>
</a-modal>
</template>
<script>
import { api } from '@/api'
import moment from 'moment'
export default {
name: 'EditTariffValueWizard',
props: {
showAction: {
type: Boolean,
default: () => false
},
resource: {
type: Object,
required: true
}
},
data () {
return {
loading: false,
pattern: 'YYYY-MM-DD'
}
},
inject: ['parentEditTariffAction', 'parentFetchData'],
beforeCreate () {
this.form = this.$form.createForm(this)
},
mounted () {
this.form.getFieldDecorator('value', {
initialValue: this.resource.tariffValue
})
},
methods: {
onClose () {
this.parentEditTariffAction(false)
},
submitTariff (e) {
e.preventDefault()
this.form.validateFields((error, values) => {
if (error) return
const params = {}
params.usageType = this.resource.usageType
params.value = values.value
params.startdate = values.startdate.format(this.pattern)
this.loading = true
api('quotaTariffUpdate', {}, 'POST', params).then(json => {
const tariffResponse = json.quotatariffupdateresponse.quotatariff || {}
if (Object.keys(tariffResponse).length > 0) {
const effectiveDate = moment(tariffResponse.effectiveDate).format(this.pattern)
const query = this.$route.query
if (query.startdate !== effectiveDate) {
this.$router.replace({ path: 'quotatariff', query: { startdate: effectiveDate } })
}
this.parentFetchData()
}
this.onClose()
}).catch(error => {
this.$notification.error({
message: 'Request Failed',
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
})
}).finally(() => {
this.loading = false
})
})
},
disabledDate (current) {
return current && current < moment().endOf('day')
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,121 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
<template>
<a-spin :spinning="loading || loading">
<a-row :gutter="12">
<a-col :md="24" :lg="24">
<a-form-item :label="$t('label.templatesubject')">
<a-textarea v-model="formModel.templatesubject" />
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="12">
<a-col :md="24" :lg="24">
<a-form-item :label="$t('label.templatebody')">
<a-textarea v-model="formModel.templatebody" />
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="12">
<a-col :md="24" :lg="24">
<a-form-item :label="$t('label.last.updated')">
<label>{{ resource.last_updated }}</label>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="12">
<a-col :md="24" :lg="24">
<a-button
style="float: right; margin-left: 10px;"
:disabled="!('quotaEmailTemplateUpdate' in $store.getters.apis)"
:loading="loading"
type="primary"
@click="handleSubmit">{{ $t('label.apply') }}</a-button>
<a-button
style="float: right;"
:disabled="!('quotaEmailTemplateUpdate' in $store.getters.apis)"
:loading="loading"
type="default"
@click="() => { $router.go(-1) }">{{ $t('label.cancel') }}</a-button>
</a-col>
</a-row>
</a-spin>
</template>
<script>
import { api } from '@/api'
export default {
name: 'EmailTemplateDetails',
beforeCreate () {
this.form = this.$form.createForm(this)
},
data () {
return {
resource: {},
formModel: {
templatesubject: null,
templatebody: null
},
loading: false
}
},
mounted () {
this.fetchData()
},
methods: {
fetchData () {
this.loading = true
const params = {}
params.templatetype = this.$route.params.id
api('quotaEmailTemplateList', params).then(json => {
const listTemplates = json.quotaemailtemplatelistresponse.quotaemailtemplate || []
this.resource = listTemplates && listTemplates.length > 0 ? listTemplates[0] : {}
this.preFillDataValues()
}).catch(e => {
this.$notifyError(e)
}).finally(() => {
this.loading = false
})
},
preFillDataValues () {
console.log(this.resource)
this.formModel.templatesubject = this.resource.templatesubject || null
this.formModel.templatebody = this.resource.templatebody || null
},
handleSubmit () {
const params = {}
params.templatesubject = this.formModel.templatesubject
params.templatebody = this.formModel.templatebody
params.templatetype = this.resource.templatetype
this.loading = true
api('quotaEmailTemplateUpdate', params).then(json => {
this.$message.success(this.$t('label.quota.email.edit') + ' - ' + this.resource.templatetype)
this.$router.go(-1)
}).catch(e => {
this.$notifyError(e)
}).finally(() => {
this.loading = false
})
}
}
}
</script>

View File

@ -0,0 +1,172 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
<template>
<div>
<a-table
size="small"
:loading="loading"
:columns="columns"
:dataSource="dataSource"
:rowKey="record => record.name"
:pagination="false"
:scroll="{ y: '55vh' }"
>
<template slot="quota" slot-scope="text">
<span v-if="text!==null">{{ `${currency} ${text}` }}</span>
</template>
<template slot="credit" slot-scope="text">
<span v-if="text!==null">{{ `${currency} ${text}` }}</span>
</template>
</a-table>
</div>
</template>
<script>
import { api } from '@/api'
import moment from 'moment'
export default {
name: 'QuotaBalance',
props: {
resource: {
type: Object,
required: true
},
tab: {
type: String,
default: () => ''
}
},
data () {
return {
loading: false,
pattern: 'YYYY-MM-DD',
currency: '',
dataSource: [],
account: null
}
},
computed: {
columns () {
return [
{
title: this.$t('label.date'),
dataIndex: 'date',
width: 'calc(100% / 3)',
scopedSlots: { customRender: 'date' }
},
{
title: this.$t('label.quota.value'),
dataIndex: 'quota',
width: 'calc(100% / 3)',
scopedSlots: { customRender: 'quota' }
},
{
title: this.$t('label.credit'),
dataIndex: 'credit',
width: 'calc(100% / 3)',
scopedSlots: { customRender: 'credit' }
}
]
}
},
watch: {
tab (newTab, oldTab) {
this.tab = newTab
if (this.tab === 'quota.statement.balance') {
this.fetchData()
}
}
},
mounted () {
this.fetchData()
},
methods: {
async fetchData () {
this.dataSource = []
this.loading = true
this.account = this.$route.query && this.$route.query.account ? this.$route.query.account : null
try {
const resource = await this.fetchResource()
const quotaBalance = await this.quotaBalance(resource)
this.currency = quotaBalance.currency
this.dataSource = await this.createDataSource(quotaBalance)
this.loading = false
} catch (e) {
console.log(e)
this.loading = false
}
},
createDataSource (quotaBalance) {
const dataSource = []
const credits = quotaBalance.credits || []
dataSource.push({
date: moment(quotaBalance.enddate).format(this.pattern),
quota: quotaBalance.endquota,
credit: null
})
dataSource.push({
date: moment(quotaBalance.startdate).format(this.pattern),
quota: quotaBalance.startquota,
credit: null
})
credits.map(item => {
dataSource.push({
date: moment(item.updated_on).format(this.pattern),
quota: null,
credit: item.credits
})
})
return dataSource
},
fetchResource () {
return new Promise((resolve, reject) => {
const params = {}
params.domainid = this.resource.domainid
params.account = this.account
api('quotaBalance', params).then(json => {
const quotaBalance = json.quotabalanceresponse.balance || {}
resolve(quotaBalance)
}).catch(error => {
reject(error)
})
})
},
quotaBalance (resource) {
return new Promise((resolve, reject) => {
const params = {}
params.domainid = this.resource.domainid
params.account = this.account
params.startdate = moment(this.resource.startdate).format(this.pattern)
params.enddate = moment(resource.startdate).format(this.pattern)
api('quotaBalance', params).then(json => {
const quotaBalance = json.quotabalanceresponse.balance || {}
resolve(quotaBalance)
}).catch(error => {
reject(error)
})
})
}
}
}
</script>

View File

@ -0,0 +1,66 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
<template>
<div>
<autogen-view
@change-resource="changeResource"/>
<quota-summary-resource
v-if="isSummaryResouce"
:resource="resource"
:tabs="$route.meta.tabs"/>
</div>
</template>
<script>
import AutogenView from '@/views/AutogenView.vue'
import QuotaSummaryResource from '@/views/plugins/quota/QuotaSummaryResource'
export default {
name: 'QuotaSummary',
components: {
AutogenView,
QuotaSummaryResource
},
data () {
return {
resource: {}
}
},
provide: function () {
return {
parentChangeResource: this.changeResource
}
},
computed: {
isSummaryResouce () {
if (this.$route.path.startsWith('/quotasummary')) {
if (this.$route.query && 'quota' in this.$route.query && this.$route.query.quota) {
return true
}
}
return false
}
},
methods: {
changeResource (resource) {
console.log(resource)
this.resource = resource
}
}
}
</script>

View File

@ -0,0 +1,92 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
<template>
<resource-view
:loading="loading"
:resource="quotaResource"
:tabs="tabs"/>
</template>
<script>
import { api } from '@/api'
import moment from 'moment'
import ResourceView from '@/components/view/ResourceView'
export default {
name: 'QuotaSummaryResource',
components: {
ResourceView
},
props: {
resource: {
type: Object,
default: () => {}
},
tabs: {
type: Array,
default: () => []
}
},
data () {
return {
loading: false,
quotaResource: {},
networkService: null,
pattern: 'YYYY-MM-DD'
}
},
mounted () {
this.fetchData()
},
watch: {
resource () {
if (Object.keys(this.resource).length === 0) {
this.fetchData()
}
}
},
inject: ['parentChangeResource'],
methods: {
fetchData () {
const params = {}
if (Object.keys(this.$route.query).length > 0) {
Object.assign(params, this.$route.query)
}
this.loading = true
api('quotaBalance', params).then(json => {
const quotaBalance = json.quotabalanceresponse.balance || {}
if (Object.keys(quotaBalance).length > 0) {
quotaBalance.currency = `${quotaBalance.currency} ${quotaBalance.startquota}`
quotaBalance.startdate = moment(quotaBalance.startdate).format(this.pattern)
quotaBalance.account = this.$route.params.id ? this.$route.params.id : null
quotaBalance.domainid = this.$route.query.domainid ? this.$route.query.domainid : null
}
this.quotaResource = Object.assign({}, this.quotaResource, quotaBalance)
this.parentChangeResource(this.quotaResource)
}).finally(() => {
this.loading = false
})
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,60 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
<template>
<div>
<autogen-view ref="autogenview" />
<edit-tariff-value-wizard
v-if="tariffAction"
:showAction="tariffAction"
:resource="tariffResource" />
</div>
</template>
<script>
import AutogenView from '@/views/AutogenView.vue'
import EditTariffValueWizard from '@/views/plugins/quota/EditTariffValueWizard'
export default {
name: 'QuotaTariff',
components: {
AutogenView,
EditTariffValueWizard
},
data () {
return {
tariffAction: false,
tariffResource: {}
}
},
provide: function () {
return {
parentFetchData: this.fetchData,
parentEditTariffAction: this.showTariffAction
}
},
methods: {
fetchData () {
this.$refs.autogenview.fetchData()
},
showTariffAction (showAction, resource) {
this.tariffAction = showAction
this.tariffResource = resource
}
}
}
</script>

View File

@ -0,0 +1,157 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
<template>
<div>
<a-table
size="small"
:loading="loading"
:columns="columns"
:dataSource="dataSource"
:rowKey="record => record.name"
:pagination="false"
:scroll="{ y: '55vh' }"
>
<template slot="quota" slot-scope="text">
<span v-if="text!==undefined">{{ `${currency} ${text}` }}</span>
</template>
</a-table>
</div>
</template>
<script>
import { api } from '@/api'
import moment from 'moment'
export default {
name: 'QuotaUsage',
props: {
resource: {
type: Object,
required: true
},
tab: {
type: String,
default: () => ''
}
},
data () {
return {
loading: false,
dataSource: [],
pattern: 'YYYY-MM-DD',
currency: '',
totalQuota: 0,
account: null
}
},
computed: {
columns () {
return [
{
title: this.$t('label.quota.type.name'),
dataIndex: 'name',
width: 'calc(100% / 3)',
scopedSlots: { customRender: 'name' }
},
{
title: this.$t('label.quota.type.unit'),
dataIndex: 'unit',
width: 'calc(100% / 3)',
scopedSlots: { customRender: 'unit' }
},
{
title: this.$t('label.quota.usage'),
dataIndex: 'quota',
width: 'calc(100% / 3)',
scopedSlots: { customRender: 'quota' }
}
]
}
},
watch: {
tab (newTab, oldTab) {
this.tab = newTab
if (this.tab === 'quota.statement.quota') {
this.fetchData()
}
}
},
mounted () {
this.fetchData()
},
methods: {
async fetchData () {
this.loading = true
this.dataSource = []
this.account = this.$route.query && this.$route.query.account ? this.$route.query.account : null
try {
const resource = await this.quotaBalance()
const quotaStatement = await this.quotaStatement(resource)
const quotaUsage = quotaStatement.quotausage
this.dataSource = this.dataSource.concat(quotaUsage)
this.currency = quotaStatement.currency
this.totalQuota = quotaStatement.totalquota
this.dataSource.push({
name: `${this.$t('label.quota.total')}: `,
quota: this.totalQuota
})
this.dataSource.unshift({
type: 0,
name: `${this.$t('startdate')}: ${moment(this.resource.startdate).format(this.pattern)}`,
unit: `${this.$t('enddate')}: ${moment(this.resource.enddate).format(this.pattern)}`
})
this.loading = false
} catch (e) {
console.log(e)
this.loading = false
}
},
quotaBalance () {
return new Promise((resolve, reject) => {
const params = {}
params.domainid = this.resource.domainid
params.account = this.account
api('quotaBalance', params).then(json => {
const quotaBalance = json.quotabalanceresponse.balance || {}
resolve(quotaBalance)
}).catch(error => {
reject(error)
})
})
},
quotaStatement (resource) {
return new Promise((resolve, reject) => {
const params = {}
params.domainid = this.resource.domainid
params.account = this.account
params.startdate = moment(this.resource.startdate).format(this.pattern)
params.enddate = moment(resource.startdate).format(this.pattern)
api('quotaStatement', params).then(json => {
const quotaStatement = json.quotastatementresponse.statement || {}
resolve(quotaStatement)
}).catch(error => {
reject(error)
})
})
}
}
}
</script>