Move sidebar tabs to individual components

Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Julius Härtl 2020-01-25 10:20:58 +01:00
Родитель ad069e5e14
Коммит cf67c2e323
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4C614C6ED2CDE6DF
5 изменённых файлов: 214 добавлений и 75 удалений

Просмотреть файл

@ -21,12 +21,11 @@
-->
<template>
<AppSidebar v-if="currentCard !== null && currentBoard && copiedCard !== null"
:actions="toolbarActions"
<AppSidebar v-if="currentBoard && currentCard && copiedCard"
:title="currentCard.title"
:subtitle="subtitle"
@close="closeSidebar">
<template #action />
<template #secondary-actions />
<AppSidebarTab :order="0" name="Details" icon="icon-home">
<div class="section-wrapper">
<div v-tooltip="t('deck', 'Tags')" class="section-label icon-tag">
@ -104,29 +103,20 @@
type="deck-card" />
</div>
<h5>Description</h5>
<h5>{{ t('deck', 'Description') }}</h5>
<VueEasymde ref="markdownEditor" v-model="copiedCard.description" :configs="mdeConfig" />
</AppSidebarTab>
<AppSidebarTab :order="1" name="Attachments" icon="icon-attach">
{{ currentCard.attachments }}
<button class="icon-upload" @click="clickAddNewAttachmment()">
{{ t('deck', 'Upload attachment') }}
</button>
<AppSidebarTab :order="1" :name="t('deck', 'Attachments')" icon="icon-attach">
<CardSidebarTabAttachments :card="currentCard" />
</AppSidebarTab>
<AppSidebarTab :order="2" name="Comments" icon="icon-comment">
<CommentsTabSidebar :card="currentCard" />
<AppSidebarTab :order="2" :name="t('deck', 'Comments')" icon="icon-comment">
<CardSidebarTabComments :card="currentCard" />
</AppSidebarTab>
<AppSidebarTab :order="3" name="Timeline" icon="icon-activity">
<div v-if="isLoading" class="icon icon-loading" />
<ActivityEntry v-for="entry in cardActivity"
v-else
:key="entry.activity_id"
:activity="entry" />
<button v-if="activityLoadMore" @click="loadMore">
Load More
</button>
<AppSidebarTab :order="3" :name="t('deck', 'Timeline')" icon="icon-activity">
<CardSidebarTabActivity :card="currentCard" />
</AppSidebarTab>
</AppSidebar>
</template>
@ -141,15 +131,16 @@ import { mapState } from 'vuex'
import VueEasymde from 'vue-easymde/dist/VueEasyMDE.common'
import { Actions } from '@nextcloud/vue/dist/Components/Actions'
import { ActionButton } from '@nextcloud/vue/dist/Components/ActionButton'
import ActivityEntry from '../ActivityEntry'
import Color from '../../mixins/color'
import { CollectionList } from 'nextcloud-vue-collections'
import CommentsTabSidebar from './CommentsTabSidebar'
import CardSidebarTabAttachments from './CardSidebarTabAttachments'
import CardSidebarTabComments from './CardSidebarTabComments'
import CardSidebarTabActivity from './CardSidebarTabActivity'
export default {
name: 'CardSidebar',
components: {
ActivityEntry,
AppSidebar,
AppSidebarTab,
Multiselect,
@ -159,7 +150,9 @@ export default {
ActionButton,
Avatar,
CollectionList,
CommentsTabSidebar,
CardSidebarTabAttachments,
CardSidebarTabComments,
CardSidebarTabActivity,
},
mixins: [
Color,
@ -174,7 +167,6 @@ export default {
return {
assignedUsers: null,
addedLabelToCard: null,
isLoading: false,
copiedCard: null,
allLabels: null,
desc: null,
@ -187,20 +179,12 @@ export default {
},
lastModifiedRelative: null,
lastCreatedRemative: null,
params: {
type: 'filter',
since: 0,
object_type: 'deck_card',
object_id: this.id,
},
}
},
computed: {
...mapState({
currentBoard: state => state.currentBoard,
assignableUsers: state => state.assignableUsers,
cardActivity: 'activity',
activityLoadMore: 'activityLoadMore',
}),
currentCard() {
return this.$store.getters.cardById(this.id)
@ -208,24 +192,6 @@ export default {
subtitle() {
return t('deck', 'Modified') + ': ' + this.lastModifiedRelative + ' ' + t('deck', 'Created') + ': ' + this.lastCreatedRemative
},
toolbarActions() {
return [
{
action: () => {
},
icon: 'icon-archive-dark',
text: t('deck', 'Assign to me'),
},
{
action: () => {
},
icon: 'icon-archive',
text: t('deck', (this.showArchived ? 'Unarchive card' : 'Archive card')),
},
]
},
},
watch: {
'currentCard': {
@ -243,9 +209,6 @@ export default {
this.desc = this.currentCard.description
this.updateRelativeTimestamps()
this.params.object_id = this.id
this.loadCardActivity()
},
},
@ -313,23 +276,6 @@ export default {
}
this.$store.dispatch('removeLabel', data)
},
loadCardActivity() {
this.isLoading = true
this.$store.dispatch('loadActivity', this.params).then(response => {
this.isLoading = false
})
},
loadMore() {
const array = Object.values(this.cardActivity)
const aId = (array[array.length - 1].activity_id)
this.params.since = aId
this.loadCardActivity()
},
clickAddNewAttachmment() {
},
},
}
</script>

Просмотреть файл

@ -0,0 +1,98 @@
<!--
- @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>
-
- @author Julius Härtl <jus@bitgrid.net>
-
- @license GNU AGPL version 3 or any later version
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-->
<template>
<div>
<div v-if="isLoading" class="icon icon-loading" />
<div v-else>
<ActivityEntry v-for="entry in cardActivity"
:key="entry.activity_id"
:activity="entry" />
</div>
<button v-if="activityLoadMore" @click="loadMore">
Load More
</button>
</div>
</template>
<script>
import ActivityEntry from '../ActivityEntry'
import { mapState } from 'vuex'
export default {
name: 'CardSidebarTabActivity',
components: {
ActivityEntry,
},
props: {
card: {
type: Object,
default: null,
},
},
data() {
return {
id: 'activity',
isLoading: false,
params: {
type: 'filter',
since: 0,
object_type: 'deck_card',
object_id: this.id,
},
}
},
computed: {
...mapState({
currentBoard: state => state.currentBoard,
assignableUsers: state => state.assignableUsers,
cardActivity: 'activity',
activityLoadMore: 'activityLoadMore',
}),
},
mounted() {
this.params.object_id = this.card.id
this.loadCardActivity()
},
methods: {
loadCardActivity() {
this.isLoading = true
this.$store.dispatch('loadActivity', this.params).then(response => {
this.isLoading = false
})
},
loadMore() {
const array = Object.values(this.cardActivity)
const aId = (array[array.length - 1].activity_id)
this.params.since = aId
this.loadCardActivity()
},
},
}
</script>
<style scoped>
</style>

Просмотреть файл

@ -0,0 +1,51 @@
<!--
- @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>
-
- @author Julius Härtl <jus@bitgrid.net>
-
- @license GNU AGPL version 3 or any later version
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-->
<template>
<div>
{{ card.attachments }}
<button class="icon-upload" @click="clickAddNewAttachmment()">
{{ t('deck', 'Upload attachment') }}
</button>
</div>
</template>
<script>
export default {
name: 'CardSidebarTabAttachments',
props: {
card: {
type: Object,
default: null,
},
},
methods: {
clickAddNewAttachmment() {
},
},
}
</script>
<style scoped>
</style>

Просмотреть файл

@ -36,7 +36,7 @@
</div>
</div>
<ul id="commentsFeed" v-if="comments[card.id] && comments[card.id].length > 0">
<ul v-if="comments[card.id] && comments[card.id].length > 0" id="commentsFeed">
<CommentItem v-for="comment in comments[card.id]"
:key="comment.id"
:comment="comment"
@ -46,8 +46,8 @@
</a>
</ul>
<div v-else-if="isLoading" class="icon icon-loading" />
<div class="emptycontent" v-else>
<div class="icon-comment"></div>
<div v-else class="emptycontent">
<div class="icon-comment" />
<p>Keine Kommentare bisher. Beginne die Diskussion!</p>
</div>
</div>
@ -64,7 +64,7 @@ import { Avatar } from '@nextcloud/vue'
import CommentItem from './CommentItem'
export default {
name: 'CommentsTabSidebar',
name: 'CardSidebarTabComments',
components: {
Avatar,
CommentItem,

44
src/css/comments.scss Normal file
Просмотреть файл

@ -0,0 +1,44 @@
.comment-form form {
display: flex;
flex-grow: 1;
position: relative;
.editor__content::v-deep {
flex-grow: 1;
margin-left: 44px;
.ProseMirror {
width: 100%;
}
}
input[type="submit"] {
width: 44px;
height: 44px;
margin: 0;
padding: 13px;
background-color: transparent;
border: none;
opacity: .3;
position: absolute;
bottom: 0;
right: 0;
}
}
.comment {
margin-bottom: 10px;
}
.comment--header {
display: flex;
align-items: center;
color: var(--color-text-light);
.username {
flex-grow: 1;
padding: 10px;
}
}
.comment--content {
margin-left: 44px;
}