@@ -140,7 +140,11 @@ export default { | |||
modals.openLogin(this, this.onLoginSucceed); | |||
}, | |||
createPin() { | |||
modals.openPinCreate(this, this.onPinCreated); | |||
modals.openPinCreate( | |||
this, | |||
this.onPinCreated, | |||
{ username: this.user.meta.username }, | |||
); | |||
}, | |||
createBoard() { | |||
modals.openBoardCreate(this); | |||
@@ -23,6 +23,10 @@ const Board = { | |||
}, | |||
); | |||
}, | |||
fetchFullList(username) { | |||
const url = `${API_PREFIX}boards-auto-complete/?submitter__username=${username}`; | |||
return axios.get(url); | |||
}, | |||
}; | |||
const Pin = { | |||
@@ -4,11 +4,12 @@ import SignUpForm from './SignUpForm.vue'; | |||
import BoardEdit from './BoardEdit.vue'; | |||
function openPinCreate(vm, onCreate) { | |||
function openPinCreate(vm, onCreate, props = null) { | |||
vm.$buefy.modal.open( | |||
{ | |||
parent: vm, | |||
component: PinCreateModal, | |||
props, | |||
hasModalCard: true, | |||
events: { | |||
'create.succeed': onCreate, | |||
@@ -0,0 +1,89 @@ | |||
<template> | |||
<div class="filter-select"> | |||
<b-field label="Select Board" | |||
:type="form.board.type" | |||
:message="form.board.error"> | |||
<b-input | |||
type="text" | |||
v-model="form.board.value" | |||
placeholder="Type to filter or Create one" | |||
maxlength="128" | |||
> | |||
</b-input> | |||
</b-field> | |||
<b-field> | |||
<button | |||
class="button is-primary"> | |||
Create New Board | |||
</button> | |||
</b-field> | |||
<b-field> | |||
<b-select | |||
class="select-list" | |||
multiple | |||
expanded | |||
native-size="8" | |||
v-model="selectedOptions"> | |||
<template v-for="option in availableOptions"> | |||
<option | |||
v-bind:key="option.value" | |||
:value="option.value">{{ option.name }}</option> | |||
</template> | |||
</b-select> | |||
</b-field> | |||
</div> | |||
</template> | |||
<script> | |||
// import API from '../api'; | |||
import ModelForm from '../utils/ModelForm'; | |||
const fields = ['board']; | |||
function getFilteredOptions(options, filterText) { | |||
return options.filter( | |||
(option) => { | |||
const index = option.name | |||
.toString() | |||
.toLowerCase() | |||
.indexOf(filterText.toLowerCase()); | |||
return index >= 0; | |||
}, | |||
); | |||
} | |||
export default { | |||
name: 'FilterSelect', | |||
props: { | |||
allOptions: { | |||
type: Array, | |||
default() { | |||
return []; | |||
}, | |||
}, | |||
}, | |||
data() { | |||
const model = ModelForm.fromFields(fields); | |||
return { | |||
form: model.form, | |||
selectedOptions: [], | |||
helper: model, | |||
availableOptions: [], | |||
}; | |||
}, | |||
watch: { | |||
'form.board.value': function (newVal) { | |||
if (newVal === '' || newVal === null) { | |||
this.availableOptions = this.allOptions; | |||
} else { | |||
this.availableOptions = getFilteredOptions( | |||
this.allOptions, this.form.board.value, | |||
); | |||
} | |||
}, | |||
allOptions() { | |||
this.availableOptions = this.allOptions; | |||
}, | |||
}, | |||
}; | |||
</script> |
@@ -24,7 +24,7 @@ | |||
v-model="form.url.value" | |||
placeholder="where to fetch the image" | |||
maxlength="256" | |||
> | |||
> | |||
</b-input> | |||
</b-field> | |||
<b-field label="Image Referer" | |||
@@ -35,7 +35,7 @@ | |||
v-model="form.referer.value" | |||
placeholder="where to find the pin" | |||
maxlength="256" | |||
> | |||
> | |||
</b-input> | |||
</b-field> | |||
<b-field label="Descripton" | |||
@@ -46,7 +46,7 @@ | |||
v-model="form.description.value" | |||
placeholder="idea from this pin" | |||
maxlength="1024" | |||
> | |||
> | |||
</b-input> | |||
</b-field> | |||
<b-field label="Tags"> | |||
@@ -58,6 +58,9 @@ | |||
</b-taginput> | |||
</b-field> | |||
</div> | |||
<div class="column"> | |||
<FilterSelect :allOptions="boardOptions"></FilterSelect> | |||
</div> | |||
</div> | |||
</section> | |||
<footer class="modal-card-foot"> | |||
@@ -75,6 +78,7 @@ | |||
<script> | |||
import API from '../api'; | |||
import FileUpload from './FileUpload.vue'; | |||
import FilterSelect from './FilterSelect.vue'; | |||
import bus from '../utils/bus'; | |||
import ModelForm from '../utils/ModelForm'; | |||
@@ -86,8 +90,10 @@ const fields = ['url', 'referer', 'description', 'tags']; | |||
export default { | |||
name: 'PinCreateModal', | |||
props: ['username'], | |||
components: { | |||
FileUpload, | |||
FilterSelect, | |||
}, | |||
data() { | |||
const form = ModelForm.createFormModel(fields); | |||
@@ -98,9 +104,30 @@ export default { | |||
formUpload: { | |||
imageId: null, | |||
}, | |||
boardOptions: [], | |||
}; | |||
}, | |||
created() { | |||
this.fetchBoardList(); | |||
}, | |||
methods: { | |||
fetchBoardList() { | |||
API.Board.fetchFullList(this.username).then( | |||
(resp) => { | |||
const boardOptions = []; | |||
resp.data.forEach( | |||
(board) => { | |||
const boardOption = { name: board.name, value: board.id }; | |||
boardOptions.push(boardOption); | |||
}, | |||
); | |||
this.boardOptions = boardOptions; | |||
}, | |||
() => { | |||
console.log('Error occurs while fetch board full list'); | |||
}, | |||
); | |||
}, | |||
onUploadProcessing() { | |||
this.disableUrlField = true; | |||
}, | |||