Compare commits
1 Commits
fix-duplic
...
enh/due-da
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7b64ea17d |
@@ -94,8 +94,8 @@ class CardController extends Controller {
|
|||||||
* @param $deletedAt
|
* @param $deletedAt
|
||||||
* @return \OCP\AppFramework\Db\Entity
|
* @return \OCP\AppFramework\Db\Entity
|
||||||
*/
|
*/
|
||||||
public function update($id, $title, $stackId, $type, $order, $description, $duedate, $deletedAt) {
|
public function update($id, $title, $stackId, $type, $order, $description, $duedate, $deletedAt, $dueDone) {
|
||||||
return $this->cardService->update($id, $title, $stackId, $type, $order, $description, $this->userId, $duedate, $deletedAt);
|
return $this->cardService->update($id, $title, $stackId, $type, $order, $description, $this->userId, $duedate, $deletedAt, null, $dueDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -36,17 +36,19 @@ class Card extends RelationalEntity {
|
|||||||
protected $lastModified;
|
protected $lastModified;
|
||||||
protected $lastEditor;
|
protected $lastEditor;
|
||||||
protected $createdAt;
|
protected $createdAt;
|
||||||
protected $labels;
|
|
||||||
protected $assignedUsers;
|
|
||||||
protected $attachments;
|
|
||||||
protected $attachmentCount;
|
|
||||||
protected $owner;
|
protected $owner;
|
||||||
protected $order;
|
protected $order;
|
||||||
protected $archived = false;
|
protected $archived = false;
|
||||||
protected $duedate;
|
protected $duedate;
|
||||||
protected $notified = false;
|
protected $notified = false;
|
||||||
protected $deletedAt = 0;
|
protected $deletedAt = 0;
|
||||||
|
protected $dueDone = false;
|
||||||
|
|
||||||
|
protected $labels;
|
||||||
|
protected $assignedUsers;
|
||||||
protected $commentsUnread = 0;
|
protected $commentsUnread = 0;
|
||||||
|
protected $attachments;
|
||||||
|
protected $attachmentCount = 0;
|
||||||
|
|
||||||
private $databaseType = 'sqlite';
|
private $databaseType = 'sqlite';
|
||||||
|
|
||||||
@@ -64,6 +66,8 @@ class Card extends RelationalEntity {
|
|||||||
$this->addType('archived', 'boolean');
|
$this->addType('archived', 'boolean');
|
||||||
$this->addType('notified', 'boolean');
|
$this->addType('notified', 'boolean');
|
||||||
$this->addType('deletedAt', 'integer');
|
$this->addType('deletedAt', 'integer');
|
||||||
|
$this->addType('dueDone', 'boolean');
|
||||||
|
|
||||||
$this->addRelation('labels');
|
$this->addRelation('labels');
|
||||||
$this->addRelation('assignedUsers');
|
$this->addRelation('assignedUsers');
|
||||||
$this->addRelation('attachments');
|
$this->addRelation('attachments');
|
||||||
|
|||||||
54
lib/Migration/Version10200Date20201104190344.php
Normal file
54
lib/Migration/Version10200Date20201104190344.php
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace OCA\Deck\Migration;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use OCP\DB\ISchemaWrapper;
|
||||||
|
use OCP\Migration\IOutput;
|
||||||
|
use OCP\Migration\SimpleMigrationStep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated migration step: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
class Version10200Date20201104190344 extends SimpleMigrationStep {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param IOutput $output
|
||||||
|
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
||||||
|
* @param array $options
|
||||||
|
*/
|
||||||
|
public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param IOutput $output
|
||||||
|
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
||||||
|
* @param array $options
|
||||||
|
* @return null|ISchemaWrapper
|
||||||
|
*/
|
||||||
|
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
|
||||||
|
/** @var ISchemaWrapper $schema */
|
||||||
|
$schema = $schemaClosure();
|
||||||
|
|
||||||
|
$table = $schema->getTable('deck_cards');
|
||||||
|
|
||||||
|
if (!$table->hasColumn('due_done')) {
|
||||||
|
$table->addColumn('due_done', 'boolean', [
|
||||||
|
'notnull' => false,
|
||||||
|
'default' => false
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param IOutput $output
|
||||||
|
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
||||||
|
* @param array $options
|
||||||
|
*/
|
||||||
|
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -261,7 +261,7 @@ class CardService {
|
|||||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||||
* @throws BadRequestException
|
* @throws BadRequestException
|
||||||
*/
|
*/
|
||||||
public function update($id, $title, $stackId, $type, $order = 0, $description = '', $owner, $duedate = null, $deletedAt = null, $archived = null) {
|
public function update($id, $title, $stackId, $type, $order = 0, $description = '', $owner, $duedate = null, ?int $deletedAt = null, ?bool $archived = null, ?bool $dueDone = null) {
|
||||||
if (is_numeric($id) === false) {
|
if (is_numeric($id) === false) {
|
||||||
throw new BadRequestException('card id must be a number');
|
throw new BadRequestException('card id must be a number');
|
||||||
}
|
}
|
||||||
@@ -320,6 +320,9 @@ class CardService {
|
|||||||
if ($archived !== null) {
|
if ($archived !== null) {
|
||||||
$card->setArchived($archived);
|
$card->setArchived($archived);
|
||||||
}
|
}
|
||||||
|
if ($dueDone !== null) {
|
||||||
|
$card->setDueDone($dueDone);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Trigger update events before setting description as it is handled separately
|
// Trigger update events before setting description as it is handled separately
|
||||||
|
|||||||
@@ -24,22 +24,43 @@
|
|||||||
<div v-if="card">
|
<div v-if="card">
|
||||||
<div @click.stop.prevent>
|
<div @click.stop.prevent>
|
||||||
<Actions v-if="canEdit && !isArchived">
|
<Actions v-if="canEdit && !isArchived">
|
||||||
<ActionButton v-if="showArchived === false && !isCurrentUserAssigned" icon="icon-user" @click="assignCardToMe()">
|
<ActionButton v-if="showArchived === false && !isCurrentUserAssigned"
|
||||||
|
icon="icon-user"
|
||||||
|
:close-after-click="true"
|
||||||
|
@click="assignCardToMe()">
|
||||||
{{ t('deck', 'Assign to me') }}
|
{{ t('deck', 'Assign to me') }}
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
<ActionButton v-if="showArchived === false && isCurrentUserAssigned" icon="icon-user" @click="unassignCardFromMe()">
|
<ActionButton v-if="showArchived === false && isCurrentUserAssigned"
|
||||||
|
icon="icon-user"
|
||||||
|
:close-after-click="true"
|
||||||
|
@click="unassignCardFromMe()">
|
||||||
{{ t('deck', 'Unassign myself') }}
|
{{ t('deck', 'Unassign myself') }}
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
<ActionButton icon="icon-external" @click.stop="modalShow=true">
|
<ActionButton v-if="showArchived === false && card.duedate && !card.dueDone"
|
||||||
|
icon="icon-checkmark"
|
||||||
|
:close-after-click="true"
|
||||||
|
@click="toggleDoneState(true)">
|
||||||
|
{{ t('deck', 'Mark card as done') }}
|
||||||
|
</ActionButton>
|
||||||
|
<ActionButton v-if="showArchived === false && card.duedate && card.dueDone"
|
||||||
|
icon="icon-checkmark"
|
||||||
|
:close-after-click="true"
|
||||||
|
@click="toggleDoneState(false)">
|
||||||
|
{{ t('deck', 'Mark card as pending') }}
|
||||||
|
</ActionButton>
|
||||||
|
<ActionButton icon="icon-external" :close-after-click="true" @click.stop="modalShow=true">
|
||||||
{{ t('deck', 'Move card') }}
|
{{ t('deck', 'Move card') }}
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
<ActionButton icon="icon-settings-dark" @click="openCard">
|
<ActionButton icon="icon-settings-dark" :close-after-click="true" @click="openCard">
|
||||||
{{ t('deck', 'Card details') }}
|
{{ t('deck', 'Card details') }}
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
<ActionButton icon="icon-archive" @click="archiveUnarchiveCard()">
|
<ActionButton icon="icon-archive" :close-after-click="true" @click="archiveUnarchiveCard()">
|
||||||
{{ showArchived ? t('deck', 'Unarchive card') : t('deck', 'Archive card') }}
|
{{ showArchived ? t('deck', 'Unarchive card') : t('deck', 'Archive card') }}
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
<ActionButton v-if="showArchived === false" icon="icon-delete" @click="deleteCard()">
|
<ActionButton v-if="showArchived === false"
|
||||||
|
icon="icon-delete"
|
||||||
|
:close-after-click="true"
|
||||||
|
@click="deleteCard()">
|
||||||
{{ t('deck', 'Delete card') }}
|
{{ t('deck', 'Delete card') }}
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
</Actions>
|
</Actions>
|
||||||
@@ -154,6 +175,9 @@ export default {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
toggleDoneState(state) {
|
||||||
|
this.$store.dispatch('updateCardDueDone', { ...this.card, dueDone: state })
|
||||||
|
},
|
||||||
moveCard() {
|
moveCard() {
|
||||||
this.copiedCard = Object.assign({}, this.card)
|
this.copiedCard = Object.assign({}, this.card)
|
||||||
this.copiedCard.stackId = this.selectedStack.id
|
this.copiedCard.stackId = this.selectedStack.id
|
||||||
|
|||||||
@@ -23,8 +23,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="card" class="duedate">
|
<div v-if="card" class="duedate">
|
||||||
<transition name="zoom">
|
<transition name="zoom">
|
||||||
<div v-if="card.duedate" :class="dueIcon">
|
<div v-if="card.duedate" v-tooltip="card.dueDone ? relativeDate : null" :class="dueIcon">
|
||||||
<span>{{ relativeDate }}</span>
|
<span v-if="!card.dueDone">{{ relativeDate }}</span>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
@@ -45,15 +45,15 @@ export default {
|
|||||||
dueIcon() {
|
dueIcon() {
|
||||||
const days = Math.floor(moment(this.card.duedate).diff(this.$root.time, 'seconds') / 60 / 60 / 24)
|
const days = Math.floor(moment(this.card.duedate).diff(this.$root.time, 'seconds') / 60 / 60 / 24)
|
||||||
if (days < 0) {
|
if (days < 0) {
|
||||||
return 'icon-calendar due icon overdue'
|
return `due icon ${!this.card.dueDone ? 'icon-calendar overdue' : 'icon-checkmark'}`
|
||||||
}
|
}
|
||||||
if (days === 0) {
|
if (days === 0) {
|
||||||
return 'icon-calendar-dark due icon now'
|
return `due icon ${!this.card.dueDone ? 'icon-calendar-dark now' : 'icon-checkmark'}`
|
||||||
}
|
}
|
||||||
if (days === 1) {
|
if (days === 1) {
|
||||||
return 'icon-calendar-dark due icon next'
|
return `due icon ${!this.card.dueDone ? 'con-calendar-dark next' : 'icon-checkmark'}`
|
||||||
}
|
}
|
||||||
return 'icon-calendar-dark due icon'
|
return `due icon ${!this.card.dueDone ? 'icon-calendar-dark' : 'icon-checkmark'}`
|
||||||
},
|
},
|
||||||
relativeDate() {
|
relativeDate() {
|
||||||
const diff = moment(this.$root.time).diff(this.card.duedate, 'seconds')
|
const diff = moment(this.$root.time).diff(this.card.duedate, 'seconds')
|
||||||
@@ -88,6 +88,10 @@ export default {
|
|||||||
background-size: contain;
|
background-size: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.icon-checkmark {
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
&.overdue {
|
&.overdue {
|
||||||
background-color: var(--color-error);
|
background-color: var(--color-error);
|
||||||
color: var(--color-primary-text);
|
color: var(--color-primary-text);
|
||||||
|
|||||||
@@ -236,5 +236,9 @@ export default {
|
|||||||
const updatedCard = await apiClient.updateCard(card)
|
const updatedCard = await apiClient.updateCard(card)
|
||||||
commit('updateCardProperty', { property: 'duedate', card: updatedCard })
|
commit('updateCardProperty', { property: 'duedate', card: updatedCard })
|
||||||
},
|
},
|
||||||
|
async updateCardDueDone({ commit }, card) {
|
||||||
|
const updatedCard = await apiClient.updateCard(card)
|
||||||
|
commit('updateCardProperty', { property: 'dueDone', card: updatedCard })
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user