fetch writeable calendars of user and display a dropdown in confirm dialog with list of calendars to choose for the event
This commit is contained in:
1 parent
f51bb830ab
commit
fa398f5b36
3 files changed
+110
-15
No files matched your search
@@ -21,7 +21,7 @@ use Sabre\VObject\Reader;
|
|||||||
class CalendarController extends Controller
|
class CalendarController extends Controller
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Target calendar for created events.
|
* Preferred calendar, preselected in the dropdown if present.
|
||||||
*/
|
*/
|
||||||
private const CALENDAR_NAME = 'Personal';
|
private const CALENDAR_NAME = 'Personal';
|
||||||
|
|
||||||
@@ -88,7 +88,17 @@ class CalendarController extends Controller
|
|||||||
$url
|
$url
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->renderConfirm($data);
|
$user = $this->userSession->getUser();
|
||||||
|
|
||||||
|
$calendars = $user === null
|
||||||
|
? []
|
||||||
|
: $this->findWritableCalendars($user->getUID());
|
||||||
|
|
||||||
|
return $this->renderConfirm(
|
||||||
|
$data,
|
||||||
|
$calendars,
|
||||||
|
$this->defaultCalendarId($calendars)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -105,7 +115,8 @@ class CalendarController extends Controller
|
|||||||
string $end = '',
|
string $end = '',
|
||||||
string $organizer = '',
|
string $organizer = '',
|
||||||
string $location = '',
|
string $location = '',
|
||||||
string $url = ''
|
string $url = '',
|
||||||
|
string $calendarId = ''
|
||||||
): RedirectResponse|TemplateResponse {
|
): RedirectResponse|TemplateResponse {
|
||||||
$data = $this->validateEventData(
|
$data = $this->validateEventData(
|
||||||
$summary,
|
$summary,
|
||||||
@@ -123,7 +134,13 @@ class CalendarController extends Controller
|
|||||||
throw new \RuntimeException('No authenticated Nextcloud user.');
|
throw new \RuntimeException('No authenticated Nextcloud user.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$calendar = $this->findWritableCalendar($user->getUID());
|
$calendars = $this->findWritableCalendars($user->getUID());
|
||||||
|
|
||||||
|
if ($calendarId === '') {
|
||||||
|
$calendarId = $this->defaultCalendarId($calendars);
|
||||||
|
}
|
||||||
|
|
||||||
|
$calendar = $this->selectCalendar($calendars, $calendarId);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Friendly error instead of a hard server error page.
|
* Friendly error instead of a hard server error page.
|
||||||
@@ -131,10 +148,14 @@ class CalendarController extends Controller
|
|||||||
if ($calendar === null) {
|
if ($calendar === null) {
|
||||||
return $this->renderConfirm(
|
return $this->renderConfirm(
|
||||||
$data,
|
$data,
|
||||||
'No writable calendar named "'
|
$calendars,
|
||||||
. self::CALENDAR_NAME
|
$calendarId,
|
||||||
. '" was found in your account. Create it in the '
|
$calendars === []
|
||||||
. 'Nextcloud Calendar app, then try again.'
|
? 'No writable calendar was found in your account. '
|
||||||
|
. 'Create one in the Nextcloud Calendar app, '
|
||||||
|
. 'then try again.'
|
||||||
|
: 'The selected calendar is no longer writable. '
|
||||||
|
. 'Pick another one and try again.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,12 +172,12 @@ class CalendarController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The user's "Personal" calendar.
|
* All writable calendars of the given principal.
|
||||||
*
|
*
|
||||||
* getCalendarsForPrincipal() returns ICalendar objects.
|
* getCalendarsForPrincipal() returns ICalendar objects.
|
||||||
* Only calendars implementing ICreateFromString are writable.
|
* Only calendars implementing ICreateFromString are writable.
|
||||||
*/
|
*/
|
||||||
private function findWritableCalendar(string $userId): ?ICreateFromString
|
private function findWritableCalendars(string $userId): array
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* IManager calendars are queried via the principal URI.
|
* IManager calendars are queried via the principal URI.
|
||||||
@@ -165,12 +186,24 @@ class CalendarController extends Controller
|
|||||||
|
|
||||||
$calendars = $this->calendarManager->getCalendarsForPrincipal($principalUri);
|
$calendars = $this->calendarManager->getCalendarsForPrincipal($principalUri);
|
||||||
|
|
||||||
|
$writable = [];
|
||||||
|
|
||||||
foreach ($calendars as $calendar) {
|
foreach ($calendars as $calendar) {
|
||||||
if (!$calendar instanceof ICreateFromString) {
|
if ($calendar instanceof ICreateFromString) {
|
||||||
continue;
|
$writable[] = $calendar;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($calendar->getDisplayName() === self::CALENDAR_NAME) {
|
return $writable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The calendar with the given key, if it is writable.
|
||||||
|
*/
|
||||||
|
private function selectCalendar(array $calendars, string $calendarId): ?ICreateFromString
|
||||||
|
{
|
||||||
|
foreach ($calendars as $calendar) {
|
||||||
|
if ($calendar->getKey() === $calendarId) {
|
||||||
return $calendar;
|
return $calendar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,11 +211,34 @@ class CalendarController extends Controller
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key of the calendar to preselect: the preferred
|
||||||
|
* CALENDAR_NAME if present, otherwise the first one.
|
||||||
|
*/
|
||||||
|
private function defaultCalendarId(array $calendars): string
|
||||||
|
{
|
||||||
|
foreach ($calendars as $calendar) {
|
||||||
|
if ($calendar->getDisplayName() === self::CALENDAR_NAME) {
|
||||||
|
return $calendar->getKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($calendars[0])) {
|
||||||
|
return $calendars[0]->getKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the confirmation page, optionally with an error message.
|
* Render the confirmation page, optionally with an error message.
|
||||||
*/
|
*/
|
||||||
private function renderConfirm(array $data, string $error = ''): TemplateResponse
|
private function renderConfirm(
|
||||||
{
|
array $data,
|
||||||
|
array $calendars,
|
||||||
|
string $calendarId = '',
|
||||||
|
string $error = ''
|
||||||
|
): TemplateResponse {
|
||||||
return new TemplateResponse(
|
return new TemplateResponse(
|
||||||
Application::APP_ID,
|
Application::APP_ID,
|
||||||
'confirm',
|
'confirm',
|
||||||
@@ -195,6 +251,16 @@ class CalendarController extends Controller
|
|||||||
'location' => $data['location'],
|
'location' => $data['location'],
|
||||||
'url' => $data['url'],
|
'url' => $data['url'],
|
||||||
'error' => $error,
|
'error' => $error,
|
||||||
|
'calendars' => array_map(
|
||||||
|
static function (ICreateFromString $calendar): array {
|
||||||
|
return [
|
||||||
|
'id' => $calendar->getKey(),
|
||||||
|
'displayName' => $calendar->getDisplayName() ?? '',
|
||||||
|
];
|
||||||
|
},
|
||||||
|
$calendars
|
||||||
|
),
|
||||||
|
'calendarId' => $calendarId,
|
||||||
'cancelUrl' => $this->urlGenerator->getAbsoluteURL('/'),
|
'cancelUrl' => $this->urlGenerator->getAbsoluteURL('/'),
|
||||||
'createUrl' => $this->urlGenerator->linkToRoute(
|
'createUrl' => $this->urlGenerator->linkToRoute(
|
||||||
Application::APP_ID . '.calendar.create'
|
Application::APP_ID . '.calendar.create'
|
||||||
|
|||||||
@@ -100,6 +100,24 @@ $h = static function (string $value): string {
|
|||||||
method="post"
|
method="post"
|
||||||
action="<?= $h($_['createUrl']) ?>"
|
action="<?= $h($_['createUrl']) ?>"
|
||||||
>
|
>
|
||||||
|
<?php if ($_['calendars'] !== []): ?>
|
||||||
|
<div class="atocal-row">
|
||||||
|
<label for="atocal-calendar">
|
||||||
|
<strong>Calendar</strong>
|
||||||
|
</label>
|
||||||
|
<select id="atocal-calendar" name="calendarId">
|
||||||
|
<?php foreach ($_['calendars'] as $calendar): ?>
|
||||||
|
<option
|
||||||
|
value="<?= $h($calendar['id']) ?>"
|
||||||
|
<?= $calendar['id'] === $_['calendarId'] ? 'selected' : '' ?>
|
||||||
|
>
|
||||||
|
<?= $h($calendar['displayName']) ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
type="hidden"
|
type="hidden"
|
||||||
name="requesttoken"
|
name="requesttoken"
|
||||||
|
|||||||
@@ -52,6 +52,17 @@
|
|||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.atocal-row select {
|
||||||
|
align-self: center;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 280px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 6px;
|
||||||
|
background: var(--color-main-background);
|
||||||
|
color: var(--color-main-text);
|
||||||
|
}
|
||||||
|
|
||||||
.atocal-row .description {
|
.atocal-row .description {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user