parent
544fcdb549
commit
5a1874910b
@ -0,0 +1,24 @@ |
||||
<?php |
||||
/** |
||||
* @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net> |
||||
* |
||||
* @author Julius Härtl <jus@bitgrid.net> |
||||
* |
||||
* @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 <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
$app = new \OCP\AppFramework\App('dashboard'); |
@ -0,0 +1,30 @@ |
||||
<?xml version="1.0"?> |
||||
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd"> |
||||
<id>dashboard</id> |
||||
<name>Dashboard</name> |
||||
<summary>Dashboard app</summary> |
||||
<description><![CDATA[Show something]]></description> |
||||
<version>7.0.0</version> |
||||
<licence>agpl</licence> |
||||
<author>Julius Härtl</author> |
||||
<namespace>Dashboard</namespace> |
||||
<default_enable/> |
||||
|
||||
<category>customization</category> |
||||
|
||||
<bugs>https://github.com/nextcloud/server/issues</bugs> |
||||
|
||||
<dependencies> |
||||
<nextcloud min-version="20" max-version="20"/> |
||||
</dependencies> |
||||
|
||||
<navigations> |
||||
<navigation> |
||||
<name>Dashboard</name> |
||||
<route>dashboard.dashboard.index</route> |
||||
<icon>dashboard.svg</icon> |
||||
<order>-1</order> |
||||
</navigation> |
||||
</navigations> |
||||
</info> |
@ -0,0 +1,28 @@ |
||||
<?php |
||||
/** |
||||
* @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net> |
||||
* |
||||
* @author Julius Härtl <jus@bitgrid.net> |
||||
* |
||||
* @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 <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
return [ |
||||
'routes' => [ |
||||
['name' => 'dashboard#index', 'url' => '/', 'verb' => 'GET'], |
||||
] |
||||
]; |
After Width: | Height: | Size: 244 B |
@ -0,0 +1,79 @@ |
||||
<?php |
||||
/** |
||||
* @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net> |
||||
* |
||||
* @author Julius Härtl <jus@bitgrid.net> |
||||
* |
||||
* @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 <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
namespace OCA\Dashboard\Controller; |
||||
|
||||
use OCA\Viewer\Event\LoadViewer; |
||||
use OCP\AppFramework\Controller; |
||||
use OCP\AppFramework\Http\TemplateResponse; |
||||
use OCP\Dashboard\IManager; |
||||
use OCP\Dashboard\IPanel; |
||||
use OCP\Dashboard\IRegisterPanelEvent; |
||||
use OCP\EventDispatcher\IEventDispatcher; |
||||
use OCP\IInitialStateService; |
||||
use OCP\IRequest; |
||||
|
||||
class DashboardController extends Controller { |
||||
|
||||
/** @var IInitialStateService */ |
||||
private $inititalStateService; |
||||
/** @var IEventDispatcher */ |
||||
private $eventDispatcher; |
||||
/** @var IManager */ |
||||
private $dashboardManager; |
||||
|
||||
public function __construct($appName, IRequest $request, IInitialStateService $initialStateService, IEventDispatcher $eventDispatcher, IManager $dashboardManager) { |
||||
parent::__construct($appName, $request); |
||||
|
||||
$this->inititalStateService = $initialStateService; |
||||
$this->eventDispatcher = $eventDispatcher; |
||||
$this->dashboardManager = $dashboardManager; |
||||
} |
||||
|
||||
/** |
||||
* @NoCSRFRequired |
||||
* @NoAdminRequired |
||||
* @return TemplateResponse |
||||
*/ |
||||
public function index(): TemplateResponse { |
||||
$this->eventDispatcher->dispatchTyped(new IRegisterPanelEvent($this->dashboardManager)); |
||||
|
||||
$dashboardManager = $this->dashboardManager; |
||||
$this->inititalStateService->provideLazyInitialState('dashboard', 'panels', function () use ($dashboardManager) { |
||||
return array_map(function (IPanel $panel) { |
||||
return [ |
||||
'id' => $panel->getId(), |
||||
'title' => $panel->getTitle(), |
||||
'iconClass' => $panel->getIconClass(), |
||||
'url' => $panel->getUrl() |
||||
]; |
||||
}, $dashboardManager->getPanels()); |
||||
}); |
||||
|
||||
if (class_exists(LoadViewer::class)) { |
||||
$this->eventDispatcher->dispatchTyped(new LoadViewer()); |
||||
} |
||||
|
||||
return new TemplateResponse('dashboard', 'index'); |
||||
} |
||||
} |
@ -0,0 +1,119 @@ |
||||
<template> |
||||
<div id="app-dashboard"> |
||||
<h2>{{ greeting }}, {{ name }}</h2> |
||||
|
||||
<div class="panels"> |
||||
<div v-for="panel in panels" :key="panel.id" class="panel"> |
||||
<a :href="panel.url"> |
||||
<h3 :class="panel.iconClass"> |
||||
{{ panel.title }} |
||||
</h3> |
||||
</a> |
||||
<div :ref="panel.id" :data-id="panel.id" /> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import Vue from 'vue' |
||||
import { loadState } from '@nextcloud/initial-state' |
||||
import { getCurrentUser } from '@nextcloud/auth' |
||||
|
||||
const panels = loadState('dashboard', 'panels') |
||||
|
||||
console.debug('Loading dashboard panels', panels) |
||||
|
||||
export default { |
||||
name: 'App', |
||||
data() { |
||||
return { |
||||
timer: new Date(), |
||||
callbacks: {}, |
||||
panels, |
||||
name: getCurrentUser()?.displayName, |
||||
} |
||||
}, |
||||
computed: { |
||||
greeting() { |
||||
const time = this.timer.getHours() |
||||
|
||||
if (time > 18) { |
||||
return t('dashboard', '🌙 Good evening') |
||||
} |
||||
if (time > 12) { |
||||
return t('dashboard', '☀ Good afternoon') |
||||
} |
||||
if (time === 12) { |
||||
return t('dashboard', '🍽 Time for lunch') |
||||
} |
||||
return t('dashboard', '🌄 Good morning') |
||||
}, |
||||
}, |
||||
watch: { |
||||
callbacks() { |
||||
for (const app in this.callbacks) { |
||||
const element = this.$refs[app] |
||||
if (this.panels[app].mounted) { |
||||
return |
||||
} |
||||
|
||||
if (element) { |
||||
this.callbacks[app](element[0]) |
||||
Vue.set(this.panels[app], 'mounted', true) |
||||
} else { |
||||
console.error('Failed to register panel in the frontend as no backend data was provided for ' + app) |
||||
} |
||||
} |
||||
}, |
||||
}, |
||||
mounted() { |
||||
setInterval(() => { |
||||
this.timer = new Date() |
||||
}, 30000) |
||||
}, |
||||
methods: { |
||||
register(app, callback) { |
||||
Vue.set(this.callbacks, app, callback) |
||||
}, |
||||
}, |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
#app-dashboard { |
||||
width: 100%; |
||||
padding-left: 50px; |
||||
padding-right: 50px; |
||||
} |
||||
h2 { |
||||
text-align: center; |
||||
padding: 40px; |
||||
} |
||||
|
||||
.panels { |
||||
width: 100%; |
||||
display: flex; |
||||
justify-content: center; |
||||
} |
||||
|
||||
.panel { |
||||
width: 250px; |
||||
margin: 0 30px 30px 0; |
||||
|
||||
&:first-child { |
||||
margin-left: 30px; |
||||
} |
||||
|
||||
h3 { |
||||
position: sticky; |
||||
top: 50px; |
||||
margin-top: 0; |
||||
background-position: 10px 32px; |
||||
padding: 30px 12px 12px 35px; |
||||
background-color: var(--color-main-background); |
||||
} |
||||
|
||||
} |
||||
|
||||
</style> |
@ -0,0 +1,9 @@ |
||||
import Vue from 'vue' |
||||
import App from './App.vue' |
||||
|
||||
const Dashboard = Vue.extend(App) |
||||
const Instance = new Dashboard({}).$mount('#app') |
||||
|
||||
window.OCA.Dashboard = { |
||||
register: (app, callback) => Instance.register(app, callback), |
||||
} |
@ -0,0 +1,4 @@ |
||||
<?php |
||||
\OC_Util::addScript('dashboard', 'dashboard'); |
||||
?> |
||||
<div id="app"></div> |
@ -0,0 +1,11 @@ |
||||
const path = require('path') |
||||
|
||||
module.exports = { |
||||
entry: path.join(__dirname, 'src', 'main.js'), |
||||
output: { |
||||
path: path.resolve(__dirname, './js'), |
||||
publicPath: '/js/', |
||||
filename: 'dashboard.js', |
||||
jsonpFunction: 'webpackJsonpDashboard' |
||||
} |
||||
} |
Loading…
Reference in new issue