Add dashboard app
Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
parent
544fcdb549
commit
5a1874910b
|
@ -17,6 +17,7 @@
|
|||
!/apps/cloud_federation_api
|
||||
!/apps/comments
|
||||
!/apps/contactsinteraction
|
||||
!/apps/dashboard
|
||||
!/apps/dav
|
||||
!/apps/files
|
||||
!/apps/federation
|
||||
|
|
|
@ -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>
|
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'
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ const { VueLoaderPlugin } = require('vue-loader')
|
|||
const accessibility = require('./apps/accessibility/webpack')
|
||||
const comments = require('./apps/comments/webpack')
|
||||
const core = require('./core/webpack')
|
||||
const dashboard = require('./apps/dashboard/webpack')
|
||||
const files = require('./apps/files/webpack')
|
||||
const files_sharing = require('./apps/files_sharing/webpack')
|
||||
const files_trashbin = require('./apps/files_trashbin/webpack')
|
||||
|
@ -21,6 +22,7 @@ const modules = {
|
|||
accessibility,
|
||||
comments,
|
||||
core,
|
||||
dashboard,
|
||||
files,
|
||||
files_sharing,
|
||||
files_trashbin,
|
||||
|
|
Loading…
Reference in New Issue