Rework skin library filter
This commit is contained in:
parent
0876d41421
commit
a1e38eec1f
|
|
@ -1,4 +1,6 @@
|
||||||
@import '~element-theme-chalk/src/button.scss';
|
@import '~element-theme-chalk/src/button.scss';
|
||||||
|
@import '~element-theme-chalk/src/button-group.scss';
|
||||||
|
@import '~element-theme-chalk/src/input.scss';
|
||||||
@import '~element-theme-chalk/src/message.scss';
|
@import '~element-theme-chalk/src/message.scss';
|
||||||
@import '~element-theme-chalk/src/message-box.scss';
|
@import '~element-theme-chalk/src/message-box.scss';
|
||||||
@import '~element-theme-chalk/src/progress.scss';
|
@import '~element-theme-chalk/src/progress.scss';
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Button from 'element-ui/lib/button'
|
import Button from 'element-ui/lib/button'
|
||||||
|
import ButtonGroup from 'element-ui/lib/button-group'
|
||||||
|
import Input from 'element-ui/lib/input'
|
||||||
import Message from 'element-ui/lib/message'
|
import Message from 'element-ui/lib/message'
|
||||||
import MessageBox from 'element-ui/lib/message-box'
|
import MessageBox from 'element-ui/lib/message-box'
|
||||||
|
|
||||||
Vue.use(Button)
|
Vue.use(Button)
|
||||||
|
Vue.use(ButtonGroup)
|
||||||
|
Vue.use(Input)
|
||||||
|
|
||||||
Vue.prototype.$message = Message
|
Vue.prototype.$message = Message
|
||||||
Vue.prototype.$msgbox = MessageBox
|
Vue.prototype.$msgbox = MessageBox
|
||||||
|
|
|
||||||
|
|
@ -23,84 +23,39 @@
|
||||||
<div class="box box-default">
|
<div class="box box-default">
|
||||||
<div class="box-header">
|
<div class="box-header">
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<div class="col-md-4">
|
<form class="col-md-6" @submit.prevent="fetchData">
|
||||||
<label>
|
<el-input
|
||||||
<input
|
v-model="keyword"
|
||||||
v-model="filter"
|
:placeholder="$t('vendor.datatable.search')"
|
||||||
type="radio"
|
clearable
|
||||||
name="filter"
|
>
|
||||||
value="skin"
|
<el-select slot="prepend" v-model="filter" class="texture-type-select">
|
||||||
>
|
<el-option :label="$t('general.skin')" value="skin" />
|
||||||
{{ $t('skinlib.anyModels') }}
|
<el-option label="Steve" value="steve" />
|
||||||
</label>
|
<el-option label="Alex" value="alex" />
|
||||||
<label>
|
<el-option :label="$t('general.cape')" value="cape" />
|
||||||
<input
|
</el-select>
|
||||||
v-model="filter"
|
<el-button slot="append" data-test="btn-search" @click="fetchData">
|
||||||
type="radio"
|
{{ $t('general.submit') }}
|
||||||
name="filter"
|
</el-button>
|
||||||
value="steve"
|
</el-input>
|
||||||
>
|
|
||||||
Steve
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<input
|
|
||||||
v-model="filter"
|
|
||||||
type="radio"
|
|
||||||
name="filter"
|
|
||||||
value="alex"
|
|
||||||
>
|
|
||||||
Alex
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<input
|
|
||||||
v-model="filter"
|
|
||||||
type="radio"
|
|
||||||
name="filter"
|
|
||||||
value="cape"
|
|
||||||
>
|
|
||||||
{{ $t('general.cape') }}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form class="col-md-4" @submit.prevent="fetchData">
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
v-model="keyword"
|
|
||||||
type="text"
|
|
||||||
:placeholder="$t('vendor.datatable.search')"
|
|
||||||
class="form-control"
|
|
||||||
>
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<button class="btn btn-success" @click="fetchData">
|
|
||||||
{{ $t('general.submit') }}
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="col-md-4">
|
<div class="col-md-6 advanced-filter">
|
||||||
<div class="btn-group filter-btn">
|
<el-button-group class="pull-right">
|
||||||
<button
|
<el-button plain @click="sort = 'likes'">
|
||||||
class="btn btn-primary dropdown-toggle"
|
{{ $t('skinlib.sort.likes') }}
|
||||||
data-toggle="dropdown"
|
</el-button>
|
||||||
aria-haspopup="true"
|
<el-button plain @click="sort = 'time'">
|
||||||
aria-expanded="false"
|
{{ $t('skinlib.sort.time') }}
|
||||||
>
|
</el-button>
|
||||||
{{ $t('skinlib.sort.title') }} <span class="caret" />
|
<el-button plain @click="uploader = currentUid">
|
||||||
</button>
|
{{ $t('skinlib.seeMyUpload') }}
|
||||||
<ul class="dropdown-menu">
|
</el-button>
|
||||||
<li><a v-t="'skinlib.sort.likes'" href="#" @click="sort = 'likes'" /></li>
|
<el-button type="info" plain @click="reset">
|
||||||
<li><a v-t="'skinlib.sort.time'" href="#" @click="sort = 'time'" /></li>
|
{{ $t('skinlib.reset') }}
|
||||||
</ul>
|
</el-button>
|
||||||
</div>
|
</el-button-group>
|
||||||
<a
|
|
||||||
v-if="currentUid"
|
|
||||||
class="btn btn-default btn-tail"
|
|
||||||
@click="uploader = currentUid"
|
|
||||||
>{{ $t('skinlib.seeMyUpload') }}</a>
|
|
||||||
<button class="btn btn-warning btn-tail" @click="reset">
|
|
||||||
{{ $t('skinlib.reset') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -154,10 +109,17 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Vue from 'vue'
|
||||||
import Paginate from 'vuejs-paginate'
|
import Paginate from 'vuejs-paginate'
|
||||||
|
import 'element-ui/lib/theme-chalk/select.css'
|
||||||
|
import Select from 'element-ui/lib/select'
|
||||||
|
import Option from 'element-ui/lib/option'
|
||||||
import { queryString } from '../../js/utils'
|
import { queryString } from '../../js/utils'
|
||||||
import SkinLibItem from '../../components/SkinLibItem.vue'
|
import SkinLibItem from '../../components/SkinLibItem.vue'
|
||||||
|
|
||||||
|
Vue.use(Select)
|
||||||
|
Vue.use(Option)
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SkinLibrary',
|
name: 'SkinLibrary',
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -191,8 +153,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
filter(value) {
|
filter() {
|
||||||
$(`[value="${value}"]`).iCheck('check')
|
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
},
|
},
|
||||||
uploader() {
|
uploader() {
|
||||||
|
|
@ -202,17 +163,6 @@ export default {
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
|
||||||
let available = true
|
|
||||||
const origin = this.fetchData
|
|
||||||
this.fetchData = () => {
|
|
||||||
if (available) {
|
|
||||||
available = false
|
|
||||||
setTimeout(() => (available = true), 50)
|
|
||||||
origin()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
},
|
},
|
||||||
|
|
@ -265,9 +215,12 @@ export default {
|
||||||
color #000
|
color #000
|
||||||
font-size 20px
|
font-size 20px
|
||||||
|
|
||||||
@media (min-width: 768px)
|
.texture-type-select
|
||||||
.filter-btn
|
width 90px
|
||||||
margin-left 25px
|
|
||||||
|
.advanced-filter
|
||||||
|
@media (max-width 850px)
|
||||||
|
display none
|
||||||
|
|
||||||
.btn-tail
|
.btn-tail
|
||||||
margin-left 6px
|
margin-left 6px
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import 'jest-extended'
|
import 'jest-extended'
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import { Button } from 'element-ui'
|
import {
|
||||||
|
Button,
|
||||||
|
Input,
|
||||||
|
} from 'element-ui'
|
||||||
|
|
||||||
window.blessing = {
|
window.blessing = {
|
||||||
base_url: '',
|
base_url: '',
|
||||||
|
|
@ -37,6 +40,7 @@ Vue.prototype.$http = {
|
||||||
}
|
}
|
||||||
|
|
||||||
Vue.use(Button)
|
Vue.use(Button)
|
||||||
|
Vue.use(Input)
|
||||||
Vue.prototype.$message = {
|
Vue.prototype.$message = {
|
||||||
info: jest.fn(),
|
info: jest.fn(),
|
||||||
success: jest.fn(),
|
success: jest.fn(),
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,48 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
|
import { Button } from 'element-ui'
|
||||||
import List from '@/views/skinlib/List.vue'
|
import List from '@/views/skinlib/List.vue'
|
||||||
|
|
||||||
|
jest.mock('element-ui/lib/select', () => ({
|
||||||
|
install(vue: typeof Vue) {
|
||||||
|
vue.component('ElSelect', {
|
||||||
|
render(h) {
|
||||||
|
return h('select', {
|
||||||
|
on: {
|
||||||
|
change: (event: Event) => this.$emit(
|
||||||
|
'change',
|
||||||
|
(event.target as HTMLSelectElement).value
|
||||||
|
),
|
||||||
|
},
|
||||||
|
attrs: {
|
||||||
|
value: this.value,
|
||||||
|
},
|
||||||
|
}, this.$slots.default)
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: String,
|
||||||
|
},
|
||||||
|
model: {
|
||||||
|
prop: 'value',
|
||||||
|
event: 'change',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
jest.mock('element-ui/lib/option', () => ({
|
||||||
|
install(vue: typeof Vue) {
|
||||||
|
vue.component('ElOption', {
|
||||||
|
render(h) {
|
||||||
|
return h('option', { attrs: { value: this.value } }, this.label)
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
label: String,
|
||||||
|
value: String,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
test('fetch data before mounting', () => {
|
test('fetch data before mounting', () => {
|
||||||
Vue.prototype.$http.get.mockResolvedValue({
|
Vue.prototype.$http.get.mockResolvedValue({
|
||||||
items: [], total_pages: 0, current_uid: 0,
|
items: [], total_pages: 0, current_uid: 0,
|
||||||
|
|
@ -27,17 +68,13 @@ test('toggle texture type', () => {
|
||||||
Vue.prototype.$http.get.mockResolvedValue({
|
Vue.prototype.$http.get.mockResolvedValue({
|
||||||
items: [], total_pages: 0, current_uid: 0,
|
items: [], total_pages: 0, current_uid: 0,
|
||||||
})
|
})
|
||||||
window.$ = jest.fn(() => ({
|
|
||||||
iCheck() {},
|
|
||||||
}))
|
|
||||||
const wrapper = mount(List)
|
const wrapper = mount(List)
|
||||||
|
const select = wrapper.find({ name: 'ElSelect' })
|
||||||
const breadcrumb = wrapper.find('.breadcrumb')
|
const breadcrumb = wrapper.find('.breadcrumb')
|
||||||
|
|
||||||
jest.runAllTimers()
|
|
||||||
expect(breadcrumb.text()).toContain('skinlib.filter.skin')
|
expect(breadcrumb.text()).toContain('skinlib.filter.skin')
|
||||||
|
|
||||||
wrapper.find('[value=steve]').setChecked()
|
select.setValue('steve')
|
||||||
jest.runAllTimers()
|
select.trigger('change')
|
||||||
expect(breadcrumb.text()).toContain('skinlib.filter.steve')
|
expect(breadcrumb.text()).toContain('skinlib.filter.steve')
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||||
'/skinlib/data',
|
'/skinlib/data',
|
||||||
|
|
@ -45,8 +82,8 @@ test('toggle texture type', () => {
|
||||||
filter: 'steve', uploader: 0, sort: 'time', keyword: '', page: 1,
|
filter: 'steve', uploader: 0, sort: 'time', keyword: '', page: 1,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
wrapper.find('[value=alex]').setChecked()
|
select.setValue('alex')
|
||||||
jest.runAllTimers()
|
select.trigger('change')
|
||||||
expect(breadcrumb.text()).toContain('skinlib.filter.alex')
|
expect(breadcrumb.text()).toContain('skinlib.filter.alex')
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||||
'/skinlib/data',
|
'/skinlib/data',
|
||||||
|
|
@ -54,8 +91,8 @@ test('toggle texture type', () => {
|
||||||
filter: 'alex', uploader: 0, sort: 'time', keyword: '', page: 1,
|
filter: 'alex', uploader: 0, sort: 'time', keyword: '', page: 1,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
wrapper.find('[value=cape]').setChecked()
|
select.setValue('cape')
|
||||||
jest.runAllTimers()
|
select.trigger('change')
|
||||||
expect(breadcrumb.text()).toContain('general.cape')
|
expect(breadcrumb.text()).toContain('general.cape')
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||||
'/skinlib/data',
|
'/skinlib/data',
|
||||||
|
|
@ -72,9 +109,10 @@ test('check specified uploader', async () => {
|
||||||
const wrapper = mount(List)
|
const wrapper = mount(List)
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
const breadcrumb = wrapper.find('.breadcrumb')
|
const breadcrumb = wrapper.find('.breadcrumb')
|
||||||
const button = wrapper.find('.btn-default')
|
const button = wrapper
|
||||||
|
.find('.advanced-filter')
|
||||||
jest.runAllTimers()
|
.findAll(Button)
|
||||||
|
.at(2)
|
||||||
expect(breadcrumb.text()).toContain('skinlib.filter.allUsers')
|
expect(breadcrumb.text()).toContain('skinlib.filter.allUsers')
|
||||||
|
|
||||||
button.trigger('click')
|
button.trigger('click')
|
||||||
|
|
@ -92,9 +130,9 @@ test('sort items', () => {
|
||||||
items: [], total_pages: 0, current_uid: 0,
|
items: [], total_pages: 0, current_uid: 0,
|
||||||
})
|
})
|
||||||
const wrapper = mount(List)
|
const wrapper = mount(List)
|
||||||
const sortByLikes = wrapper.find('.dropdown-menu > li:nth-child(1) > a')
|
const buttons = wrapper.find('.advanced-filter').findAll(Button)
|
||||||
const sortByTime = wrapper.find('.dropdown-menu > li:nth-child(2) > a')
|
const sortByLikes = buttons.at(0)
|
||||||
jest.runAllTimers()
|
const sortByTime = buttons.at(1)
|
||||||
|
|
||||||
sortByLikes.trigger('click')
|
sortByLikes.trigger('click')
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||||
|
|
@ -104,7 +142,6 @@ test('sort items', () => {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
expect(wrapper.text()).toContain('skinlib.sort.likes')
|
expect(wrapper.text()).toContain('skinlib.sort.likes')
|
||||||
jest.runAllTimers()
|
|
||||||
|
|
||||||
sortByTime.trigger('click')
|
sortByTime.trigger('click')
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||||
|
|
@ -121,10 +158,8 @@ test('search by keyword', () => {
|
||||||
items: [], total_pages: 0, current_uid: 0,
|
items: [], total_pages: 0, current_uid: 0,
|
||||||
})
|
})
|
||||||
const wrapper = mount(List)
|
const wrapper = mount(List)
|
||||||
const searchBox = wrapper.find('input[type=text]')
|
|
||||||
jest.runAllTimers()
|
|
||||||
|
|
||||||
searchBox.setValue('a')
|
wrapper.setData({ keyword: 'a' })
|
||||||
wrapper.find('form').trigger('submit')
|
wrapper.find('form').trigger('submit')
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||||
'/skinlib/data',
|
'/skinlib/data',
|
||||||
|
|
@ -132,10 +167,9 @@ test('search by keyword', () => {
|
||||||
filter: 'skin', uploader: 0, sort: 'time', keyword: 'a', page: 1,
|
filter: 'skin', uploader: 0, sort: 'time', keyword: 'a', page: 1,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
jest.runAllTimers()
|
|
||||||
|
|
||||||
searchBox.setValue('b')
|
wrapper.setData({ keyword: 'b' })
|
||||||
wrapper.find('.input-group-btn > button').trigger('click')
|
wrapper.find('[data-test="btn-search"]').trigger('click')
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||||
'/skinlib/data',
|
'/skinlib/data',
|
||||||
{
|
{
|
||||||
|
|
@ -145,23 +179,18 @@ test('search by keyword', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('reset all filters', () => {
|
test('reset all filters', () => {
|
||||||
window.$ = jest.fn(() => ({
|
|
||||||
iCheck() {},
|
|
||||||
}))
|
|
||||||
Vue.prototype.$http.get.mockResolvedValue({
|
Vue.prototype.$http.get.mockResolvedValue({
|
||||||
items: [], total_pages: 0, current_uid: 0,
|
items: [], total_pages: 0, current_uid: 0,
|
||||||
})
|
})
|
||||||
const wrapper = mount(List)
|
const wrapper = mount(List)
|
||||||
jest.runAllTimers()
|
wrapper.findAll('option').at(3)
|
||||||
wrapper.find('input[value=cape]').setChecked()
|
.setSelected()
|
||||||
jest.runAllTimers()
|
wrapper.setData({ keyword: 'abc' })
|
||||||
wrapper.find('input[type=text]').setValue('abc')
|
const buttons = wrapper.find('.advanced-filter').findAll(Button)
|
||||||
jest.runAllTimers()
|
buttons.at(1).trigger('click')
|
||||||
wrapper.find('.dropdown-menu > li:nth-child(1) > a').trigger('click')
|
|
||||||
jest.runAllTimers()
|
|
||||||
|
|
||||||
Vue.prototype.$http.get.mockClear()
|
Vue.prototype.$http.get.mockClear()
|
||||||
wrapper.find('.btn-warning').trigger('click')
|
buttons.at(3).trigger('click')
|
||||||
expect(Vue.prototype.$http.get).toBeCalledTimes(1)
|
expect(Vue.prototype.$http.get).toBeCalledTimes(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -178,7 +207,6 @@ test('on page changed', () => {
|
||||||
items: [], total_pages: 0, current_uid: 0,
|
items: [], total_pages: 0, current_uid: 0,
|
||||||
})
|
})
|
||||||
const wrapper = mount<Vue & { pageChanged(page: number): void }>(List)
|
const wrapper = mount<Vue & { pageChanged(page: number): void }>(List)
|
||||||
jest.runAllTimers()
|
|
||||||
wrapper.vm.pageChanged(2)
|
wrapper.vm.pageChanged(2)
|
||||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||||
'/skinlib/data',
|
'/skinlib/data',
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,7 @@ skinlib:
|
||||||
emptyItemName: Empty texture name.
|
emptyItemName: Empty texture name.
|
||||||
setNewTextureName: 'Please enter the new texture name:'
|
setNewTextureName: 'Please enter the new texture name:'
|
||||||
emptyNewTextureName: Empty new texture name.
|
emptyNewTextureName: Empty new texture name.
|
||||||
anyModels: Any Models
|
seeMyUpload: My Uploads
|
||||||
seeMyUpload: Check My Upload
|
|
||||||
apply: Quick Apply
|
apply: Quick Apply
|
||||||
filter:
|
filter:
|
||||||
skin: (Any Model)
|
skin: (Any Model)
|
||||||
|
|
@ -59,7 +58,7 @@ skinlib:
|
||||||
allUsers: All Users
|
allUsers: All Users
|
||||||
sort:
|
sort:
|
||||||
title: Sort
|
title: Sort
|
||||||
time: Newestly Uploaded
|
time: Latest
|
||||||
likes: Most Likes
|
likes: Most Likes
|
||||||
badSkinSize: The size of selected skin file is not valid
|
badSkinSize: The size of selected skin file is not valid
|
||||||
badCapeSize: The size of selected cape file is not valid
|
badCapeSize: The size of selected cape file is not valid
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,7 @@ skinlib:
|
||||||
emptyItemName: 你还没有填写要收藏的材质名称啊
|
emptyItemName: 你还没有填写要收藏的材质名称啊
|
||||||
anonymous: 请先登录
|
anonymous: 请先登录
|
||||||
private: 私密
|
private: 私密
|
||||||
anyModels: 任意模型
|
seeMyUpload: 我上传的
|
||||||
seeMyUpload: 查看我上传的
|
|
||||||
apply: 立即使用
|
apply: 立即使用
|
||||||
filter:
|
filter:
|
||||||
skin: (任意模型)
|
skin: (任意模型)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user