Compare commits

...

6 Commits

Author SHA1 Message Date
Jakob Röhrl
45f811f595 new component
Signed-off-by: Jakob Röhrl <jakob.roehrl@web.de>
2020-10-16 11:27:39 +02:00
Jakob Röhrl
e11f048a91 preselect board and stack
Signed-off-by: Jakob Röhrl <jakob.roehrl@web.de>
2020-10-06 13:16:39 +02:00
Jakob Röhrl
d8c0240437 default due: today
Signed-off-by: Jakob Röhrl <jakob.roehrl@web.de>
2020-10-01 11:09:54 +02:00
Jakob Röhrl
6e6ae23d88 add card in upcoming cards view
Signed-off-by: Jakob Röhrl <jakob.roehrl@web.de>
2020-10-01 10:07:54 +02:00
Nextcloud bot
d61a08baf5 [tx-robot] updated from transifex 2020-09-30 02:28:49 +00:00
Nextcloud bot
f7209fbe5b [tx-robot] updated from transifex 2020-09-29 02:28:54 +00:00
7 changed files with 210 additions and 3 deletions

View File

@@ -121,6 +121,7 @@ OC.L10N.register(
"Apply filter" : "Primijeni filtar",
"Filter by tag" : "Filtriraj prema oznaci",
"Filter by assigned user" : "Filtriraj prema dodijeljenom korisniku",
"Unassigned" : "Nedodijeljeno",
"Filter by due date" : "Filtriraj prema datumu dospijeća",
"Overdue" : "Kasni",
"Next 24 hours" : "Sljedeća 24 sata",
@@ -133,6 +134,8 @@ OC.L10N.register(
"Toggle compact mode" : "Prebaci u kompaktni način rada",
"Details" : "Pojedinosti",
"Loading board" : "Učitavanje ploče",
"No lists available" : "Nema dostupnih popisa",
"Create a new list to add cards to this board" : "Stvorite novi popis kako biste dodali kartice na ovu ploču",
"Board not found" : "Ploča nije pronađena",
"Sharing" : "Dijeljenje",
"Tags" : "Oznake",

View File

@@ -119,6 +119,7 @@
"Apply filter" : "Primijeni filtar",
"Filter by tag" : "Filtriraj prema oznaci",
"Filter by assigned user" : "Filtriraj prema dodijeljenom korisniku",
"Unassigned" : "Nedodijeljeno",
"Filter by due date" : "Filtriraj prema datumu dospijeća",
"Overdue" : "Kasni",
"Next 24 hours" : "Sljedeća 24 sata",
@@ -131,6 +132,8 @@
"Toggle compact mode" : "Prebaci u kompaktni način rada",
"Details" : "Pojedinosti",
"Loading board" : "Učitavanje ploče",
"No lists available" : "Nema dostupnih popisa",
"Create a new list to add cards to this board" : "Stvorite novi popis kako biste dodali kartice na ovu ploču",
"Board not found" : "Ploča nije pronađena",
"Sharing" : "Dijeljenje",
"Tags" : "Oznake",

View File

@@ -191,6 +191,7 @@ OC.L10N.register(
"Select Date" : "Tarih Seçin",
"Modified" : "Değiştirilme",
"Created" : "Oluşturulma",
"The title cannot be empty." : "Başlık boş olamaz.",
"No comments yet. Begin the discussion!" : "Henüz bir yorum yapılmamış. Tartışmayı başlatın!",
"Save" : "Kaydet",
"The comment cannot be empty." : "Yorum boş olamaz.",
@@ -216,6 +217,7 @@ OC.L10N.register(
"Show boards in calendar/tasks" : "Takvimler ve görevlerde panolar görüntülensin",
"Limit deck usage of groups" : "Tahtayı şu gruplar kullanabilsin",
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Tahta kullanımı gruplar ile sınırlandığında belirtilen grupların üyesi olmayan kişiler kendi tahtalarını oluşturamaz. Bu kullanıcılar ancak kendileri ile paylaşılan tahtalar üzerinde çalışabilir.",
"Board name" : "Pano adı",
"Edit board" : "Panoyu sil",
"Clone board " : "Panoyu kopyala",
"Unarchive board " : "Panoyu arşivden çıkar",

View File

@@ -189,6 +189,7 @@
"Select Date" : "Tarih Seçin",
"Modified" : "Değiştirilme",
"Created" : "Oluşturulma",
"The title cannot be empty." : "Başlık boş olamaz.",
"No comments yet. Begin the discussion!" : "Henüz bir yorum yapılmamış. Tartışmayı başlatın!",
"Save" : "Kaydet",
"The comment cannot be empty." : "Yorum boş olamaz.",
@@ -214,6 +215,7 @@
"Show boards in calendar/tasks" : "Takvimler ve görevlerde panolar görüntülensin",
"Limit deck usage of groups" : "Tahtayı şu gruplar kullanabilsin",
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Tahta kullanımı gruplar ile sınırlandığında belirtilen grupların üyesi olmayan kişiler kendi tahtalarını oluşturamaz. Bu kullanıcılar ancak kendileri ile paylaşılan tahtalar üzerinde çalışabilir.",
"Board name" : "Pano adı",
"Edit board" : "Panoyu sil",
"Clone board " : "Panoyu kopyala",
"Unarchive board " : "Panoyu arşivden çıkar",

View File

@@ -78,8 +78,8 @@ class CardController extends Controller {
* @param int $order
* @return \OCP\AppFramework\Db\Entity
*/
public function create($title, $stackId, $type = 'plain', $order = 999) {
return $this->cardService->create($title, $stackId, $type, $order, $this->userId);
public function create($title, $stackId, $type = 'plain', $order = 999, $description = '', $duedate = null) {
return $this->cardService->create($title, $stackId, $type, $order, $this->userId, $description, $duedate);
}
/**

View File

@@ -32,6 +32,11 @@
</div>
<div v-if="overviewName" class="board-title">
<h2><a href="#">{{ overviewName }}</a></h2>
<Actions>
<ActionButton icon="icon-add" @click.stop="modalShow=true">
{{ t('deck', 'Add card on today') }}
</ActionButton>
</Actions>
</div>
<div v-if="board" class="board-actions">
<div v-if="canManage && !showArchived && !board.archived"
@@ -193,6 +198,8 @@
</Actions>
</div>
</div>
<ControlsModal :modal-show="modalShow" />
</div>
</template>
@@ -200,11 +207,12 @@
import { mapState, mapGetters } from 'vuex'
import { Actions, ActionButton, Popover, Avatar } from '@nextcloud/vue'
import labelStyle from '../mixins/labelStyle'
import ControlsModal from './ControlsModal'
export default {
name: 'Controls',
components: {
Actions, ActionButton, Popover, Avatar,
Actions, ActionButton, Popover, Avatar, ControlsModal,
},
mixins: [ labelStyle ],
props: {
@@ -226,6 +234,12 @@ export default {
showArchived: false,
isAddStackVisible: false,
filter: { tags: [], users: [], due: '', unassigned: false },
modalShow: false,
selectedBoard: '',
selectedStack: '',
stacksFromBoard: [],
newCardTitle: '',
}
},
@@ -233,6 +247,8 @@ export default {
...mapGetters([
'canEdit',
'canManage',
'lastBoardId',
'lastListId',
]),
...mapState({
compactMode: state => state.compactMode,
@@ -257,6 +273,15 @@ export default {
labelsSorted() {
return [...this.board.labels].sort((a, b) => (a.title < b.title) ? -1 : 1)
},
boards() {
return this.$store.getters.boards
},
addCardSetRequiredFields() {
if (this.selectedBoard === '' || this.selectedStack === '' || this.newCardTitle.trim() === '') {
return false
}
return true
},
},
watch: {
board() {
@@ -319,6 +344,10 @@ export default {
</script>
<style lang="scss" scoped>
#new-stack-input-main {
width: 100%;
}
.controls {
display: flex;

View File

@@ -0,0 +1,168 @@
<!--
* @copyright Copyright (c) 2020 Jakob Röhrl <jakob.roehrl@web.de>
*
* @author Jakob Röhrl <jakob.roehrl@web.de>
*
* @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>
<Modal v-if="modalShow" :title="t('deck', 'Add card on Today')" @close="modalShow=false">
<div class="modal__content">
{{ lastBoardId - selectedBoard }}
{{ lastListId }}
<h3>{{ t('deck', 'Add card on Today') }}</h3>
<Multiselect v-model="selectedBoard"
:placeholder="t('deck', 'Select a board')"
:options="boards"
:max-height="100"
label="title"
@select="loadStacksFromBoard" />
<Multiselect v-model="selectedStack"
:placeholder="t('deck', 'Select a list')"
:options="stacksFromBoard"
:max-height="100"
label="title" />
<label for="new-stack-input-main" class="hidden-visually">{{ t('deck', 'Add card on Today') }}</label>
<input id="new-stack-input-main"
ref="newCardInput"
v-model="newCardTitle"
v-focus
type="text"
class="no-close"
:placeholder="t('deck', 'Card name')">
<button :disabled="!addCardSetRequiredFields" class="primary" @click="addCard">
{{ t('deck', 'Add card') }}
</button>
<button @click="modalShow=false">
{{ t('deck', 'Cancel') }}
</button>
</div>
</Modal>
</template>
<script>
import { Modal, Multiselect } from '@nextcloud/vue'
import labelStyle from '../mixins/labelStyle'
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { showError } from '@nextcloud/dialogs'
export default {
name: 'ControlsModal',
components: {
Modal, Multiselect,
},
mixins: [ labelStyle ],
props: {
modalShow: {
default: false,
type: Boolean,
},
},
data() {
return {
selectedBoard: '',
selectedStack: '',
stacksFromBoard: [],
newCardTitle: '',
lastBoardId: localStorage.getItem('deck.lastBoardId'),
lastListId: localStorage.getItem('deck.lastListId'),
}
},
computed: {
boards() {
return this.$store.getters.boards
},
addCardSetRequiredFields() {
if (this.selectedBoard === '' || this.selectedStack === '' || this.newCardTitle.trim() === '') {
return false
}
return true
},
},
mounted() {
this.setLastBoardId()
},
methods: {
setLastBoardId() {
if (this.lastBoardId === null || this.lastBoardId === 0) {
this.selectedBoard = ''
return
}
this.selectedBoard = this.selectedBoard = this.boards.filter(board => {
return board.id === this.lastBoardId
})
},
async loadStacksFromBoard(selectedBoard) {
try {
const url = generateUrl('/apps/deck/stacks/' + selectedBoard.id)
const response = await axios.get(url)
this.stacksFromBoard = response.data
} catch (err) {
return err
}
},
async addCard() {
try {
const today = new Date()
today.setHours(23, 59, 59, 999)
await this.$store.dispatch('addCard', {
title: this.newCardTitle,
stackId: this.selectedStack.id,
boardId: this.selectedBoard.id,
duedate: today.toISOString(),
})
this.newCardTitle = ''
localStorage.setItem('deck.lastBoardId', this.selectedBoard.id)
localStorage.setItem('deck.lastListId', this.selectedStack.id)
} catch (e) {
showError('Could not create card: ' + e.response.data.message)
}
// this.modalShow = false
},
},
}
</script>
<style lang="scss" scoped>
#new-stack-input-main {
width: 100%;
}
.modal__content {
width: 25vw;
min-width: 250px;
min-height: 120px;
text-align: center;
margin: 20px 20px 100px 20px;
.multiselect {
margin-bottom: 10px;
}
}
.modal__content button {
float: right;
margin-top: 50px;
}
</style>