Skip to content

Commit

Permalink
draft first dashboard
Browse files Browse the repository at this point in the history
Signed-off-by: Benjamin Brahmer <[email protected]>
  • Loading branch information
Grotax committed Mar 1, 2023
1 parent 7dfa189 commit a131dd3
Show file tree
Hide file tree
Showing 11 changed files with 335 additions and 2 deletions.
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,7 @@ appstore:

# on macOS there is no option "--parents" for the "cp" command
mkdir -p $(appstore_sign_dir)/$(app_name)/js/build $(appstore_sign_dir)/$(app_name)/js/admin
cp js/build/app.min.js $(appstore_sign_dir)/$(app_name)/js/build
cp js/build/news-admin-settings.js* $(appstore_sign_dir)/$(app_name)/js/build
cp js/build/* $(appstore_sign_dir)/$(app_name)/js/build

# export the key and cert to a file
@if [ ! -f $(cert_dir)/$(app_name).key ] || [ ! -f $(cert_dir)/$(app_name).crt ]; then \
Expand Down
12 changes: 12 additions & 0 deletions css/dashboard.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.icon-newsdashboard {
background-image: url('../img/app-dark.svg');
filter: var(--background-invert-if-dark);
}

.widget-list li {
list-style-type: disc;
}

#app-dashboard .panels .panel--header h2 {
display: flex;
}
4 changes: 4 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
use OCA\News\Search\FeedSearchProvider;
use OCA\News\Search\FolderSearchProvider;
use OCA\News\Search\ItemSearchProvider;
use OCA\News\Dashboard\ItemWidget;
use OCA\News\Dashboard\FeedWidget;

use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
Expand Down Expand Up @@ -85,6 +87,8 @@ public function register(IRegistrationContext $context): void
$context->registerSearchProvider(FeedSearchProvider::class);
$context->registerSearchProvider(ItemSearchProvider::class);

$context->registerDashboardWidget(ItemWidget::class);
$context->registerDashboardWidget(FeedWidget::class);

$context->registerEventListener(BeforeUserDeletedEvent::class, UserDeleteHook::class);

Expand Down
91 changes: 91 additions & 0 deletions lib/Dashboard/FeedWidget.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

namespace OCA\News\Dashboard;

use OCA\News\Service\FeedServiceV2;
use OCP\AppFramework\Services\IInitialState;
use OCP\Dashboard\IAPIWidget;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\Dashboard\Model\WidgetItem;

use Psr\Log\LoggerInterface;

use OCA\News\AppInfo\Application;
use OCA\News\Db\ListType;
use OCP\Util;

class FeedWidget implements IAPIWidget
{


private $l10n;
private $feedService;
private $initialStateService;
private $userId;
private $urlGenerator;
private $logger;

public function __construct(IL10N $l10n,
IURLGenerator $urlGenerator,
FeedServiceV2 $feedService,
IInitialState $initialStateService,
LoggerInterface $loggerInterface,
?string $userId
) {
$this->l10n = $l10n;
$this->feedService = $feedService;
$this->initialStateService = $initialStateService;
$this->userId = $userId;
$this->urlGenerator = $urlGenerator;
$this->logger = $loggerInterface;
}

public function getId(): string
{
return 'news-feed-widget';
}

public function getTitle(): string
{
$this->logger->debug("Requested title");
return $this->l10n->t('News Feed widget');
}

public function getOrder(): int
{
$this->logger->debug("Requested order");
return 20;
}

public function getIconClass(): string
{
return 'icon-newsdashboard';
$this->logger->debug("Requested icon");
}

public function getUrl(): ?string
{
return $this->urlGenerator->linkToRoute('news.page.index');
$this->logger->debug("Requested url");
}

public function load(): void
{
$this->logger->debug("Requested load with user: " . $this->userId);
if ($this->userId !== null) {
$items = $this->getItems($this->userId);
$this->initialStateService->provideInitialState('dashboard-widget-feeds', $items);
}

Util::addScript(Application::NAME, 'build/' . Application::NAME . '-dashboard-feeds');
Util::addStyle(Application::NAME, 'dashboard');
}

public function getItems(string $userId, ?string $since = null, int $limit = 7): array
{
$items = $this->feedService->findAllForUser($userId);

return $items;
}
}
93 changes: 93 additions & 0 deletions lib/Dashboard/ItemWidget.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace OCA\News\Dashboard;

use OCA\News\Service\ItemServiceV2;
use OCP\AppFramework\Services\IInitialState;
use OCP\Dashboard\IAPIWidget;
use OCP\IL10N;
use OCP\IURLGenerator;
//maybe this can be used to craft items with things from the feed
use OCP\Dashboard\Model\WidgetItem;

use Psr\Log\LoggerInterface;

use OCA\News\AppInfo\Application;
use OCA\News\Db\ListType;
use OCP\Util;

class ItemWidget implements IAPIWidget
{


private $l10n;
private $itemService;
private $initialStateService;
private $userId;
private $urlGenerator;
private $logger;

public function __construct(IL10N $l10n,
IURLGenerator $urlGenerator,
ItemServiceV2 $itemService,
IInitialState $initialStateService,
LoggerInterface $loggerInterface,
?string $userId
) {
$this->l10n = $l10n;
$this->itemService = $itemService;
$this->initialStateService = $initialStateService;
$this->userId = $userId;
$this->urlGenerator = $urlGenerator;
$this->logger = $loggerInterface;
}

public function getId(): string
{
return 'news-item-widget';
}

public function getTitle(): string
{
$this->logger->debug("Requested title");
return $this->l10n->t('News Item widget');
}

public function getOrder(): int
{
$this->logger->debug("Requested order");
return 20;
}

public function getIconClass(): string
{
return 'icon-newsdashboard'; // TODO
$this->logger->debug("Requested icon");
}

public function getUrl(): ?string
{
return $this->urlGenerator->linkToRoute('news.page.index');
$this->logger->debug("Requested url");
}

public function load(): void
{
$this->logger->debug("Requested load with user: " . $this->userId);
if ($this->userId !== null) {
$items = $this->getItems($this->userId);
$this->initialStateService->provideInitialState('dashboard-widget-items', $items);
}

Util::addScript(Application::NAME, 'build/' . Application::NAME . '-dashboard-items');
Util::addStyle(Application::NAME, 'dashboard');
}

public function getItems(string $userId, ?string $since = null, int $limit = 7): array
{
$offset = (int) ($since ?? 0);
$items = $this->itemService->findAllWithFilters($userId, ListType::ALL_ITEMS, $limit, $offset, false);

return $items;
}
}
53 changes: 53 additions & 0 deletions src/components/FeedDashboard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<NcDashboardWidget :items="items">
<template #default="{ item }">
<NcDashboardWidgetItem
:main-text="item.mainText"
:sub-text="item.subText"
:target-url="item.targetURL"
:avatar-is-no-user="true"
:avatar-url="item.favicon">

<NcDashboardWidgetItem>
</template>
</NcDashboardWidget>
</template>

<script>
import NcDashboardWidget from '@nextcloud/vue/dist/Components/NcDashboardWidget.js'
import NcDashboardWidgetItem from '@nextcloud/vue/dist/Components/NcDashboardWidgetItem'
import { loadState } from '@nextcloud/initial-state'
import { generateUrl } from '@nextcloud/router'
const newsItems = loadState('news', 'dashboard-widget-feeds')
console.log(newsItems)
export default {
name: 'NewsFeedWidget',
components: {
NcDashboardWidget,
NcDashboardWidgetItem,
},
props: [],
data() {
return {
newsItems: newsItems
}
},
computed: {
items() {
return this.newsItems.map((g) => {
return {
id: g.id,
mainText: g.title,
subText: `Unread: ${g.unreadCount}`,
targetURL: generateUrl(`/apps/news/#/items/feeds/${g.id}`),
favicon: g.faviconLink,
}
})
}
}
}
</script>
50 changes: 50 additions & 0 deletions src/components/ItemDashboard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<template>
<NcDashboardWidget :items="items">
<template #default="{ item }">
<NcDashboardWidgetItem
:main-text="item.mainText"
:sub-text="item.subText"
:target-url="item.targetURL">

<NcDashboardWidgetItem>
</template>
</NcDashboardWidget>
</template>

<script>
import NcDashboardWidget from '@nextcloud/vue/dist/Components/NcDashboardWidget.js'
import NcDashboardWidgetItem from '@nextcloud/vue/dist/Components/NcDashboardWidgetItem'
import { loadState } from '@nextcloud/initial-state'
import { generateUrl } from '@nextcloud/router'
const newsItems = loadState('news', 'dashboard-widget-items')
console.log(newsItems)
export default {
name: 'NewsItemWidget',
components: {
NcDashboardWidget,
NcDashboardWidgetItem,
},
props: [],
data() {
return {
newsItems: newsItems
}
},
computed: {
items() {
return this.newsItems.map((g) => {
return {
id: g.id,
mainText: g.title,
subText: g.intro,
targetURL: generateUrl(`/apps/news/#/items/feeds/${g.feedId}`)
}
})
}
}
}
</script>
11 changes: 11 additions & 0 deletions src/dashboard-feeds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Vue from 'vue'
import NewsFeedWidget from './components/FeedDashboard.vue'

document.addEventListener('DOMContentLoaded', () => {
console.log("I'm alive")
OCA.Dashboard.register('news-feed-widget', (el) => {
console.log("Dashboard registered")
const View = Vue.extend(NewsFeedWidget)
new View().$mount(el)
})
})
11 changes: 11 additions & 0 deletions src/dashboard-items.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Vue from 'vue'
import NewsItemWidget from './components/ItemDashboard.vue'

document.addEventListener('DOMContentLoaded', () => {
console.log("I'm alive")
OCA.Dashboard.register('news-item-widget', (el) => {
console.log("Dashboard registered")
const View = Vue.extend(NewsItemWidget)
new View().$mount(el)
})
})
7 changes: 7 additions & 0 deletions src/vueBootstrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Vue from 'vue'
import { translate, translatePlural } from '@nextcloud/l10n'

Vue.prototype.t = translate
Vue.prototype.n = translatePlural
Vue.prototype.OC = window.OC
Vue.prototype.OCA = window.OCA
2 changes: 2 additions & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const webpackConfig = require('@nextcloud/webpack-vue-config')

webpackConfig.entry = {
'admin-settings': path.join(__dirname, 'src', 'main-admin.js'),
'dashboard-items': path.join(__dirname, 'src', 'dashboard-items.js'),
'dashboard-feeds': path.join(__dirname, 'src', 'dashboard-feeds.js'),
}
webpackConfig.output.path = path.resolve('./js/build/')
webpackConfig.output.publicPath = path.join('/apps/', process.env.npm_package_name, '/js/build/')
Expand Down

0 comments on commit a131dd3

Please sign in to comment.