diff --git a/src/api.js b/src/api.js index d47a79c321ef28448e35670d4a6168e960fd08b9..7d02836eb18dc9bd91fe3de0ea10a7551cd5ec79 100644 --- a/src/api.js +++ b/src/api.js @@ -170,6 +170,21 @@ export const api = { return false } }, + async removeComment (id) { + const token = await localStorage.getItem('token') + const url = serverurl + 'comments' + '?id=' + id + try { + await fetch(url, { + method: 'DELETE', + headers: { + Authorization: 'Bearer ' + token + } + }) + return true + } catch (error) { + return false + } + }, async removeUser (id) { const token = await localStorage.getItem('token') const url = serverurl + 'user' + '?id=' + id @@ -227,5 +242,51 @@ export const api = { } catch (error) { return null } + }, + async getModelComments (id) { + const url = serverurl + 'comments' + '?id=' + id + const response = await fetch(url) + try { + return await response.json() + } catch (error) { + return null + } + }, + async getCommentList (id) { + const token = await localStorage.getItem('token') + const url = serverurl + 'comments/list' + const response = await fetch(url, { + headers: { + Authorization: 'Bearer ' + token + } + }) + try { + return await response.json() + } catch (error) { + return null + } + }, + async addComment (id, content) { + const url = serverurl + 'comments' + const token = await localStorage.getItem('token') + try { + const response = await fetch( + url, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: 'Bearer ' + token + }, + body: JSON.stringify({ + modelId: id, + content: content + }) + } + ) + return await response.json() + } catch (error) { + return null + } } } diff --git a/src/components/Comments.vue b/src/components/Comments.vue index 85c823308f6d56ba462ef69c21772411bf43ffb0..6f375ce36f8176bcf555b4466f4defc9889bd068 100644 --- a/src/components/Comments.vue +++ b/src/components/Comments.vue @@ -1,24 +1,76 @@ <template> - <div class="comments" v-if="comments"> + <div class="comments"> <h1 class="title is-5">{{comments.length}} comments</h1> <article class="media" v-for="comment in comments" v-bind:key="comment.id"> <div class="media-content"> <div class="content"> <p> - <strong>{{comment.author}}</strong> - <small>{{new Date(comment.date).toLocaleDateString()}}</small> + <strong>{{comment.author.username}}</strong> - <small>{{new Date(comment.added).toLocaleDateString()}}</small> <br> {{comment.content}} </p> </div> </div> + <div class="media-right details" v-if="isAdmin"> + <b-button class="actionButton" icon-left="delete" type="is-danger" @click="removePrompt(comment.id)" outlined/> + </div> </article> + + <div v-if="isLoggedIn"> + <hr> + <b-field label="Add a comment"> + <b-input maxlength="1000" type="textarea" v-model="postContent"/> + </b-field> + <b-field> + <b-button @click="postComment">Post</b-button> + </b-field> + </div> </div> </template> <script> +import { api } from '@/api.js' + export default { name: 'Comments', - props: ['comments'] + props: ['modelId'], + data () { + return { + isLoggedIn: false, + isLoading: true, + isAdmin: false, + comments: [], + postContent: '' + } + }, + async mounted () { + this.comments = await api.getModelComments(this.modelId) + + const userRole = await localStorage.getItem('user_role') + if (userRole) this.isLoggedIn = true + if (userRole === 'ROLE_ADMIN') this.isAdmin = true + }, + methods: { + async postComment () { + await api.addComment(this.modelId, this.postContent) + this.comments = await api.getModelComments(this.modelId) + this.postContent = null + }, + removePrompt (id) { + this.$buefy.dialog.confirm({ + message: 'Delete comment ?', + cancelText: 'Abort', + confirmText: 'Delete', + type: 'is-danger', + hasIcon: true, + onConfirm: async () => { + await api.removeComment(id) + this.comments = await api.getModelComments(this.modelId) + this.$buefy.toast.open('Comment deleted') + } + }) + } + } } </script> diff --git a/src/components/ModelTable.vue b/src/components/ModelTable.vue index b2c3c363a8cf30959dbfc3ac63122d708104b919..40f4ae081e628d89ae76cf4e1403f88d05cb1ffc 100644 --- a/src/components/ModelTable.vue +++ b/src/components/ModelTable.vue @@ -38,7 +38,7 @@ export default { } }, async mounted () { - this.models = await api.getModels() + this.models = await api.getUserModels() this.isLoading = false }, methods: { @@ -49,24 +49,12 @@ export default { confirmText: 'Delete', type: 'is-danger', hasIcon: true, - onConfirm: () => this.remove(id, name) + onConfirm: async () => { + await api.removeModel(id) + this.$buefy.toast.open(name + ' deleted') + this.models = await api.getUserModels() + } }) - }, - async remove (id, name) { - const token = await localStorage.getItem('token') - const url = this.$serverurl + 'models' + '?id=' + id - try { - await fetch(url, { - method: 'DELETE', - headers: { - Authorization: 'Bearer ' + token - } - }) - this.$buefy.toast.open(name + ' deleted') - this.getModels() - } catch (error) { - this.$buefy.toast.open('Delete error ' + error) - } } } } diff --git a/src/components/ModelUpload.vue b/src/components/ModelUpload.vue index b67ffa0c328a07cfee2fbead41436947849060b3..1d1e304ad2ff49e9dc7f9d9e9fac8c7f09cd6595 100644 --- a/src/components/ModelUpload.vue +++ b/src/components/ModelUpload.vue @@ -116,6 +116,8 @@ export default { shortDescription: this.model.shortDescription, longDescription: this.model.longDescription, performance: this.model.performance, + performanceUnit: this.model.performanceUnit, + parameterCount: this.model.parameterCount, tags: this.model.tags }) }) diff --git a/src/views/Account.vue b/src/views/Account.vue index 1d33f8cf2ee02ff5cbacebb426f004aaff949e56..dbcc6329fd76c058c7de9a26f9b96fd10c6e3f2a 100644 --- a/src/views/Account.vue +++ b/src/views/Account.vue @@ -59,7 +59,7 @@ export default { }, async mounted () { this.account = await api.getUser() - this.models = await api.getModels() + this.models = await api.getUserModels() await localStorage.setItem('user_role', this.account.role) await localStorage.setItem('user_id', this.account.id) }, diff --git a/src/views/Admin.vue b/src/views/Admin.vue index a0639a5fa293084a709e20129987530d4262de1f..faffdeffc47d39c7260e566531adb54f84eb12ef 100644 --- a/src/views/Admin.vue +++ b/src/views/Admin.vue @@ -80,6 +80,25 @@ </b-tab-item> <b-tab-item label="Comments"> + <b-table :data="commentList" :loading="isLoading" striped hoverable> + <template slot-scope="props"> + <b-table-column field="content" label="Content"> + {{ props.row.content }} + </b-table-column> + + <b-table-column field="username" label="Username" searchable sortable> + {{ props.row.author.username }} + </b-table-column> + + <b-table-column field="added" label="Added" sortable> + {{ props.row.added }} + </b-table-column> + + <b-table-column label="" centered> + <b-button class="actionButton" icon-left="delete" type="is-danger" @click="removePrompt(props.row.id, props.row.content, 'comment')" outlined/> + </b-table-column> + </template> + </b-table> </b-tab-item> </b-tabs> </div> @@ -96,13 +115,15 @@ export default { isLoading: true, userList: [], modelList: [], - tagList: [] + tagList: [], + commentList: [] } }, async mounted () { this.modelList = await api.getModelList() this.userList = await api.getUserList() this.tagList = await api.getTags() + this.commentList = await api.getCommentList() this.isLoading = false }, methods: { @@ -119,11 +140,13 @@ export default { case 'model' : api.removeModel(id); break case 'tag' : api.removeTag(id); break case 'category' : api.removeCategory(id); break + case 'comment' : api.removeComment(id); break } this.$buefy.toast.open(name + ' deleted') this.modelList = await api.getModelList() this.userList = await api.getUserList() this.tagList = await api.getTags() + this.commentList = await api.getCommentList() } }) }, diff --git a/src/views/Model.vue b/src/views/Model.vue index fda6e635790aa3ed7b30a4f84995a6fd3220353e..1969ae6b0489f13a5b259ed5e11251bd59648d6a 100644 --- a/src/views/Model.vue +++ b/src/views/Model.vue @@ -56,7 +56,7 @@ <b-tab-item label="Comments"> <div class="box"> - <Comments v-bind:comments="model.comments"/> + <Comments v-if="!isLoading" v-bind:modelId="model.id"/> </div> </b-tab-item> </b-tabs>