diff --git a/l10n/de_DE.json b/l10n/de_DE.json index cb4954327..82c7f7772 100644 --- a/l10n/de_DE.json +++ b/l10n/de_DE.json @@ -325,4 +325,4 @@ "Limit deck usage of groups" : "Nutzung auf Gruppen einschränken", "Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Wenn Sie Deck einschränken, können Benutzer, die nicht zu diesen Gruppen gehören, keine eigenen Boards erstellen. Die Benutzer können weiterhin an Boards arbeiten, die für sie freigegeben wurden." },"pluralForm" :"nplurals=2; plural=(n != 1);" -} \ No newline at end of file +} diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index bf4514280..bd8e32e02 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -30,7 +30,9 @@ use OCA\Deck\Activity\CommentEventHandler; use OCA\Deck\Capabilities; use OCA\Deck\Collaboration\Resources\ResourceProvider; use OCA\Deck\Collaboration\Resources\ResourceProviderCard; -use OCA\Deck\Dashboard\DeckWidget; +use OCA\Deck\Dashboard\DeckWidgetToday; +use OCA\Deck\Dashboard\DeckWidgetTomorrow; +use OCA\Deck\Dashboard\DeckWidgetUpcoming; use OCA\Deck\Db\Acl; use OCA\Deck\Db\CardMapper; use OCA\Deck\Event\AclCreatedEvent; @@ -135,7 +137,9 @@ class Application extends App implements IBootstrap { $context->registerSearchProvider(DeckProvider::class); $context->registerSearchProvider(CardCommentProvider::class); - $context->registerDashboardWidget(DeckWidget::class); + $context->registerDashboardWidget(DeckWidgetUpcoming::class); + $context->registerDashboardWidget(DeckWidgetToday::class); + $context->registerDashboardWidget(DeckWidgetTomorrow::class); $context->registerReferenceProvider(CreateCardReferenceProvider::class); diff --git a/lib/Dashboard/DeckWidgetToday.php b/lib/Dashboard/DeckWidgetToday.php new file mode 100644 index 000000000..2006fec40 --- /dev/null +++ b/lib/Dashboard/DeckWidgetToday.php @@ -0,0 +1,85 @@ + + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Deck\Dashboard; + +use OCP\Dashboard\IWidget; +use OCP\IL10N; + +class DeckWidgetToday implements IWidget { + + /** + * + * @var IL10N + */ + private $l10n; + + public function __construct(IL10N $l10n) { + $this->l10n = $l10n; + } + + /** + * @inheritDoc + */ + public function getId(): string { + return 'deckToday'; + } + + /** + * @inheritDoc + */ + public function getTitle(): string { + return $this->l10n->t('Cards due today'); + } + + /** + * @inheritDoc + */ + public function getOrder(): int { + return 20; + } + + /** + * @inheritDoc + */ + public function getIconClass(): string { + return 'icon-deck'; + } + + /** + * @inheritDoc + */ + public function getUrl(): ?string { + return null; + } + + /** + * @inheritDoc + */ + public function load(): void { + \OCP\Util::addScript('deck', 'dashboard'); + } +} diff --git a/lib/Dashboard/DeckWidgetTomorrow.php b/lib/Dashboard/DeckWidgetTomorrow.php new file mode 100644 index 000000000..946a62802 --- /dev/null +++ b/lib/Dashboard/DeckWidgetTomorrow.php @@ -0,0 +1,85 @@ + + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Deck\Dashboard; + +use OCP\Dashboard\IWidget; +use OCP\IL10N; + +class DeckWidgetTomorrow implements IWidget { + + /** + * + * @var IL10N + */ + private $l10n; + + public function __construct(IL10N $l10n) { + $this->l10n = $l10n; + } + + /** + * @inheritDoc + */ + public function getId(): string { + return 'deckTomorrow'; + } + + /** + * @inheritDoc + */ + public function getTitle(): string { + return $this->l10n->t('Cards due tomorrow'); + } + + /** + * @inheritDoc + */ + public function getOrder(): int { + return 20; + } + + /** + * @inheritDoc + */ + public function getIconClass(): string { + return 'icon-deck'; + } + + /** + * @inheritDoc + */ + public function getUrl(): ?string { + return null; + } + + /** + * @inheritDoc + */ + public function load(): void { + \OCP\Util::addScript('deck', 'dashboard'); + } +} diff --git a/lib/Dashboard/DeckWidget.php b/lib/Dashboard/DeckWidgetUpcoming.php similarity index 98% rename from lib/Dashboard/DeckWidget.php rename to lib/Dashboard/DeckWidgetUpcoming.php index 0435b6125..0729c0ddb 100644 --- a/lib/Dashboard/DeckWidget.php +++ b/lib/Dashboard/DeckWidgetUpcoming.php @@ -40,7 +40,7 @@ use OCP\IL10N; use OCP\IURLGenerator; use OCP\Util; -class DeckWidget implements IAPIWidget, IButtonWidget, IIconWidget { +class DeckWidgetUpcoming implements IAPIWidget, IButtonWidget, IIconWidget { private IL10N $l10n; private OverviewService $dashboardService; private IURLGenerator $urlGenerator; diff --git a/src/components/dashboard/Card.vue b/src/components/dashboard/Card.vue new file mode 100644 index 000000000..c680e52b6 --- /dev/null +++ b/src/components/dashboard/Card.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/src/init-dashboard.js b/src/init-dashboard.js index 9b579fb91..3200acf91 100644 --- a/src/init-dashboard.js +++ b/src/init-dashboard.js @@ -26,25 +26,64 @@ import './shared-init.js' const debug = process.env.NODE_ENV !== 'production' +let _imports = null + +const getAsyncImports = async () => { + if (_imports) { + return _imports + } + + const { default: Vue } = await import('vue') + const { default: Vuex } = await import('vuex') + const { default: dashboard } = await import('./store/dashboard.js') + + Vue.prototype.t = t + Vue.prototype.n = n + Vue.prototype.OC = OC + Vue.use(Vuex) + + const store = new Vuex.Store({ + modules: { + dashboard, + }, + strict: debug, + }) + + _imports = { + store, Vue, + } + + return _imports +} + document.addEventListener('DOMContentLoaded', () => { OCA.Dashboard.register('deck', async (el) => { - const { default: Vue } = await import('vue') - const { default: Vuex } = await import('vuex') - const { default: dashboard } = await import('./store/dashboard.js') + const { Vue, store } = await getAsyncImports() + const { default: DashboardUpcoming } = await import('./views/DashboardUpcoming.vue') - const { default: Dashboard } = await import('./views/Dashboard.vue') - Vue.prototype.t = t - Vue.prototype.n = n - Vue.prototype.OC = OC - Vue.use(Vuex) + const View = Vue.extend(DashboardUpcoming) + const vm = new View({ + propsData: {}, + store, + }).$mount(el) + return vm + }) - const store = new Vuex.Store({ - modules: { - dashboard, - }, - strict: debug, - }) - const View = Vue.extend(Dashboard) + OCA.Dashboard.register('deckToday', async (el) => { + const { Vue, store } = await getAsyncImports() + const { default: DashboardToday } = await import('./views/DashboardToday.vue') + const View = Vue.extend(DashboardToday) + const vm = new View({ + propsData: {}, + store, + }).$mount(el) + return vm + }) + + OCA.Dashboard.register('deckTomorrow', async (el) => { + const { Vue, store } = await getAsyncImports() + const { default: DashboardTomorrow } = await import('./views/DashboardTomorrow.vue') + const View = Vue.extend(DashboardTomorrow) const vm = new View({ propsData: {}, store, diff --git a/src/store/overview.js b/src/store/overview.js index d06095308..5ac6fb6e7 100644 --- a/src/store/overview.js +++ b/src/store/overview.js @@ -29,6 +29,7 @@ const apiClient = new OverviewApi() export default { state: { assignedCards: [], + loading: false, }, getters: { assignedCardsDashboard: state => { @@ -39,18 +40,27 @@ export default { setAssignedCards(state, assignedCards) { state.assignedCards = assignedCards }, + setLoading(state, promise) { + state.loading = promise + }, }, actions: { - async loadUpcoming({ commit }) { - commit('setCurrentBoard', null) - const upcommingCards = await apiClient.get('upcoming') - - for (const dueStatus in upcommingCards) { - for (const idx in upcommingCards[dueStatus]) { - commit('addCard', upcommingCards[dueStatus][idx]) - } + async loadUpcoming({ state, commit }) { + if (state.loading) { + return state.loading } - commit('setAssignedCards', upcommingCards) + const promise = (async () => { + commit('setCurrentBoard', null) + const assignedCards = await apiClient.get('upcoming') + const assignedCardsFlat = assignedCards.flat() + for (const i in assignedCardsFlat) { + commit('addCard', assignedCardsFlat[i]) + } + commit('setAssignedCards', assignedCardsFlat) + commit('setLoading', false) + })() + commit('setLoading', promise) + return promise }, }, } diff --git a/src/views/DashboardToday.vue b/src/views/DashboardToday.vue new file mode 100644 index 000000000..3c6a1e551 --- /dev/null +++ b/src/views/DashboardToday.vue @@ -0,0 +1,91 @@ + + + + + + + diff --git a/src/views/DashboardTomorrow.vue b/src/views/DashboardTomorrow.vue new file mode 100644 index 000000000..53ccd273d --- /dev/null +++ b/src/views/DashboardTomorrow.vue @@ -0,0 +1,92 @@ + + + + + + + diff --git a/src/views/Dashboard.vue b/src/views/DashboardUpcoming.vue similarity index 81% rename from src/views/Dashboard.vue rename to src/views/DashboardUpcoming.vue index 2ed2510cc..ab837fe1c 100644 --- a/src/views/Dashboard.vue +++ b/src/views/DashboardUpcoming.vue @@ -30,21 +30,7 @@ @hide="() => {}" @markDone="() => {}">
@@ -65,22 +51,20 @@ import PlusIcon from 'vue-material-design-icons/Plus.vue' import { NcButton, NcDashboardWidget, NcModal } from '@nextcloud/vue' import { mapGetters } from 'vuex' -import labelStyle from './../mixins/labelStyle.js' -import DueDate from '../components/cards/badges/DueDate.vue' +import Card from '../components/dashboard/Card.vue' import { generateUrl } from '@nextcloud/router' import CreateNewCardCustomPicker from './CreateNewCardCustomPicker.vue' export default { - name: 'Dashboard', + name: 'DashboardUpcoming', components: { CreateNewCardCustomPicker, NcModal, - DueDate, NcDashboardWidget, NcButton, PlusIcon, + Card, }, - mixins: [labelStyle], data() { return { loading: false, @@ -102,11 +86,6 @@ export default { }) return list.slice(0, 5) }, - cardLink() { - return (card) => { - return generateUrl('/apps/deck') + `#/board/${card.boardId}/card/${card.id}` - } - }, showMoreUrl() { return this.cards.length > 7 ? generateUrl('/apps/deck') : null }, @@ -126,8 +105,6 @@ export default {