Newer
Older
<div class="ui vertical stripe segment" v-title="'Radio Builder'">
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<div>
<div>
<h2 class="ui header">Builder</h2>
<p>
You can use this interface to build your own custom radio, which
will play tracks according to your criteria
</p>
<div class="ui form">
<div class="inline fields">
<div class="field">
<label for="name">Radio name</label>
<input id="name" type="text" v-model="radioName" placeholder="My awesome radio" />
</div>
<div class="field">
<input id="public" type="checkbox" v-model="isPublic" />
<label for="public">Display publicly</label>
</div>
<button :disabled="!canSave" @click="save" class="ui green button">Save</button>
<radio-button v-if="id" type="custom" :custom-radio-id="id"></radio-button>
</div>
</div>
<div class="ui form">
<p>Add filters to customize your radio</p>
<div class="inline field">
<select class="ui dropdown" v-model="currentFilterType">
<option value="">Select a filter</option>
<option v-for="f in availableFilters" :value="f.type">{{ f.label }}</option>
</select>
<button :disabled="!currentFilterType" @click="add" class="ui button">Add filter</button>
</div>
<p v-if="currentFilter">
{{ currentFilter.help_text }}
</p>
</div>
<table class="ui table">
<thead>
<tr>
<th class="two wide">Filter name</th>
<th class="one wide">Exclude</th>
<th class="six wide">Config</th>
<th class="five wide">Candidates</th>
<th class="two wide">Actions</th>
</tr>
</thead>
<tbody>
<builder-filter
v-for="(f, index) in filters"
:key="(f, index, f.hash)"
:index="index"
@update-config="updateConfig"
@delete="deleteFilter"
:config="f.config"
:filter="f.filter">
</builder-filter>
</tbody>
</table>
<template v-if="checkResult">
<h3 class="ui header">
{{ checkResult.candidates.count }} tracks matching combined filters
</h3>
<track-table v-if="checkResult.candidates.sample" :tracks="checkResult.candidates.sample"></track-table>
</template>
</div>
</div>
</div>
</template>
<script>
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import $ from 'jquery'
import _ from 'lodash'
import BuilderFilter from './Filter'
import TrackTable from '@/components/audio/track/Table'
import RadioButton from '@/components/radios/Button'
export default {
props: {
id: {required: false}
},
components: {
BuilderFilter,
TrackTable,
RadioButton
},
data: function () {
return {
availableFilters: [],
currentFilterType: null,
filters: [],
checkResult: null,
radioName: '',
isPublic: true
}
},
created: function () {
let self = this
this.fetchFilters().then(() => {
if (self.id) {
self.fetch()
}
})
},
mounted () {
$('.ui.dropdown').dropdown()
},
methods: {
fetchFilters: function () {
let self = this
let url = 'radios/radios/filters/'
return axios.get(url).then((response) => {
self.availableFilters = response.data
})
},
add () {
this.filters.push({
config: {},
filter: this.currentFilter,
hash: +new Date()
})
this.fetchCandidates()
},
updateConfig (index, field, value) {
this.filters[index].config[field] = value
this.fetchCandidates()
},
deleteFilter (index) {
this.filters.splice(index, 1)
this.fetchCandidates()
},
fetch: function () {
let self = this
let url = 'radios/radios/' + this.id + '/'
axios.get(url).then((response) => {
self.filters = response.data.config.map(f => {
return {
config: f,
filter: this.availableFilters.filter(e => { return e.type === f.type })[0],
hash: +new Date()
}
})
self.radioName = response.data.name
self.isPublic = response.data.is_public
})
},
fetchCandidates: function () {
let self = this
let final = this.filters.map(f => {
let c = _.clone(f.config)
c.type = f.filter.type
return c
})
final = {
'filters': [
{'type': 'group', filters: final}
]
}
axios.post(url, final).then((response) => {
self.checkResult = response.data.filters[0]
})
},
save: function () {
let self = this
let final = this.filters.map(f => {
let c = _.clone(f.config)
c.type = f.filter.type
return c
})
final = {
'name': this.radioName,
'is_public': this.isPublic,
'config': final
}
if (this.id) {
let url = 'radios/radios/' + this.id + '/'
axios.put(url, final).then((response) => {
let url = 'radios/radios/'
axios.post(url, final).then((response) => {
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
params: {
id: response.data.id
}
})
})
}
}
},
computed: {
canSave: function () {
return (
this.radioName.length > 0 && this.checkErrors.length === 0
)
},
checkErrors: function () {
if (!this.checkResult) {
return []
}
let errors = this.checkResult.errors
return errors
},
currentFilter: function () {
let self = this
return this.availableFilters.filter(e => {
return e.type === self.currentFilterType
})[0]
}
},
watch: {
filters: {
handler: function () {
this.fetchCandidates()
},
deep: true
}
}
}
</script>