331 lines
10 KiB
Vue
331 lines
10 KiB
Vue
<template>
|
|
<div>
|
|
<form class="ui form" :class="{ loading: loading }" @submit.prevent="insertNewBook">
|
|
<div class="field">
|
|
<label v-lang.books.gridColumns.title></label>
|
|
<input name="title" :placeholder="langBooks.gridColumns.title" type="text" v-model="book.Title" required v-focus>
|
|
</div>
|
|
<div class="three fields">
|
|
<div class="field">
|
|
<label v-lang.books.gridColumns.isbn></label>
|
|
<input name="isbn" :placeholder="langBooks.gridColumns.isbn" type="text" v-model="book.Isbn">
|
|
</div>
|
|
<div class="field">
|
|
<label v-lang.books.gridColumns.price></label>
|
|
<div class="ui right labeled input ">
|
|
<input name="price" :placeholder="langBooks.gridColumns.price" type="number" step="0.01" min="0" v-model.number="book.Price">
|
|
<label class="ui label">€</label>
|
|
</div>
|
|
</div>
|
|
<div class="field">
|
|
<label v-lang.books.gridColumns.year></label>
|
|
<input name="year" :placeholder="langBooks.gridColumns.year" type="number" step="1" min="1800" v-model.number="book.Year">
|
|
</div>
|
|
<div class="field">
|
|
<label v-lang.books.gridColumns.quantity></label>
|
|
<input :placeholder="langBooks.gridColumns.quantity" type="number" min="0" step="1" v-model.number="book.Quantity">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="field" v-if="!addPublisherForm">
|
|
<label v-lang.books.gridColumns.publisher></label>
|
|
<a class="ui green icon button add-publisher-btn" @click="toggleAddPublisher()"><i class="plus icon"></i></a>
|
|
<multiselect
|
|
v-model="book.PublisherFull"
|
|
track-by="ID"
|
|
:label="langGeneral.name"
|
|
:placeholder="langGeneral.selectOne"
|
|
:options="publishers"
|
|
:searchable="true"
|
|
:allow-empty="false"
|
|
class="add-btn-input">
|
|
</multiselect>
|
|
</div>
|
|
<div class="field" v-if="addPublisherForm">
|
|
<label v-lang.publishers.newPublisher></label>
|
|
<a class="ui green icon button add-publisher-btn" @click="toggleAddPublisher()"><i class="list icon"></i></a>
|
|
<input name="name" :placeholder="langPublishers.newPublisher" type="text" v-model="book.PublisherFull.Name" class="add-publisher">
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label>Authors</label>
|
|
<multiselect
|
|
v-model="book.Authors"
|
|
track-by="ID"
|
|
:label="langGeneral.name"
|
|
:placeholder="langGeneral.selectOneOrMore"
|
|
:options="authors"
|
|
:searchable="true"
|
|
:multiple="true"
|
|
:allow-empty="false">
|
|
</multiselect>
|
|
</div>
|
|
|
|
<template v-for="(inputModel, index) in addAuthorForm">
|
|
<div class="field" v-if="addAuthorForm">
|
|
<label v-lang.authors.newAuthor></label>
|
|
<a class="ui red icon button add-publisher-btn" @click="removeAuthor(index)"><i class="cancel icon"></i></a>
|
|
<input name="name" :placeholder="langBooks.gridColumns.authors" v-model="newAuthors[inputModel.modelName]" type="text" class="add-publisher">
|
|
</div>
|
|
</template>
|
|
|
|
<div class="field">
|
|
<a class="ui green icon button" @click="addAddAuthor()"><i class="plus icon"></i> <span v-lang.author.newAuthor></span></a>
|
|
</div>
|
|
|
|
<div class="inline fields">
|
|
<label v-lang.books.gridColumns.status></label>
|
|
<div class="field" v-for="status in allStatus">
|
|
<div class="ui radio checkbox">
|
|
<input name="status" :id="status.ID" :value="status.ID" class="hidden" type="radio" v-model="book.Status"/>
|
|
<label :for="status.ID">{{ status.Name }}</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<button class="ui blue button" type="submit" v-lang.general.submit></button>
|
|
</form>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import {HTTP} from '../http-common'
|
|
import router from '../router'
|
|
|
|
export default {
|
|
name: 'BooksAddEdit',
|
|
data () {
|
|
return {
|
|
loading: false,
|
|
bookID: this.$route.params.id,
|
|
edit: false,
|
|
book: {
|
|
Title: '',
|
|
Isbn: '',
|
|
Year: (new Date()).getFullYear(),
|
|
Price: 0,
|
|
Status: 0,
|
|
Quantity: 0,
|
|
PublisherFull: {
|
|
ID: 0,
|
|
Name: ''
|
|
},
|
|
Authors: []
|
|
},
|
|
publishers: [],
|
|
authors: [],
|
|
addPublisherForm: false,
|
|
addAuthorForm: [],
|
|
newAuthors: {},
|
|
newestAuthor: 0,
|
|
allStatus: []
|
|
}
|
|
},
|
|
computed: {
|
|
langBooks () {
|
|
return this.translate('books')
|
|
},
|
|
langPublishers () {
|
|
return this.translate('publishers')
|
|
},
|
|
langGeneral () {
|
|
return this.translate('general')
|
|
}
|
|
},
|
|
created () {
|
|
this.loading = true
|
|
this.loadPublishers()
|
|
this.loadAuthors()
|
|
this.loadStatus()
|
|
|
|
// Look if we're in edit mode and get the book infos if nessesary
|
|
if (this.bookID) {
|
|
HTTP.get('books/' + this.bookID)
|
|
.then(response => {
|
|
this.book = response.data
|
|
this.edit = true
|
|
|
|
// Loop through all authors and reverse them
|
|
let as = this.book.Authors
|
|
|
|
for (const i in as) {
|
|
this.book.Authors[i] = {
|
|
ID: as[i].ID,
|
|
Name: as[i].Forename + ' ' + as[i].Lastname
|
|
}
|
|
}
|
|
})
|
|
.catch(e => {
|
|
this.errorNotification(e)
|
|
})
|
|
}
|
|
this.loading = false
|
|
},
|
|
methods: {
|
|
errorNotification (e) {
|
|
// Build the notification text from error response
|
|
let err = e.message
|
|
if (e.response.data) {
|
|
err += '<br/>' + e.response.data.Message
|
|
}
|
|
|
|
// Fire a notification
|
|
this.$notify({
|
|
type: 'error',
|
|
title: this.langGeneral.error,
|
|
text: err
|
|
})
|
|
},
|
|
loadPublishers: function () {
|
|
HTTP.get('publishers')
|
|
.then(response => {
|
|
this.publishers = response.data
|
|
})
|
|
.catch(e => {
|
|
this.errorNotification(e)
|
|
})
|
|
},
|
|
loadAuthors: function () {
|
|
HTTP.get('authors')
|
|
.then(response => {
|
|
let as = response.data
|
|
|
|
for (const i in as) {
|
|
this.authors[i] = {
|
|
ID: as[i].ID,
|
|
Name: as[i].Forename + ' ' + as[i].Lastname
|
|
}
|
|
}
|
|
})
|
|
.catch(e => {
|
|
this.errorNotification(e)
|
|
})
|
|
},
|
|
loadStatus: function () {
|
|
HTTP.get('status')
|
|
.then(response => {
|
|
this.allStatus = response.data
|
|
})
|
|
.catch(e => {
|
|
this.errorNotification(e)
|
|
})
|
|
},
|
|
toggleAddPublisher: function () {
|
|
this.addPublisherForm = !this.addPublisherForm
|
|
this.book.PublisherFull = {ID: 0, Name: ''}
|
|
},
|
|
addAddAuthor: function () {
|
|
this.addAuthorForm.push({
|
|
modelName: 'newAuthor' + this.newestAuthor
|
|
})
|
|
this.newestAuthor++
|
|
},
|
|
removeAuthor: function (i) {
|
|
delete this.newAuthors[this.addAuthorForm[i].modelName]
|
|
this.addAuthorForm.splice(i, 1)
|
|
},
|
|
insertNewBook: function () {
|
|
if (this.book.Title === '') {
|
|
// Fire a notification
|
|
this.$notify({
|
|
type: 'warn',
|
|
text: this.translate('books').errorNoTitle
|
|
})
|
|
} else {
|
|
this.loading = true
|
|
|
|
// Add all newly created authors to it
|
|
let as = this.newAuthors
|
|
|
|
for (const i in as) {
|
|
this.book.Authors.push({
|
|
ID: 0,
|
|
Name: as[i]
|
|
})
|
|
}
|
|
|
|
// Beautify all Authors aka split the names in forename and lastname
|
|
for (const i in this.book.Authors) {
|
|
let author = this.book.Authors[i].Name
|
|
let firstname = ''
|
|
let lastname = ''
|
|
|
|
// Check if the name contains a space, if so split it up
|
|
if ((new RegExp(' ')).test(author)) {
|
|
let split = author.indexOf(' ')
|
|
let splits = [author.slice(0, split), author.slice(split + 1)]
|
|
firstname = splits[0]
|
|
lastname = splits[1]
|
|
} else {
|
|
lastname = author
|
|
}
|
|
|
|
// Put it all together
|
|
this.book.Authors[i] = {
|
|
ID: this.book.Authors[i].ID,
|
|
Forename: firstname,
|
|
Lastname: lastname
|
|
}
|
|
}
|
|
|
|
// Finally Send it
|
|
// If we want to newly insert it, make a different request
|
|
if (this.edit) {
|
|
HTTP.post('books/' + this.book.ID, {book: this.book})
|
|
.then(response => {
|
|
this.loading = false
|
|
|
|
// Fire a notification
|
|
this.$notify({
|
|
type: 'success',
|
|
title: this.translate('general').success,
|
|
text: this.translate('books').updatedSuccess
|
|
})
|
|
})
|
|
.catch(e => {
|
|
this.loading = false
|
|
this.errorNotification(e)
|
|
})
|
|
} else { // insert a new book
|
|
HTTP.put('books', {book: this.book})
|
|
.then(response => {
|
|
this.loading = false
|
|
// Fire a notification
|
|
this.$notify({
|
|
type: 'success',
|
|
title: this.translate('general').success,
|
|
text: this.translate('books').insertedSuccess
|
|
})
|
|
})
|
|
.catch(e => {
|
|
this.loading = false
|
|
this.errorNotification(e)
|
|
})
|
|
}
|
|
|
|
// Redirect to books list
|
|
router.push({ name: 'books' })
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
|
|
<style>
|
|
.multiselect__input {
|
|
border: none !important;
|
|
margin-top: -0.5rem !important;
|
|
margin-left: -0.5rem !important;
|
|
}
|
|
|
|
.add-publisher-btn{
|
|
float: right;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.add-btn-input, .field input.add-publisher {
|
|
width: 97% !important;
|
|
}
|
|
</style>
|