diff --git a/lib/Db/Card.php b/lib/Db/Card.php index ed710d716..5a80ed35a 100644 --- a/lib/Db/Card.php +++ b/lib/Db/Card.php @@ -158,6 +158,20 @@ class Card extends RelationalEntity { return $calendar; } + public function getDaysUntilDue(): ?int { + $today = new DateTime(); + $match_date = $this->getDuedate(); + if ($match_date === null) { + return null; + } + + $today->setTime(0, 0); + $match_date->setTime(0, 0); + + $diff = $today->diff($match_date); + return (int) $diff->format('%R%a'); // Extract days count in interval + } + public function getCalendarPrefix(): string { return 'card'; } diff --git a/lib/Db/RelationalEntity.php b/lib/Db/RelationalEntity.php index b4683b05b..683f1611f 100644 --- a/lib/Db/RelationalEntity.php +++ b/lib/Db/RelationalEntity.php @@ -127,7 +127,7 @@ class RelationalEntity extends Entity implements \JsonSerializable { } } - public function __call($methodName, $args) { + public function __call(string $methodName, array $args) { $attr = lcfirst(substr($methodName, 7)); if (array_key_exists($attr, $this->_resolvedProperties) && strpos($methodName, 'resolve') === 0) { if ($this->_resolvedProperties[$attr] !== null) { diff --git a/lib/Model/BoardSummary.php b/lib/Model/BoardSummary.php index 4c363ff3e..7924222ba 100644 --- a/lib/Model/BoardSummary.php +++ b/lib/Model/BoardSummary.php @@ -39,6 +39,10 @@ class BoardSummary extends Board { ]; } + protected function getter(string $name): mixed { + return $this->board->getter($name); + } + public function __call($name, $arguments) { return $this->board->__call($name, $arguments); } diff --git a/lib/Model/CardDetails.php b/lib/Model/CardDetails.php index 58523ab14..ca39b9211 100644 --- a/lib/Model/CardDetails.php +++ b/lib/Model/CardDetails.php @@ -22,7 +22,6 @@ */ namespace OCA\Deck\Model; -use DateTime; use OCA\Deck\Db\Board; use OCA\Deck\Db\Card; @@ -41,6 +40,14 @@ class CardDetails extends Card { } public function jsonSerialize(array $extras = []): array { + $array = parent::jsonSerialize(); + $array['overdue'] = $this->getDueStatus(); + + unset($array['notified']); + unset($array['descriptionPrev']); + unset($array['relatedStack']); + unset($array['relatedBoard']); + $array = $this->card->jsonSerialize(); unset($array['notified'], $array['descriptionPrev'], $array['relatedStack'], $array['relatedBoard']); @@ -51,30 +58,18 @@ class CardDetails extends Card { } private function getDueStatus(): int { - $today = new DateTime(); - $today->setTime(0, 0); - - $match_date = $this->card->getDuedate(); - if (!$match_date) { - return Card::DUEDATE_FUTURE; + $diffDays = $this->getDaysUntilDue(); + if ($diffDays === null || $diffDays > 1) { + return static::DUEDATE_FUTURE; } - $match_date->setTime(0, 0); - - $diff = $today->diff($match_date); - $diffDays = (int) $diff->format('%R%a'); // Extract days count in interval - - if ($diffDays === 1) { - return Card::DUEDATE_NEXT; + return static::DUEDATE_NEXT; } if ($diffDays === 0) { - return Card::DUEDATE_NOW; - } - if ($diffDays < 0) { - return Card::DUEDATE_OVERDUE; + return static::DUEDATE_NOW; } - return Card::DUEDATE_FUTURE; + return static::DUEDATE_OVERDUE; } private function appendBoardDetails(&$array): void { @@ -86,7 +81,11 @@ class CardDetails extends Card { $array['board'] = (new BoardSummary($this->board))->jsonSerialize(); } - public function __call($name, $arguments) { - return $this->card->__call($name, $arguments); + protected function getter(string $name): mixed { + return $this->card->getter($name); + } + + public function __call(string $methodName, array $args) { + return $this->card->__call($methodName, $args); } } diff --git a/lib/Service/OverviewService.php b/lib/Service/OverviewService.php index 0d883141c..8b8b07511 100644 --- a/lib/Service/OverviewService.php +++ b/lib/Service/OverviewService.php @@ -93,7 +93,7 @@ class OverviewService { public function findUpcomingCards(string $userId): array { $userBoards = $this->boardMapper->findAllForUser($userId); - $foundCards = []; + $overview = []; foreach ($userBoards as $userBoard) { if (count($userBoard->getAcl()) === 0) { // private board: get cards with due date @@ -103,14 +103,27 @@ class OverviewService { $cards = $this->cardMapper->findToMeOrNotAssignedCards($userBoard->getId(), $userId); } - $foundCards[] = array_map( - function (Card $card) use ($userBoard, $userId) { - $this->enrich($card, $userId); - return (new CardDetails($card, $userBoard))->jsonSerialize(); - }, - $cards - ); + foreach ($cards as $card) { + $this->enrich($card, $userId); + $diffDays = $card->getDaysUntilDue(); + + $key = 'later'; + if ($diffDays === null) { + $key = 'nodue'; + } elseif ($diffDays < 0) { + $key = 'overdue'; + } elseif ($diffDays === 0) { + $key = 'today'; + } elseif ($diffDays === 1) { + $key = 'tomorrow'; + } elseif ($diffDays <= 7) { + $key = 'nextSevenDays'; + } + + $card = (new CardDetails($card, $userBoard)); + $overview[$key][] = $card->jsonSerialize(); + } } - return array_merge(...$foundCards); + return $overview; } } diff --git a/src/components/overview/Overview.vue b/src/components/overview/Overview.vue index a7dedef39..4f1b0a6a5 100644 --- a/src/components/overview/Overview.vue +++ b/src/components/overview/Overview.vue @@ -31,44 +31,44 @@
-
+

{{ t('deck', 'Overdue') }}

-
+

{{ t('deck', 'Today') }}

-
+

{{ t('deck', 'Tomorrow') }}

-
+

{{ t('deck', 'Next 7 days') }}

-
+

{{ t('deck', 'Later') }}

-
+

{{ t('deck', 'No due') }}

-
+
@@ -83,7 +83,6 @@ import Controls from '../Controls.vue' import CardItem from '../cards/CardItem.vue' import { mapGetters } from 'vuex' -import moment from '@nextcloud/moment' import GlobalSearchResults from '../search/GlobalSearchResults.vue' const FILTER_UPCOMING = 'upcoming' @@ -125,13 +124,6 @@ export default { ...mapGetters([ 'assignedCardsDashboard', ]), - cardsByDueDate() { - switch (this.filter) { - case FILTER_UPCOMING: - return this.groupByDue(this.assignedCardsDashboard) - } - return null - }, }, watch: { '$route.params.filter'() { @@ -153,47 +145,6 @@ export default { } this.loading = false }, - - groupByDue(dataset) { - const all = { - nodue: [], - overdue: [], - today: [], - tomorrow: [], - nextSevenDays: [], - later: [], - } - dataset.forEach(card => { - if (card.duedate === null) { - all.nodue.push(card) - } else { - const hours = Math.floor(moment(card.duedate).diff(this.$root.time, 'seconds') / 60 / 60) - const d = new Date() - const currentHour = d.getHours() - if (hours < 0) { - all.overdue.push(card) - } - if (hours >= 0 && hours < (24 - currentHour)) { - all.today.push(card) - } - if (hours >= (24 - currentHour) && hours < (48 - currentHour)) { - all.tomorrow.push(card) - } - if (hours >= (48 - currentHour) && hours < (24 * 7)) { - all.nextSevenDays.push(card) - } - if (hours >= (24 * 7)) { - all.later.push(card) - } - } - }) - Object.keys(all).forEach((list) => { - all[list] = all[list].sort((a, b) => { - return (new Date(a.duedate)).getTime() - (new Date(b.duedate)).getTime() - }) - }) - return all - }, }, } diff --git a/src/store/overview.js b/src/store/overview.js index e6eeb3c02..d06095308 100644 --- a/src/store/overview.js +++ b/src/store/overview.js @@ -43,12 +43,14 @@ export default { actions: { async loadUpcoming({ commit }) { commit('setCurrentBoard', null) - const assignedCards = await apiClient.get('upcoming') - const assignedCardsFlat = assignedCards.flat() - for (const i in assignedCardsFlat) { - commit('addCard', assignedCardsFlat[i]) + const upcommingCards = await apiClient.get('upcoming') + + for (const dueStatus in upcommingCards) { + for (const idx in upcommingCards[dueStatus]) { + commit('addCard', upcommingCards[dueStatus][idx]) + } } - commit('setAssignedCards', assignedCardsFlat) + commit('setAssignedCards', upcommingCards) }, }, } diff --git a/tests/psalm-baseline.xml b/tests/psalm-baseline.xml index 2eb5d9228..1fed3db61 100644 --- a/tests/psalm-baseline.xml +++ b/tests/psalm-baseline.xml @@ -1,40 +1,40 @@ - + - + $types - + void - + $this->boardMapper $this->stackMapper - + $this->boardMapper $this->stackMapper - + $modified === null $modified === null - + Util - + $this->userId - + $this->userId - + $cardId $cardId $cardId @@ -44,95 +44,108 @@ - + LoadSidebar - + $modified !== null - + Util - + ExternalCalendar - + ICalendarObject - + ICalendarProvider - + NotFound - + VCalendar VCalendar - + $entity->getId() - + getUserIdGroups - + $labelId - - - $attribute - - - + VCalendar VCalendar + + + public function __construct(Board $board) { + public function __construct(Board $board) { + + + + + public function __construct(Card $card, ?Board $board = null) { + public function __construct(Card $card, ?Board $board = null) { + + - + + try { + $attachment = $this->attachmentMapper->find($attachmentId); + } catch (IMapperException $e) { + throw new NoPermissionException('Permission denied'); + } + - + findAll findAll - + $member !== null - + is_resource($content) is_resource($content) - + getShareByToken - + [self::class, 'listenPreShare']