Make all api fields snake_case (#105)

Change all snake/camelCase mix and match to camelCase everywhere

Fix conversion to not interfer with service interceptors

Add dynamic conversion between camelCase and snake_case to services

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#105
This commit is contained in:
konrad 2020-04-12 21:54:46 +00:00
parent de36296bac
commit 4a413e7f3c
60 changed files with 296 additions and 189 deletions

View File

@ -9,10 +9,12 @@
}, },
"dependencies": { "dependencies": {
"bulma": "0.8.2", "bulma": "0.8.2",
"camel-case": "^4.1.1",
"copy-to-clipboard": "3.3.1", "copy-to-clipboard": "3.3.1",
"date-fns": "2.12.0", "date-fns": "2.12.0",
"lodash": "4.17.15", "lodash": "4.17.15",
"register-service-worker": "1.7.1", "register-service-worker": "1.7.1",
"snake-case": "^3.0.3",
"v-tooltip": "2.0.3", "v-tooltip": "2.0.3",
"verte": "0.0.12", "verte": "0.0.12",
"vue": "2.6.11", "vue": "2.6.11",

View File

@ -126,10 +126,10 @@
</router-link> </router-link>
<label class="menu-label" v-tooltip="n.name + ' (' + n.lists.length + ')'" :for="n.id + 'checker'"> <label class="menu-label" v-tooltip="n.name + ' (' + n.lists.length + ')'" :for="n.id + 'checker'">
<span class="name"> <span class="name">
<span class="color-bubble" v-if="n.hex_color !== ''" :style="{ backgroundColor: n.hex_color }"></span> <span class="color-bubble" v-if="n.hexColor !== ''" :style="{ backgroundColor: n.hexColor }"></span>
{{n.name}} ({{n.lists.length}}) {{n.name}} ({{n.lists.length}})
</span> </span>
<span class="is-archived" v-if="n.is_archived"> <span class="is-archived" v-if="n.isArchived">
Archived Archived
</span> </span>
</label> </label>
@ -140,10 +140,10 @@
<li v-for="l in n.lists" :key="l.id"> <li v-for="l in n.lists" :key="l.id">
<router-link :to="{ name: 'showList', params: { id: l.id} }"> <router-link :to="{ name: 'showList', params: { id: l.id} }">
<span class="name"> <span class="name">
<span class="color-bubble" v-if="l.hex_color !== ''" :style="{ backgroundColor: l.hex_color }"></span> <span class="color-bubble" v-if="l.hexColor !== ''" :style="{ backgroundColor: l.hexColor }"></span>
{{l.title}} {{l.title}}
</span> </span>
<span class="is-archived" v-if="l.is_archived"> <span class="is-archived" v-if="l.isArchived">
Archived Archived
</span> </span>
</router-link> </router-link>
@ -301,7 +301,7 @@
}, },
loadNamespaces() { loadNamespaces() {
this.namespaceService = new NamespaceService() this.namespaceService = new NamespaceService()
this.namespaceService.getAll({}, {is_archived: this.showArchived}) this.namespaceService.getAll({}, {isArchived: this.showArchived})
.then(r => { .then(r => {
this.$set(this, 'namespaces', r) this.$set(this, 'namespaces', r)
}) })

View File

@ -10,11 +10,11 @@
<span <span
v-for="l in labels" :key="l.id" v-for="l in labels" :key="l.id"
class="tag" class="tag"
:class="{'disabled': user.infos.id !== l.created_by.id}" :class="{'disabled': user.infos.id !== l.createdBy.id}"
:style="{'background': l.hex_color, 'color': l.textColor}" :style="{'background': l.hexColor, 'color': l.textColor}"
> >
<span <span
v-if="user.infos.id !== l.created_by.id" v-if="user.infos.id !== l.createdBy.id"
v-tooltip.bottom="'You are not allowed to edit this label because you dont own it.'"> v-tooltip.bottom="'You are not allowed to edit this label because you dont own it.'">
{{ l.title }} {{ l.title }}
</span> </span>
@ -24,7 +24,7 @@
v-else> v-else>
{{ l.title }} {{ l.title }}
</a> </a>
<a class="delete is-small" @click="deleteLabel(l)" v-if="user.infos.id === l.created_by.id"></a> <a class="delete is-small" @click="deleteLabel(l)" v-if="user.infos.id === l.createdBy.id"></a>
</span> </span>
</div> </div>
<div class="column is-4" v-if="isLabelEdit"> <div class="column is-4" v-if="isLabelEdit">
@ -57,7 +57,7 @@
<label class="label">Color</label> <label class="label">Color</label>
<div class="control"> <div class="control">
<verte <verte
v-model="labelEditLabel.hex_color" v-model="labelEditLabel.hexColor"
menuPosition="top" menuPosition="top"
picker="square" picker="square"
model="hex" model="hex"
@ -155,7 +155,7 @@
}) })
}, },
editLabel(label) { editLabel(label) {
if(label.created_by.id !== this.user.infos.id) { if(label.createdBy.id !== this.user.infos.id) {
return return
} }
this.labelEditLabel = label this.labelEditLabel = label

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="loader-container" :class="{ 'is-loading': listService.loading}"> <div class="loader-container" :class="{ 'is-loading': listService.loading}">
<div class="notification is-warning" v-if="list.is_archived"> <div class="notification is-warning" v-if="list.isArchived">
This list is archived. This list is archived.
It is not possible to create new or edit tasks or it. It is not possible to create new or edit tasks or it.
</div> </div>
@ -28,7 +28,7 @@
<div class="field"> <div class="field">
<label class="label" for="isArchivedCheck">Is Archived</label> <label class="label" for="isArchivedCheck">Is Archived</label>
<div class="control"> <div class="control">
<fancycheckbox v-model="list.is_archived" v-tooltip="'If a list is archived, you cannot create new tasks or edit the list or existing tasks.'"> <fancycheckbox v-model="list.isArchived" v-tooltip="'If a list is archived, you cannot create new tasks or edit the list or existing tasks.'">
This list is archived This list is archived
</fancycheckbox> </fancycheckbox>
</div> </div>
@ -37,7 +37,7 @@
<label class="label">Color</label> <label class="label">Color</label>
<div class="control"> <div class="control">
<verte <verte
v-model="list.hex_color" v-model="list.hexColor"
menuPosition="top" menuPosition="top"
picker="square" picker="square"
model="hex" model="hex"

View File

@ -5,7 +5,7 @@
<icon icon="cog" size="2x"/> <icon icon="cog" size="2x"/>
</router-link> </router-link>
<h1 :style="{ 'opacity': list.title === '' ? '0': '1' }">{{ list.title === '' ? 'Loading...': list.title}}</h1> <h1 :style="{ 'opacity': list.title === '' ? '0': '1' }">{{ list.title === '' ? 'Loading...': list.title}}</h1>
<div class="notification is-warning" v-if="list.is_archived"> <div class="notification is-warning" v-if="list.isArchived">
This list is archived. This list is archived.
It is not possible to create new or edit tasks or it. It is not possible to create new or edit tasks or it.
</div> </div>

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="loader-container" v-bind:class="{ 'is-loading': namespaceService.loading}"> <div class="loader-container" v-bind:class="{ 'is-loading': namespaceService.loading}">
<div class="notification is-warning" v-if="namespace.is_archived"> <div class="notification is-warning" v-if="namespace.isArchived">
This namespace is archived. This namespace is archived.
It is not possible to create new lists or edit it. It is not possible to create new lists or edit it.
</div> </div>
@ -28,7 +28,7 @@
<div class="field"> <div class="field">
<label class="label" for="isArchivedCheck">Is Archived</label> <label class="label" for="isArchivedCheck">Is Archived</label>
<div class="control"> <div class="control">
<fancycheckbox v-model="namespace.is_archived" v-tooltip="'If a namespace is archived, you cannot create new lists or edit it.'"> <fancycheckbox v-model="namespace.isArchived" v-tooltip="'If a namespace is archived, you cannot create new lists or edit it.'">
This namespace is archived This namespace is archived
</fancycheckbox> </fancycheckbox>
</div> </div>
@ -37,7 +37,7 @@
<label class="label">Color</label> <label class="label">Color</label>
<div class="control"> <div class="control">
<verte <verte
v-model="namespace.hex_color" v-model="namespace.hexColor"
menuPosition="top" menuPosition="top"
picker="square" picker="square"
model="hex" model="hex"

View File

@ -52,7 +52,7 @@
</div> </div>
</td> </td>
<td> <td>
{{ s.shared_by.username }} {{ s.sharedBy.username }}
</td> </td>
<td class="type"> <td class="type">
<template v-if="s.right === rights.ADMIN"> <template v-if="s.right === rights.ADMIN">
@ -145,7 +145,7 @@
return return
} }
this.linkShareService.getAll({listID: this.listID}) this.linkShareService.getAll({listId: this.listID})
.then(r => { .then(r => {
this.linkShares = r this.linkShares = r
}) })
@ -154,7 +154,7 @@
}) })
}, },
add() { add() {
let newLinkShare = new LinkShareModel({right: this.selectedRight, listID: this.listID}) let newLinkShare = new LinkShareModel({right: this.selectedRight, listId: this.listID})
this.linkShareService.create(newLinkShare) this.linkShareService.create(newLinkShare)
.then(() => { .then(() => {
this.selectedRight = rights.READ this.selectedRight = rights.READ
@ -166,7 +166,7 @@
}) })
}, },
remove() { remove() {
let linkshare = new LinkShareModel({id: this.linkIDToDelete, listID: this.listID}) let linkshare = new LinkShareModel({id: this.linkIDToDelete, listId: this.listID})
this.linkShareService.delete(linkshare) this.linkShareService.delete(linkshare)
.then(() => { .then(() => {
this.success({message: 'The link share was successfully deleted'}, this) this.success({message: 'The link share was successfully deleted'}, this)

View File

@ -28,7 +28,7 @@
auth.linkShareAuth(this.$route.params.share) auth.linkShareAuth(this.$route.params.share)
.then((r) => { .then((r) => {
this.loading = false this.loading = false
router.push({name: 'showList', params: {id: r.list_id}}) router.push({name: 'showList', params: {id: r.listId}})
}) })
.catch(e => { .catch(e => {
this.error(e, this) this.error(e, this)

View File

@ -175,7 +175,7 @@
if (this.type === 'list') { if (this.type === 'list') {
this.typeString = `list` this.typeString = `list`
this.stuffService = new UserListService() this.stuffService = new UserListService()
this.stuffModel = new UserListModel({listID: this.id}) this.stuffModel = new UserListModel({listId: this.id})
} else if (this.type === 'namespace') { } else if (this.type === 'namespace') {
this.typeString = `namespace` this.typeString = `namespace`
this.stuffService = new UserNamespaceService() this.stuffService = new UserNamespaceService()
@ -192,7 +192,7 @@
if (this.type === 'list') { if (this.type === 'list') {
this.typeString = `list` this.typeString = `list`
this.stuffService = new TeamListService() this.stuffService = new TeamListService()
this.stuffModel = new TeamListModel({listID: this.id}) this.stuffModel = new TeamListModel({listId: this.id})
} else if (this.type === 'namespace') { } else if (this.type === 'namespace') {
this.typeString = `namespace` this.typeString = `namespace`
this.stuffService = new TeamNamespaceService() this.stuffService = new TeamNamespaceService()
@ -219,17 +219,17 @@
deleteSharable() { deleteSharable() {
if (this.shareType === 'user') { if (this.shareType === 'user') {
this.stuffModel.userID = this.sharable.username this.stuffModel.userId = this.sharable.username
} else if (this.shareType === 'team') { } else if (this.shareType === 'team') {
this.stuffModel.teamID = this.sharable.id this.stuffModel.teamId = this.sharable.id
} }
this.stuffService.delete(this.stuffModel) this.stuffService.delete(this.stuffModel)
.then(() => { .then(() => {
this.showDeleteModal = false this.showDeleteModal = false
for (const i in this.sharables) { for (const i in this.sharables) {
if ( if (
(this.sharables[i].id === this.stuffModel.userID && this.shareType === 'user') || (this.sharables[i].id === this.stuffModel.userId && this.shareType === 'user') ||
(this.sharables[i].id === this.stuffModel.teamID && this.shareType === 'team') (this.sharables[i].id === this.stuffModel.teamId && this.shareType === 'team')
) { ) {
this.sharables.splice(i, 1) this.sharables.splice(i, 1)
} }
@ -250,9 +250,9 @@
} }
if (this.shareType === 'user') { if (this.shareType === 'user') {
this.stuffModel.userID = this.sharable.username this.stuffModel.userId = this.sharable.username
} else if (this.shareType === 'team') { } else if (this.shareType === 'team') {
this.stuffModel.teamID = this.sharable.id this.stuffModel.teamId = this.sharable.id
} }
this.stuffService.create(this.stuffModel) this.stuffService.create(this.stuffModel)
@ -275,17 +275,17 @@
if (this.shareType === 'user') { if (this.shareType === 'user') {
this.stuffModel.userID = sharable.username this.stuffModel.userId = sharable.username
} else if (this.shareType === 'team') { } else if (this.shareType === 'team') {
this.stuffModel.teamID = sharable.id this.stuffModel.teamId = sharable.id
} }
this.stuffService.update(this.stuffModel) this.stuffService.update(this.stuffModel)
.then(r => { .then(r => {
for (const i in this.sharables) { for (const i in this.sharables) {
if ( if (
(this.sharables[i].id === this.stuffModel.userID && this.shareType === 'user') || (this.sharables[i].id === this.stuffModel.userId && this.shareType === 'user') ||
(this.sharables[i].id === this.stuffModel.teamID && this.shareType === 'team') (this.sharables[i].id === this.stuffModel.teamId && this.shareType === 'team')
) { ) {
this.$set(this.sharables[i], 'right', r.right) this.$set(this.sharables[i], 'right', r.right)
} }

View File

@ -32,7 +32,7 @@
</button> </button>
</div> </div>
<div class="field task-add" v-if="!list.is_archived"> <div class="field task-add" v-if="!list.isArchived">
<div class="field is-grouped"> <div class="field is-grouped">
<p class="control has-icons-left is-expanded" :class="{ 'is-loading': taskService.loading}"> <p class="control has-icons-left is-expanded" :class="{ 'is-loading': taskService.loading}">
<input v-focus class="input" :class="{ 'disabled': taskService.loading}" v-model="newTaskText" type="text" placeholder="Add a new task..." @keyup.enter="addTask()"/> <input v-focus class="input" :class="{ 'disabled': taskService.loading}" v-model="newTaskText" type="text" placeholder="Add a new task..." @keyup.enter="addTask()"/>
@ -59,7 +59,7 @@
<div class="tasks" v-if="tasks && tasks.length > 0" :class="{'short': isTaskEdit}"> <div class="tasks" v-if="tasks && tasks.length > 0" :class="{'short': isTaskEdit}">
<div class="task" v-for="t in tasks" :key="t.id"> <div class="task" v-for="t in tasks" :key="t.id">
<single-task-in-list :the-task="t" @taskUpdated="updateTasks"/> <single-task-in-list :the-task="t" @taskUpdated="updateTasks"/>
<div @click="editTask(t.id)" class="icon settings" v-if="!list.is_archived"> <div @click="editTask(t.id)" class="icon settings" v-if="!list.isArchived">
<icon icon="pencil-alt"/> <icon icon="pencil-alt"/>
</div> </div>
</div> </div>
@ -159,7 +159,7 @@
} }
this.showError = false this.showError = false
let task = new TaskModel({text: this.newTaskText, listID: this.$route.params.id}) let task = new TaskModel({text: this.newTaskText, listId: this.$route.params.id})
this.taskService.create(task) this.taskService.create(task)
.then(r => { .then(r => {
this.tasks.push(r) this.tasks.push(r)

View File

@ -46,7 +46,7 @@
}, },
methods: { methods: {
loadPendingTasks() { loadPendingTasks() {
let params = {sort_by: ['due_date_unix', 'id'], order_by: ['desc', 'desc']} let params = {sort_by: ['dueDate_unix', 'id'], order_by: ['desc', 'desc']}
if (!this.showAll) { if (!this.showAll) {
params.startdate = Math.round(+ this.startDate / 1000) params.startdate = Math.round(+ this.startDate / 1000)
params.enddate = Math.round(+ this.endDate / 1000) params.enddate = Math.round(+ this.endDate / 1000)

View File

@ -55,15 +55,15 @@
</th> </th>
<th v-if="activeColumns.dueDate"> <th v-if="activeColumns.dueDate">
Due&nbsp;Date Due&nbsp;Date
<sort :order="sortBy.due_date_unix" @click="sort('due_date_unix')"/> <sort :order="sortBy.dueDate_unix" @click="sort('dueDate_unix')"/>
</th> </th>
<th v-if="activeColumns.startDate"> <th v-if="activeColumns.startDate">
Start&nbsp;Date Start&nbsp;Date
<sort :order="sortBy.start_date_unix" @click="sort('start_date_unix')"/> <sort :order="sortBy.startDate_unix" @click="sort('startDate_unix')"/>
</th> </th>
<th v-if="activeColumns.endDate"> <th v-if="activeColumns.endDate">
End&nbsp;Date End&nbsp;Date
<sort :order="sortBy.end_date_unix" @click="sort('end_date_unix')"/> <sort :order="sortBy.endDate_unix" @click="sort('endDate_unix')"/>
</th> </th>
<th v-if="activeColumns.percentDone"> <th v-if="activeColumns.percentDone">
%&nbsp;Done %&nbsp;Done

View File

@ -28,7 +28,7 @@
</div> </div>
<edit-assignees <edit-assignees
:task-i-d="task.id" :task-i-d="task.id"
:list-i-d="task.listID" :list-i-d="task.listId"
:initial-assignees="task.assignees" :initial-assignees="task.assignees"
ref="assignees" ref="assignees"
/> />
@ -193,8 +193,8 @@
</h3> </h3>
<related-tasks <related-tasks
:task-i-d="taskID" :task-i-d="taskID"
:list-id="task.listID" :list-id="task.listId"
:initial-related-tasks="task.related_tasks" :initial-related-tasks="task.relatedTasks"
:show-no-relations-notice="true" :show-no-relations-notice="true"
ref="relatedTasks" ref="relatedTasks"
/> />
@ -397,7 +397,7 @@
this.activeFields.repeatAfter = this.task.repeatAfter.amount > 0 this.activeFields.repeatAfter = this.task.repeatAfter.amount > 0
this.activeFields.labels = this.task.labels.length > 0 this.activeFields.labels = this.task.labels.length > 0
this.activeFields.attachments = this.task.attachments.length > 0 this.activeFields.attachments = this.task.attachments.length > 0
this.activeFields.relatedTasks = Object.keys(this.task.related_tasks).length > 0 this.activeFields.relatedTasks = Object.keys(this.task.relatedTasks).length > 0
}, },
saveTaskOnChange() { saveTaskOnChange() {
this.$refs.taskTitle.spellcheck = false this.$refs.taskTitle.spellcheck = false
@ -444,7 +444,7 @@
// FIXME: Throw this away once we have vuex // FIXME: Throw this away once we have vuex
this.$parent.namespaces.forEach(n => { this.$parent.namespaces.forEach(n => {
n.lists.forEach(l => { n.lists.forEach(l => {
if (l.id === this.task.listID) { if (l.id === this.task.listId) {
this.list = l this.list = l
this.namespace = n this.namespace = n
return return

View File

@ -114,7 +114,7 @@
<div class="field has-addons"> <div class="field has-addons">
<div class="control is-expanded"> <div class="control is-expanded">
<edit-assignees :task-i-d="taskEditTask.id" :list-i-d="taskEditTask.listID" :initial-assignees="taskEditTask.assignees"/> <edit-assignees :task-i-d="taskEditTask.id" :list-i-d="taskEditTask.listId" :initial-assignees="taskEditTask.assignees"/>
</div> </div>
</div> </div>
@ -128,8 +128,8 @@
<related-tasks <related-tasks
class="is-narrow" class="is-narrow"
:task-i-d="task.id" :task-i-d="task.id"
:list-id="task.listID" :list-id="task.listId"
:initial-related-tasks="task.related_tasks" :initial-related-tasks="task.relatedTasks"
/> />
<button type="submit" class="button is-success is-fullwidth" :class="{ 'is-loading': taskService.loading}"> <button type="submit" class="button is-success is-fullwidth" :class="{ 'is-loading': taskService.loading}">

View File

@ -235,7 +235,7 @@
prepareTasks() { prepareTasks() {
const getAllTasks = (page = 1) => { const getAllTasks = (page = 1) => {
return this.taskCollectionService.getAll({listID: this.$route.params.id}, {}, page) return this.taskCollectionService.getAll({listId: this.$route.params.id}, {}, page)
.then(tasks => { .then(tasks => {
if(page < this.taskCollectionService.totalPages) { if(page < this.taskCollectionService.totalPages) {
return getAllTasks(page + 1) return getAllTasks(page + 1)
@ -367,7 +367,7 @@
if (!this.newTaskFieldActive) { if (!this.newTaskFieldActive) {
return return
} }
let task = new TaskModel({text: this.newTaskTitle, listID: this.list.id}) let task = new TaskModel({text: this.newTaskTitle, listId: this.list.id})
this.taskService.create(task) this.taskService.create(task)
.then(r => { .then(r => {
this.tasksWithoutDates.push(this.addGantAttributes(r)) this.tasksWithoutDates.push(this.addGantAttributes(r))

View File

@ -27,7 +27,7 @@ export default {
if (search !== '') { if (search !== '') {
params.s = search params.s = search
} }
this.taskCollectionService.getAll({listID: this.$route.params.id}, params, page) this.taskCollectionService.getAll({listId: this.$route.params.id}, params, page)
.then(r => { .then(r => {
this.$set(this, 'tasks', r) this.$set(this, 'tasks', r)
this.$set(this, 'pages', []) this.$set(this, 'pages', [])

View File

@ -33,7 +33,7 @@
<td>{{ a.file.getHumanSize() }}</td> <td>{{ a.file.getHumanSize() }}</td>
<td>{{ a.file.mime }}</td> <td>{{ a.file.mime }}</td>
<td v-tooltip="formatDate(a.created)">{{ formatDateSince(a.created) }}</td> <td v-tooltip="formatDate(a.created)">{{ formatDateSince(a.created) }}</td>
<td><user :user="a.created_by" :avatar-size="30"/></td> <td><user :user="a.createdBy" :avatar-size="30"/></td>
<td> <td>
<div class="buttons has-addons"> <div class="buttons has-addons">
<a class="button is-primary noshadow" @click="downloadAttachment(a)" v-tooltip="'Download this attachment'"> <a class="button is-primary noshadow" @click="downloadAttachment(a)" v-tooltip="'Download this attachment'">
@ -153,7 +153,7 @@
this.uploadFiles(this.$refs.files.files) this.uploadFiles(this.$refs.files.files)
}, },
uploadFiles(files) { uploadFiles(files) {
const attachmentModel = new AttachmentModel({task_id: this.taskID}) const attachmentModel = new AttachmentModel({taskId: this.taskID})
this.attachmentService.create(attachmentModel, files) this.attachmentService.create(attachmentModel, files)
.then(r => { .then(r => {
if(r.success !== null) { if(r.success !== null) {

View File

@ -94,9 +94,9 @@
}, },
created() { created() {
this.taskCommentService = new TaskCommentService() this.taskCommentService = new TaskCommentService()
this.newComment = new TaskCommentModel({task_id: this.taskID}) this.newComment = new TaskCommentModel({taskId: this.taskID})
this.commentEdit = new TaskCommentModel({task_id: this.taskID}) this.commentEdit = new TaskCommentModel({taskId: this.taskID})
this.commentToDelete = new TaskCommentModel({task_id: this.taskID}) this.commentToDelete = new TaskCommentModel({taskId: this.taskID})
this.comments = [] this.comments = []
}, },
mounted() { mounted() {
@ -109,7 +109,7 @@
}, },
methods: { methods: {
loadComments() { loadComments() {
this.taskCommentService.getAll({task_id: this.taskID}) this.taskCommentService.getAll({taskId: this.taskID})
.then(r => { .then(r => {
this.$set(this, 'comments', r) this.$set(this, 'comments', r)
}) })
@ -143,7 +143,7 @@
if (this.commentEdit.comment === '') { if (this.commentEdit.comment === '') {
return return
} }
this.commentEdit.task_id = this.taskID this.commentEdit.taskId = this.taskID
this.taskCommentService.update(this.commentEdit) this.taskCommentService.update(this.commentEdit)
.then(r => { .then(r => {
for (const c in this.comments) { for (const c in this.comments) {

View File

@ -84,7 +84,7 @@
}, },
methods: { methods: {
addAssignee(user) { addAssignee(user) {
const taskAssignee = new TaskAssigneeModel({user_id: user.id, task_id: this.taskID}) const taskAssignee = new TaskAssigneeModel({userId: user.id, taskId: this.taskID})
this.taskAssigneeService.create(taskAssignee) this.taskAssigneeService.create(taskAssignee)
.then(() => { .then(() => {
this.success({message: 'The user was successfully assigned.'}, this) this.success({message: 'The user was successfully assigned.'}, this)
@ -94,7 +94,7 @@
}) })
}, },
removeAssignee(user) { removeAssignee(user) {
const taskAssignee = new TaskAssigneeModel({user_id: user.id, task_id: this.taskID}) const taskAssignee = new TaskAssigneeModel({userId: user.id, taskId: this.taskID})
this.taskAssigneeService.delete(taskAssignee) this.taskAssigneeService.delete(taskAssignee)
.then(() => { .then(() => {
// Remove the assignee from the list // Remove the assignee from the list
@ -115,7 +115,7 @@
return return
} }
this.listUserService.getAll({listID: this.listID}, {s: query}) this.listUserService.getAll({listId: this.listID}, {s: query})
.then(response => { .then(response => {
// Filter the results to not include users who are already assigned // Filter the results to not include users who are already assigned
this.$set(this, 'foundUsers', differenceWith(response, this.assignees, (first, second) => { this.$set(this, 'foundUsers', differenceWith(response, this.assignees, (first, second) => {

View File

@ -22,7 +22,7 @@
> >
<template slot="tag" slot-scope="{ option }"> <template slot="tag" slot-scope="{ option }">
<span class="tag" <span class="tag"
:style="{'background': option.hex_color, 'color': option.textColor}"> :style="{'background': option.hexColor, 'color': option.textColor}">
<span>{{ option.title }}</span> <span>{{ option.title }}</span>
<a class="delete is-small" @click="removeLabel(option)"></a> <a class="delete is-small" @click="removeLabel(option)"></a>
</span> </span>
@ -108,7 +108,7 @@
this.$set(this, 'foundLabels', []) this.$set(this, 'foundLabels', [])
}, },
addLabel(label) { addLabel(label) {
let labelTask = new LabelTaskModel({taskID: this.taskID, label_id: label.id}) let labelTask = new LabelTaskModel({taskID: this.taskID, labelId: label.id})
this.labelTaskService.create(labelTask) this.labelTaskService.create(labelTask)
.then(() => { .then(() => {
this.success({message: 'The label was successfully added.'}, this) this.success({message: 'The label was successfully added.'}, this)
@ -119,7 +119,7 @@
}) })
}, },
removeLabel(label) { removeLabel(label) {
let labelTask = new LabelTaskModel({taskID: this.taskID, label_id: label.id}) let labelTask = new LabelTaskModel({taskID: this.taskID, labelId: label.id})
this.labelTaskService.delete(labelTask) this.labelTaskService.delete(labelTask)
.then(() => { .then(() => {
// Remove the label from the list // Remove the label from the list

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="label-wrapper"> <div class="label-wrapper">
<span class="tag" v-for="label in labels" :style="{'background': label.hex_color, 'color': label.textColor}" :key="label.id"> <span class="tag" v-for="label in labels" :style="{'background': label.hexColor, 'color': label.textColor}" :key="label.id">
<span>{{ label.title }}</span> <span>{{ label.title }}</span>
</span> </span>
</div> </div>

View File

@ -54,7 +54,7 @@
{{t.text}} {{t.text}}
</span> </span>
</router-link> </router-link>
<a class="remove" @click="() => {showDeleteModal = true; relationToDelete = {relation_kind: kind, other_task_id: t.id}}"> <a class="remove" @click="() => {showDeleteModal = true; relationToDelete = {relationKind: kind, otherTaskId: t.id}}">
<icon icon="trash-alt"/> <icon icon="trash-alt"/>
</a> </a>
</div> </div>
@ -156,9 +156,9 @@
}, },
addTaskRelation() { addTaskRelation() {
let rel = new TaskRelationModel({ let rel = new TaskRelationModel({
task_id: this.taskID, taskId: this.taskID,
other_task_id: this.newTaskRelationTask.id, otherTaskId: this.newTaskRelationTask.id,
relation_kind: this.newTaskRelationKind, relationKind: this.newTaskRelationKind,
}) })
this.taskRelationService.create(rel) this.taskRelationService.create(rel)
.then(() => { .then(() => {
@ -176,15 +176,15 @@
}, },
removeTaskRelation() { removeTaskRelation() {
let rel = new TaskRelationModel({ let rel = new TaskRelationModel({
relation_kind: this.relationToDelete.relation_kind, relationKind: this.relationToDelete.relationKind,
task_id: this.taskID, taskId: this.taskID,
other_task_id: this.relationToDelete.other_task_id, otherTaskId: this.relationToDelete.otherTaskId,
}) })
this.taskRelationService.delete(rel) this.taskRelationService.delete(rel)
.then(r => { .then(r => {
Object.keys(this.relatedTasks).forEach(relationKind => { Object.keys(this.relatedTasks).forEach(relationKind => {
for (const t in this.relatedTasks[relationKind]) { for (const t in this.relatedTasks[relationKind]) {
if (this.relatedTasks[relationKind][t].id === this.relationToDelete.other_task_id && relationKind === this.relationToDelete.relation_kind) { if (this.relatedTasks[relationKind][t].id === this.relationToDelete.otherTaskId && relationKind === this.relationToDelete.relationKind) {
this.relatedTasks[relationKind].splice(t, 1) this.relatedTasks[relationKind].splice(t, 1)
} }
} }
@ -199,7 +199,7 @@
}) })
}, },
createAndRelateTask(text) { createAndRelateTask(text) {
const newTask = new TaskModel({text: text, listID: this.listId}) const newTask = new TaskModel({text: text, listId: this.listId})
this.taskService.create(newTask) this.taskService.create(newTask)
.then(r => { .then(r => {
this.newTaskRelationTask = r this.newTaskRelationTask = r

View File

@ -3,9 +3,9 @@
<fancycheckbox v-model="task.done" @change="markAsDone" :disabled="isArchived"/> <fancycheckbox v-model="task.done" @change="markAsDone" :disabled="isArchived"/>
<router-link :to="{ name: 'taskDetailView', params: { id: task.id } }" class="tasktext" :class="{ 'done': task.done}"> <router-link :to="{ name: 'taskDetailView', params: { id: task.id } }" class="tasktext" :class="{ 'done': task.done}">
<!-- Show any parent tasks to make it clear this task is a sub task of something --> <!-- Show any parent tasks to make it clear this task is a sub task of something -->
<span class="parent-tasks" v-if="typeof task.related_tasks.parenttask !== 'undefined'"> <span class="parent-tasks" v-if="typeof task.relatedTasks.parenttask !== 'undefined'">
<template v-for="(pt, i) in task.related_tasks.parenttask"> <template v-for="(pt, i) in task.relatedTasks.parenttask">
{{ pt.text }}<template v-if="(i + 1) < task.related_tasks.parenttask.length">,&nbsp;</template> {{ pt.text }}<template v-if="(i + 1) < task.relatedTasks.parenttask.length">,&nbsp;</template>
</template> </template>
> >
</span> </span>

View File

@ -175,14 +175,14 @@
}, },
methods: { methods: {
loadTeam() { loadTeam() {
this.member = new TeamMemberModel({teamID: this.$route.params.id}) this.member = new TeamMemberModel({teamId: this.$route.params.id})
this.team = new TeamModel({id: this.$route.params.id}) this.team = new TeamModel({id: this.$route.params.id})
this.teamService.get(this.team) this.teamService.get(this.team)
.then(response => { .then(response => {
this.$set(this, 'team', response) this.$set(this, 'team', response)
let members = response.members let members = response.members
for (const m in members) { for (const m in members) {
members[m].teamID = this.$route.params.id members[m].teamId = this.$route.params.id
if (members[m].id === this.user.infos.id && members[m].admin) { if (members[m].id === this.user.infos.id && members[m].admin) {
this.userIsAdmin = true this.userIsAdmin = true
} }

View File

@ -66,7 +66,7 @@
return return
} }
let passwordReset = new PasswordResetModel({new_password: this.credentials.password}) let passwordReset = new PasswordResetModel({newPassword: this.credentials.password})
this.passwordResetService.resetPassword(passwordReset) this.passwordResetService.resetPassword(passwordReset)
.then(response => { .then(response => {
this.successMessage = response.data.message this.successMessage = response.data.message

View File

@ -5,7 +5,7 @@ import FileModel from './file'
export default class AttachmentModel extends AbstractModel { export default class AttachmentModel extends AbstractModel {
constructor(data) { constructor(data) {
super(data) super(data)
this.created_by = new UserModel(this.created_by) this.createdBy = new UserModel(this.createdBy)
this.file = new FileModel(this.file) this.file = new FileModel(this.file)
this.created = new Date(this.created) this.created = new Date(this.created)
} }
@ -13,9 +13,9 @@ export default class AttachmentModel extends AbstractModel {
defaults() { defaults() {
return { return {
id: 0, id: 0,
task_id: 0, taskId: 0,
file: FileModel, file: FileModel,
created_by: UserModel, createdBy: UserModel,
created: null, created: null,
} }
} }

View File

@ -5,14 +5,14 @@ export default class LabelModel extends AbstractModel {
constructor(data) { constructor(data) {
super(data) super(data)
// Set the default color // Set the default color
if (this.hex_color === '') { if (this.hexColor === '') {
this.hex_color = 'e8e8e8' this.hexColor = 'e8e8e8'
} }
if (this.hex_color.substring(0, 1) !== '#') { if (this.hexColor.substring(0, 1) !== '#') {
this.hex_color = '#' + this.hex_color this.hexColor = '#' + this.hexColor
} }
this.textColor = this.hasDarkColor() ? '#4a4a4a' : '#e5e5e5' this.textColor = this.hasDarkColor() ? '#4a4a4a' : '#e5e5e5'
this.created_by = new UserModel(this.created_by) this.createdBy = new UserModel(this.createdBy)
this.created = new Date(this.created) this.created = new Date(this.created)
this.updated = new Date(this.updated) this.updated = new Date(this.updated)
@ -22,10 +22,10 @@ export default class LabelModel extends AbstractModel {
return { return {
id: 0, id: 0,
title: '', title: '',
hex_color: '', hexColor: '',
description: '', description: '',
created_by: UserModel, createdBy: UserModel,
listID: 0, listId: 0,
textColor: '', textColor: '',
created: null, created: null,
@ -34,11 +34,11 @@ export default class LabelModel extends AbstractModel {
} }
hasDarkColor() { hasDarkColor() {
if (this.hex_color === '#') { if (this.hexColor === '#') {
return true // Defaults to dark return true // Defaults to dark
} }
let rgb = parseInt(this.hex_color.substring(1, 7), 16); // convert rrggbb to decimal let rgb = parseInt(this.hexColor.substring(1, 7), 16); // convert rrggbb to decimal
let r = (rgb >> 16) & 0xff; // extract red let r = (rgb >> 16) & 0xff; // extract red
let g = (rgb >> 8) & 0xff; // extract green let g = (rgb >> 8) & 0xff; // extract green
let b = (rgb >> 0) & 0xff; // extract blue let b = (rgb >> 0) & 0xff; // extract blue

View File

@ -5,7 +5,7 @@ export default class LabelTask extends AbstractModel {
return { return {
id: 0, id: 0,
taskID: 0, taskID: 0,
label_id: 0, labelId: 0,
} }
} }
} }

View File

@ -7,7 +7,7 @@ export default class ListModel extends AbstractModel {
// The constructor of AbstractModel handles all the default parsing. // The constructor of AbstractModel handles all the default parsing.
super(data) super(data)
this.shared_by = new UserModel(this.shared_by) this.sharedBy = new UserModel(this.sharedBy)
this.created = new Date(this.created) this.created = new Date(this.created)
this.updated = new Date(this.updated) this.updated = new Date(this.updated)
@ -19,8 +19,8 @@ export default class ListModel extends AbstractModel {
id: 0, id: 0,
hash: '', hash: '',
right: 0, right: 0,
shared_by: UserModel, sharedBy: UserModel,
sharing_type: 0, sharingType: 0,
listID: 0, listID: 0,
created: null, created: null,

View File

@ -7,8 +7,8 @@ export default class ListModel extends AbstractModel {
constructor(data) { constructor(data) {
super(data) super(data)
if (this.hex_color !== '' && this.hex_color.substring(0, 1) !== '#') { if (this.hexColor !== '' && this.hexColor.substring(0, 1) !== '#') {
this.hex_color = '#' + this.hex_color this.hexColor = '#' + this.hexColor
} }
// Make all tasks to task models // Make all tasks to task models
@ -31,8 +31,8 @@ export default class ListModel extends AbstractModel {
owner: UserModel, owner: UserModel,
tasks: [], tasks: [],
namespaceID: 0, namespaceID: 0,
is_archived: false, isArchived: false,
hex_color: '', hexColor: '',
created: null, created: null,
updated: null, updated: null,

View File

@ -6,8 +6,8 @@ export default class NamespaceModel extends AbstractModel {
constructor(data) { constructor(data) {
super(data) super(data)
if (this.hex_color !== '' && this.hex_color.substring(0, 1) !== '#') { if (this.hexColor !== '' && this.hexColor.substring(0, 1) !== '#') {
this.hex_color = '#' + this.hex_color this.hexColor = '#' + this.hexColor
} }
this.lists = this.lists.map(l => { this.lists = this.lists.map(l => {
@ -27,8 +27,8 @@ export default class NamespaceModel extends AbstractModel {
description: '', description: '',
owner: UserModel, owner: UserModel,
lists: [], lists: [],
is_archived: false, isArchived: false,
hex_color: '', hexColor: '',
created: null, created: null,
updated: null, updated: null,

View File

@ -10,7 +10,7 @@ export default class PasswordResetModel extends AbstractModel {
defaults() { defaults() {
return { return {
token: '', token: '',
new_password: '', newPassword: '',
email: '', email: '',
} }
} }

View File

@ -9,7 +9,7 @@ export default class TaskModel extends AbstractModel {
super(data) super(data)
this.id = Number(this.id) this.id = Number(this.id)
this.listID = Number(this.listID) this.listId = Number(this.listId)
// Make date objects from timestamps // Make date objects from timestamps
this.dueDate = this.dueDate ? new Date(this.dueDate) : null this.dueDate = this.dueDate ? new Date(this.dueDate) : null
@ -50,8 +50,8 @@ export default class TaskModel extends AbstractModel {
} }
// Make all subtasks to task models // Make all subtasks to task models
Object.keys(this.related_tasks).forEach(relationKind => { Object.keys(this.relatedTasks).forEach(relationKind => {
this.related_tasks[relationKind] = this.related_tasks[relationKind].map(t => { this.relatedTasks[relationKind] = this.relatedTasks[relationKind].map(t => {
return new TaskModel(t) return new TaskModel(t)
}) })
}) })
@ -83,14 +83,14 @@ export default class TaskModel extends AbstractModel {
parentTaskID: 0, parentTaskID: 0,
hexColor: '', hexColor: '',
percentDone: 0, percentDone: 0,
related_tasks: {}, relatedTasks: {},
attachments: [], attachments: [],
createdBy: UserModel, createdBy: UserModel,
created: null, created: null,
updated: null, updated: null,
listID: 0, // Meta, only used when creating a new task listId: 0, // Meta, only used when creating a new task
} }
} }

View File

@ -9,8 +9,8 @@ export default class TaskAssigneeModel extends AbstractModel {
defaults() { defaults() {
return { return {
created: null, created: null,
user_id: 0, userId: 0,
task_id: 0, taskId: 0,
} }
} }
} }

View File

@ -12,7 +12,7 @@ export default class TaskCommentModel extends AbstractModel {
defaults() { defaults() {
return { return {
id: 0, id: 0,
task_id: 0, taskId: 0,
comment: '', comment: '',
author: UserModel, author: UserModel,
created: null, created: null,

View File

@ -4,18 +4,18 @@ import UserModel from './user'
export default class TaskRelationModel extends AbstractModel { export default class TaskRelationModel extends AbstractModel {
constructor(data) { constructor(data) {
super(data) super(data)
this.created_by = new UserModel(this.created_by) this.createdBy = new UserModel(this.createdBy)
this.created = new Date(this.created) this.created = new Date(this.created)
} }
defaults() { defaults() {
return { return {
id: 0, id: 0,
other_task_id: 0, otherTaskId: 0,
task_id: 0, taskId: 0,
relation_kind: '', relationKind: '',
created_by: UserModel, createdBy: UserModel,
created: null, created: null,
} }
} }

View File

@ -6,7 +6,7 @@ export default class TeamListModel extends TeamShareBaseModel {
return merge( return merge(
super.defaults(), super.defaults(),
{ {
listID: 0, listId: 0,
} }
) )
} }

View File

@ -7,7 +7,7 @@ export default class TeamMemberModel extends UserModel {
super.defaults(), super.defaults(),
{ {
admin: false, admin: false,
teamID: 0, teamId: 0,
} }
) )
} }

View File

@ -13,7 +13,7 @@ export default class TeamShareBaseModel extends AbstractModel {
defaults() { defaults() {
return { return {
teamID: 0, teamId: 0,
right: 0, right: 0,
created: null, created: null,

View File

@ -7,7 +7,7 @@ export default class UserListModel extends UserShareBaseModel {
return merge( return merge(
super.defaults(), super.defaults(),
{ {
listID: 0, listId: 0,
} }
) )
} }

View File

@ -9,7 +9,7 @@ export default class UserShareBaseModel extends AbstractModel {
defaults() { defaults() {
return { return {
userID: '', userId: '',
right: 0, right: 0,
created: null, created: null,

View File

@ -1,5 +1,7 @@
import axios from 'axios' import axios from 'axios'
import {reduce, replace} from 'lodash' import {reduce, replace} from 'lodash'
import {camelCase} from 'camel-case'
import {snakeCase} from 'snake-case'
let config = require('../../public/config.json') let config = require('../../public/config.json')
@ -40,19 +42,25 @@ export default class AbstractService {
// Set the interceptors to process every request // Set the interceptors to process every request
let self = this let self = this
this.http.interceptors.request.use( (config) => { this.http.interceptors.request.use((config) => {
switch (config.method) { switch (config.method) {
case 'post': case 'post':
if(this.useUpdateInterceptor()) if (this.useUpdateInterceptor()) {
config.data = JSON.stringify(self.beforeUpdate(config.data)) config.data = self.beforeUpdate(config.data)
}
config.data = JSON.stringify(this.modelToSnakeCase(config.data))
break break
case 'put': case 'put':
if(this.useCreateInterceptor()) if (this.useCreateInterceptor()) {
config.data = JSON.stringify(self.beforeCreate(config.data)) config.data = self.beforeCreate(config.data)
}
config.data = JSON.stringify(this.modelToSnakeCase(config.data))
break break
case 'delete': case 'delete':
if(this.useDeleteInterceptor()) if (this.useDeleteInterceptor()) {
config.data = JSON.stringify(self.beforeDelete(config.data)) config.data = self.beforeDelete(config.data)
}
config.data = JSON.stringify(this.modelToSnakeCase(config.data))
break break
} }
return config return config
@ -66,7 +74,7 @@ export default class AbstractService {
) { ) {
this.http.defaults.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('token') this.http.defaults.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('token')
} }
this.paths = { this.paths = {
create: paths.create !== undefined ? paths.create : '', create: paths.create !== undefined ? paths.create : '',
get: paths.get !== undefined ? paths.get : '', get: paths.get !== undefined ? paths.get : '',
@ -112,7 +120,7 @@ export default class AbstractService {
errorHandler(error) { errorHandler(error) {
return Promise.reject(error) return Promise.reject(error)
} }
///////////////// /////////////////
// Helper functions // Helper functions
/////////////// ///////////////
@ -231,6 +239,32 @@ export default class AbstractService {
// Preprocessors // Preprocessors
//////////// ////////////
/**
* Transforms field names to camel case.
* @param model
* @returns {*}
*/
modelToCamelCase(model) {
let parsedModel = {}
for (const m in model) {
parsedModel[camelCase(m)] = model[m]
}
return parsedModel
}
/**
* Transforms field names to snake case - used before making an api request.
* @param model
* @returns {*}
*/
modelToSnakeCase(model) {
let parsedModel = {}
for (const m in model) {
parsedModel[snakeCase(m)] = model[m]
}
return parsedModel
}
/** /**
* Default preprocessor for get requests * Default preprocessor for get requests
* @param model * @param model
@ -295,12 +329,16 @@ export default class AbstractService {
*/ */
getM(url, model = {}, params = {}) { getM(url, model = {}, params = {}) {
const cancel = this.setLoading() const cancel = this.setLoading()
model = this.beforeGet(model) model = this.beforeGet(model)
return this.http.get(this.getReplacedRoute(url, model), {params: params}) const finalUrl = this.getReplacedRoute(url, model)
return this.http.get(finalUrl, {params: params})
.catch(error => { .catch(error => {
return this.errorHandler(error) return this.errorHandler(error)
}) })
.then(response => { .then(response => {
response.data = this.modelToCamelCase(response.data)
return Promise.resolve(this.modelGetFactory(response.data)) return Promise.resolve(this.modelGetFactory(response.data))
}) })
.finally(() => { .finally(() => {
@ -325,7 +363,9 @@ export default class AbstractService {
const cancel = this.setLoading() const cancel = this.setLoading()
model = this.beforeGet(model) model = this.beforeGet(model)
return this.http.get(this.getReplacedRoute(this.paths.getAll, model), {params: params}) const finalUrl = this.getReplacedRoute(this.paths.getAll, model)
return this.http.get(finalUrl, {params: params})
.catch(error => { .catch(error => {
return this.errorHandler(error) return this.errorHandler(error)
}) })
@ -338,16 +378,17 @@ export default class AbstractService {
return this.modelGetAllFactory(entry) return this.modelGetAllFactory(entry)
})) }))
} }
if(response.data === null) { if (response.data === null) {
return Promise.resolve([]) return Promise.resolve([])
} }
response.data = this.modelToCamelCase(response.data)
return Promise.resolve(this.modelGetAllFactory(response.data)) return Promise.resolve(this.modelGetAllFactory(response.data))
}) })
.finally(() => { .finally(() => {
cancel() cancel()
}) })
} }
/** /**
* Performs a put request to the url specified before * Performs a put request to the url specified before
* @param model * @param model
@ -359,18 +400,21 @@ export default class AbstractService {
} }
const cancel = this.setLoading() const cancel = this.setLoading()
return this.http.put(this.getReplacedRoute(this.paths.create, model), model) const finalUrl = this.getReplacedRoute(this.paths.create, model)
return this.http.put(finalUrl, model)
.catch(error => { .catch(error => {
return this.errorHandler(error) return this.errorHandler(error)
}) })
.then(response => { .then(response => {
response.data = this.modelToCamelCase(response.data)
return Promise.resolve(this.modelCreateFactory(response.data)) return Promise.resolve(this.modelCreateFactory(response.data))
}) })
.finally(() => { .finally(() => {
cancel() cancel()
}) })
} }
/** /**
* Performs a post request to the update url * Performs a post request to the update url
* @param model * @param model
@ -382,11 +426,14 @@ export default class AbstractService {
} }
const cancel = this.setLoading() const cancel = this.setLoading()
return this.http.post(this.getReplacedRoute(this.paths.update, model), model) const finalUrl = this.getReplacedRoute(this.paths.update, model)
return this.http.post(finalUrl, model)
.catch(error => { .catch(error => {
return this.errorHandler(error) return this.errorHandler(error)
}) })
.then(response => { .then(response => {
response.data = this.modelToCamelCase(response.data)
return Promise.resolve(this.modelUpdateFactory(response.data)) return Promise.resolve(this.modelUpdateFactory(response.data))
}) })
.finally(() => { .finally(() => {
@ -405,11 +452,14 @@ export default class AbstractService {
} }
const cancel = this.setLoading() const cancel = this.setLoading()
return this.http.delete(this.getReplacedRoute(this.paths.delete, model), model) const finalUrl = this.getReplacedRoute(this.paths.delete, model)
return this.http.delete(finalUrl, model)
.catch(error => { .catch(error => {
return this.errorHandler(error) return this.errorHandler(error)
}) })
.then(response => { .then(response => {
response.data = this.modelToCamelCase(response.data)
return Promise.resolve(response.data) return Promise.resolve(response.data)
}) })
.finally(() => { .finally(() => {

View File

@ -5,9 +5,9 @@ import {formatISO} from 'date-fns'
export default class AttachmentService extends AbstractService { export default class AttachmentService extends AbstractService {
constructor() { constructor() {
super({ super({
create: '/tasks/{task_id}/attachments', create: '/tasks/{taskId}/attachments',
getAll: '/tasks/{task_id}/attachments', getAll: '/tasks/{taskId}/attachments',
delete: '/tasks/{task_id}/attachments/{id}', delete: '/tasks/{taskId}/attachments/{id}',
}) })
} }
@ -36,7 +36,7 @@ export default class AttachmentService extends AbstractService {
download(model) { download(model) {
this.http({ this.http({
url: '/tasks/' + model.task_id + '/attachments/' + model.id, url: '/tasks/' + model.taskId + '/attachments/' + model.id,
method: 'GET', method: 'GET',
responseType: 'blob', responseType: 'blob',
}).then((response) => { }).then((response) => {

View File

@ -24,12 +24,12 @@ export default class LabelService extends AbstractService {
} }
beforeUpdate(label) { beforeUpdate(label) {
label.hex_color = label.hex_color.substring(1, 7) label.hexColor = label.hexColor.substring(1, 7)
return label return label
} }
beforeCreate(label) { beforeCreate(label) {
label.hex_color = label.hex_color.substring(1, 7) label.hexColor = label.hexColor.substring(1, 7)
return label return label
} }
} }

View File

@ -6,7 +6,7 @@ export default class LabelTaskService extends AbstractService {
super({ super({
create: '/tasks/{taskID}/labels', create: '/tasks/{taskID}/labels',
getAll: '/tasks/{taskID}/labels', getAll: '/tasks/{taskID}/labels',
delete: '/tasks/{taskID}/labels/{label_id}', delete: '/tasks/{taskID}/labels/{labelId}',
}) })
} }

View File

@ -5,10 +5,10 @@ import {formatISO} from 'date-fns'
export default class ListService extends AbstractService { export default class ListService extends AbstractService {
constructor() { constructor() {
super({ super({
getAll: '/lists/{listID}/shares', getAll: '/lists/{listId}/shares',
get: '/lists/{listID}/shares/{id}', get: '/lists/{listId}/shares/{id}',
create: '/lists/{listID}/shares', create: '/lists/{listId}/shares',
delete: '/lists/{listID}/shares/{id}', delete: '/lists/{listId}/shares/{id}',
}) })
} }

View File

@ -28,12 +28,12 @@ export default class ListService extends AbstractService {
model.tasks = model.tasks.map(task => { model.tasks = model.tasks.map(task => {
return taskService.beforeUpdate(task) return taskService.beforeUpdate(task)
}) })
model.hex_color = model.hex_color.substring(1, 7) model.hexColor = model.hexColor.substring(1, 7)
return model return model
} }
beforeCreate(list) { beforeCreate(list) {
list.hex_color = list.hex_color.substring(1, 7) list.hexColor = list.hexColor.substring(1, 7)
return list return list
} }
} }

View File

@ -5,7 +5,7 @@ import {formatISO} from 'date-fns'
export default class ListUserService extends AbstractService { export default class ListUserService extends AbstractService {
constructor() { constructor() {
super({ super({
getAll: '/lists/{listID}/listusers' getAll: '/lists/{listId}/listusers'
}) })
} }

View File

@ -24,12 +24,12 @@ export default class NamespaceService extends AbstractService {
} }
beforeUpdate(namespace) { beforeUpdate(namespace) {
namespace.hex_color = namespace.hex_color.substring(1, 7) namespace.hexColor = namespace.hexColor.substring(1, 7)
return namespace return namespace
} }
beforeCreate(namespace) { beforeCreate(namespace) {
namespace.hex_color = namespace.hex_color.substring(1, 7) namespace.hexColor = namespace.hexColor.substring(1, 7)
return namespace return namespace
} }
} }

View File

@ -6,7 +6,7 @@ import {formatISO} from 'date-fns'
export default class TaskService extends AbstractService { export default class TaskService extends AbstractService {
constructor() { constructor() {
super({ super({
create: '/lists/{listID}', create: '/lists/{listId}',
getAll: '/tasks/all', getAll: '/tasks/all',
get: '/tasks/{id}', get: '/tasks/{id}',
update: '/tasks/{id}', update: '/tasks/{id}',
@ -27,8 +27,11 @@ export default class TaskService extends AbstractService {
} }
processModel(model) { processModel(model) {
// Ensure the listID is an int
model.listID = Number(model.listID) console.log(model)
// Ensure that listId is an int
model.listId = Number(model.listId)
// Convert dates into an iso string // Convert dates into an iso string
model.dueDate = model.dueDate === null ? null : formatISO(new Date(model.dueDate)) model.dueDate = model.dueDate === null ? null : formatISO(new Date(model.dueDate))
@ -79,8 +82,8 @@ export default class TaskService extends AbstractService {
} }
// Do the same for all related tasks // Do the same for all related tasks
Object.keys(model.related_tasks).forEach(relationKind => { Object.keys(model.relatedTasks).forEach(relationKind => {
model.related_tasks[relationKind] = model.related_tasks[relationKind].map(t => { model.relatedTasks[relationKind] = model.relatedTasks[relationKind].map(t => {
return this.processModel(t) return this.processModel(t)
}) })
}) })

View File

@ -5,8 +5,8 @@ import {formatISO} from 'date-fns'
export default class TaskAssigneeService extends AbstractService { export default class TaskAssigneeService extends AbstractService {
constructor() { constructor() {
super({ super({
create: '/tasks/{task_id}/assignees', create: '/tasks/{taskId}/assignees',
delete: '/tasks/{task_id}/assignees/{user_id}', delete: '/tasks/{taskId}/assignees/{userId}',
}) })
} }

View File

@ -5,7 +5,7 @@ import {formatISO} from 'date-fns'
export default class TaskCollectionService extends AbstractService { export default class TaskCollectionService extends AbstractService {
constructor() { constructor() {
super({ super({
getAll: '/lists/{listID}/tasks', getAll: '/lists/{listId}/tasks',
}) })
} }

View File

@ -5,11 +5,11 @@ import {formatISO} from 'date-fns'
export default class TaskCommentService extends AbstractService { export default class TaskCommentService extends AbstractService {
constructor() { constructor() {
super({ super({
create: '/tasks/{task_id}/comments', create: '/tasks/{taskId}/comments',
getAll: '/tasks/{task_id}/comments', getAll: '/tasks/{taskId}/comments',
get: '/tasks/{task_id}/comments/{id}', get: '/tasks/{taskId}/comments/{id}',
update: '/tasks/{task_id}/comments/{id}', update: '/tasks/{taskId}/comments/{id}',
delete: '/tasks/{task_id}/comments/{id}', delete: '/tasks/{taskId}/comments/{id}',
}) })
} }

View File

@ -5,8 +5,8 @@ import {formatISO} from 'date-fns'
export default class TaskRelationService extends AbstractService { export default class TaskRelationService extends AbstractService {
constructor() { constructor() {
super({ super({
create: '/tasks/{task_id}/relations', create: '/tasks/{taskId}/relations',
delete: '/tasks/{task_id}/relations', delete: '/tasks/{taskId}/relations',
}) })
} }

View File

@ -6,10 +6,10 @@ import {formatISO} from 'date-fns'
export default class TeamListService extends AbstractService { export default class TeamListService extends AbstractService {
constructor() { constructor() {
super({ super({
create: '/lists/{listID}/teams', create: '/lists/{listId}/teams',
getAll: '/lists/{listID}/teams', getAll: '/lists/{listId}/teams',
update: '/lists/{listID}/teams/{teamID}', update: '/lists/{listId}/teams/{teamId}',
delete: '/lists/{listID}/teams/{teamID}', delete: '/lists/{listId}/teams/{teamId}',
}) })
} }

View File

@ -5,8 +5,8 @@ import {formatISO} from 'date-fns'
export default class TeamMemberService extends AbstractService { export default class TeamMemberService extends AbstractService {
constructor() { constructor() {
super({ super({
create: '/teams/{teamID}/members', create: '/teams/{teamId}/members',
delete: '/teams/{teamID}/members/{id}', // "id" is the user id because we're intheriting from a normal user delete: '/teams/{teamId}/members/{id}', // "id" is the user id because we're intheriting from a normal user
}); });
} }
@ -21,7 +21,7 @@ export default class TeamMemberService extends AbstractService {
} }
beforeCreate(model) { beforeCreate(model) {
model.userID = model.id // The api wants to get the user id as userID model.userId = model.id // The api wants to get the user id as user_ID
model.admin = model.admin === null ? false : model.admin model.admin = model.admin === null ? false : model.admin
return model return model
} }

View File

@ -8,8 +8,8 @@ export default class TeamNamespaceService extends AbstractService {
super({ super({
create: '/namespaces/{namespaceID}/teams', create: '/namespaces/{namespaceID}/teams',
getAll: '/namespaces/{namespaceID}/teams', getAll: '/namespaces/{namespaceID}/teams',
update: '/namespaces/{namespaceID}/teams/{teamID}', update: '/namespaces/{namespaceID}/teams/{teamId}',
delete: '/namespaces/{namespaceID}/teams/{teamID}', delete: '/namespaces/{namespaceID}/teams/{teamId}',
}) })
} }

View File

@ -6,10 +6,10 @@ import {formatISO} from 'date-fns'
export default class UserListService extends AbstractService { export default class UserListService extends AbstractService {
constructor() { constructor() {
super({ super({
create: '/lists/{listID}/users', create: '/lists/{listId}/users',
getAll: '/lists/{listID}/users', getAll: '/lists/{listId}/users',
update: '/lists/{listID}/users/{userID}', update: '/lists/{listId}/users/{userId}',
delete: '/lists/{listID}/users/{userID}', delete: '/lists/{listId}/users/{userId}',
}) })
} }

View File

@ -8,8 +8,8 @@ export default class UserNamespaceService extends AbstractService {
super({ super({
create: '/namespaces/{namespaceID}/users', create: '/namespaces/{namespaceID}/users',
getAll: '/namespaces/{namespaceID}/users', getAll: '/namespaces/{namespaceID}/users',
update: '/namespaces/{namespaceID}/users/{userID}', update: '/namespaces/{namespaceID}/users/{userId}',
delete: '/namespaces/{namespaceID}/users/{userID}', delete: '/namespaces/{namespaceID}/users/{userId}',
}) })
} }

View File

@ -4146,6 +4146,14 @@ camel-case@3.0.x, camel-case@^3.0.0:
no-case "^2.2.0" no-case "^2.2.0"
upper-case "^1.1.1" upper-case "^1.1.1"
camel-case@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.1.tgz#1fc41c854f00e2f7d0139dfeba1542d6896fe547"
integrity sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q==
dependencies:
pascal-case "^3.1.1"
tslib "^1.10.0"
camelcase-keys@^2.0.0: camelcase-keys@^2.0.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
@ -5601,6 +5609,14 @@ dot-case@^2.1.0:
dependencies: dependencies:
no-case "^2.2.0" no-case "^2.2.0"
dot-case@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.3.tgz#21d3b52efaaba2ea5fda875bb1aa8124521cf4aa"
integrity sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA==
dependencies:
no-case "^3.0.3"
tslib "^1.10.0"
dot-prop@^4.1.0, dot-prop@^4.1.1: dot-prop@^4.1.0, dot-prop@^4.1.1:
version "4.2.0" version "4.2.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57"
@ -8728,6 +8744,13 @@ lower-case@^1.1.0, lower-case@^1.1.1, lower-case@^1.1.2:
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw=
lower-case@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.1.tgz#39eeb36e396115cc05e29422eaea9e692c9408c7"
integrity sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ==
dependencies:
tslib "^1.10.0"
lowercase-keys@1.0.0: lowercase-keys@1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306"
@ -9232,6 +9255,14 @@ no-case@^2.2.0, no-case@^2.3.2:
dependencies: dependencies:
lower-case "^1.1.1" lower-case "^1.1.1"
no-case@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.3.tgz#c21b434c1ffe48b39087e86cfb4d2582e9df18f8"
integrity sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw==
dependencies:
lower-case "^2.0.1"
tslib "^1.10.0"
node-dir@^0.1.17: node-dir@^0.1.17:
version "0.1.17" version "0.1.17"
resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5"
@ -9962,6 +9993,14 @@ pascal-case@^2.0.0:
camel-case "^3.0.0" camel-case "^3.0.0"
upper-case-first "^1.1.0" upper-case-first "^1.1.0"
pascal-case@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.1.tgz#5ac1975133ed619281e88920973d2cd1f279de5f"
integrity sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA==
dependencies:
no-case "^3.0.3"
tslib "^1.10.0"
pascalcase@^0.1.1: pascalcase@^0.1.1:
version "0.1.1" version "0.1.1"
resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
@ -11656,6 +11695,14 @@ snake-case@^2.1.0:
dependencies: dependencies:
no-case "^2.2.0" no-case "^2.2.0"
snake-case@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.3.tgz#c598b822ab443fcbb145ae8a82c5e43526d5bbee"
integrity sha512-WM1sIXEO+rsAHBKjGf/6R1HBBcgbncKS08d2Aqec/mrDSpU80SiOU41hO7ny6DToHSyrlwTYzQBIK1FPSx4Y3Q==
dependencies:
dot-case "^3.0.3"
tslib "^1.10.0"
snapdragon-node@^2.0.1: snapdragon-node@^2.0.1:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
@ -12578,6 +12625,11 @@ tslib@^1, tslib@^1.9.0, tslib@^1.9.3:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
tslib@^1.10.0:
version "1.11.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==
tty-browserify@0.0.0: tty-browserify@0.0.0:
version "0.0.0" version "0.0.0"
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"