new functions

Signed-off-by: Jakob <jakob.roehrl@web.de>
This commit is contained in:
Jakob
2019-07-24 08:08:46 +02:00
committed by Julius Härtl
parent 38dc7945dd
commit 4a45687a28
9 changed files with 226 additions and 55 deletions

View File

@@ -1,18 +1,33 @@
<template> <template>
<div> <div>
<h3>{{ t('deck', 'Deleted stacks') }}</h3>
<h3>{{ t('deck', 'Deleted stacks') }}</h3>
<ul> <ul>
<!-- <li ng-repeat="deletedStack in stackservice.deleted"> <li v-for="deletedStack in deletedStacks" :key="deletedStack.id">
<span class="icon icon-deck"></span> <span class="icon icon-deck" />
<span class="title">{{deletedStack.title}}</span> <span class="title">{{ deletedStack.title }}</span>
<span class="live-relative-timestamp" data-timestamp="{{ deletedStack.deletedAt*1000 }}">{{deletedStack.deletedAt | relativeDateFilter }}</span> <span class="live-relative-timestamp" />
<a ng-click="stackUndoDelete(deletedStack)"><span class="icon icon-history"></span></a> <button
</li> --> :title="t('settings', 'Undo')"
class="app-navigation-entry-deleted-button icon-history"
@click="stackUndoDelete(deletedStack)" />
<!-- <span class="live-relative-timestamp" data-timestamp="{{ deletedStack.deletedAt*1000 }}">{{deletedStack.deletedAt | relativeDateFilter }}</span>
<a @click="stackUndoDelete(deletedStack)"><span class="icon icon-history"></span></a> -->
</li>
</ul> </ul>
<h3>{{ t('deck', 'Deleted cards') }}</h3> <h3>{{ t('deck', 'Deleted cards') }}</h3>
<ul> <ul>
<li v-for="deletedCard in deletedCards" :key="deletedCard.id">
<div class="icon icon-deck" />
<span class="title">{{ deletedCard.title }}</span>
<button
:title="t('settings', 'Undo')"
class="app-navigation-entry-deleted-button icon-history"
@click="cardUndoDelete(deletedCards)" />
</li>
<!-- <li ng-repeat="deletedCard in cardservice.deleted"> <!-- <li ng-repeat="deletedCard in cardservice.deleted">
<span class="icon icon-deck"></span> <span class="icon icon-deck"></span>
<span class="title">{{deletedCard.title}} ({{stackservice.tryAllThenDeleted(deletedCard.stackId).title}})</span> <span class="title">{{deletedCard.title}} ({{stackservice.tryAllThenDeleted(deletedCard.stackId).title}})</span>
@@ -40,13 +55,16 @@ export default {
}, },
data() { data() {
return { return {
isLoading: false isLoading: false,
copiedDeletedStack: null,
copiedDeletedCard: null
} }
}, },
computed: { computed: {
...mapState({ ...mapState({
deletedStacks: state => state.deletedStacks deletedStacks: state => state.stack.deletedStacks,
// deletedCards: state => state.deletedCards deletedCards: state => state.stack.deletedCards,
currentBoard: state => state.currentBoard
}) })
}, },
@@ -56,10 +74,19 @@ export default {
methods: { methods: {
getData() { getData() {
this.isLoading = true this.isLoading = true
this.$store.dispatch('deletedItems', this.currentBoard.id).then(response => {
this.$store.dispatch('deletedItems', 1).then(response => {
this.isLoading = false this.isLoading = false
}) })
},
stackUndoDelete(deletedStack) {
this.copiedDeletedStack = Object.assign({}, deletedStack)
this.copiedDeletedStack.deletedAt = 0
this.$store.dispatch('stackUndoDelete', this.copiedDeletedStack)
},
cardUndoDelete(deletedCard) {
this.copiedDeletedCard = Object.assign({}, deletedCard)
this.copiedDeletedCard.deletedAt = 0
this.$store.dispatch('cardUndoDelete', this.copiedDeletedCard)
} }
} }
} }
@@ -81,4 +108,20 @@ export default {
flex-grow: 1; flex-grow: 1;
} }
} }
li {
display: flex;
flex-direction: row;
* {
flex-basis: 44px;
}
.title {
flex-grow: 2;
}
.live-relative-timestamp {
flex-grow: 1;
}
}
</style> </style>

View File

