Make sure all popups & dropdowns are animated
continuous-integration/drone/push Build is passing Details

This commit is contained in:
kolaente 2021-01-23 18:54:22 +01:00
parent a4fb3e19be
commit 0d64506d73
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
10 changed files with 276 additions and 252 deletions

View File

@ -97,19 +97,21 @@
</table> </table>
</div> </div>
<modal <transition name="modal">
@close="showDeleteModal = false" <modal
@submit="remove()" @close="showDeleteModal = false"
v-if="showDeleteModal" @submit="remove()"
> v-if="showDeleteModal"
<span slot="header">Remove a link share</span> >
<p slot="text"> <span slot="header">Remove a link share</span>
Are you sure you want to remove this link share?<br/> <p slot="text">
It will no longer be possible to access this list with this link Are you sure you want to remove this link share?<br/>
share.<br/> It will no longer be possible to access this list with this link
<b>This CANNOT BE UNDONE!</b> share.<br/>
</p> <b>This CANNOT BE UNDONE!</b>
</modal> </p>
</modal>
</transition>
</card> </card>
</template> </template>

View File

@ -16,114 +16,116 @@
/> />
</p> </p>
<p class="control"> <p class="control">
<x-button @click="add()"> Share </x-button> <x-button @click="add()"> Share</x-button>
</p> </p>
</div> </div>
</div> </div>
<table class="table is-striped is-hoverable is-fullwidth"> <table class="table is-striped is-hoverable is-fullwidth">
<tbody> <tbody>
<tr :key="s.id" v-for="s in sharables"> <tr :key="s.id" v-for="s in sharables">
<template v-if="shareType === 'user'"> <template v-if="shareType === 'user'">
<td>{{ s.getDisplayName() }}</td> <td>{{ s.getDisplayName() }}</td>
<td> <td>
<template v-if="s.id === userInfo.id"> <template v-if="s.id === userInfo.id">
<b class="is-success">You</b> <b class="is-success">You</b>
</template> </template>
</td> </td>
</template> </template>
<template v-if="shareType === 'team'"> <template v-if="shareType === 'team'">
<td> <td>
<router-link <router-link
:to="{ :to="{
name: 'teams.edit', name: 'teams.edit',
params: { id: s.id }, params: { id: s.id },
}" }"
> >
{{ s.name }} {{ s.name }}
</router-link> </router-link>
</td>
</template>
<td class="type">
<template v-if="s.right === rights.ADMIN">
<span class="icon is-small">
<icon icon="lock" />
</span>
Admin
</template>
<template v-else-if="s.right === rights.READ_WRITE">
<span class="icon is-small">
<icon icon="pen" />
</span>
Write
</template>
<template v-else>
<span class="icon is-small">
<icon icon="users" />
</span>
Read-only
</template>
</td> </td>
<td class="actions" v-if="userIsAdmin"> </template>
<div class="select"> <td class="type">
<select <template v-if="s.right === rights.ADMIN">
@change="toggleType(s)" <span class="icon is-small">
class="button mr-2" <icon icon="lock"/>
v-model="selectedRight[s.id]" </span>
Admin
</template>
<template v-else-if="s.right === rights.READ_WRITE">
<span class="icon is-small">
<icon icon="pen"/>
</span>
Write
</template>
<template v-else>
<span class="icon is-small">
<icon icon="users"/>
</span>
Read-only
</template>
</td>
<td class="actions" v-if="userIsAdmin">
<div class="select">
<select
@change="toggleType(s)"
class="button mr-2"
v-model="selectedRight[s.id]"
>
<option
:selected="s.right === rights.READ"
:value="rights.READ"
> >
<option Read only
:selected="s.right === rights.READ" </option>
:value="rights.READ" <option
> :selected="s.right === rights.READ_WRITE"
Read only :value="rights.READ_WRITE"
</option> >
<option Read & write
:selected="s.right === rights.READ_WRITE" </option>
:value="rights.READ_WRITE" <option
> :selected="s.right === rights.ADMIN"
Read & write :value="rights.ADMIN"
</option> >
<option Admin
:selected="s.right === rights.ADMIN" </option>
:value="rights.ADMIN" </select>
> </div>
Admin <x-button
</option> @click="
</select>
</div>
<x-button
@click="
() => { () => {
sharable = s sharable = s
showDeleteModal = true showDeleteModal = true
} }
" "
class="is-danger" class="is-danger"
icon="trash-alt" icon="trash-alt"
/> />
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<modal <transition name="modal">
@close="showDeleteModal = false" <modal
@submit="deleteSharable()" @close="showDeleteModal = false"
v-if="showDeleteModal" @submit="deleteSharable()"
> v-if="showDeleteModal"
<span slot="header"
>Remove a {{ shareType }} from the {{ typeString }}</span
> >
<p slot="text"> <span slot="header"
Are you sure you want to remove this {{ shareType }} from the >Remove a {{ shareType }} from the {{ typeString }}</span
{{ typeString }}?<br /> >
<b>This CANNOT BE UNDONE!</b> <p slot="text">
</p> Are you sure you want to remove this {{ shareType }} from the
</modal> {{ typeString }}?<br/>
<b>This CANNOT BE UNDONE!</b>
</p>
</modal>
</transition>
</card> </card>
</template> </template>
<script> <script>
import { mapState } from 'vuex' import {mapState} from 'vuex'
import UserNamespaceService from '../../services/userNamespace' import UserNamespaceService from '../../services/userNamespace'
import UserNamespaceModel from '../../models/userNamespace' import UserNamespaceModel from '../../models/userNamespace'
@ -194,7 +196,7 @@ export default {
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()
@ -212,7 +214,7 @@ export default {
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()
@ -362,7 +364,7 @@ export default {
} }
this.searchService this.searchService
.getAll({}, { s: query }) .getAll({}, {s: query})
.then((response) => { .then((response) => {
this.$set(this, 'found', response) this.$set(this, 'found', response)
}) })

View File

@ -2,7 +2,7 @@
<div class="attachments"> <div class="attachments">
<h3> <h3>
<span class="icon is-grey"> <span class="icon is-grey">
<icon icon="paperclip" /> <icon icon="paperclip"/>
</span> </span>
Attachments Attachments
</h3> </h3>
@ -38,8 +38,8 @@
<span> <span>
created created
<span v-tooltip="formatDate(a.created)">{{ <span v-tooltip="formatDate(a.created)">{{
formatDateSince(a.created) formatDateSince(a.created)
}}</span> }}</span>
by by
<user <user
:avatar-size="24" :avatar-size="24"
@ -93,25 +93,27 @@
> >
<div class="drop-hint"> <div class="drop-hint">
<div class="icon"> <div class="icon">
<icon icon="cloud-upload-alt" /> <icon icon="cloud-upload-alt"/>
</div> </div>
<div class="hint">Drop files here to upload</div> <div class="hint">Drop files here to upload</div>
</div> </div>
</div> </div>
<!-- Delete modal --> <!-- Delete modal -->
<modal <transition name="modal">
@close="showDeleteModal = false" <modal
v-if="showDeleteModal" @close="showDeleteModal = false"
@submit="deleteAttachment()" v-if="showDeleteModal"
> @submit="deleteAttachment()"
<span slot="header">Delete attachment</span> >
<p slot="text"> <span slot="header">Delete attachment</span>
Are you sure you want to delete the attachment <p slot="text">
{{ attachmentToDelete.file.name }}?<br /> Are you sure you want to delete the attachment
<b>This CANNOT BE UNDONE!</b> {{ attachmentToDelete.file.name }}?<br/>
</p> <b>This CANNOT BE UNDONE!</b>
</modal> </p>
</modal>
</transition>
<transition name="modal"> <transition name="modal">
<modal <modal
@ -123,7 +125,7 @@
" "
v-if="showImageModal" v-if="showImageModal"
> >
<img :src="attachmentImageBlobUrl" alt="" /> <img :src="attachmentImageBlobUrl" alt=""/>
</modal> </modal>
</transition> </transition>
</div> </div>
@ -134,7 +136,7 @@ import AttachmentService from '../../../services/attachment'
import AttachmentModel from '../../../models/attachment' import AttachmentModel from '../../../models/attachment'
import User from '../../misc/user' import User from '../../misc/user'
import attachmentUpload from '@/components/tasks/mixins/attachmentUpload' import attachmentUpload from '@/components/tasks/mixins/attachmentUpload'
import { mapState } from 'vuex' import {mapState} from 'vuex'
export default { export default {
name: 'attachments', name: 'attachments',

View File

@ -2,7 +2,7 @@
<div class="content details"> <div class="content details">
<h3 v-if="canWrite || comments.length > 0"> <h3 v-if="canWrite || comments.length > 0">
<span class="icon is-grey"> <span class="icon is-grey">
<icon :icon="['far', 'comments']" /> <icon :icon="['far', 'comments']"/>
</span> </span>
Comments Comments
</h3> </h3>
@ -38,8 +38,8 @@
<strong>{{ c.author.getDisplayName() }}</strong <strong>{{ c.author.getDisplayName() }}</strong
>&nbsp; >&nbsp;
<span v-tooltip="formatDate(c.created)">{{ <span v-tooltip="formatDate(c.created)">{{
formatDateSince(c.created) formatDateSince(c.created)
}}</span> }}</span>
<span <span
v-if="+new Date(c.created) !== +new Date(c.updated)" v-if="+new Date(c.created) !== +new Date(c.updated)"
v-tooltip="formatDate(c.updated)" v-tooltip="formatDate(c.updated)"
@ -140,17 +140,20 @@
</div> </div>
</div> </div>
</div> </div>
<modal
@close="showDeleteModal = false" <transition name="modal">
@submit="deleteComment()" <modal
v-if="showDeleteModal" @close="showDeleteModal = false"
> @submit="deleteComment()"
<span slot="header">Delete this comment</span> v-if="showDeleteModal"
<p slot="text"> >
Are you sure you want to delete this comment? <br />This <span slot="header">Delete this comment</span>
<b>CANNOT BE UNDONE!</b> <p slot="text">
</p> Are you sure you want to delete this comment? <br/>This
</modal> <b>CANNOT BE UNDONE!</b>
</p>
</modal>
</transition>
</div> </div>
</template> </template>
@ -167,7 +170,7 @@ export default {
editor: () => ({ editor: () => ({
component: import( component: import(
/* webpackChunkName: "editor" */ '../../input/editor' /* webpackChunkName: "editor" */ '../../input/editor'
), ),
loading: LoadingComponent, loading: LoadingComponent,
error: ErrorComponent, error: ErrorComponent,
timeout: 60000, timeout: 60000,
@ -205,9 +208,9 @@ export default {
}, },
created() { created() {
this.taskCommentService = new TaskCommentService() this.taskCommentService = new TaskCommentService()
this.newComment = new TaskCommentModel({ taskId: this.taskId }) this.newComment = new TaskCommentModel({taskId: this.taskId})
this.commentEdit = new TaskCommentModel({ taskId: this.taskId }) this.commentEdit = new TaskCommentModel({taskId: this.taskId})
this.commentToDelete = new TaskCommentModel({ taskId: this.taskId }) this.commentToDelete = new TaskCommentModel({taskId: this.taskId})
this.comments = [] this.comments = []
}, },
mounted() { mounted() {
@ -229,7 +232,7 @@ export default {
methods: { methods: {
loadComments() { loadComments() {
this.taskCommentService this.taskCommentService
.getAll({ taskId: this.taskId }) .getAll({taskId: this.taskId})
.then((r) => { .then((r) => {
this.$set(this, 'comments', r) this.$set(this, 'comments', r)
this.makeActions() this.makeActions()
@ -258,7 +261,7 @@ export default {
this.comments.push(r) this.comments.push(r)
this.newComment.comment = '' this.newComment.comment = ''
this.success( this.success(
{ message: 'The comment was added successfully.' }, {message: 'The comment was added successfully.'},
this this
) )
}) })

View File

@ -88,14 +88,16 @@
</p> </p>
<!-- Delete modal --> <!-- Delete modal -->
<modal <transition name="modal">
@close="showDeleteModal = false" <modal
@submit="removeTaskRelation()" @close="showDeleteModal = false"
v-if="showDeleteModal"> @submit="removeTaskRelation()"
<span slot="header">Delete Task Relation</span> v-if="showDeleteModal">
<p slot="text">Are you sure you want to delete this task relation?<br/> <span slot="header">Delete Task Relation</span>
<b>This CANNOT BE UNDONE!</b></p> <p slot="text">Are you sure you want to delete this task relation?<br/>
</modal> <b>This CANNOT BE UNDONE!</b></p>
</modal>
</transition>
</div> </div>
</template> </template>

View File

@ -128,14 +128,16 @@
<link-sharing :list-id="$route.params.id" v-if="linkSharingEnabled"/> <link-sharing :list-id="$route.params.id" v-if="linkSharingEnabled"/>
<modal <transition name="modal">
@close="showDeleteModal = false" <modal
@submit="deleteList()" @close="showDeleteModal = false"
v-if="showDeleteModal"> @submit="deleteList()"
<span slot="header">Delete the list</span> v-if="showDeleteModal">
<p slot="text">Are you sure you want to delete this list and all of its contents? <span slot="header">Delete the list</span>
<br/>This includes all tasks and <b>CANNOT BE UNDONE!</b></p> <p slot="text">Are you sure you want to delete this list and all of its contents?
</modal> <br/>This includes all tasks and <b>CANNOT BE UNDONE!</b></p>
</modal>
</transition>
</div> </div>
</template> </template>

View File

@ -33,8 +33,7 @@
{{ bucket.tasks.length }}/{{ bucket.limit }} {{ bucket.tasks.length }}/{{ bucket.limit }}
</span> </span>
<div <div
:class="{ 'is-active': bucketOptionsDropDownActive[bucket.id] }" class="dropdown is-right is-active options"
class="dropdown is-right options"
v-if="canWrite" v-if="canWrite"
> >
<div @click.stop="toggleBucketDropdown(bucket.id)" class="dropdown-trigger"> <div @click.stop="toggleBucketDropdown(bucket.id)" class="dropdown-trigger">
@ -42,45 +41,47 @@
<icon icon="ellipsis-v"/> <icon icon="ellipsis-v"/>
</span> </span>
</div> </div>
<div class="dropdown-menu" role="menu"> <transition name="fade">
<div class="dropdown-content"> <div class="dropdown-menu" role="menu" v-if="bucketOptionsDropDownActive[bucket.id]">
<a <div class="dropdown-content">
@click.stop="showSetLimitInput = true" <a
class="dropdown-item" @click.stop="showSetLimitInput = true"
> class="dropdown-item"
<div class="field has-addons" v-if="showSetLimitInput"> >
<div class="control"> <div class="field has-addons" v-if="showSetLimitInput">
<input <div class="control">
@change="() => updateBucket(bucket)" <input
@keyup.enter="() => updateBucket(bucket)" @change="() => updateBucket(bucket)"
class="input" @keyup.enter="() => updateBucket(bucket)"
type="number" class="input"
v-focus.always type="number"
v-model="bucket.limit" v-focus.always
/> v-model="bucket.limit"
/>
</div>
<div class="control">
<x-button
:icon="['far', 'save']"
:shadow="false"
/>
</div>
</div> </div>
<div class="control"> <template v-else>
<x-button Limit: {{ bucket.limit > 0 ? bucket.limit : 'Not set' }}
:icon="['far', 'save']" </template>
:shadow="false" </a>
/> <a
</div> :class="{'is-disabled': buckets.length <= 1}"
</div> @click="() => deleteBucketModal(bucket.id)"
<template v-else> class="dropdown-item has-text-danger"
Limit: {{ bucket.limit > 0 ? bucket.limit : 'Not set' }} v-tooltip="buckets.length <= 1 ? 'You cannot remove the last bucket.' : ''"
</template> >
</a> <span class="icon is-small"><icon icon="trash-alt"/></span>
<a Delete
:class="{'is-disabled': buckets.length <= 1}" </a>
@click="() => deleteBucketModal(bucket.id)" </div>
class="dropdown-item has-text-danger"
v-tooltip="buckets.length <= 1 ? 'You cannot remove the last bucket.' : ''"
>
<span class="icon is-small"><icon icon="trash-alt"/></span>
Delete
</a>
</div> </div>
</div> </transition>
</div> </div>
</div> </div>
<div :ref="`tasks-container${bucket.id}`" class="tasks"> <div :ref="`tasks-container${bucket.id}`" class="tasks">
@ -241,17 +242,18 @@
<router-view/> <router-view/>
</transition> </transition>
<modal <transition name="modal">
@close="showBucketDeleteModal = false" <modal
@submit="deleteBucket()" @close="showBucketDeleteModal = false"
v-if="showBucketDeleteModal"> @submit="deleteBucket()"
<span slot="header">Delete the bucket</span> v-if="showBucketDeleteModal">
<p slot="text"> <span slot="header">Delete the bucket</span>
Are you sure you want to delete this bucket?<br/> <p slot="text">
This will not delete any tasks but move them into the default bucket. Are you sure you want to delete this bucket?<br/>
</p> This will not delete any tasks but move them into the default bucket.
</modal> </p>
</modal>
</transition>
</div> </div>
</template> </template>
@ -448,8 +450,9 @@ export default {
this.$set(this.showNewTaskInput, bucket, !this.showNewTaskInput[bucket]) this.$set(this.showNewTaskInput, bucket, !this.showNewTaskInput[bucket])
}, },
toggleBucketDropdown(bucketId) { toggleBucketDropdown(bucketId) {
const oldState = this.bucketOptionsDropDownActive[bucketId]
this.closeBucketDropdowns() // Close all eventually open dropdowns this.closeBucketDropdowns() // Close all eventually open dropdowns
this.$set(this.bucketOptionsDropDownActive, bucketId, !this.bucketOptionsDropDownActive[bucketId]) this.$set(this.bucketOptionsDropDownActive, bucketId, !oldState)
}, },
closeBucketDropdowns() { closeBucketDropdowns() {
this.showSetLimitInput = false this.showSetLimitInput = false

View File

@ -86,14 +86,16 @@
shareType="team" shareType="team"
type="namespace"/> type="namespace"/>
<modal <transition name="modal">
@close="showDeleteModal = false" <modal
v-if="showDeleteModal" @close="showDeleteModal = false"
@submit="deleteNamespace()"> v-if="showDeleteModal"
<span slot="header">Delete the namespace</span> @submit="deleteNamespace()">
<p slot="text">Are you sure you want to delete this namespace and all of its contents? <span slot="header">Delete the namespace</span>
<br/>This includes lists & tasks and <b>CANNOT BE UNDONE!</b></p> <p slot="text">Are you sure you want to delete this namespace and all of its contents?
</modal> <br/>This includes lists & tasks and <b>CANNOT BE UNDONE!</b></p>
</modal>
</transition>
</div> </div>
</template> </template>

View File

@ -382,17 +382,19 @@
</div> </div>
</div> </div>
<modal <transition name="modal">
@close="showDeleteModal = false" <modal
@submit="deleteTask()" @close="showDeleteModal = false"
v-if="showDeleteModal"> @submit="deleteTask()"
<span slot="header">Delete this task</span> v-if="showDeleteModal">
<p slot="text"> <span slot="header">Delete this task</span>
Are you sure you want to remove this task? <br/> <p slot="text">
This will also remove all attachments, reminders and relations associated with this task and Are you sure you want to remove this task? <br/>
<b>cannot be undone!</b> This will also remove all attachments, reminders and relations associated with this task and
</p> <b>cannot be undone!</b>
</modal> </p>
</modal>
</transition>
</div> </div>
</template> </template>

View File

@ -134,34 +134,38 @@
</card> </card>
<!-- Team delete modal --> <!-- Team delete modal -->
<modal <transition name="modal">
@close="showDeleteModal = false" <modal
@submit="deleteTeam()" @close="showDeleteModal = false"
v-if="showDeleteModal" @submit="deleteTeam()"
> v-if="showDeleteModal"
<span slot="header">Delete the team</span> >
<p slot="text"> <span slot="header">Delete the team</span>
Are you sure you want to delete this team and all of its <p slot="text">
members?<br/> Are you sure you want to delete this team and all of its
All team members will loose access to lists and namespaces members?<br/>
shared with this team.<br/> All team members will loose access to lists and namespaces
<b>This CANNOT BE UNDONE!</b> shared with this team.<br/>
</p> <b>This CANNOT BE UNDONE!</b>
</modal> </p>
</modal>
</transition>
<!-- User delete modal --> <!-- User delete modal -->
<modal <transition name="modal">
@close="showUserDeleteModal = false" <modal
@submit="deleteUser()" @close="showUserDeleteModal = false"
v-if="showUserDeleteModal" @submit="deleteUser()"
> v-if="showUserDeleteModal"
<span slot="header">Remove a user from the team</span> >
<p slot="text"> <span slot="header">Remove a user from the team</span>
Are you sure you want to remove this user from the team?<br/> <p slot="text">
They will loose access to all lists and namespaces this team has Are you sure you want to remove this user from the team?<br/>
access to.<br/> They will loose access to all lists and namespaces this team has
<b>This CANNOT BE UNDONE!</b> access to.<br/>
</p> <b>This CANNOT BE UNDONE!</b>
</modal> </p>
</modal>
</transition>
</div> </div>
</template> </template>