Skip to content

Commit f9836d4

Browse files
authored
Merge pull request #4033 from nextcloud/enh/4032/implement-new-dashboard-widget-interfaces
2 parents 982b867 + 6449082 commit f9836d4

File tree

2 files changed

+110
-13
lines changed

2 files changed

+110
-13
lines changed

lib/Dashboard/DeckWidget.php

Lines changed: 97 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,34 @@
2626

2727
namespace OCA\Deck\Dashboard;
2828

29-
use OCP\Dashboard\IWidget;
29+
use DateTime;
30+
use OCA\Deck\AppInfo\Application;
31+
use OCA\Deck\Db\Label;
32+
use OCA\Deck\Service\OverviewService;
33+
use OCP\Dashboard\IAPIWidget;
34+
use OCP\Dashboard\IButtonWidget;
35+
use OCP\Dashboard\IIconWidget;
36+
use OCP\Dashboard\Model\WidgetButton;
37+
use OCP\Dashboard\Model\WidgetItem;
38+
use OCP\IDateTimeFormatter;
3039
use OCP\IL10N;
40+
use OCP\IURLGenerator;
41+
use OCP\Util;
3142

32-
class DeckWidget implements IWidget {
43+
class DeckWidget implements IAPIWidget, IButtonWidget, IIconWidget {
44+
private IL10N $l10n;
45+
private OverviewService $dashboardService;
46+
private IURLGenerator $urlGenerator;
47+
private IDateTimeFormatter $dateTimeFormatter;
3348

34-
/**
35-
* @var IL10N
36-
*/
37-
private $l10n;
38-
39-
public function __construct(IL10N $l10n) {
49+
public function __construct(IL10N $l10n,
50+
OverviewService $dashboardService,
51+
IDateTimeFormatter $dateTimeFormatter,
52+
IURLGenerator $urlGenerator) {
4053
$this->l10n = $l10n;
54+
$this->dashboardService = $dashboardService;
55+
$this->urlGenerator = $urlGenerator;
56+
$this->dateTimeFormatter = $dateTimeFormatter;
4157
}
4258

4359
/**
@@ -68,17 +84,88 @@ public function getIconClass(): string {
6884
return 'icon-deck';
6985
}
7086

87+
/**
88+
* @inheritDoc
89+
*/
90+
public function getIconUrl(): string {
91+
return $this->urlGenerator->getAbsoluteURL(
92+
$this->urlGenerator->imagePath(Application::APP_ID, 'deck-dark.svg')
93+
);
94+
}
95+
7196
/**
7297
* @inheritDoc
7398
*/
7499
public function getUrl(): ?string {
75-
return null;
100+
return $this->urlGenerator->getAbsoluteURL(
101+
$this->urlGenerator->linkToRoute(Application::APP_ID . '.page.index')
102+
);
76103
}
77104

78105
/**
79106
* @inheritDoc
80107
*/
81108
public function load(): void {
82-
\OCP\Util::addScript('deck', 'deck-dashboard');
109+
Util::addScript('deck', 'deck-dashboard');
110+
}
111+
112+
/**
113+
* @inheritDoc
114+
*/
115+
public function getItems(string $userId, ?string $since = null, int $limit = 7): array {
116+
$upcomingCards = $this->dashboardService->findUpcomingCards($userId);
117+
$nowTimestamp = (new Datetime())->getTimestamp();
118+
$sinceTimestamp = $since !== null ? (new Datetime($since))->getTimestamp() : null;
119+
$upcomingCards = array_filter($upcomingCards, static function (array $card) use ($nowTimestamp, $sinceTimestamp) {
120+
if ($card['duedate']) {
121+
$ts = (new Datetime($card['duedate']))->getTimestamp();
122+
return $ts > $nowTimestamp && ($sinceTimestamp === null || $ts > $sinceTimestamp);
123+
}
124+
return false;
125+
});
126+
usort($upcomingCards, static function ($a, $b) {
127+
$a = new Datetime($a['duedate']);
128+
$ta = $a->getTimestamp();
129+
$b = new Datetime($b['duedate']);
130+
$tb = $b->getTimestamp();
131+
return ($ta > $tb) ? 1 : -1;
132+
});
133+
$upcomingCards = array_slice($upcomingCards, 0, $limit);
134+
$urlGenerator = $this->urlGenerator;
135+
$dateTimeFormatter = $this->dateTimeFormatter;
136+
return array_map(static function (array $card) use ($urlGenerator, $dateTimeFormatter) {
137+
$formattedDueDate = $dateTimeFormatter->formatDateTime(new DateTime($card['duedate']));
138+
return new WidgetItem(
139+
$card['title'] . ' (' . $formattedDueDate . ')',
140+
implode(
141+
', ',
142+
array_map(static function (Label $label) {
143+
return $label->jsonSerialize()['title'];
144+
}, $card['labels'])
145+
),
146+
$urlGenerator->getAbsoluteURL(
147+
$urlGenerator->linkToRoute(Application::APP_ID . '.page.redirectToCard', ['cardId' => $card['id']])
148+
),
149+
$urlGenerator->getAbsoluteURL(
150+
$urlGenerator->imagePath(Application::APP_ID, 'deck-dark.svg')
151+
),
152+
$card['duedate']
153+
);
154+
}, $upcomingCards);
155+
}
156+
157+
/**
158+
* @inheritDoc
159+
*/
160+
public function getWidgetButtons(string $userId): array {
161+
return [
162+
new WidgetButton(
163+
WidgetButton::TYPE_MORE,
164+
$this->urlGenerator->getAbsoluteURL(
165+
$this->urlGenerator->linkToRoute(Application::APP_ID . '.page.index')
166+
),
167+
$this->l10n->t('Load more')
168+
),
169+
];
83170
}
84171
}

src/views/Dashboard.vue

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,28 +48,35 @@
4848
</template>
4949
</NcDashboardWidget>
5050
<div class="center-button">
51-
<button @click="toggleAddCardModel">
51+
<NcButton @click="toggleAddCardModel">
52+
<template #icon>
53+
<PlusIcon :size="20" />
54+
</template>
5255
{{ t('deck', 'Add card') }}
53-
</button>
56+
</NcButton>
5457
<CardCreateDialog v-if="showAddCardModal" @close="toggleAddCardModel" />
5558
</div>
5659
</div>
5760
</template>
5861

5962
<script>
63+
import PlusIcon from 'vue-material-design-icons/Plus.vue'
6064
import { NcDashboardWidget } from '@nextcloud/vue'
6165
import { mapGetters } from 'vuex'
6266
import labelStyle from './../mixins/labelStyle.js'
6367
import DueDate from '../components/cards/badges/DueDate.vue'
6468
import { generateUrl } from '@nextcloud/router'
6569
import CardCreateDialog from '../CardCreateDialog.vue'
70+
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
6671
6772
export default {
6873
name: 'Dashboard',
6974
components: {
7075
DueDate,
7176
NcDashboardWidget,
7277
CardCreateDialog,
78+
NcButton,
79+
PlusIcon,
7380
},
7481
mixins: [labelStyle],
7582
data() {
@@ -120,7 +127,10 @@ export default {
120127
@import './../css/labels';
121128
122129
.center-button {
123-
text-align: center;
130+
display: flex;
131+
align-items: center;
132+
justify-content: center;
133+
margin-top: 8px;
124134
}
125135
126136
#deck-widget-empty-content {

0 commit comments

Comments
 (0)