-
-
-
-
- {{ motd }}
+
+
+
+
+
-
@@ -33,7 +35,9 @@ export default {
this.$route.name !== 'user.password-reset.reset' &&
this.$route.name !== 'user.register' &&
this.$route.name !== 'link-share.auth' &&
- this.$route.name !== 'openid.auth'
+ this.$route.name !== 'openid.auth' &&
+ localStorage.getItem('passwordResetToken') === null &&
+ localStorage.getItem('emailConfirmToken') === null
) {
this.$router.push({name: 'user.login'})
}
diff --git a/src/components/home/navigation.vue b/src/components/home/navigation.vue
index d94d27bb6..29f9c3fa8 100644
--- a/src/components/home/navigation.vue
+++ b/src/components/home/navigation.vue
@@ -21,14 +21,6 @@
Upcoming
-
-
-
-
-
- Teams
-
-
@@ -45,52 +37,36 @@
Labels
+
+
+
+
+
+ Teams
+
+
+
+
+ Upload attachment
+
-
+
-
- Drop files here to upload
-
+
Drop files here to upload
-
- Delete attachment
- Are you sure you want to delete the attachment {{ attachmentToDelete.file.name }}?
- This CANNOT BE UNDONE!
-
+
+
+ Delete attachment
+
+ Are you sure you want to delete the attachment
+ {{ attachmentToDelete.file.name }}?
+ This CANNOT BE UNDONE!
+
+
+
+
+
+ {
+ showImageModal = false
+ attachmentImageBlobUrl = null
+ }
+ "
+ v-if="showImageModal"
+ >
+
+
+
@@ -101,6 +135,7 @@
import AttachmentService from '../../../services/attachment'
import AttachmentModel from '../../../models/attachment'
import User from '../../misc/user'
+import attachmentUpload from '@/components/tasks/mixins/attachmentUpload'
import {mapState} from 'vuex'
export default {
@@ -108,6 +143,9 @@ export default {
components: {
User,
},
+ mixins: [
+ attachmentUpload,
+ ],
data() {
return {
attachmentService: AttachmentService,
@@ -115,6 +153,9 @@ export default {
showDeleteModal: false,
attachmentToDelete: AttachmentModel,
+
+ showImageModal: false,
+ attachmentImageBlobUrl: null,
}
},
props: {
@@ -133,28 +174,28 @@ export default {
this.attachmentService = new AttachmentService()
},
computed: mapState({
- attachments: state => state.attachments.attachments,
+ attachments: (state) => state.attachments.attachments,
}),
mounted() {
- document.addEventListener('dragenter', e => {
+ document.addEventListener('dragenter', (e) => {
e.stopPropagation()
e.preventDefault()
this.showDropzone = true
})
- window.addEventListener('dragleave', e => {
+ window.addEventListener('dragleave', (e) => {
e.stopPropagation()
e.preventDefault()
this.showDropzone = false
})
- document.addEventListener('dragover', e => {
+ document.addEventListener('dragover', (e) => {
e.stopPropagation()
e.preventDefault()
this.showDropzone = true
})
- document.addEventListener('drop', e => {
+ document.addEventListener('drop', (e) => {
e.stopPropagation()
e.preventDefault()
@@ -175,38 +216,40 @@ export default {
this.uploadFiles(this.$refs.files.files)
},
uploadFiles(files) {
- const attachmentModel = new AttachmentModel({taskId: this.taskId})
- this.attachmentService.create(attachmentModel, files)
- .then(r => {
- if (r.success !== null) {
- r.success.forEach(a => {
- this.$store.commit('attachments/add', a)
- this.$store.dispatch('tasks/addTaskAttachment', {taskId: this.taskId, attachment: a})
- })
- }
- if (r.errors !== null) {
- r.errors.forEach(m => {
- this.error(m)
- })
- }
- })
- .catch(e => {
- this.error(e, this)
- })
+ this.createAttachment(this.attachmentService, files)
},
deleteAttachment() {
- this.attachmentService.delete(this.attachmentToDelete)
- .then(r => {
- this.$store.commit('attachments/removeById', this.attachmentToDelete.id)
+ this.attachmentService
+ .delete(this.attachmentToDelete)
+ .then((r) => {
+ this.$store.commit(
+ 'attachments/removeById',
+ this.attachmentToDelete.id
+ )
this.success(r, this)
})
- .catch(e => {
+ .catch((e) => {
this.error(e, this)
})
.finally(() => {
this.showDeleteModal = false
})
},
+ viewOrDownload(attachment) {
+ if (
+ attachment.file.name.endsWith('.jpg') ||
+ attachment.file.name.endsWith('.png') ||
+ attachment.file.name.endsWith('.bmp') ||
+ attachment.file.name.endsWith('.gif')
+ ) {
+ this.showImageModal = true
+ this.attachmentService.getBlobUrl(attachment).then((url) => {
+ this.attachmentImageBlobUrl = url
+ })
+ } else {
+ this.downloadAttachment(attachment)
+ }
+ },
},
}
diff --git a/src/components/tasks/partials/comments.vue b/src/components/tasks/partials/comments.vue
index d35fd87e4..8f798f299 100644
--- a/src/components/tasks/partials/comments.vue
+++ b/src/components/tasks/partials/comments.vue
@@ -1,34 +1,71 @@
-
Are you sure you want to delete this comment? -
-This CANNOT BE UNDONE!
+ Are you sure you want to delete this comment?
+This + CANNOT BE UNDONE! +
- #{{ task.index }} -
-- {{ task.identifier }} +Done
+ {{ task.getTextIdentifier && task.getTextIdentifier() ? task.getTextIdentifier() : '' }}
- {{ task.title }} -
+ ref="taskTitle">{{ task.title.trim() }}Each
@@ -11,7 +30,9 @@ @change="updateData" class="input" placeholder="Specify an amount..." - v-model="repeatAfter.amount"/> + v-model="repeatAfter.amount" + type="number" + />- Avatar -
-Hi {{ userInfo.name !== '' ? userInfo.name : userInfo.username }}!
++ Hi {{ userInfo.name !== '' ? userInfo.name : userInfo.username }}! +
-Click on a list or namespace on the left to get started.
-+ Or import your lists and tasks from other services into Vikunja: +
+Create A Saved Filter
-- A saved filter is a virtual list which is computed from a set of filters each time it is - accessed. Once created, it will appear in a special namespace. -
-+ A saved filter is a virtual list which is computed from a set of filters each time it is + accessed. Once created, it will appear in a special namespace. +
+- Edit Saved Filter -
-- Are you sure you want to delete this saved filter? -
-+ Are you sure you want to delete this saved filter? +
+Manage labels
-- Click on a label to edit it. - You can edit all labels you created, you can use all labels which are associated with a task to whose list - you have access. -
+Manage labels
++ Click on a label to edit it. + You can edit all labels you created, you can use all labels which are associated with a task to whose + list you have access. +
++ You currently do not have any labels. +Create a new label.
+
++ Please specify a title. +
+- Edit List -
-- Duplicate this list -
-Select a namespace which should hold the duplicated list:
--
-
-- -
-Are you sure you want to delete this list and all of its contents? -
-This includes all tasks and CANNOT BE UNDONE!
Create a new list
-+
+
+
+
-
-
- -
+ v-model="list.title" + /> +Please specify a title.
-+ You will be able to create new tasks or edit it. +
++ You won't be able to edit this list or create new tasks until you un-archive it. +
+- Set list background -
-Powered by Unsplash
-Powered by Unsplash
+Are you sure you want to delete this list and all of its contents? +
+This includes all tasks and CANNOT BE UNDONE!
Select a namespace which should hold the duplicated list:
+saveBucketTitle(bucket.id)" - @keyup.enter="() => saveBucketTitle(bucket.id)" + @keydown.enter.prevent.stop="() => saveBucketTitle(bucket.id)" class="title input" contenteditable="true" spellcheck="false">{{ bucket.title }}
@@ -14,59 +37,62 @@ :class="{'is-max': bucket.tasks.length >= bucket.limit}" class="limit" v-if="bucket.limit > 0"> - {{ bucket.tasks.length }}/{{ bucket.limit }} - -{{ task.title }}
-{{ task.title }}
+ +- Are you sure you want to delete this bucket?
-- This will not delete any tasks but move them into the default bucket. -
+ Are you sure you want to delete this bucket?
++ This will not delete any tasks but move them into the default bucket. +
- - +
+
+
+
+
-
+ +
-
-- +
++
+ Add
+
+
++ Please specify a list title.
- Please specify a list title. -
-- This list is currently empty. -
+- Edit Task -
- - -