@@ -23,7 +23,7 @@
<template> <template>
<div> <div>
order: {{ stack.order }}
<h3 v-if="!editing" @click="startEditing(stack)">{{ stack.title }} <h3 v-if="!editing" @click="startEditing(stack)">{{ stack.title }}
<button v-tooltip="t('deck', 'Delete')" class="icon-delete" <button v-tooltip="t('deck', 'Delete')" class="icon-delete"
@click="deleteStack(stack)" /> @click="deleteStack(stack)" />
@@ -38,7 +38,8 @@
</div> </div>
</transition> </transition>
<container :get-child-payload="payloadForCard(stack.id)" group-name="stack" @drop="($event) => onDropCard(stack.id, $event)"> <!-- <container :get-child-payload="payloadForCard(stack.id)" group-name="stack" @drop="($event) => onDropCard(stack.id, $event)"> -->
<container :get-child-payload="payloadForCard(stack.id)" group-name="stack" @drop="onDropCard">
<draggable v-for="card in cardsByStack(stack.id)" :key="card.id"> <draggable v-for="card in cardsByStack(stack.id)" :key="card.id">
<card-item v-if="card" :id="card.id" /> <card-item v-if="card" :id="card.id" />
</draggable> </draggable>
@@ -93,7 +94,6 @@ export default {
methods: { methods: {
onDropCard({ removedIndex, addedIndex }) { onDropCard({ removedIndex, addedIndex }) {
}, },
payloadForCard(stackId) { payloadForCard(stackId) {
return index => { return index => {

View File

@@ -24,30 +24,35 @@
<app-sidebar v-if="currentCard != null" <app-sidebar v-if="currentCard != null"
:actions="toolbarActions" :actions="toolbarActions"
:title="currentCard.title" :title="currentCard.title"
:subtitle="subtitle"
@close="closeSidebar"> @close="closeSidebar">
<template #action /> <template #action />
<AppSidebarTab name="Details" icon="icon-home"> <AppSidebarTab name="Details" icon="icon-home">
{{ currentCard }}
<p>Tags</p> <p>Tags</p>
<multiselect v-model="addedLabelToCard" :options="currentBoard.labels" label="label" <multiselect v-model="allLabels" :multiple="true" :options="currentBoard.labels"
@input="clickaddLabelToCard"> :taggable="true" label="title"
track-by="id" @select="addLabelToCard" @remove="removeLabelFromCard">
<template #option="scope"> <template #option="scope">
{{ scope.option.title }} <span>{{ scope.option.title }}</span>
</template> </template>
</multiselect> </multiselect>
<p>Assign to user</p> <p>Assign to user</p>
<multiselect v-model="addAclToCard" :options="unallocatedSharees" label="label" <multiselect v-model="addAclToCard" :options="unallocatedSharees" label="label"
@input="clickAddAclToCard" @search-change="asyncFind"> track-by="value.shareWith"
@select="assignUserToCard" @remove="removeUserFromCard" @search-change="asyncFind">
<template #option="scope"> <template #option="scope">
{{ scope.option.label }} {{ scope.option.label }}
</template> </template>
</multiselect> </multiselect>
<p>Due to</p> <p>Due to</p>
<DatetimePicker v-model="copiedCard.duedate" type="datetime" lang="en"
format="YYYY-MM-DD HH:mm" confirm @change="setDue()" />
<DatetimePicker /> <hr>
<p>{{ subtitle }}</p>
</AppSidebarTab> </AppSidebarTab>
<AppSidebarTab name="Description" icon="icon-description"> <AppSidebarTab name="Description" icon="icon-description">
@@ -80,7 +85,8 @@ export default {
addAclToCard: null, addAclToCard: null,
addedLabelToCard: null, addedLabelToCard: null,
isLoading: false, isLoading: false,
copiedCard: null copiedCard: null,
allLabels: null
} }
}, },
computed: { computed: {
@@ -127,22 +133,37 @@ export default {
watch: { watch: {
currentCard() { currentCard() {
this.copiedCard = JSON.parse(JSON.stringify(this.currentCard)) this.copiedCard = JSON.parse(JSON.stringify(this.currentCard))
this.allLabels = this.currentCard.labels
this.addAclToCard = this.currentCard.assignedUsers
} }
},
created() {
}, },
methods: { methods: {
saveDesc() { setDue() {
this.$store.dispatch('updateCard', this.copiedCard) this.$store.dispatch('updateCardDue', this.copiedCard)
}, },
saveDesc() {
this.$store.dispatch('updateCardDesc', this.copiedCard)
},
asyncFind(query) { asyncFind(query) {
this.isLoading = true this.isLoading = true
this.$store.dispatch('loadSharees').then(response => { this.$store.dispatch('loadSharees').then(response => {
this.isLoading = false this.isLoading = false
}) })
}, },
closeSidebar() { closeSidebar() {
this.$router.push({ name: 'board' }) this.$router.push({ name: 'board' })
}, },
clickAddAclToCard() {
assignUserToCard(user) {
this.copiedCard.assignedUsers.push(user)
this.copiedCard.newUserUid = user.value.shareWith
this.$store.dispatch('assignCardToUser', this.copiedCard)
/* this.addAclForAPI = { /* this.addAclForAPI = {
type: 0, type: 0,
participant: this.addAcl.value.shareWith, participant: this.addAcl.value.shareWith,
@@ -152,18 +173,35 @@ export default {
} }
this.$store.dispatch('addAclToCurrentBoard', this.addAclForAPI) */ this.$store.dispatch('addAclToCurrentBoard', this.addAclForAPI) */
}, },
clickaddLabelToCard() {
this.copiedCard.labels.push(this.addedLabelToCard) removeUserFromCard(user) {
},
addLabelToCard(newLabel) {
this.copiedCard.labels.push(newLabel)
let data = { let data = {
cardId: this.copiedCard.id, card: this.copiedCard,
labelId: this.addedLabelToCard.id labelId: newLabel.id
} }
this.$store.dispatch('assignLabel', data) this.$store.dispatch('addLabel', data)
},
removeLabelFromCard(removedLabel) {
let removeIndex = this.copiedCard.labels.findIndex((label) => {
return label.id === removedLabel.id
})
if (removeIndex !== -1) {
this.copiedCard.labels.splice(removeIndex, 1)
}
let data = {
card: this.copiedCard,
labelId: removedLabel.id
}
this.$store.dispatch('removeLabel', data)
} }
} }
} }
</script> </script>
<style lang="scss" scoped>
</style>

View File

@@ -24,14 +24,15 @@
<div class="badges"> <div class="badges">
<div v-if="card.attechments" class="card-files icon icon-files-dark" /> <div v-if="card.attechments" class="card-files icon icon-files-dark" />
<div v-if="card.description" class="card-comments icon icon-comment" /> <div v-if="card.description" class="card-comments icon icon-comment" />
<div v-if="card.duedate" :class="{'icon-calendar': true, 'icon-calendar-dark': false}" class="due icon now"> <div v-if="card.duedate" :class="{'icon-calendar': true, 'icon-calendar-dark': false}" class="due icon now">
<span>Now</span> <span>{{ dueTimeDiff }}</span>
</div> </div>
<div v-if="true" class="card-tasks icon icon-checkmark"> <div v-if="true" class="card-tasks icon icon-checkmark">
<span>0/0</span> <span>0/0</span>
</div> </div>
<div v-if="true" class="card-assigned-users"> <div v-if="card.assignedUsers" class="card-assigned-users">
<avatar user="admin" /> <avatar v-for="user in card.assignedUsers" :key="user.id" user="user.participant.primaryKey" />
</div> </div>
</div> </div>
</template> </template>
@@ -51,6 +52,40 @@ export default {
compactMode() { compactMode() {
return false return false
}, },
dueIcon() {
let timeInHours = Math.round((Date.parse(this.card.duedate) - Date.now()) / 1000 / 60 / 60 / 24)
if (timeInHours === 1) {
return 'due icon next'
}
if (timeInHours === 0) {
return 'due icon now'
}
if (timeInHours < 0) {
return 'due icon overdue'
}
},
dueTimeDiff() {
let unit = 'Minutes'
let timeInMin = (Date.parse(this.card.duedate) - Date.now()) / 60000
if (timeInMin > 59) {
timeInMin /= 60
unit = 'Hours'
}
if (timeInMin > 23) {
timeInMin /= 24
unit = 'Days'
}
if (timeInMin > 355) {
timeInMin /= 355
unit = 'Years'
}
return Math.round(timeInMin) + ' ' + unit
},
card() { card() {
return this.$store.getters.cardById(this.id) return this.$store.getters.cardById(this.id)
} }

View File

@@ -154,7 +154,7 @@ export default {
assignCardToMe() { assignCardToMe() {
this.copiedCard = Object.assign({}, this.card) this.copiedCard = Object.assign({}, this.card)
this.copiedCard.newUserUid = this.card.owner.uid this.copiedCard.newUserUid = this.card.owner.uid
this.$store.dispatch('assignCardToMe', this.copiedCard) this.$store.dispatch('assignCardToUser', this.copiedCard)
}, },
setCurrentCard() { setCurrentCard() {
this.$store.dispatch('setCurrentCard', this.card) this.$store.dispatch('setCurrentCard', this.card)

View File

@@ -75,7 +75,7 @@ export class CardApi {
} }
assignUser(card) { assignUser(card) {
return axios.post(this.url(`/cards/${card.id}/assign`), card.newUserUid) return axios.post(this.url(`/cards/${card.id}/assign`), { userId: card.newUserUid })
.then( .then(
(response) => { (response) => {
return Promise.resolve(response.data) return Promise.resolve(response.data)
@@ -120,7 +120,22 @@ export class CardApi {
} }
assignLabelToCard(data) { assignLabelToCard(data) {
return axios.post(this.url(`/cards/${data.cardId}/label/${data.labelId}`)) return axios.post(this.url(`/cards/${data.card.id}/label/${data.labelId}`))
.then(
(response) => {
return Promise.resolve(response.data)
},
(err) => {
return Promise.reject(err)
}
)
.catch((err) => {
return Promise.reject(err)
})
}
removeLabelFromCard(data) {
return axios.delete(this.url(`/cards/${data.card.id}/label/${data.labelId}`))
.then( .then(
(response) => { (response) => {
return Promise.resolve(response.data) return Promise.resolve(response.data)

View File

@@ -62,20 +62,30 @@ export default {
state.cards[existingIndex].title = card.title state.cards[existingIndex].title = card.title
} }
}, },
assignCardToMe(state, card) { assignCardToUser(state, card) {
console.log(card)
// let existingIndex = state.cards.findIndex(_card => _card.id === card.id) // let existingIndex = state.cards.findIndex(_card => _card.id === card.id)
/* if (existingIndex !== -1) { /* if (existingIndex !== -1) {
} */ } */
}, },
updateCard(state, card) { updateCardDesc(state, card) {
// console.log(card) let existingIndex = state.cards.findIndex(_card => _card.id === card.id)
// new card is not returned! if (existingIndex !== -1) {
// let existingIndex = state.cards.findIndex(_card => _card.id === card.id) state.cards[existingIndex].description = card.description
/* if (existingIndex !== -1) { }
state.cards[existingIndex] = card },
} */ updateCardDue(state, card) {
let existingIndex = state.cards.findIndex(_card => _card.id === card.id)
if (existingIndex !== -1) {
state.cards[existingIndex].duedate = card.duedate
}
},
updateCardLabels(state, card) {
let existingIndex = state.cards.findIndex(_card => _card.id === card.id)
if (existingIndex !== -1) {
let existingCard = state.cards.find(_card => _card.id === card.id)
existingCard.labels = card.labels
}
} }
}, },
actions: { actions: {
@@ -108,17 +118,41 @@ export default {
commit('deleteCard', card) commit('deleteCard', card)
}) })
}, },
assignCardToMe({ commit }, card) { assignCardToUser({ commit }, card) {
apiClient.assignUser(card) apiClient.assignUser(card)
.then((card) => { .then(() => {
commit('assignCardToMe', card) commit('assignCardToUser')
}) })
}, },
assignLabel({ commit }, data) { addLabel({ commit }, data) {
apiClient.assignLabelToCard(data) apiClient.assignLabelToCard(data)
.then(() => {
commit('updateCardLabels', data.card)
})
},
removeLabel({ commit }, data) {
apiClient.removeLabelFromCard(data)
.then(() => {
commit('updateCardLabels', data.card)
})
},
cardUndoDelete({ commit }, card) {
apiClient.updateCard(card)
.then((card) => { .then((card) => {
commit('updateCard', card) commit('updateCard', card)
}) })
},
updateCardDesc({ commit }, card) {
apiClient.updateCard(card)
.then((updatedCard) => {
commit('updateCardDesc', updatedCard)
})
},
updateCardDue({ commit }, card) {
apiClient.updateCard(card)
.then((card) => {
commit('updateCardDue', card)
})
} }
} }
} }

View File

@@ -262,7 +262,6 @@ export default new Vuex.Store({
params.append('itemType', 0) params.append('itemType', 0)
params.append('itemType', 1) params.append('itemType', 1)
axios.get(OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees', { params }).then((response) => { axios.get(OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees', { params }).then((response) => {
// commit('setSharees', response.data.ocs.data.users)
commit('setSharees', response.data.ocs.data) commit('setSharees', response.data.ocs.data)
}) })
}, },

View File

@@ -68,7 +68,7 @@ export default {
} }
}, },
setDeletedStacks(state, delStacks) { setDeletedStacks(state, delStacks) {
state.deletedStacks.push(delStacks) state.deletedStacks.push(delStacks[0])
}, },
setDeletedCards(state, delCards) { setDeletedCards(state, delCards) {
state.deletedCards.push(delCards) state.deletedCards.push(delCards)
@@ -130,6 +130,13 @@ export default {
.then((deletedCards) => { .then((deletedCards) => {
commit('setDeletedCards', deletedCards) commit('setDeletedCards', deletedCards)
}) })
},
stackUndoDelete({ commit }, stack) {
apiClient.updateStack(stack)
.then((stack) => {
commit('addStack', stack)
})
} }
} }
} }