diff --git a/lib/Dashboard/DeckWidget.php b/lib/Dashboard/DeckWidget.php index 99a6b5dd2..cdb5db1d8 100644 --- a/lib/Dashboard/DeckWidget.php +++ b/lib/Dashboard/DeckWidget.php @@ -26,18 +26,34 @@ declare(strict_types=1); namespace OCA\Deck\Dashboard; -use OCP\Dashboard\IWidget; +use DateTime; +use OCA\Deck\AppInfo\Application; +use OCA\Deck\Db\Label; +use OCA\Deck\Service\OverviewService; +use OCP\Dashboard\IAPIWidget; +use OCP\Dashboard\IButtonWidget; +use OCP\Dashboard\IIconWidget; +use OCP\Dashboard\Model\WidgetButton; +use OCP\Dashboard\Model\WidgetItem; +use OCP\IDateTimeFormatter; use OCP\IL10N; +use OCP\IURLGenerator; +use OCP\Util; -class DeckWidget implements IWidget { +class DeckWidget implements IAPIWidget, IButtonWidget, IIconWidget { + private IL10N $l10n; + private OverviewService $dashboardService; + private IURLGenerator $urlGenerator; + private IDateTimeFormatter $dateTimeFormatter; - /** - * @var IL10N - */ - private $l10n; - - public function __construct(IL10N $l10n) { + public function __construct(IL10N $l10n, + OverviewService $dashboardService, + IDateTimeFormatter $dateTimeFormatter, + IURLGenerator $urlGenerator) { $this->l10n = $l10n; + $this->dashboardService = $dashboardService; + $this->urlGenerator = $urlGenerator; + $this->dateTimeFormatter = $dateTimeFormatter; } /** @@ -68,17 +84,88 @@ class DeckWidget implements IWidget { return 'icon-deck'; } + /** + * @inheritDoc + */ + public function getIconUrl(): string { + return $this->urlGenerator->getAbsoluteURL( + $this->urlGenerator->imagePath(Application::APP_ID, 'deck-dark.svg') + ); + } + /** * @inheritDoc */ public function getUrl(): ?string { - return null; + return $this->urlGenerator->getAbsoluteURL( + $this->urlGenerator->linkToRoute(Application::APP_ID . '.page.index') + ); } /** * @inheritDoc */ public function load(): void { - \OCP\Util::addScript('deck', 'deck-dashboard'); + Util::addScript('deck', 'deck-dashboard'); + } + + /** + * @inheritDoc + */ + public function getItems(string $userId, ?string $since = null, int $limit = 7): array { + $upcomingCards = $this->dashboardService->findUpcomingCards($userId); + $nowTimestamp = (new Datetime())->getTimestamp(); + $sinceTimestamp = $since !== null ? (new Datetime($since))->getTimestamp() : null; + $upcomingCards = array_filter($upcomingCards, static function (array $card) use ($nowTimestamp, $sinceTimestamp) { + if ($card['duedate']) { + $ts = (new Datetime($card['duedate']))->getTimestamp(); + return $ts > $nowTimestamp && ($sinceTimestamp === null || $ts > $sinceTimestamp); + } + return false; + }); + usort($upcomingCards, static function ($a, $b) { + $a = new Datetime($a['duedate']); + $ta = $a->getTimestamp(); + $b = new Datetime($b['duedate']); + $tb = $b->getTimestamp(); + return ($ta > $tb) ? 1 : -1; + }); + $upcomingCards = array_slice($upcomingCards, 0, $limit); + $urlGenerator = $this->urlGenerator; + $dateTimeFormatter = $this->dateTimeFormatter; + return array_map(static function (array $card) use ($urlGenerator, $dateTimeFormatter) { + $formattedDueDate = $dateTimeFormatter->formatDateTime(new DateTime($card['duedate'])); + return new WidgetItem( + $card['title'] . ' (' . $formattedDueDate . ')', + implode( + ', ', + array_map(static function (Label $label) { + return $label->jsonSerialize()['title']; + }, $card['labels']) + ), + $urlGenerator->getAbsoluteURL( + $urlGenerator->linkToRoute(Application::APP_ID . '.page.redirectToCard', ['cardId' => $card['id']]) + ), + $urlGenerator->getAbsoluteURL( + $urlGenerator->imagePath(Application::APP_ID, 'deck-dark.svg') + ), + $card['duedate'] + ); + }, $upcomingCards); + } + + /** + * @inheritDoc + */ + public function getWidgetButtons(string $userId): array { + return [ + new WidgetButton( + WidgetButton::TYPE_MORE, + $this->urlGenerator->getAbsoluteURL( + $this->urlGenerator->linkToRoute(Application::APP_ID . '.page.index') + ), + $this->l10n->t('Load more') + ), + ]; } } diff --git a/src/views/Dashboard.vue b/src/views/Dashboard.vue index 958d07d8c..57816a293 100644 --- a/src/views/Dashboard.vue +++ b/src/views/Dashboard.vue @@ -48,21 +48,26 @@