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