1
0
Fork 0
mirror of https://github.com/nextcloud/calendar.git synced 2024-10-07 16:40:09 +02:00

Add appointments overview page

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
This commit is contained in:
Christoph Wurst 2021-10-22 11:41:32 +02:00
parent 9087968333
commit 3104adcf81
No known key found for this signature in database
GPG key ID: CC42AC2A7F0E56D8
7 changed files with 330 additions and 0 deletions

View file

@ -34,6 +34,8 @@ return [
['name' => 'view#index', 'url' => '/{view}/{timeRange}', 'verb' => 'GET', 'requirements' => ['view' => 'timeGridDay|timeGridWeek|dayGridMonth|listMonth'], 'postfix' => 'view.timerange'],
['name' => 'view#index', 'url' => '/{view}/{timeRange}/new/{mode}/{isAllDay}/{dtStart}/{dtEnd}', 'verb' => 'GET', 'requirements' => ['view' => 'timeGridDay|timeGridWeek|dayGridMonth|listMonth'], 'postfix' => 'view.timerange.new'],
['name' => 'view#index', 'url' => '/{view}/{timeRange}/edit/{mode}/{objectId}/{recurrenceId}', 'verb' => 'GET', 'requirements' => ['view' => 'timeGridDay|timeGridWeek|dayGridMonth|listMonth'], 'postfix' => 'view.timerange.edit'],
// Appointments
['name' => 'appointment#index', 'url' => '/appointments/{userId}', 'verb' => 'GET'],
// Public views
['name' => 'publicView#public_index_with_branding', 'url' => '/p/{token}', 'verb' => 'GET'],
['name' => 'publicView#public_index_with_branding', 'url' => '/p/{token}/{view}/{timeRange}', 'verb' => 'GET', 'postfix' => 'publicview.timerange'],

View file

@ -0,0 +1,100 @@
<?php
declare(strict_types=1);
/*
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @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\Calendar\Controller;
use OCA\Calendar\AppInfo\Application;
use OCA\Calendar\Db\AppointmentConfig;
use OCA\Calendar\Service\Appointments\AppointmentConfigService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Services\IInitialState;
use OCP\IRequest;
use OCP\IUserManager;
use function array_filter;
class AppointmentController extends Controller {
/** @var IUserManager */
private $userManager;
/** @var AppointmentConfigService */
private $configService;
/** @var IInitialState */
private $initialState;
public function __construct(IRequest $request,
IUserManager $userManager,
AppointmentConfigService $configService,
IInitialState $initialState) {
parent::__construct(Application::APP_ID, $request);
$this->userManager = $userManager;
$this->configService = $configService;
$this->initialState = $initialState;
}
/**
* @PublicPage
* @NoAdminRequired
* @NoCSRFRequired
*
* @return Response
*/
public function index(string $userId): Response {
$user = $this->userManager->get($userId);
if ($user === null) {
return new TemplateResponse(
Application::APP_ID,
'appointments/404-index',
[],
TemplateResponse::RENDER_AS_GUEST
);
}
$this->initialState->provideInitialState(
'userInfo',
[
'uid' => $user->getUID(),
'displayName' => $user->getDisplayName(),
],
);
$this->initialState->provideInitialState(
'appointmentConfigs',
array_filter($this->configService->getAllAppointmentConfigurations($userId), function (AppointmentConfig $config): bool {
return $config->getVisibility() === AppointmentConfig::VISIBILITY_PUBLIC;
}),
);
return new TemplateResponse(
Application::APP_ID,
'appointments/index',
[],
TemplateResponse::RENDER_AS_PUBLIC
);
}
}

View file

@ -0,0 +1,53 @@
/**
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
* @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/>.
*/
import { getRequestToken } from '@nextcloud/auth'
import { loadState } from '@nextcloud/initial-state'
import { linkTo } from '@nextcloud/router'
import Vue from 'vue'
import { translate, translatePlural } from '@nextcloud/l10n'
import Overview from '../views/Appointments/Overview'
// CSP config for webpack dynamic chunk loading
// eslint-disable-next-line
__webpack_nonce__ = btoa(getRequestToken())
// Correct the root of the app for chunk loading
// OC.linkTo matches the apps folders
// OC.generateUrl ensure the index.php (or not)
// We do not want the index.php since we're loading files
// eslint-disable-next-line
__webpack_public_path__ = linkTo('calendar', 'js/')
const configs = loadState('calendar', 'appointmentConfigs')
const userInfo = loadState('calendar', 'userInfo')
Vue.prototype.$t = translate
Vue.prototype.$n = translatePlural
export default new Vue({
el: '#appointments-overview',
render: h => h(Overview, {
props: {
configs,
userInfo,
},
}),
})

View file

@ -0,0 +1,112 @@
<!--
- @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
-
- @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
-
- @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/>.
-->
<template>
<div class="overview-info">
<Avatar
:user="userInfo.uid"
:display-name="userInfo.displayName"
:disable-tooltip="true"
:disable-menu="true"
:size="180" />
<div class="user-info">
<strong> {{ userInfo.displayName }} </strong>
</div>
<div class="config-info">
<a v-for="config in configs"
:key="config.id"
target="#"
class="config-name">
<p> <strong>{{ config.name }} </strong> </p>
<span class="icon-arrow-right" />
</a>
</div>
<div v-if="configs.length === 0">
<EmptyContent icon="icon-calendar-dark" />
{{ $t('calendar', 'No public appointments found for {displayname}', { displayname: userInfo.displayName }) }}
</div>
</div>
</template>
<script>
import Avatar from '@nextcloud/vue/dist/Components/Avatar'
import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent'
export default {
name: 'Overview',
components: {
Avatar,
EmptyContent,
},
props: {
configs: {
required: true,
type: Array,
},
userInfo: {
required: true,
type: Object,
},
},
}
</script>
<style lang="scss" scoped>
.overview-info {
display: flex;
align-items: center;
flex-direction: column;
max-width: 900px;
margin: 50px auto;
height: 150px;
}
.config-info {
display: flex;
flex-wrap: wrap;
max-width: 500px;
width: 100%;
}
.config-name:hover {
background-color: var(--color-background-hover);
border-radius: 16px;
}
.config-name {
display: flex;
flex: 1 auto;
margin-left: 40px;
font-size: 16px;
align-items: center;
}
.icon-arrow-right {
background-image: var(--icon-triangle-e-000);
margin-left: 10px;
}
.user-info {
color: var( --color-text-maxcontrast);
margin-bottom: 50px;
margin-top: 20px;
}
</style>

View file

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
/*
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @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/>.
*/
/** @var \OCP\IL10N $l */
?>
<?php p($l->t('User not found')); ?>

View file

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
/*
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @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/>.
*/
script(\OCA\Calendar\AppInfo\Application::APP_ID, 'calendar-appointments-overview');
?>
<div id="appointments-overview"></div>

View file

@ -12,6 +12,9 @@ const appVersion = JSON.stringify(process.env.npm_package_version)
// Add dashboard entry
webpackConfig.entry.dashboard = path.join(__dirname, 'src', 'dashboard.js')
// Add appointments entries
webpackConfig.entry['appointments-overview'] = path.join(__dirname, 'src', 'appointments/main-overview.js')
// Edit JS rule
webpackRules.RULE_JS.test = /\.m?js$/
webpackRules.RULE_JS.exclude = BabelLoaderExcludeNodeModulesExcept([