cloudstack/ui/src/components/view/ActionButton.vue
Hoang Nguyen 338de72665 Explore Test Automation (#320)
* config jest and add setup for unittest

* config jest coverage

* example of unit testing a Status widget/component

* add license for test file

* add test/run command in the .travis.yml

* add mock store and i18n for vue jest

* add mock file missing

* add mock router

* add lincence to mock file & decodeHtml to setup file

* add mock axios instance & fix eslint on tests folder

* add test components > views > ActionButton component

* fix for test coverage success

* refactor test file

* add test Views > Autogenview.vue (Navigation Guard, Watchers, Computed)

* history mode mockRouter, refactor test code, test Autogenview > fetchData (routeName)

* test Views > AutogenView.vue (processing 31%)

* add mock router exception & test Views > AutogenView.vue (processing 43%)

* test Views > AutogenView (processing 65%), add test onSearch, closeAction, execAction, listUuidOpts

* refactor and add comment test files

* test Views > AutogenView (processing 91%)

* add comment file AutogenView.spec.js

* test Views > AutogenView.vue (handleSubmit method)

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
2021-01-20 07:06:24 +05:30

193 lines
5.9 KiB
Vue

// 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>
<span class="row-action-button">
<console :resource="resource" :size="size" v-if="resource && resource.id && dataView" />
<a-tooltip
v-for="(action, actionIndex) in actions"
:key="actionIndex"
arrowPointAtCenter
placement="bottomRight">
<template slot="title">
{{ $t(action.label) }}
</template>
<a-badge
class="button-action-badge"
:overflowCount="9"
:count="actionBadge[action.api] ? actionBadge[action.api].badgeNum : 0"
v-if="action.api in $store.getters.apis &&
action.showBadge && (
(!dataView && ((action.listView && ('show' in action ? action.show(resource, $store.getters) : true)) || (action.groupAction && selectedRowKeys.length > 0 && ('groupShow' in action ? action.show(resource, $store.getters) : true)))) ||
(dataView && action.dataView && ('show' in action ? action.show(resource, $store.getters) : true))
)" >
<a-button
:type="action.icon === 'delete' ? 'danger' : (action.icon === 'plus' ? 'primary' : 'default')"
:shape="!dataView && action.icon === 'plus' ? 'round' : 'circle'"
style="margin-left: 5px"
:size="size"
@click="execAction(action)">
<span v-if="!dataView && action.icon === 'plus'">
{{ $t(action.label) }}
</span>
<a-icon v-if="(typeof action.icon === 'string')" :type="action.icon" />
<font-awesome-icon v-else :icon="action.icon" />
</a-button>
</a-badge>
<a-button
v-if="action.api in $store.getters.apis &&
!action.showBadge && (
(!dataView && ((action.listView && ('show' in action ? action.show(resource, $store.getters) : true)) || (action.groupAction && selectedRowKeys.length > 0 && ('groupShow' in action ? action.show(resource, $store.getters) : true)))) ||
(dataView && action.dataView && ('show' in action ? action.show(resource, $store.getters) : true))
)"
:type="action.icon === 'delete' ? 'danger' : (action.icon === 'plus' ? 'primary' : 'default')"
:shape="!dataView && ['plus', 'user-add'].includes(action.icon) ? 'round' : 'circle'"
style="margin-left: 5px"
:size="size"
@click="execAction(action)">
<span v-if="!dataView && ['plus', 'user-add'].includes(action.icon)">
{{ $t(action.label) }}
</span>
<a-icon v-if="(typeof action.icon === 'string')" :type="action.icon" />
<font-awesome-icon v-else :icon="action.icon" />
</a-button>
</a-tooltip>
</span>
</template>
<script>
import { api } from '@/api'
import Console from '@/components/widgets/Console'
export default {
name: 'ActionButton',
components: {
Console
},
data () {
return {
actionBadge: {}
}
},
mounted () {
this.handleShowBadge()
},
props: {
actions: {
type: Array,
default () {
return []
}
},
resource: {
type: Object,
default () {
return {}
}
},
dataView: {
type: Boolean,
default: false
},
selectedRowKeys: {
type: Array,
default () {
return []
}
},
loading: {
type: Boolean,
default: false
},
size: {
type: String,
default: 'default'
}
},
watch: {
resource (newItem, oldItem) {
if (!newItem || !newItem.id) {
return
}
this.handleShowBadge()
}
},
methods: {
execAction (action) {
action.resource = this.resource
this.$emit('exec-action', action)
},
handleShowBadge () {
this.actionBadge = {}
const arrAsync = []
const actionBadge = this.actions.filter(action => action.showBadge === true)
if (actionBadge && actionBadge.length > 0) {
const dataLength = actionBadge.length
for (let i = 0; i < dataLength; i++) {
const action = actionBadge[i]
arrAsync.push(new Promise((resolve, reject) => {
api(action.api, action.param).then(json => {
let responseJsonName
const response = {}
response.api = action.api
response.count = 0
for (const key in json) {
if (key.includes('response')) {
responseJsonName = key
break
}
}
if (json[responseJsonName] && json[responseJsonName].count && json[responseJsonName].count > 0) {
response.count = json[responseJsonName].count
}
resolve(response)
}).catch(error => {
reject(error)
})
}))
}
Promise.all(arrAsync).then(response => {
for (let j = 0; j < response.length; j++) {
this.$set(this.actionBadge, response[j].api, {})
this.$set(this.actionBadge[response[j].api], 'badgeNum', response[j].count)
}
}).catch(() => {})
}
}
}
}
</script>
<style scoped >
.button-action-badge {
margin-left: 5px;
}
/deep/.button-action-badge .ant-badge-count {
right: 10px;
z-index: 8;
}
</style>