@@ -48,7 +48,7 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="board-action-buttons">
|
||||
<button title="Show archived cards" class="icon icon-archive" />
|
||||
<button title="Show archived cards" class="icon icon-archive" @click="toggleShowArchived" />
|
||||
<button :class="[(compactMode ? 'icon-toggle-compact-collapsed' : 'icon-toggle-compact-expanded')]" title="Toggle compact mode" class="icon"
|
||||
@click="toggleCompactMode" />
|
||||
<router-link v-tooltip="t('deck', 'Board settings')" :to="{name: 'board.details'}" class="icon-settings-dark"
|
||||
@@ -91,6 +91,9 @@ export default {
|
||||
toggleCompactMode() {
|
||||
this.$store.dispatch('toggleCompactMode')
|
||||
},
|
||||
toggleShowArchived() {
|
||||
this.$store.dispatch('toggleShowArchived')
|
||||
},
|
||||
clickAddNewStack() {
|
||||
this.stack = { title: this.newStackTitle }
|
||||
this.$store.dispatch('createStack', this.stack)
|
||||
|
||||
@@ -27,22 +27,6 @@
|
||||
<container lock-axix="y" orientation="horizontal" @drop="onDropStack">
|
||||
<draggable v-for="stack in stacksByBoard" :key="stack.id" class="stack">
|
||||
<stack :stack="stack" />
|
||||
<!-- <h3>{{ stack.title }}
|
||||
<button v-tooltip="t('deck', 'Delete')" class="icon-delete"
|
||||
@click="deleteStack(stack)" />
|
||||
</h3>
|
||||
<container :get-child-payload="payloadForCard(stack.id)" group-name="stack" @drop="($event) => onDropCard(stack.id, $event)">
|
||||
<draggable v-for="card in cardsByStack(stack.id)" :key="card.id">
|
||||
<card-item v-if="card" :id="card.id" />
|
||||
</draggable>
|
||||
</container>
|
||||
<div class="card create">
|
||||
<div title="Add card">
|
||||
<i class="icon icon-add" />
|
||||
<span class="hidden-visually">Add card</span>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
</draggable>
|
||||
</container>
|
||||
</div>
|
||||
@@ -59,13 +43,11 @@
|
||||
import { Container, Draggable } from 'vue-smooth-dnd'
|
||||
import { mapState } from 'vuex'
|
||||
import Controls from '../Controls'
|
||||
/* import CardItem from '../cards/CardItem' */
|
||||
import Stack from './Stack'
|
||||
|
||||
export default {
|
||||
name: 'Board',
|
||||
components: {
|
||||
/* CardItem, */
|
||||
Controls,
|
||||
Container,
|
||||
Draggable,
|
||||
@@ -87,7 +69,8 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
board: state => state.currentBoard
|
||||
board: state => state.currentBoard,
|
||||
showArchived: state => state.showArchived
|
||||
}),
|
||||
stacksByBoard() {
|
||||
return this.$store.getters.stacksByBoard(this.board.id)
|
||||
@@ -97,7 +80,11 @@ export default {
|
||||
} */
|
||||
},
|
||||
watch: {
|
||||
'$route': 'fetchData'
|
||||
'$route': 'fetchData',
|
||||
showArchived() {
|
||||
|
||||
this.fetchData()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<app-sidebar
|
||||
<app-sidebar v-if="board != null"
|
||||
:actions="[]"
|
||||
:title="board.title"
|
||||
@close="closeSidebar">
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<collection-list v-if="board.id" :id=""board.id"" :name="board.title"
|
||||
<collection-list v-if="board.id" :id="`${board.id}`" :name="board.title"
|
||||
type="deck" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
- @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
|
||||
-
|
||||
- @author Julius Härtl <jus@bitgrid.net>
|
||||
- @author Jakob Röhrl <jakob.roehrl@web.de>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
|
||||
@@ -21,17 +21,17 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<app-sidebar
|
||||
<app-sidebar v-if="currentCard != null"
|
||||
:actions="[]"
|
||||
title="andy-yeo-1387151-unsplash.jpg"
|
||||
subtitle="4,3 MB, last edited 19 days ago"
|
||||
:title="currentCard.title"
|
||||
:subtitle="subtitle"
|
||||
@close="closeSidebar">
|
||||
<template #action />
|
||||
<AppSidebarTab name="Description" icon="icon-description">
|
||||
this is the description tab
|
||||
{{ currentCard.description }}
|
||||
</AppSidebarTab>
|
||||
<AppSidebarTab name="Attachments" icon="icon-files-dark">
|
||||
this is the files tab
|
||||
{{ currentCard.attachments }}
|
||||
</AppSidebarTab>
|
||||
<AppSidebarTab name="Timeline" icon="icon-activity">
|
||||
this is the activity tab
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
<script>
|
||||
import { AppSidebar, AppSidebarTab } from 'nextcloud-vue'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'CardSidebar',
|
||||
@@ -52,6 +53,17 @@ export default {
|
||||
return {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
currentCard: state => state.currentCard
|
||||
}),
|
||||
subtitle() {
|
||||
let lastModified = this.currentCard.lastModified
|
||||
let createdAt = this.currentCard.createdAt
|
||||
|
||||
return t('deck', 'Modified') + ': ' + lastModified + ' ' + t('deck', 'Created') + ': ' + createdAt
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
closeSidebar() {
|
||||
this.$router.push({ name: 'board' })
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
<div :class="{'compact': compactMode}" tag="div" class="card"
|
||||
@click="openCard">
|
||||
<div class="card-upper">
|
||||
<h3 @click.stop="startEditing">{{ card.title }}</h3>
|
||||
<h3 @click.stop="startEditing(card)">{{ card.title }}</h3>
|
||||
<transition name="fade" mode="out-in">
|
||||
<form v-if="editing">
|
||||
<input :value="card.title" type="text" autofocus>
|
||||
<input type="button" class="icon-confirm" @click="clickTitleEditSave">
|
||||
<input v-model="copiedCard.title" type="text" autofocus>
|
||||
<input type="button" class="icon-confirm" @click="finishedEdit(card)">
|
||||
</form>
|
||||
<action v-if="!editing" :actions="visibilityPopover" @click.stop="" />
|
||||
</transition>
|
||||
@@ -67,12 +67,14 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
menuOpened: false,
|
||||
editing: false
|
||||
editing: false,
|
||||
copiedCard: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
compactMode: state => state.compactMode
|
||||
compactMode: state => state.compactMode,
|
||||
showArchived: state => state.showArchived
|
||||
}),
|
||||
card() {
|
||||
return this.$store.getters.cardById(this.id)
|
||||
@@ -97,22 +99,30 @@ export default {
|
||||
visibilityPopover() {
|
||||
return [
|
||||
{
|
||||
action: () => {},
|
||||
action: () => {
|
||||
this.assignCardToMe()
|
||||
},
|
||||
icon: 'icon-archive-dark',
|
||||
text: t('deck', 'Assign to me')
|
||||
},
|
||||
{
|
||||
action: () => {},
|
||||
icon: 'icon-archive-dark',
|
||||
text: t('deck', 'Archive card')
|
||||
action: () => {
|
||||
this.archiveUnarchiveCard()
|
||||
},
|
||||
icon: 'icon-archive',
|
||||
text: t('deck', (this.showArchived ? 'Unarchive card' : 'Archive card'))
|
||||
},
|
||||
{
|
||||
action: () => {},
|
||||
icon: 'icon-delete-dark',
|
||||
action: () => {
|
||||
this.deleteCard()
|
||||
},
|
||||
icon: 'icon-delete',
|
||||
text: t('deck', 'Delete card')
|
||||
},
|
||||
{
|
||||
action: () => {},
|
||||
action: () => {
|
||||
this.setCurrentCard()
|
||||
},
|
||||
icon: 'icon-settings-dark',
|
||||
text: t('deck', 'Card details')
|
||||
}
|
||||
@@ -121,7 +131,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
openCard() {
|
||||
this.$router.push({ name: 'card', params: { cardId: 123 } })
|
||||
this.$router.push({ name: 'card', params: { cardId: this.id } })
|
||||
},
|
||||
togglePopoverMenu() {
|
||||
this.menuOpened = !this.menuOpened
|
||||
@@ -129,13 +139,33 @@ export default {
|
||||
hidePopoverMenu() {
|
||||
this.menuOpened = false
|
||||
},
|
||||
startEditing() {
|
||||
startEditing(card) {
|
||||
this.copiedCard = Object.assign({}, card)
|
||||
this.editing = true
|
||||
},
|
||||
clickTitleEditSave() {
|
||||
|
||||
this.editing = false
|
||||
finishedEdit(card) {
|
||||
if (this.copiedCard.title !== card.title) {
|
||||
this.$store.dispatch('updateCard', this.copiedCard)
|
||||
}
|
||||
this.editing = false
|
||||
},
|
||||
deleteCard() {
|
||||
this.$store.dispatch('deleteCard', this.card)
|
||||
},
|
||||
archiveUnarchiveCard() {
|
||||
this.copiedCard = Object.assign({}, this.card)
|
||||
this.copiedCard.archived = !this.copiedCard.archived
|
||||
this.$store.dispatch('archiveUnarchiveCard', this.copiedCard)
|
||||
},
|
||||
assignCardToMe() {
|
||||
this.copiedCard = Object.assign({}, this.card)
|
||||
this.copiedCard.assignUser = this.card.owner.uid
|
||||
this.$store.dispatch('assignCardToMe', this.copiedCard)
|
||||
},
|
||||
setCurrentCard() {
|
||||
this.$store.dispatch('setCurrentCard', this.card)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -44,4 +44,79 @@ export class CardApi {
|
||||
})
|
||||
}
|
||||
|
||||
deleteCard(cardId) {
|
||||
return axios.delete(this.url(`/cards/${cardId}`))
|
||||
.then(
|
||||
(response) => {
|
||||
return Promise.resolve(response.data)
|
||||
},
|
||||
(err) => {
|
||||
return Promise.reject(err)
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
}
|
||||
|
||||
updateCard(card) {
|
||||
return axios.put(this.url(`/cards/${card.id}`), card)
|
||||
.then(
|
||||
(response) => {
|
||||
return Promise.resolve(response.data)
|
||||
},
|
||||
(err) => {
|
||||
return Promise.reject(err)
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
}
|
||||
|
||||
assignUser(card) {
|
||||
return axios.put(this.url(`/cards/${card.id}/assignUser`), card.assignUser)
|
||||
.then(
|
||||
(response) => {
|
||||
return Promise.resolve(response.data)
|
||||
},
|
||||
(err) => {
|
||||
return Promise.reject(err)
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
}
|
||||
|
||||
archiveCard(card) {
|
||||
return axios.put(this.url(`/cards/${card.id}/archive`))
|
||||
.then(
|
||||
(response) => {
|
||||
return Promise.resolve(response.data)
|
||||
},
|
||||
(err) => {
|
||||
return Promise.reject(err)
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
}
|
||||
|
||||
unArchiveCard(card) {
|
||||
return axios.put(this.url(`/cards/${card.id}/unarchive`))
|
||||
.then(
|
||||
(response) => {
|
||||
return Promise.resolve(response.data)
|
||||
},
|
||||
(err) => {
|
||||
return Promise.reject(err)
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,6 +44,21 @@ export class StackApi {
|
||||
})
|
||||
}
|
||||
|
||||
loadArchivedStacks(boardId) {
|
||||
return axios.get(this.url(`/stacks/${boardId}/archived`))
|
||||
.then(
|
||||
(response) => {
|
||||
return Promise.resolve(response.data)
|
||||
},
|
||||
(err) => {
|
||||
return Promise.reject(err)
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Stack} stack
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
import { CardApi } from './../services/CardApi'
|
||||
import Vue from 'vue'
|
||||
|
||||
const apiClient = new CardApi()
|
||||
|
||||
@@ -37,6 +38,9 @@ export default {
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
clearCards(state) {
|
||||
state.cards = []
|
||||
},
|
||||
addCard(state, card) {
|
||||
let existingIndex = state.cards.findIndex(_card => _card.id === card.id)
|
||||
if (existingIndex !== -1) {
|
||||
@@ -45,6 +49,21 @@ export default {
|
||||
} else {
|
||||
state.cards.push(card)
|
||||
}
|
||||
},
|
||||
deleteCard(state, card) {
|
||||
let existingIndex = state.cards.findIndex(_card => _card.id === card.id)
|
||||
if (existingIndex !== -1) {
|
||||
state.cards.splice(existingIndex, 1)
|
||||
}
|
||||
},
|
||||
updateTitle(state, card) {
|
||||
let existingIndex = state.cards.findIndex(_card => _card.id === card.id)
|
||||
if (existingIndex !== -1) {
|
||||
state.cards[existingIndex].title = card.title
|
||||
}
|
||||
},
|
||||
assignCardToMe(state, card) {
|
||||
// let existingIndex = state.cards.findIndex(_card => _card.id === card.id)
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
@@ -53,6 +72,35 @@ export default {
|
||||
.then((createdCard) => {
|
||||
commit('addCard', createdCard)
|
||||
})
|
||||
},
|
||||
updateCard({ commit }, card) {
|
||||
apiClient.updateCard(card)
|
||||
.then((updatedCard) => {
|
||||
commit('updateTitle', updatedCard)
|
||||
})
|
||||
},
|
||||
deleteCard({ commit }, card) {
|
||||
apiClient.deleteCard(card.id)
|
||||
.then((card) => {
|
||||
commit('deleteCard', card)
|
||||
})
|
||||
},
|
||||
archiveUnarchiveCard({ commit }, card) {
|
||||
let call = 'archiveCard'
|
||||
if (card.archived === false) {
|
||||
call = 'unArchiveCard'
|
||||
}
|
||||
|
||||
apiClient[call](card)
|
||||
.then((card) => {
|
||||
commit('deleteCard', card)
|
||||
})
|
||||
},
|
||||
assignCardToMe({ commit }, card) {
|
||||
apiClient.assignUser(card)
|
||||
.then((card) => {
|
||||
commit('assignCardToMe', card)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,10 +46,12 @@ export default new Vuex.Store({
|
||||
},
|
||||
strict: debug,
|
||||
state: {
|
||||
showArchived: false,
|
||||
navShown: true,
|
||||
compactMode: false,
|
||||
sidebarShown: false,
|
||||
currentBoard: null,
|
||||
currentCard: null,
|
||||
boards: [],
|
||||
sharees: [],
|
||||
boardFilter: BOARD_FILTERS.ALL
|
||||
@@ -90,6 +92,9 @@ export default new Vuex.Store({
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
toggleShowArchived(state) {
|
||||
state.showArchived = !state.showArchived
|
||||
},
|
||||
/**
|
||||
* Adds or replaces a board in the store.
|
||||
* Matches a board by it's id.
|
||||
@@ -143,6 +148,9 @@ export default new Vuex.Store({
|
||||
setCurrentBoard(state, board) {
|
||||
state.currentBoard = board
|
||||
},
|
||||
setCurrentCard(state, card) {
|
||||
state.currentCard = card
|
||||
},
|
||||
|
||||
// label mutators
|
||||
removeLabelFromCurrentBoard(state, labelId) {
|
||||
@@ -196,6 +204,9 @@ export default new Vuex.Store({
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
toggleShowArchived({ commit }) {
|
||||
commit('toggleShowArchived')
|
||||
},
|
||||
/**
|
||||
* @param commit
|
||||
* @param state
|
||||
@@ -272,6 +283,9 @@ export default new Vuex.Store({
|
||||
setCurrentBoard({ commit }, board) {
|
||||
commit('setCurrentBoard', board)
|
||||
},
|
||||
setCurrentCard({ commit }, card) {
|
||||
commit('setCurrentCard', card)
|
||||
},
|
||||
|
||||
// label actions
|
||||
removeLabelFromCurrentBoard({ commit }, label) {
|
||||
|
||||
@@ -77,7 +77,12 @@ export default {
|
||||
})
|
||||
},
|
||||
loadStacks({ commit }, board) {
|
||||
apiClient.loadStacks(board.id)
|
||||
commit('clearCards')
|
||||
let call = 'loadStacks'
|
||||
if (this.state.showArchived === true) {
|
||||
call = 'loadArchivedStacks'
|
||||
}
|
||||
apiClient[call](board.id)
|
||||
.then((stacks) => {
|
||||
for (let i in stacks) {
|
||||
let stack = stacks[i]
|
||||
|
||||
Reference in New Issue
Block a user