Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 97 additions & 10 deletions lib/Dashboard/DeckWidget.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,34 @@

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;
}

/**
Expand Down Expand Up @@ -68,17 +84,88 @@ public function getIconClass(): string {
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')
),
];
}
}
16 changes: 13 additions & 3 deletions src/views/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,28 +48,35 @@
</template>
</NcDashboardWidget>
<div class="center-button">
<button @click="toggleAddCardModel">
<NcButton @click="toggleAddCardModel">
<template #icon>
<PlusIcon :size="20" />
</template>
{{ t('deck', 'Add card') }}
</button>
</NcButton>
<CardCreateDialog v-if="showAddCardModal" @close="toggleAddCardModel" />
</div>
</div>
</template>

<script>
import PlusIcon from 'vue-material-design-icons/Plus.vue'
import { NcDashboardWidget } from '@nextcloud/vue'
import { mapGetters } from 'vuex'
import labelStyle from './../mixins/labelStyle.js'
import DueDate from '../components/cards/badges/DueDate.vue'
import { generateUrl } from '@nextcloud/router'
import CardCreateDialog from '../CardCreateDialog.vue'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'

export default {
name: 'Dashboard',
components: {
DueDate,
NcDashboardWidget,
CardCreateDialog,
NcButton,
PlusIcon,
},
mixins: [labelStyle],
data() {
Expand Down Expand Up @@ -120,7 +127,10 @@ export default {
@import './../css/labels';

.center-button {
text-align: center;
display: flex;
align-items: center;
justify-content: center;
margin-top: 8px;
}

#deck-widget-empty-content {
Expand Down