No known key found for this signature in database
GPG Key ID: 4C614C6ED2CDE6DF
11 changed files with 308 additions and 0 deletions
-
1.gitignore
-
24apps/dashboard/appinfo/app.php
-
30apps/dashboard/appinfo/info.xml
-
28apps/dashboard/appinfo/routes.php
-
1apps/dashboard/img/dashboard.svg
-
79apps/dashboard/lib/Controller/DashboardController.php
-
119apps/dashboard/src/App.vue
-
9apps/dashboard/src/main.js
-
4apps/dashboard/templates/index.php
-
11apps/dashboard/webpack.js
-
2webpack.common.js
@ -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'], |
|||
] |
|||
]; |
|||
@ -0,0 +1 @@ |
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"><g stroke-width=".905" fill="#fff" paint-order="stroke fill markers"><path d="M2.096 2.902h3.26v10.046h-3.26zM6.49 2.85h3.26v10.046H6.49zM11.052 2.824h3.26V12.87h-3.26z"/></g></svg> |
|||
@ -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' |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue