Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/dav/composer/composer/autoload_classmap.php2
-rw-r--r--apps/dav/composer/composer/autoload_static.php2
-rw-r--r--apps/dav/lib/AppInfo/Application.php6
-rw-r--r--apps/dav/lib/BackgroundJob/UserStatusAutomation.php188
-rw-r--r--apps/dav/lib/Listener/UserPreferenceListener.php59
-rw-r--r--apps/dav/lib/Settings/AvailabilitySettings.php24
-rw-r--r--apps/dav/src/service/PreferenceService.js50
-rw-r--r--apps/dav/src/views/Availability.vue17
-rw-r--r--apps/user_status/lib/Service/PredefinedStatusService.php7
-rw-r--r--dist/dav-settings-personal-availability.js4
-rw-r--r--dist/dav-settings-personal-availability.js.LICENSE.txt21
-rw-r--r--dist/dav-settings-personal-availability.js.map2
-rw-r--r--lib/public/UserStatus/IUserStatus.php12
13 files changed, 390 insertions, 4 deletions
diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php
index 8c1bcf17516..b01ae68e43a 100644
--- a/apps/dav/composer/composer/autoload_classmap.php
+++ b/apps/dav/composer/composer/autoload_classmap.php
@@ -22,6 +22,7 @@ return array(
'OCA\\DAV\\BackgroundJob\\RegisterRegenerateBirthdayCalendars' => $baseDir . '/../lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php',
'OCA\\DAV\\BackgroundJob\\UpdateCalendarResourcesRoomsBackgroundJob' => $baseDir . '/../lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php',
'OCA\\DAV\\BackgroundJob\\UploadCleanup' => $baseDir . '/../lib/BackgroundJob/UploadCleanup.php',
+ 'OCA\\DAV\\BackgroundJob\\UserStatusAutomation' => $baseDir . '/../lib/BackgroundJob/UserStatusAutomation.php',
'OCA\\DAV\\BulkUpload\\BulkUploadPlugin' => $baseDir . '/../lib/BulkUpload/BulkUploadPlugin.php',
'OCA\\DAV\\BulkUpload\\MultipartRequestParser' => $baseDir . '/../lib/BulkUpload/MultipartRequestParser.php',
'OCA\\DAV\\CalDAV\\Activity\\Backend' => $baseDir . '/../lib/CalDAV/Activity/Backend.php',
@@ -247,6 +248,7 @@ return array(
'OCA\\DAV\\Listener\\ClearPhotoCacheListener' => $baseDir . '/../lib/Listener/ClearPhotoCacheListener.php',
'OCA\\DAV\\Listener\\SubscriptionListener' => $baseDir . '/../lib/Listener/SubscriptionListener.php',
'OCA\\DAV\\Listener\\TrustedServerRemovedListener' => $baseDir . '/../lib/Listener/TrustedServerRemovedListener.php',
+ 'OCA\\DAV\\Listener\\UserPreferenceListener' => $baseDir . '/../lib/Listener/UserPreferenceListener.php',
'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndex.php',
'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
'OCA\\DAV\\Migration\\BuildSocialSearchIndex' => $baseDir . '/../lib/Migration/BuildSocialSearchIndex.php',
diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php
index 29085a868de..4c9a1dcc793 100644
--- a/apps/dav/composer/composer/autoload_static.php
+++ b/apps/dav/composer/composer/autoload_static.php
@@ -37,6 +37,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\BackgroundJob\\RegisterRegenerateBirthdayCalendars' => __DIR__ . '/..' . '/../lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php',
'OCA\\DAV\\BackgroundJob\\UpdateCalendarResourcesRoomsBackgroundJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php',
'OCA\\DAV\\BackgroundJob\\UploadCleanup' => __DIR__ . '/..' . '/../lib/BackgroundJob/UploadCleanup.php',
+ 'OCA\\DAV\\BackgroundJob\\UserStatusAutomation' => __DIR__ . '/..' . '/../lib/BackgroundJob/UserStatusAutomation.php',
'OCA\\DAV\\BulkUpload\\BulkUploadPlugin' => __DIR__ . '/..' . '/../lib/BulkUpload/BulkUploadPlugin.php',
'OCA\\DAV\\BulkUpload\\MultipartRequestParser' => __DIR__ . '/..' . '/../lib/BulkUpload/MultipartRequestParser.php',
'OCA\\DAV\\CalDAV\\Activity\\Backend' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Backend.php',
@@ -262,6 +263,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\Listener\\ClearPhotoCacheListener' => __DIR__ . '/..' . '/../lib/Listener/ClearPhotoCacheListener.php',
'OCA\\DAV\\Listener\\SubscriptionListener' => __DIR__ . '/..' . '/../lib/Listener/SubscriptionListener.php',
'OCA\\DAV\\Listener\\TrustedServerRemovedListener' => __DIR__ . '/..' . '/../lib/Listener/TrustedServerRemovedListener.php',
+ 'OCA\\DAV\\Listener\\UserPreferenceListener' => __DIR__ . '/..' . '/../lib/Listener/UserPreferenceListener.php',
'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndex.php',
'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
'OCA\\DAV\\Migration\\BuildSocialSearchIndex' => __DIR__ . '/..' . '/../lib/Migration/BuildSocialSearchIndex.php',
diff --git a/apps/dav/lib/AppInfo/Application.php b/apps/dav/lib/AppInfo/Application.php
index fe8405e09e2..86749862626 100644
--- a/apps/dav/lib/AppInfo/Application.php
+++ b/apps/dav/lib/AppInfo/Application.php
@@ -85,6 +85,7 @@ use OCA\DAV\Listener\CardListener;
use OCA\DAV\Listener\ClearPhotoCacheListener;
use OCA\DAV\Listener\SubscriptionListener;
use OCA\DAV\Listener\TrustedServerRemovedListener;
+use OCA\DAV\Listener\UserPreferenceListener;
use OCA\DAV\Search\ContactsSearchProvider;
use OCA\DAV\Search\EventsSearchProvider;
use OCA\DAV\Search\TasksSearchProvider;
@@ -96,6 +97,8 @@ use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\AppFramework\IAppContainer;
use OCP\Calendar\IManager as ICalendarManager;
+use OCP\Config\BeforePreferenceDeletedEvent;
+use OCP\Config\BeforePreferenceSetEvent;
use OCP\Contacts\IManager as IContactsManager;
use OCP\IServerContainer;
use OCP\IUser;
@@ -186,6 +189,9 @@ class Application extends App implements IBootstrap {
$context->registerEventListener(CardUpdatedEvent::class, ClearPhotoCacheListener::class);
$context->registerEventListener(TrustedServerRemovedEvent::class, TrustedServerRemovedListener::class);
+ $context->registerEventListener(BeforePreferenceDeletedEvent::class, UserPreferenceListener::class);
+ $context->registerEventListener(BeforePreferenceSetEvent::class, UserPreferenceListener::class);
+
$context->registerNotifierService(Notifier::class);
$context->registerCalendarProvider(CalendarProvider::class);
diff --git a/apps/dav/lib/BackgroundJob/UserStatusAutomation.php b/apps/dav/lib/BackgroundJob/UserStatusAutomation.php
new file mode 100644
index 00000000000..bbd92d903ee
--- /dev/null
+++ b/apps/dav/lib/BackgroundJob/UserStatusAutomation.php
@@ -0,0 +1,188 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2022 Joas Schilling <coding@schilljs.com>
+ *
+ * @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\DAV\BackgroundJob;
+
+use OCA\DAV\CalDAV\Schedule\Plugin;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\BackgroundJob\IJobList;
+use OCP\BackgroundJob\TimedJob;
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IConfig;
+use OCP\IDBConnection;
+use OCP\UserStatus\IManager;
+use OCP\UserStatus\IUserStatus;
+use Psr\Log\LoggerInterface;
+use Sabre\VObject\Component\Available;
+use Sabre\VObject\Component\VAvailability;
+use Sabre\VObject\Reader;
+use Sabre\VObject\Recur\RRuleIterator;
+
+class UserStatusAutomation extends TimedJob {
+ protected IDBConnection $connection;
+ protected IJobList $jobList;
+ protected LoggerInterface $logger;
+ protected IManager $manager;
+ protected IConfig $config;
+
+ public function __construct(ITimeFactory $timeFactory,
+ IDBConnection $connection,
+ IJobList $jobList,
+ LoggerInterface $logger,
+ IManager $manager,
+ IConfig $config) {
+ parent::__construct($timeFactory);
+ $this->connection = $connection;
+ $this->jobList = $jobList;
+ $this->logger = $logger;
+ $this->manager = $manager;
+ $this->config = $config;
+
+ // Interval 0 might look weird, but the last_checked is always moved
+ // to the next time we need this and then it's 0 seconds ago.
+ $this->setInterval(0);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ protected function run($argument) {
+ if (!isset($argument['userId'])) {
+ $this->jobList->remove(self::class, $argument);
+ $this->logger->info('Removing invalid ' . self::class . ' background job');
+ return;
+ }
+
+ $userId = $argument['userId'];
+ $automationEnabled = $this->config->getUserValue($userId, 'dav', 'user_status_automation', 'no') === 'yes';
+ if (!$automationEnabled) {
+ $this->logger->info('Removing ' . self::class . ' background job for user "' . $userId . '" because the setting is disabled');
+ $this->jobList->remove(self::class, $argument);
+ return;
+ }
+
+ $property = $this->getAvailabilityFromPropertiesTable($userId);
+
+ if (!$property) {
+ $this->logger->info('Removing ' . self::class . ' background job for user "' . $userId . '" because the user has no availability settings');
+ $this->jobList->remove(self::class, $argument);
+ return;
+ }
+
+ $isCurrentlyAvailable = false;
+ $nextPotentialToggles = [];
+
+ $now = new \DateTime('now');
+ $lastMidnight = (clone $now)->setTime(0, 0);
+
+ $vObject = Reader::read($property);
+ foreach ($vObject->getComponents() as $component) {
+ if ($component->name !== 'VAVAILABILITY') {
+ continue;
+ }
+ /** @var VAvailability $component */
+ $availables = $component->getComponents();
+ foreach ($availables as $available) {
+ /** @var Available $available */
+ if ($available->name === 'AVAILABLE') {
+ /** @var \DateTimeInterface $effectiveStart */
+ /** @var \DateTimeInterface $effectiveEnd */
+ [$effectiveStart, $effectiveEnd] = $available->getEffectiveStartEnd();
+
+ try {
+ $it = new RRuleIterator((string) $available->RRULE, $effectiveStart);
+ $it->fastForward($lastMidnight);
+
+ $startToday = $it->current();
+ if ($startToday && $startToday <= $now) {
+ $duration = $effectiveStart->diff($effectiveEnd);
+ $endToday = $startToday->add($duration);
+ if ($endToday > $now) {
+ // User is currently available
+ // Also queuing the end time as next status toggle
+ $isCurrentlyAvailable = true;
+ $nextPotentialToggles[] = $endToday->getTimestamp();
+ }
+
+ // Availability enabling already done for today,
+ // so jump to the next recurrence to find the next status toggle
+ $it->next();
+ }
+
+ if ($it->current()) {
+ $nextPotentialToggles[] = $it->current()->getTimestamp();
+ }
+ } catch (\Exception $e) {
+ $this->logger->error($e->getMessage(), ['exception' => $e]);
+ }
+ }
+ }
+ }
+
+ $nextAutomaticToggle = min($nextPotentialToggles);
+ $this->setLastRunToNextToggleTime($userId, $nextAutomaticToggle - 1);
+
+ if ($isCurrentlyAvailable) {
+ $this->manager->revertUserStatus($userId, IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::DND);
+ } else {
+ // The DND status automation is more important than the "Away - In call" so we also restore that one if it exists.
+ $this->manager->revertUserStatus($userId, IUserStatus::MESSAGE_CALL, IUserStatus::AWAY);
+ $this->manager->setUserStatus($userId, IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::DND, true);
+ }
+ $this->logger->debug('User status automation ran');
+ }
+
+ protected function setLastRunToNextToggleTime(string $userId, int $timestamp): void {
+ $query = $this->connection->getQueryBuilder();
+
+ $query->update('jobs')
+ ->set('last_run', $query->createNamedParameter($timestamp, IQueryBuilder::PARAM_INT))
+ ->where($query->expr()->eq('id', $query->createNamedParameter($this->getId(), IQueryBuilder::PARAM_INT)));
+ $query->executeStatement();
+
+ $this->logger->debug('Updated user status automation last_run to ' . $timestamp . ' for user ' . $userId);
+ }
+
+ /**
+ * @param string $userId
+ * @return false|string
+ */
+ protected function getAvailabilityFromPropertiesTable(string $userId) {
+ $propertyPath = 'calendars/' . $userId . '/inbox';
+ $propertyName = '{' . Plugin::NS_CALDAV . '}calendar-availability';
+
+ $query = $this->connection->getQueryBuilder();
+ $query->select('propertyvalue')
+ ->from('properties')
+ ->where($query->expr()->eq('userid', $query->createNamedParameter($userId)))
+ ->andWhere($query->expr()->eq('propertypath', $query->createNamedParameter($propertyPath)))
+ ->where($query->expr()->eq('propertyname', $query->createNamedParameter($propertyName)))
+ ->setMaxResults(1);
+
+ $result = $query->executeQuery();
+ $property = $result->fetchOne();
+ $result->closeCursor();
+
+ return $property;
+ }
+}
diff --git a/apps/dav/lib/Listener/UserPreferenceListener.php b/apps/dav/lib/Listener/UserPreferenceListener.php
new file mode 100644
index 00000000000..947f6d3fd01
--- /dev/null
+++ b/apps/dav/lib/Listener/UserPreferenceListener.php
@@ -0,0 +1,59 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2022 Joas Schilling <coding@schilljs.com>
+ *
+ * @author Joas Schilling <coding@schilljs.com>
+ *
+ * @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\DAV\Listener;
+
+use OCA\DAV\BackgroundJob\UserStatusAutomation;
+use OCP\BackgroundJob\IJobList;
+use OCP\Config\BeforePreferenceDeletedEvent;
+use OCP\Config\BeforePreferenceSetEvent;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+
+class UserPreferenceListener implements IEventListener {
+
+ protected IJobList $jobList;
+
+ public function __construct(IJobList $jobList) {
+ $this->jobList = $jobList;
+ }
+
+ public function handle(Event $event): void {
+ if ($event instanceof BeforePreferenceSetEvent) {
+ if ($event->getAppId() === 'dav' && $event->getConfigKey() === 'user_status_automation' && $event->getConfigValue() === 'yes') {
+ $event->setValid(true);
+
+ // Not the cleanest way, but we just add the job in the before event.
+ // If something ever turns wrong the first execution will remove the job again.
+ // We also first delete the current job, so the next run time is reset.
+ $this->jobList->remove(UserStatusAutomation::class, ['userId' => $event->getUserId()]);
+ $this->jobList->add(UserStatusAutomation::class, ['userId' => $event->getUserId()]);
+ }
+ } elseif ($event instanceof BeforePreferenceDeletedEvent) {
+ if ($event->getAppId() === 'dav' && $event->getConfigKey() === 'user_status_automation') {
+ $event->setValid(true);
+ }
+ }
+ }
+}
diff --git a/apps/dav/lib/Settings/AvailabilitySettings.php b/apps/dav/lib/Settings/AvailabilitySettings.php
index 9a163e21edb..d2b75ba4866 100644
--- a/apps/dav/lib/Settings/AvailabilitySettings.php
+++ b/apps/dav/lib/Settings/AvailabilitySettings.php
@@ -27,10 +27,34 @@ namespace OCA\DAV\Settings;
use OCA\DAV\AppInfo\Application;
use OCP\AppFramework\Http\TemplateResponse;
+use OCP\AppFramework\Services\IInitialState;
+use OCP\IConfig;
use OCP\Settings\ISettings;
class AvailabilitySettings implements ISettings {
+ protected IConfig $config;
+ protected IInitialState $initialState;
+ protected ?string $userId;
+
+ public function __construct(IConfig $config,
+ IInitialState $initialState,
+ ?string $userId) {
+ $this->config = $config;
+ $this->initialState = $initialState;
+ $this->userId = $userId;
+ }
+
public function getForm(): TemplateResponse {
+ $this->initialState->provideInitialState(
+ 'user_status_automation',
+ $this->config->getUserValue(
+ $this->userId,
+ 'dav',
+ 'user_status_automation',
+ 'no'
+ )
+ );
+
return new TemplateResponse(Application::APP_ID, 'settings-personal-availability');
}
diff --git a/apps/dav/src/service/PreferenceService.js b/apps/dav/src/service/PreferenceService.js
new file mode 100644
index 00000000000..6b8d29029b5
--- /dev/null
+++ b/apps/dav/src/service/PreferenceService.js
@@ -0,0 +1,50 @@
+/**
+ * @copyright 2022 Joas Schilling <coding@schilljs.com>
+ *
+ * @author Joas Schilling <coding@schilljs.com>
+ *
+ * @license AGPL-3.0-or-later
+ *
+ * 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 axios from '@nextcloud/axios'
+import { generateOcsUrl } from '@nextcloud/router'
+
+/**
+ * Enable user status automation based on availability
+ */
+export async function enableUserStatusAutomation() {
+ return await axios.post(
+ generateOcsUrl('/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {
+ appId: 'dav',
+ configKey: 'user_status_automation',
+ }),
+ {
+ configValue: 'yes',
+ }
+ )
+}
+
+/**
+ * Disable user status automation based on availability
+ */
+export async function disableUserStatusAutomation() {
+ return await axios.delete(
+ generateOcsUrl('/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {
+ appId: 'dav',
+ configKey: 'user_status_automation',
+ })
+ )
+}
diff --git a/apps/dav/src/views/Availability.vue b/apps/dav/src/views/Availability.vue
index f3b3ec34bd2..21a0c3a5227 100644
--- a/apps/dav/src/views/Availability.vue
+++ b/apps/dav/src/views/Availability.vue
@@ -24,6 +24,10 @@
:l10n-saturday="$t('dav', 'Saturday')"
:l10n-sunday="$t('dav', 'Sunday')" />
+ <CheckboxRadioSwitch :checked.sync="automated">
+ {{ $t('dav', 'Automatically set user status to "Do not distrub" outside of availability to mute all notifications.') }}
+ </CheckboxRadioSwitch>
+
<Button :disabled="loading || saving"
type="primary"
@click="save">
@@ -34,6 +38,7 @@
<script>
import { CalendarAvailability } from '@nextcloud/calendar-availability-vue'
+import { loadState } from '@nextcloud/initial-state'
import {
showError,
showSuccess,
@@ -43,8 +48,13 @@ import {
getEmptySlots,
saveScheduleInboxAvailability,
} from '../service/CalendarService'
+import {
+ enableUserStatusAutomation,
+ disableUserStatusAutomation,
+} from '../service/PreferenceService'
import jstz from 'jstimezonedetect'
import Button from '@nextcloud/vue/dist/Components/Button'
+import CheckboxRadioSwitch from '@nextcloud/vue/dist/Components/CheckboxRadioSwitch'
import SettingsSection from '@nextcloud/vue/dist/Components/SettingsSection'
import TimezonePicker from '@nextcloud/vue/dist/Components/TimezonePicker'
@@ -52,6 +62,7 @@ export default {
name: 'Availability',
components: {
Button,
+ CheckboxRadioSwitch,
CalendarAvailability,
SettingsSection,
TimezonePicker,
@@ -66,6 +77,7 @@ export default {
saving: false,
timezone: defaultTimezoneId,
slots: getEmptySlots(),
+ automated: loadState('dav', 'user_status_automation') === 'yes',
}
},
async mounted() {
@@ -96,6 +108,11 @@ export default {
this.saving = true
await saveScheduleInboxAvailability(this.slots, this.timezone)
+ if (this.automated) {
+ await enableUserStatusAutomation()
+ } else {
+ await disableUserStatusAutomation()
+ }
showSuccess(t('dav', 'Saved availability'))
} catch (e) {
diff --git a/apps/user_status/lib/Service/PredefinedStatusService.php b/apps/user_status/lib/Service/PredefinedStatusService.php
index 354e0f16b32..40f6052aa95 100644
--- a/apps/user_status/lib/Service/PredefinedStatusService.php
+++ b/apps/user_status/lib/Service/PredefinedStatusService.php
@@ -26,6 +26,7 @@ declare(strict_types=1);
namespace OCA\UserStatus\Service;
use OCP\IL10N;
+use OCP\UserStatus\IUserStatus;
/**
* Class DefaultStatusService
@@ -41,6 +42,9 @@ class PredefinedStatusService {
private const SICK_LEAVE = 'sick-leave';
private const VACATIONING = 'vacationing';
private const REMOTE_WORK = 'remote-work';
+ /**
+ * @depreacted See \OCP\UserStatus\IUserStatus::MESSAGE_CALL
+ */
public const CALL = 'call';
/** @var IL10N */
@@ -196,7 +200,8 @@ class PredefinedStatusService {
self::SICK_LEAVE,
self::VACATIONING,
self::REMOTE_WORK,
- self::CALL,
+ IUserStatus::MESSAGE_CALL,
+ IUserStatus::MESSAGE_AVAILABILITY,
], true);
}
}
diff --git a/dist/dav-settings-personal-availability.js b/dist/dav-settings-personal-availability.js
index 9329fc7323c..ebaa2595b84 100644
--- a/dist/dav-settings-personal-availability.js
+++ b/dist/dav-settings-personal-availability.js
@@ -1,3 +1,3 @@
/*! For license information please see dav-settings-personal-availability.js.LICENSE.txt */
-!function(){var n,e={56584:function(n,e,r){"use strict";var a=r(20144),o=r(9944),i=r(51796),l=r(26932),d=r(81063),s=r(4820),u=r(56580),c=r.n(u),p=r(79753),A=r(22200),f=c()((function(n){return s.default.defaults.headers["X-Requested-With"]="XMLHttpRequest",d.getPatcher().patch("request",s.default),d.createClient((0,p.generateRemoteUrl)("dav/".concat(n,"/").concat((0,A.getCurrentUser)().uid)))})),v=(0,r(17499).IY)().setApp("dav").detectUser().build(),b=r(7582);function m(n,t){var e=Object.keys(n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(n);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(n,t).enumerable}))),e.push.apply(e,r)}return e}function y(n){for(var t=1;t<arguments.length;t++){var e=null!=arguments[t]?arguments[t]:{};t%2?m(Object(e),!0).forEach((function(t){C(n,t,e[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(e)):m(Object(e)).forEach((function(t){Object.defineProperty(n,t,Object.getOwnPropertyDescriptor(e,t))}))}return n}function C(n,t,e){return t in n?Object.defineProperty(n,t,{value:e,enumerable:!0,configurable:!0,writable:!0}):n[t]=e,n}function x(n){return function(n){if(Array.isArray(n))return g(n)}(n)||function(n){if("undefined"!=typeof Symbol&&null!=n[Symbol.iterator]||null!=n["@@iterator"])return Array.from(n)}(n)||function(n,t){if(n){if("string"==typeof n)return g(n,t);var e=Object.prototype.toString.call(n).slice(8,-1);return"Object"===e&&n.constructor&&(e=n.constructor.name),"Map"===e||"Set"===e?Array.from(n):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?g(n,t):void 0}}(n)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function g(n,t){(null==t||t>n.length)&&(t=n.length);for(var e=0,r=new Array(t);e<t;e++)r[e]=n[e];return r}function h(n,t,e,r,a,o,i){try{var l=n[o](i),d=l.value}catch(n){return void e(n)}l.done?t(d):Promise.resolve(d).then(r,a)}function w(n){return function(){var t=this,e=arguments;return new Promise((function(r,a){var o=n.apply(t,e);function i(n){h(o,r,a,i,l,"next",n)}function l(n){h(o,r,a,i,l,"throw",n)}i(void 0)}))}}function O(){return k.apply(this,arguments)}function k(){return(k=w(regeneratorRuntime.mark((function n(){var t,e,r,a,o,l,d;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return a=f("calendars"),n.next=3,a.customRequest("inbox",{method:"PROPFIND",data:'<?xml version="1.0"?>\n\t\t\t<x0:propfind xmlns:x0="DAV:">\n\t\t\t <x0:prop>\n\t\t\t\t<x1:calendar-availability xmlns:x1="urn:ietf:params:xml:ns:caldav"/>\n\t\t\t </x0:prop>\n\t\t\t</x0:propfind>'});case 3:return o=n.sent,n.next=6,(0,b.parseXML)(o.data);case 6:if(l=n.sent){n.next=9;break}return n.abrupt("return",void 0);case 9:if(d=null==l||null===(t=l.multistatus)||void 0===t||null===(e=t.response[0])||void 0===e||null===(r=e.propstat)||void 0===r?void 0:r.prop["calendar-availability"]){n.next=12;break}return n.abrupt("return",void 0);case 12:return n.abrupt("return",(0,i.Xg)(d));case 13:case"end":return n.stop()}}),n)})))).apply(this,arguments)}function B(n,t){return S.apply(this,arguments)}function S(){return(S=w(regeneratorRuntime.mark((function n(t,e){var r,a,o;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return r=x(Object.keys(t).flatMap((function(n){return t[n].map((function(t){return y(y({},t),{},{day:n})}))}))),a=(0,i.ST)(r,e),v.debug("New availability ical created",{vavailability:a}),o=f("calendars"),n.next=6,o.customRequest("inbox",{method:"PROPPATCH",data:'<?xml version="1.0"?>\n\t\t\t<x0:propertyupdate xmlns:x0="DAV:">\n\t\t\t <x0:set>\n\t\t\t\t<x0:prop>\n\t\t\t\t <x1:calendar-availability xmlns:x1="urn:ietf:params:xml:ns:caldav">'.concat(a,"</x1:calendar-availability>\n\t\t\t\t</x0:prop>\n\t\t\t </x0:set>\n\t\t\t</x0:propertyupdate>")});case 6:case"end":return n.stop()}}),n)})))).apply(this,arguments)}var P=r(55586),j=r.n(P),D=r(1412),E=r.n(D),$=r(67776),R=r.n($),T=r(48254),z=r.n(T);function U(n,t,e,r,a,o,i){try{var l=n[o](i),d=l.value}catch(n){return void e(n)}l.done?t(d):Promise.resolve(d).then(r,a)}function _(n){return function(){var t=this,e=arguments;return new Promise((function(r,a){var o=n.apply(t,e);function i(n){U(o,r,a,i,l,"next",n)}function l(n){U(o,r,a,i,l,"throw",n)}i(void 0)}))}}var I={name:"Availability",components:{Button:E(),CalendarAvailability:i.Dx,SettingsSection:R(),TimezonePicker:z()},data:function(){var n=j().determine();return{loading:!0,saving:!1,timezone:n?n.name():"UTC",slots:{MO:[],TU:[],WE:[],TH:[],FR:[],SA:[],SU:[]}}},mounted:function(){var n=this;return _(regeneratorRuntime.mark((function e(){var r,a,o;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,O();case 3:(r=e.sent)?(a=r.slots,o=r.timezoneId,n.slots=a,o&&(n.timezone=o),console.info("availability loaded",n.slots,n.timezoneId)):(console.info("no availability is set"),n.slots={MO:[],TU:[],WE:[],TH:[],FR:[],SA:[],SU:[]}),e.next=11;break;case 7:e.prev=7,e.t0=e.catch(0),console.error("could not load existing availability",e.t0),(0,l.x2)(t("dav","Failed to load availability"));case 11:return e.prev=11,n.loading=!1,e.finish(11);case 14:case"end":return e.stop()}}),e,null,[[0,7,11,14]])})))()},methods:{save:function(){var n=this;return _(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,n.saving=!0,e.next=4,B(n.slots,n.timezone);case 4:(0,l.s$)(t("dav","Saved availability")),e.next=11;break;case 7:e.prev=7,e.t0=e.catch(0),console.error("could not save availability",e.t0),(0,l.x2)(t("dav","Failed to save availability"));case 11:return e.prev=11,n.saving=!1,e.finish(11);case 14:case"end":return e.stop()}}),e,null,[[0,7,11,14]])})))()}}},M=r(93379),F=r.n(M),q=r(7795),W=r.n(q),Z=r(90569),H=r.n(Z),Y=r(3565),X=r.n(Y),N=r(19216),L=r.n(N),V=r(44589),G=r.n(V),Q=r(84960),J={};J.styleTagTransform=G(),J.setAttributes=X(),J.insert=H().bind(null,"head"),J.domAPI=W(),J.insertStyleElement=L(),F()(Q.Z,J),Q.Z&&Q.Z.locals&&Q.Z.locals;var K=(0,r(51900).Z)(I,(function(){var n=this,t=n.$createElement,e=n._self._c||t;return e("SettingsSection",{attrs:{title:n.$t("dav","Availability"),description:n.$t("dav","If you configure your working hours, other users will see when you are out of office when they book a meeting.")}},[e("div",{staticClass:"time-zone"},[e("strong",[n._v("\n\t\t\t"+n._s(n.$t("dav","Time zone:"))+"\n\t\t")]),n._v(" "),e("span",{staticClass:"time-zone-text"},[e("TimezonePicker",{model:{value:n.timezone,callback:function(t){n.timezone=t},expression:"timezone"}})],1)]),n._v(" "),e("CalendarAvailability",{attrs:{slots:n.slots,loading:n.loading,"l10n-to":n.$t("dav","to"),"l10n-delete-slot":n.$t("dav","Delete slot"),"l10n-empty-day":n.$t("dav","No working hours set"),"l10n-add-slot":n.$t("dav","Add slot"),"l10n-monday":n.$t("dav","Monday"),"l10n-tuesday":n.$t("dav","Tuesday"),"l10n-wednesday":n.$t("dav","Wednesday"),"l10n-thursday":n.$t("dav","Thursday"),"l10n-friday":n.$t("dav","Friday"),"l10n-saturday":n.$t("dav","Saturday"),"l10n-sunday":n.$t("dav","Sunday")},on:{"update:slots":function(t){n.slots=t}}}),n._v(" "),e("Button",{attrs:{disabled:n.loading||n.saving,type:"primary"},on:{click:n.save}},[n._v("\n\t\t"+n._s(n.$t("dav","Save"))+"\n\t")])],1)}),[],!1,null,"b996f2b8",null).exports;a.default.prototype.$t=o.translate,new(a.default.extend(K))({}).$mount("#settings-personal-availability")},84960:function(n,t,e){"use strict";var r=e(87537),a=e.n(r),o=e(23645),i=e.n(o)()(a());i.push([n.id,".availability-day[data-v-b996f2b8]{padding:0 10px 0 10px;position:absolute}.availability-slots[data-v-b996f2b8]{display:flex;white-space:nowrap}.availability-slot[data-v-b996f2b8]{display:flex;flex-direction:row;align-items:center}.availability-slot-group[data-v-b996f2b8]{display:flex;flex-direction:column}[data-v-b996f2b8] .mx-input-wrapper{width:85px}[data-v-b996f2b8] .mx-datepicker{width:97px}[data-v-b996f2b8] .multiselect{border:1px solid var(--color-border-dark);width:120px}.time-zone[data-v-b996f2b8]{padding:32px 12px 12px 0}.grid-table[data-v-b996f2b8]{display:grid;margin-bottom:32px;grid-column-gap:24px;grid-row-gap:6px;grid-template-columns:min-content min-content min-content}.button[data-v-b996f2b8]{align-self:flex-end}.label-weekday[data-v-b996f2b8]{position:relative;display:inline-flex;padding-top:4px}.delete-slot[data-v-b996f2b8]{background-color:rgba(0,0,0,0);border:none;padding-bottom:12px;opacity:.5}.delete-slot[data-v-b996f2b8]:hover{opacity:1}.add-another[data-v-b996f2b8]{background-color:rgba(0,0,0,0);border:none;opacity:.5;display:inline-flex;padding:0;margin:0;margin-bottom:3px}.add-another[data-v-b996f2b8]:hover{opacity:1}.to-text[data-v-b996f2b8]{padding-right:12px}.time-zone-text[data-v-b996f2b8]{padding-left:22px}.empty-content[data-v-b996f2b8]{color:var(--color-text-lighter);margin-top:4px}","",{version:3,sources:["webpack://./apps/dav/src/views/Availability.vue"],names:[],mappings:"AAiHA,mCACC,qBAAA,CACA,iBAAA,CAED,qCACC,YAAA,CACA,kBAAA,CAED,oCACC,YAAA,CACA,kBAAA,CACA,kBAAA,CAED,0CACC,YAAA,CACA,qBAAA,CAED,oCACC,UAAA,CAED,iCACC,UAAA,CAED,+BACC,yCAAA,CACA,WAAA,CAED,4BACC,wBAAA,CAED,6BACC,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,gBAAA,CACA,yDAAA,CAED,yBACC,mBAAA,CAED,gCACC,iBAAA,CACA,mBAAA,CACA,eAAA,CAED,8BACC,8BAAA,CACA,WAAA,CACA,mBAAA,CACA,UAAA,CACA,oCACC,SAAA,CAIF,8BACC,8BAAA,CACA,WAAA,CACA,UAAA,CACA,mBAAA,CACA,SAAA,CACA,QAAA,CACA,iBAAA,CAEA,oCACC,SAAA,CAGF,0BACC,kBAAA,CAED,iCACC,iBAAA,CAED,gCACC,+BAAA,CACA,cAAA",sourcesContent:["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.availability-day {\n\tpadding: 0 10px 0 10px;\n\tposition: absolute;\n}\n.availability-slots {\n\tdisplay: flex;\n\twhite-space: nowrap;\n}\n.availability-slot {\n\tdisplay: flex;\n\tflex-direction: row;\n\talign-items: center;\n}\n.availability-slot-group {\n\tdisplay: flex;\n\tflex-direction: column;\n}\n::v-deep .mx-input-wrapper {\n\twidth: 85px;\n}\n::v-deep .mx-datepicker {\n\twidth: 97px;\n}\n::v-deep .multiselect {\n\tborder: 1px solid var(--color-border-dark);\n\twidth: 120px;\n}\n.time-zone {\n\tpadding: 32px 12px 12px 0;\n}\n.grid-table {\n\tdisplay: grid;\n\tmargin-bottom: 32px;\n\tgrid-column-gap: 24px;\n\tgrid-row-gap: 6px;\n\tgrid-template-columns: min-content min-content min-content;\n}\n.button {\n\talign-self: flex-end;\n}\n.label-weekday {\n\tposition: relative;\n\tdisplay: inline-flex;\n\tpadding-top: 4px;\n}\n.delete-slot {\n\tbackground-color: transparent;\n\tborder: none;\n\tpadding-bottom: 12px;\n\topacity: .5;\n\t&:hover {\n\t\topacity: 1;\n\t}\n}\n\n.add-another {\n\tbackground-color: transparent;\n\tborder: none;\n\topacity: .5;\n\tdisplay: inline-flex;\n\tpadding: 0;\n\tmargin: 0;\n\tmargin-bottom: 3px;\n\n\t&:hover {\n\t\topacity: 1;\n\t}\n}\n.to-text {\n\tpadding-right: 12px;\n}\n.time-zone-text{\n\tpadding-left: 22px;\n}\n.empty-content {\n\tcolor: var(--color-text-lighter);\n\tmargin-top: 4px;\n}\n\n"],sourceRoot:""}]),t.Z=i},69862:function(){},40964:function(){}},r={};function a(n){var t=r[n];if(void 0!==t)return t.exports;var o=r[n]={id:n,loaded:!1,exports:{}};return e[n].call(o.exports,o,o.exports,a),o.loaded=!0,o.exports}a.m=e,a.amdD=function(){throw new Error("define cannot be used indirect")},a.amdO={},n=[],a.O=function(t,e,r,o){if(!e){var i=1/0;for(u=0;u<n.length;u++){e=n[u][0],r=n[u][1],o=n[u][2];for(var l=!0,d=0;d<e.length;d++)(!1&o||i>=o)&&Object.keys(a.O).every((function(n){return a.O[n](e[d])}))?e.splice(d--,1):(l=!1,o<i&&(i=o));if(l){n.splice(u--,1);var s=r();void 0!==s&&(t=s)}}return t}o=o||0;for(var u=n.length;u>0&&n[u-1][2]>o;u--)n[u]=n[u-1];n[u]=[e,r,o]},a.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return a.d(t,{a:t}),t},a.d=function(n,t){for(var e in t)a.o(t,e)&&!a.o(n,e)&&Object.defineProperty(n,e,{enumerable:!0,get:t[e]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(n){if("object"==typeof window)return window}}(),a.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},a.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},a.nmd=function(n){return n.paths=[],n.children||(n.children=[]),n},a.j=3347,function(){a.b=document.baseURI||self.location.href;var n={3347:0};a.O.j=function(t){return 0===n[t]};var t=function(t,e){var r,o,i=e[0],l=e[1],d=e[2],s=0;if(i.some((function(t){return 0!==n[t]}))){for(r in l)a.o(l,r)&&(a.m[r]=l[r]);if(d)var u=d(a)}for(t&&t(e);s<i.length;s++)o=i[s],a.o(n,o)&&n[o]&&n[o][0](),n[o]=0;return a.O(u)},e=self.webpackChunknextcloud=self.webpackChunknextcloud||[];e.forEach(t.bind(null,0)),e.push=t.bind(null,e.push.bind(e))}(),a.nc=void 0;var o=a.O(void 0,[7874],(function(){return a(56584)}));o=a.O(o)}();
-//# sourceMappingURL=dav-settings-personal-availability.js.map?v=6395ec3a45a9fa3578a7 \ No newline at end of file
+!function(){var n,e={86635:function(n,e,r){"use strict";var a=r(20144),o=r(9944),i=r(51796),l=r(16453),s=r(26932),d=r(81063),u=r(4820),c=r(56580),p=r.n(c),A=r(79753),v=r(22200),f=p()((function(n){return u.default.defaults.headers["X-Requested-With"]="XMLHttpRequest",d.getPatcher().patch("request",u.default),d.createClient((0,A.generateRemoteUrl)("dav/".concat(n,"/").concat((0,v.getCurrentUser)().uid)))})),m=(0,r(17499).IY)().setApp("dav").detectUser().build(),y=r(7582);function x(n,t){var e=Object.keys(n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(n);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(n,t).enumerable}))),e.push.apply(e,r)}return e}function b(n){for(var t=1;t<arguments.length;t++){var e=null!=arguments[t]?arguments[t]:{};t%2?x(Object(e),!0).forEach((function(t){g(n,t,e[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(e)):x(Object(e)).forEach((function(t){Object.defineProperty(n,t,Object.getOwnPropertyDescriptor(e,t))}))}return n}function g(n,t,e){return t in n?Object.defineProperty(n,t,{value:e,enumerable:!0,configurable:!0,writable:!0}):n[t]=e,n}function C(n){return function(n){if(Array.isArray(n))return h(n)}(n)||function(n){if("undefined"!=typeof Symbol&&null!=n[Symbol.iterator]||null!=n["@@iterator"])return Array.from(n)}(n)||function(n,t){if(n){if("string"==typeof n)return h(n,t);var e=Object.prototype.toString.call(n).slice(8,-1);return"Object"===e&&n.constructor&&(e=n.constructor.name),"Map"===e||"Set"===e?Array.from(n):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?h(n,t):void 0}}(n)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function h(n,t){(null==t||t>n.length)&&(t=n.length);for(var e=0,r=new Array(t);e<t;e++)r[e]=n[e];return r}function w(n,t,e,r,a,o,i){try{var l=n[o](i),s=l.value}catch(n){return void e(n)}l.done?t(s):Promise.resolve(s).then(r,a)}function k(n){return function(){var t=this,e=arguments;return new Promise((function(r,a){var o=n.apply(t,e);function i(n){w(o,r,a,i,l,"next",n)}function l(n){w(o,r,a,i,l,"throw",n)}i(void 0)}))}}function O(){return S.apply(this,arguments)}function S(){return(S=k(regeneratorRuntime.mark((function n(){var t,e,r,a,o,l,s;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return a=f("calendars"),n.next=3,a.customRequest("inbox",{method:"PROPFIND",data:'<?xml version="1.0"?>\n\t\t\t<x0:propfind xmlns:x0="DAV:">\n\t\t\t <x0:prop>\n\t\t\t\t<x1:calendar-availability xmlns:x1="urn:ietf:params:xml:ns:caldav"/>\n\t\t\t </x0:prop>\n\t\t\t</x0:propfind>'});case 3:return o=n.sent,n.next=6,(0,y.parseXML)(o.data);case 6:if(l=n.sent){n.next=9;break}return n.abrupt("return",void 0);case 9:if(s=null==l||null===(t=l.multistatus)||void 0===t||null===(e=t.response[0])||void 0===e||null===(r=e.propstat)||void 0===r?void 0:r.prop["calendar-availability"]){n.next=12;break}return n.abrupt("return",void 0);case 12:return n.abrupt("return",(0,i.Xg)(s));case 13:case"end":return n.stop()}}),n)})))).apply(this,arguments)}function B(n,t){return P.apply(this,arguments)}function P(){return(P=k(regeneratorRuntime.mark((function n(t,e){var r,a,o;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return r=C(Object.keys(t).flatMap((function(n){return t[n].map((function(t){return b(b({},t),{},{day:n})}))}))),a=(0,i.ST)(r,e),m.debug("New availability ical created",{vavailability:a}),o=f("calendars"),n.next=6,o.customRequest("inbox",{method:"PROPPATCH",data:'<?xml version="1.0"?>\n\t\t\t<x0:propertyupdate xmlns:x0="DAV:">\n\t\t\t <x0:set>\n\t\t\t\t<x0:prop>\n\t\t\t\t <x1:calendar-availability xmlns:x1="urn:ietf:params:xml:ns:caldav">'.concat(a,"</x1:calendar-availability>\n\t\t\t\t</x0:prop>\n\t\t\t </x0:set>\n\t\t\t</x0:propertyupdate>")});case 6:case"end":return n.stop()}}),n)})))).apply(this,arguments)}function j(n,t,e,r,a,o,i){try{var l=n[o](i),s=l.value}catch(n){return void e(n)}l.done?t(s):Promise.resolve(s).then(r,a)}function D(n){return function(){var t=this,e=arguments;return new Promise((function(r,a){var o=n.apply(t,e);function i(n){j(o,r,a,i,l,"next",n)}function l(n){j(o,r,a,i,l,"throw",n)}i(void 0)}))}}function R(){return _.apply(this,arguments)}function _(){return(_=D(regeneratorRuntime.mark((function n(){return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return n.next=2,u.default.post((0,A.generateOcsUrl)("/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}",{appId:"dav",configKey:"user_status_automation"}),{configValue:"yes"});case 2:return n.abrupt("return",n.sent);case 3:case"end":return n.stop()}}),n)})))).apply(this,arguments)}function E(){return $.apply(this,arguments)}function $(){return($=D(regeneratorRuntime.mark((function n(){return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return n.next=2,u.default.delete((0,A.generateOcsUrl)("/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}",{appId:"dav",configKey:"user_status_automation"}));case 2:return n.abrupt("return",n.sent);case 3:case"end":return n.stop()}}),n)})))).apply(this,arguments)}var T=r(55586),z=r.n(T),I=r(1412),U=r.n(I),M=r(7826),F=r.n(M),q=r(67776),W=r.n(q),Z=r(48254),Y=r.n(Z);function H(n,t,e,r,a,o,i){try{var l=n[o](i),s=l.value}catch(n){return void e(n)}l.done?t(s):Promise.resolve(s).then(r,a)}function K(n){return function(){var t=this,e=arguments;return new Promise((function(r,a){var o=n.apply(t,e);function i(n){H(o,r,a,i,l,"next",n)}function l(n){H(o,r,a,i,l,"throw",n)}i(void 0)}))}}var X={name:"Availability",components:{Button:U(),CheckboxRadioSwitch:F(),CalendarAvailability:i.Dx,SettingsSection:W(),TimezonePicker:Y()},data:function(){var n=z().determine();return{loading:!0,saving:!1,timezone:n?n.name():"UTC",slots:{MO:[],TU:[],WE:[],TH:[],FR:[],SA:[],SU:[]},automated:"yes"===(0,l.loadState)("dav","user_status_automation")}},mounted:function(){var n=this;return K(regeneratorRuntime.mark((function e(){var r,a,o;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,O();case 3:(r=e.sent)?(a=r.slots,o=r.timezoneId,n.slots=a,o&&(n.timezone=o),console.info("availability loaded",n.slots,n.timezoneId)):(console.info("no availability is set"),n.slots={MO:[],TU:[],WE:[],TH:[],FR:[],SA:[],SU:[]}),e.next=11;break;case 7:e.prev=7,e.t0=e.catch(0),console.error("could not load existing availability",e.t0),(0,s.x2)(t("dav","Failed to load availability"));case 11:return e.prev=11,n.loading=!1,e.finish(11);case 14:case"end":return e.stop()}}),e,null,[[0,7,11,14]])})))()},methods:{save:function(){var n=this;return K(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,n.saving=!0,e.next=4,B(n.slots,n.timezone);case 4:if(!n.automated){e.next=9;break}return e.next=7,R();case 7:e.next=11;break;case 9:return e.next=11,E();case 11:(0,s.s$)(t("dav","Saved availability")),e.next=18;break;case 14:e.prev=14,e.t0=e.catch(0),console.error("could not save availability",e.t0),(0,s.x2)(t("dav","Failed to save availability"));case 18:return e.prev=18,n.saving=!1,e.finish(18);case 21:case"end":return e.stop()}}),e,null,[[0,14,18,21]])})))()}}},N=r(93379),V=r.n(N),L=r(7795),G=r.n(L),Q=r(90569),J=r.n(Q),nn=r(3565),tn=r.n(nn),en=r(19216),rn=r.n(en),an=r(44589),on=r.n(an),ln=r(34717),sn={};sn.styleTagTransform=on(),sn.setAttributes=tn(),sn.insert=J().bind(null,"head"),sn.domAPI=G(),sn.insertStyleElement=rn(),V()(ln.Z,sn),ln.Z&&ln.Z.locals&&ln.Z.locals;var dn=(0,r(51900).Z)(X,(function(){var n=this,t=n.$createElement,e=n._self._c||t;return e("SettingsSection",{attrs:{title:n.$t("dav","Availability"),description:n.$t("dav","If you configure your working hours, other users will see when you are out of office when they book a meeting.")}},[e("div",{staticClass:"time-zone"},[e("strong",[n._v("\n\t\t\t"+n._s(n.$t("dav","Time zone:"))+"\n\t\t")]),n._v(" "),e("span",{staticClass:"time-zone-text"},[e("TimezonePicker",{model:{value:n.timezone,callback:function(t){n.timezone=t},expression:"timezone"}})],1)]),n._v(" "),e("CalendarAvailability",{attrs:{slots:n.slots,loading:n.loading,"l10n-to":n.$t("dav","to"),"l10n-delete-slot":n.$t("dav","Delete slot"),"l10n-empty-day":n.$t("dav","No working hours set"),"l10n-add-slot":n.$t("dav","Add slot"),"l10n-monday":n.$t("dav","Monday"),"l10n-tuesday":n.$t("dav","Tuesday"),"l10n-wednesday":n.$t("dav","Wednesday"),"l10n-thursday":n.$t("dav","Thursday"),"l10n-friday":n.$t("dav","Friday"),"l10n-saturday":n.$t("dav","Saturday"),"l10n-sunday":n.$t("dav","Sunday")},on:{"update:slots":function(t){n.slots=t}}}),n._v(" "),e("CheckboxRadioSwitch",{attrs:{checked:n.automated},on:{"update:checked":function(t){n.automated=t}}},[n._v("\n\t\t"+n._s(n.$t("dav",'Automatically set user status to "Do not distrub" outside of availability to mute all notifications.'))+"\n\t")]),n._v(" "),e("Button",{attrs:{disabled:n.loading||n.saving,type:"primary"},on:{click:n.save}},[n._v("\n\t\t"+n._s(n.$t("dav","Save"))+"\n\t")])],1)}),[],!1,null,"90d70a18",null).exports;a.default.prototype.$t=o.translate,new(a.default.extend(dn))({}).$mount("#settings-personal-availability")},34717:function(n,t,e){"use strict";var r=e(87537),a=e.n(r),o=e(23645),i=e.n(o)()(a());i.push([n.id,".availability-day[data-v-90d70a18]{padding:0 10px 0 10px;position:absolute}.availability-slots[data-v-90d70a18]{display:flex;white-space:nowrap}.availability-slot[data-v-90d70a18]{display:flex;flex-direction:row;align-items:center}.availability-slot-group[data-v-90d70a18]{display:flex;flex-direction:column}[data-v-90d70a18] .mx-input-wrapper{width:85px}[data-v-90d70a18] .mx-datepicker{width:97px}[data-v-90d70a18] .multiselect{border:1px solid var(--color-border-dark);width:120px}.time-zone[data-v-90d70a18]{padding:32px 12px 12px 0}.grid-table[data-v-90d70a18]{display:grid;margin-bottom:32px;grid-column-gap:24px;grid-row-gap:6px;grid-template-columns:min-content min-content min-content}.button[data-v-90d70a18]{align-self:flex-end}.label-weekday[data-v-90d70a18]{position:relative;display:inline-flex;padding-top:4px}.delete-slot[data-v-90d70a18]{background-color:rgba(0,0,0,0);border:none;padding-bottom:12px;opacity:.5}.delete-slot[data-v-90d70a18]:hover{opacity:1}.add-another[data-v-90d70a18]{background-color:rgba(0,0,0,0);border:none;opacity:.5;display:inline-flex;padding:0;margin:0;margin-bottom:3px}.add-another[data-v-90d70a18]:hover{opacity:1}.to-text[data-v-90d70a18]{padding-right:12px}.time-zone-text[data-v-90d70a18]{padding-left:22px}.empty-content[data-v-90d70a18]{color:var(--color-text-lighter);margin-top:4px}","",{version:3,sources:["webpack://./apps/dav/src/views/Availability.vue"],names:[],mappings:"AAkIA,mCACC,qBAAA,CACA,iBAAA,CAED,qCACC,YAAA,CACA,kBAAA,CAED,oCACC,YAAA,CACA,kBAAA,CACA,kBAAA,CAED,0CACC,YAAA,CACA,qBAAA,CAED,oCACC,UAAA,CAED,iCACC,UAAA,CAED,+BACC,yCAAA,CACA,WAAA,CAED,4BACC,wBAAA,CAED,6BACC,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,gBAAA,CACA,yDAAA,CAED,yBACC,mBAAA,CAED,gCACC,iBAAA,CACA,mBAAA,CACA,eAAA,CAED,8BACC,8BAAA,CACA,WAAA,CACA,mBAAA,CACA,UAAA,CACA,oCACC,SAAA,CAIF,8BACC,8BAAA,CACA,WAAA,CACA,UAAA,CACA,mBAAA,CACA,SAAA,CACA,QAAA,CACA,iBAAA,CAEA,oCACC,SAAA,CAGF,0BACC,kBAAA,CAED,iCACC,iBAAA,CAED,gCACC,+BAAA,CACA,cAAA",sourcesContent:["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.availability-day {\n\tpadding: 0 10px 0 10px;\n\tposition: absolute;\n}\n.availability-slots {\n\tdisplay: flex;\n\twhite-space: nowrap;\n}\n.availability-slot {\n\tdisplay: flex;\n\tflex-direction: row;\n\talign-items: center;\n}\n.availability-slot-group {\n\tdisplay: flex;\n\tflex-direction: column;\n}\n::v-deep .mx-input-wrapper {\n\twidth: 85px;\n}\n::v-deep .mx-datepicker {\n\twidth: 97px;\n}\n::v-deep .multiselect {\n\tborder: 1px solid var(--color-border-dark);\n\twidth: 120px;\n}\n.time-zone {\n\tpadding: 32px 12px 12px 0;\n}\n.grid-table {\n\tdisplay: grid;\n\tmargin-bottom: 32px;\n\tgrid-column-gap: 24px;\n\tgrid-row-gap: 6px;\n\tgrid-template-columns: min-content min-content min-content;\n}\n.button {\n\talign-self: flex-end;\n}\n.label-weekday {\n\tposition: relative;\n\tdisplay: inline-flex;\n\tpadding-top: 4px;\n}\n.delete-slot {\n\tbackground-color: transparent;\n\tborder: none;\n\tpadding-bottom: 12px;\n\topacity: .5;\n\t&:hover {\n\t\topacity: 1;\n\t}\n}\n\n.add-another {\n\tbackground-color: transparent;\n\tborder: none;\n\topacity: .5;\n\tdisplay: inline-flex;\n\tpadding: 0;\n\tmargin: 0;\n\tmargin-bottom: 3px;\n\n\t&:hover {\n\t\topacity: 1;\n\t}\n}\n.to-text {\n\tpadding-right: 12px;\n}\n.time-zone-text{\n\tpadding-left: 22px;\n}\n.empty-content {\n\tcolor: var(--color-text-lighter);\n\tmargin-top: 4px;\n}\n\n"],sourceRoot:""}]),t.Z=i},69862:function(){},40964:function(){}},r={};function a(n){var t=r[n];if(void 0!==t)return t.exports;var o=r[n]={id:n,loaded:!1,exports:{}};return e[n].call(o.exports,o,o.exports,a),o.loaded=!0,o.exports}a.m=e,a.amdD=function(){throw new Error("define cannot be used indirect")},a.amdO={},n=[],a.O=function(t,e,r,o){if(!e){var i=1/0;for(u=0;u<n.length;u++){e=n[u][0],r=n[u][1],o=n[u][2];for(var l=!0,s=0;s<e.length;s++)(!1&o||i>=o)&&Object.keys(a.O).every((function(n){return a.O[n](e[s])}))?e.splice(s--,1):(l=!1,o<i&&(i=o));if(l){n.splice(u--,1);var d=r();void 0!==d&&(t=d)}}return t}o=o||0;for(var u=n.length;u>0&&n[u-1][2]>o;u--)n[u]=n[u-1];n[u]=[e,r,o]},a.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return a.d(t,{a:t}),t},a.d=function(n,t){for(var e in t)a.o(t,e)&&!a.o(n,e)&&Object.defineProperty(n,e,{enumerable:!0,get:t[e]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(n){if("object"==typeof window)return window}}(),a.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},a.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},a.nmd=function(n){return n.paths=[],n.children||(n.children=[]),n},a.j=3347,function(){a.b=document.baseURI||self.location.href;var n={3347:0};a.O.j=function(t){return 0===n[t]};var t=function(t,e){var r,o,i=e[0],l=e[1],s=e[2],d=0;if(i.some((function(t){return 0!==n[t]}))){for(r in l)a.o(l,r)&&(a.m[r]=l[r]);if(s)var u=s(a)}for(t&&t(e);d<i.length;d++)o=i[d],a.o(n,o)&&n[o]&&n[o][0](),n[o]=0;return a.O(u)},e=self.webpackChunknextcloud=self.webpackChunknextcloud||[];e.forEach(t.bind(null,0)),e.push=t.bind(null,e.push.bind(e))}(),a.nc=void 0;var o=a.O(void 0,[7874],(function(){return a(86635)}));o=a.O(o)}();
+//# sourceMappingURL=dav-settings-personal-availability.js.map?v=b80f0d65a5bdb5fae1e6 \ No newline at end of file
diff --git a/dist/dav-settings-personal-availability.js.LICENSE.txt b/dist/dav-settings-personal-availability.js.LICENSE.txt
index 0cd798840fb..8234089242e 100644
--- a/dist/dav-settings-personal-availability.js.LICENSE.txt
+++ b/dist/dav-settings-personal-availability.js.LICENSE.txt
@@ -18,3 +18,24 @@
* 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/>.
*/
+
+/**
+ * @copyright 2022 Joas Schilling <coding@schilljs.com>
+ *
+ * @author Joas Schilling <coding@schilljs.com>
+ *
+ * @license AGPL-3.0-or-later
+ *
+ * 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/>.
+ */
diff --git a/dist/dav-settings-personal-availability.js.map b/dist/dav-settings-personal-availability.js.map
index 431c964173e..a68efef5d89 100644
--- a/dist/dav-settings-personal-availability.js.map
+++ b/dist/dav-settings-personal-availability.js.map
@@ -1 +1 @@
-{"version":3,"file":"dav-settings-personal-availability.js?v=6395ec3a45a9fa3578a7","mappings":";gBAAIA,sJC2BSC,EAAYC,GAAAA,EAAQ,SAACC,GAQjC,OANAC,EAAAA,QAAAA,SAAAA,QAAAA,oBAA6C,iBAG7BC,EAAAA,aACRC,MAAM,UAAWF,EAAAA,SAElBC,EAAAA,cACNE,EAAAA,EAAAA,mBAAkB,OAAD,OAAQJ,EAAR,aAAmBK,EAAAA,EAAAA,kBAAiBC,UCTvD,GALeC,WAAAA,MACbC,OAAO,OACPC,aACAC,qvDCsBK,SAAeC,IAAtB,gFAAO,sHACAC,EAASd,EAAU,aADnB,SAGiBc,EAAOC,cAAc,QAAS,CACpDC,OAAQ,WACRC,KAAM,0MALD,cAGAC,EAHA,iBAaYC,EAAAA,EAAAA,UAASD,EAASD,MAb9B,UAaAG,EAbA,qDAgBEC,GAhBF,UAmBAC,EAAeF,MAAAA,GAnBf,UAmBeA,EAAKG,mBAnBpB,iBAmBe,EAAkBL,SAAS,UAnB1C,iBAmBe,EAA+BM,gBAnB9C,aAmBe,EAAyCC,KAAK,yBAnB7D,+CAqBEJ,GArBF,kCAwBCK,EAAAA,EAAAA,IAAqBJ,IAxBtB,mEA+BA,SAAeK,EAAtB,qFAAO,WAA6CC,EAAOC,GAApD,iGACAC,EADA,EACUC,OAAOC,KAAKJ,GAAOK,SAAQ,SAAAC,GAAK,OAAIN,EAAMM,GAAOC,KAAI,SAAAC,GAAI,cACrEA,GADqE,IAExEC,IAAKH,WAGAI,GAAgBC,EAAAA,EAAAA,IAAqBT,EAAKD,GAEhDW,EAAAA,MAAa,gCAAiC,CAC7CF,cAAAA,IAGKxB,EAASd,EAAU,aAZnB,SAaAc,EAAOC,cAAc,QAAS,CACnCC,OAAQ,YACRC,KAAM,uLAAF,OAIqEqB,EAJrE,oGAfC,idC5BP,IClDyL,EDkDzL,CACA,oBACA,YACA,WACA,0BACA,oBACA,oBAEA,KARA,WAUA,sBAGA,OACA,WACA,UACA,SALA,iBAMA,MDlCQ,CACNG,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,MC8BN,QApBA,WAoBA,6KAEA,IAFA,QAEA,EAFA,SAOA,yBACA,UACA,IACA,cAEA,2DARA,uCACA,QD1CQ,CACNN,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,KC8BN,gDAeA,4DAEA,gDAjBA,yBAmBA,aAnBA,+EAsBA,SACA,KADA,WACA,0JAEA,YAFA,SAIA,sBAJA,QAMA,uCANA,gDAQA,mDAEA,gDAVA,yBAYA,YAZA,kNElFIC,EAAU,GAEdA,EAAQC,kBAAoB,IAC5BD,EAAQE,cAAgB,IAElBF,EAAQG,OAAS,SAAc,KAAM,QAE3CH,EAAQI,OAAS,IACjBJ,EAAQK,mBAAqB,IAEhB,IAAI,IAASL,GAKJ,KAAW,YAAiB,WALlD,ICFA,GAXgB,cACd,GCTW,WAAa,IAAIM,EAAIC,KAASC,EAAGF,EAAIG,eAAmBC,EAAGJ,EAAIK,MAAMD,IAAIF,EAAG,OAAOE,EAAG,kBAAkB,CAACE,MAAM,CAAC,MAAQN,EAAIO,GAAG,MAAO,gBAAgB,YAAcP,EAAIO,GAAG,MAAO,oHAAoH,CAACH,EAAG,MAAM,CAACI,YAAY,aAAa,CAACJ,EAAG,SAAS,CAACJ,EAAIS,GAAG,WAAWT,EAAIU,GAAGV,EAAIO,GAAG,MAAO,eAAe,YAAYP,EAAIS,GAAG,KAAKL,EAAG,OAAO,CAACI,YAAY,kBAAkB,CAACJ,EAAG,iBAAiB,CAACO,MAAM,CAACC,MAAOZ,EAAY,SAAEa,SAAS,SAAUC,GAAMd,EAAIe,SAASD,GAAKE,WAAW,eAAe,KAAKhB,EAAIS,GAAG,KAAKL,EAAG,uBAAuB,CAACE,MAAM,CAAC,MAAQN,EAAI1B,MAAM,QAAU0B,EAAIiB,QAAQ,UAAUjB,EAAIO,GAAG,MAAO,MAAM,mBAAmBP,EAAIO,GAAG,MAAO,eAAe,iBAAiBP,EAAIO,GAAG,MAAO,wBAAwB,gBAAgBP,EAAIO,GAAG,MAAO,YAAY,cAAcP,EAAIO,GAAG,MAAO,UAAU,eAAeP,EAAIO,GAAG,MAAO,WAAW,iBAAiBP,EAAIO,GAAG,MAAO,aAAa,gBAAgBP,EAAIO,GAAG,MAAO,YAAY,cAAcP,EAAIO,GAAG,MAAO,UAAU,gBAAgBP,EAAIO,GAAG,MAAO,YAAY,cAAcP,EAAIO,GAAG,MAAO,WAAWW,GAAG,CAAC,eAAe,SAASC,GAAQnB,EAAI1B,MAAM6C,MAAWnB,EAAIS,GAAG,KAAKL,EAAG,SAAS,CAACE,MAAM,CAAC,SAAWN,EAAIiB,SAAWjB,EAAIoB,OAAO,KAAO,WAAWF,GAAG,CAAC,MAAQlB,EAAIqB,OAAO,CAACrB,EAAIS,GAAG,SAAST,EAAIU,GAAGV,EAAIO,GAAG,MAAO,SAAS,WAAW,KACn0C,IDWpB,EACA,KACA,WACA,MAI8B,QEfhCe,EAAAA,QAAAA,UAAAA,GAAmBC,EAAAA,UAIlB,IAFYD,EAAAA,QAAAA,OAAWE,GAEvB,CAAS,IAAKC,OAAO,0GCLlBC,QAA0B,GAA4B,KAE1DA,EAAwBC,KAAK,CAACC,EAAOC,GAAI,4zCAA6zC,GAAG,CAAC,QAAU,EAAE,QAAU,CAAC,mDAAmD,MAAQ,GAAG,SAAW,shBAAshB,eAAiB,CAAC,gjDAAgjD,WAAa,MAE/iH,8CCNIC,EAA2B,GAG/B,SAASC,EAAoBC,GAE5B,IAAIC,EAAeH,EAAyBE,GAC5C,QAAqBjE,IAAjBkE,EACH,OAAOA,EAAaC,QAGrB,IAAIN,EAASE,EAAyBE,GAAY,CACjDH,GAAIG,EACJG,QAAQ,EACRD,QAAS,IAUV,OANAE,EAAoBJ,GAAUK,KAAKT,EAAOM,QAASN,EAAQA,EAAOM,QAASH,GAG3EH,EAAOO,QAAS,EAGTP,EAAOM,QAIfH,EAAoBO,EAAIF,EC5BxBL,EAAoBQ,KAAO,WAC1B,MAAM,IAAIC,MAAM,mCCDjBT,EAAoBU,KAAO,GbAvBhG,EAAW,GACfsF,EAAoBW,EAAI,SAASC,EAAQC,EAAUC,EAAIC,GACtD,IAAGF,EAAH,CAMA,IAAIG,EAAeC,EAAAA,EACnB,IAASC,EAAI,EAAGA,EAAIxG,EAASyG,OAAQD,IAAK,CACrCL,EAAWnG,EAASwG,GAAG,GACvBJ,EAAKpG,EAASwG,GAAG,GACjBH,EAAWrG,EAASwG,GAAG,GAE3B,IAJA,IAGIE,GAAY,EACPC,EAAI,EAAGA,EAAIR,EAASM,OAAQE,MACpB,EAAXN,GAAsBC,GAAgBD,IAAarE,OAAOC,KAAKqD,EAAoBW,GAAGW,OAAM,SAASC,GAAO,OAAOvB,EAAoBW,EAAEY,GAAKV,EAASQ,OAC3JR,EAASW,OAAOH,IAAK,IAErBD,GAAY,EACTL,EAAWC,IAAcA,EAAeD,IAG7C,GAAGK,EAAW,CACb1G,EAAS8G,OAAON,IAAK,GACrB,IAAIO,EAAIX,SACE9E,IAANyF,IAAiBb,EAASa,IAGhC,OAAOb,EAzBNG,EAAWA,GAAY,EACvB,IAAI,IAAIG,EAAIxG,EAASyG,OAAQD,EAAI,GAAKxG,EAASwG,EAAI,GAAG,GAAKH,EAAUG,IAAKxG,EAASwG,GAAKxG,EAASwG,EAAI,GACrGxG,EAASwG,GAAK,CAACL,EAAUC,EAAIC,IcJ/Bf,EAAoB0B,EAAI,SAAS7B,GAChC,IAAI8B,EAAS9B,GAAUA,EAAO+B,WAC7B,WAAa,OAAO/B,EAAgB,SACpC,WAAa,OAAOA,GAErB,OADAG,EAAoB6B,EAAEF,EAAQ,CAAEG,EAAGH,IAC5BA,GCLR3B,EAAoB6B,EAAI,SAAS1B,EAAS4B,GACzC,IAAI,IAAIR,KAAOQ,EACX/B,EAAoBgC,EAAED,EAAYR,KAASvB,EAAoBgC,EAAE7B,EAASoB,IAC5E7E,OAAOuF,eAAe9B,EAASoB,EAAK,CAAEW,YAAY,EAAMC,IAAKJ,EAAWR,MCJ3EvB,EAAoBoC,EAAI,WACvB,GAA0B,iBAAfC,WAAyB,OAAOA,WAC3C,IACC,OAAOnE,MAAQ,IAAIoE,SAAS,cAAb,GACd,MAAOC,GACR,GAAsB,iBAAXC,OAAqB,OAAOA,QALjB,GCAxBxC,EAAoBgC,EAAI,SAASS,EAAKrG,GAAQ,OAAOM,OAAOgG,UAAUC,eAAerC,KAAKmC,EAAKrG,ICC/F4D,EAAoByB,EAAI,SAAStB,GACX,oBAAXyC,QAA0BA,OAAOC,aAC1CnG,OAAOuF,eAAe9B,EAASyC,OAAOC,YAAa,CAAEhE,MAAO,WAE7DnC,OAAOuF,eAAe9B,EAAS,aAAc,CAAEtB,OAAO,KCLvDmB,EAAoB8C,IAAM,SAASjD,GAGlC,OAFAA,EAAOkD,MAAQ,GACVlD,EAAOmD,WAAUnD,EAAOmD,SAAW,IACjCnD,GCHRG,EAAoBqB,EAAI,gBCAxBrB,EAAoBiD,EAAIC,SAASC,SAAWC,KAAKC,SAASC,KAK1D,IAAIC,EAAkB,CACrB,KAAM,GAaPvD,EAAoBW,EAAEU,EAAI,SAASmC,GAAW,OAAoC,IAA7BD,EAAgBC,IAGrE,IAAIC,EAAuB,SAASC,EAA4B9H,GAC/D,IAKIqE,EAAUuD,EALV3C,EAAWjF,EAAK,GAChB+H,EAAc/H,EAAK,GACnBgI,EAAUhI,EAAK,GAGIsF,EAAI,EAC3B,GAAGL,EAASgD,MAAK,SAAS/D,GAAM,OAA+B,IAAxByD,EAAgBzD,MAAe,CACrE,IAAIG,KAAY0D,EACZ3D,EAAoBgC,EAAE2B,EAAa1D,KACrCD,EAAoBO,EAAEN,GAAY0D,EAAY1D,IAGhD,GAAG2D,EAAS,IAAIhD,EAASgD,EAAQ5D,GAGlC,IADG0D,GAA4BA,EAA2B9H,GACrDsF,EAAIL,EAASM,OAAQD,IACzBsC,EAAU3C,EAASK,GAChBlB,EAAoBgC,EAAEuB,EAAiBC,IAAYD,EAAgBC,IACrED,EAAgBC,GAAS,KAE1BD,EAAgBC,GAAW,EAE5B,OAAOxD,EAAoBW,EAAEC,IAG1BkD,EAAqBV,KAA4B,sBAAIA,KAA4B,uBAAK,GAC1FU,EAAmBC,QAAQN,EAAqBO,KAAK,KAAM,IAC3DF,EAAmBlE,KAAO6D,EAAqBO,KAAK,KAAMF,EAAmBlE,KAAKoE,KAAKF,OClDvF9D,EAAoBiE,QAAKjI,ECGzB,IAAIkI,EAAsBlE,EAAoBW,OAAE3E,EAAW,CAAC,OAAO,WAAa,OAAOgE,EAAoB,UAC3GkE,EAAsBlE,EAAoBW,EAAEuD","sources":["webpack:///nextcloud/webpack/runtime/chunk loaded","webpack:///nextcloud/apps/dav/src/dav/client.js","webpack:///nextcloud/apps/dav/src/service/logger.js","webpack:///nextcloud/apps/dav/src/service/CalendarService.js","webpack:///nextcloud/apps/dav/src/views/Availability.vue","webpack:///nextcloud/apps/dav/src/views/Availability.vue?vue&type=script&lang=js&","webpack://nextcloud/./apps/dav/src/views/Availability.vue?3f32","webpack://nextcloud/./apps/dav/src/views/Availability.vue?aa5a","webpack:///nextcloud/apps/dav/src/views/Availability.vue?vue&type=template&id=b996f2b8&scoped=true&","webpack:///nextcloud/apps/dav/src/settings-personal-availability.js","webpack:///nextcloud/apps/dav/src/views/Availability.vue?vue&type=style&index=0&id=b996f2b8&lang=scss&scoped=true&","webpack:///nextcloud/webpack/bootstrap","webpack:///nextcloud/webpack/runtime/amd define","webpack:///nextcloud/webpack/runtime/amd options","webpack:///nextcloud/webpack/runtime/compat get default export","webpack:///nextcloud/webpack/runtime/define property getters","webpack:///nextcloud/webpack/runtime/global","webpack:///nextcloud/webpack/runtime/hasOwnProperty shorthand","webpack:///nextcloud/webpack/runtime/make namespace object","webpack:///nextcloud/webpack/runtime/node module decorator","webpack:///nextcloud/webpack/runtime/runtimeId","webpack:///nextcloud/webpack/runtime/jsonp chunk loading","webpack:///nextcloud/webpack/runtime/nonce","webpack:///nextcloud/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","/*\n * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>\n *\n * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport * as webdav from 'webdav'\nimport axios from '@nextcloud/axios'\nimport memoize from 'lodash/fp/memoize'\nimport { generateRemoteUrl } from '@nextcloud/router'\nimport { getCurrentUser } from '@nextcloud/auth'\n\nexport const getClient = memoize((service) => {\n\t// Add this so the server knows it is an request from the browser\n\taxios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'\n\n\t// force our axios\n\tconst patcher = webdav.getPatcher()\n\tpatcher.patch('request', axios)\n\n\treturn webdav.createClient(\n\t\tgenerateRemoteUrl(`dav/${service}/${getCurrentUser().uid}`)\n\t)\n})\n","/*\n * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>\n *\n * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport { getLoggerBuilder } from '@nextcloud/logger'\n\nconst logger = getLoggerBuilder()\n\t.setApp('dav')\n\t.detectUser()\n\t.build()\n\nexport default logger\n","/**\n * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>\n *\n * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport { getClient } from '../dav/client'\nimport logger from './logger'\nimport { parseXML } from 'webdav/dist/node/tools/dav'\n\nimport {\n\tslotsToVavailability,\n\tvavailabilityToSlots,\n} from '@nextcloud/calendar-availability-vue'\n\n/**\n *\n */\nexport function getEmptySlots() {\n\treturn {\n\t\tMO: [],\n\t\tTU: [],\n\t\tWE: [],\n\t\tTH: [],\n\t\tFR: [],\n\t\tSA: [],\n\t\tSU: [],\n\t}\n}\n\n/**\n *\n */\nexport async function findScheduleInboxAvailability() {\n\tconst client = getClient('calendars')\n\n\tconst response = await client.customRequest('inbox', {\n\t\tmethod: 'PROPFIND',\n\t\tdata: `<?xml version=\"1.0\"?>\n\t\t\t<x0:propfind xmlns:x0=\"DAV:\">\n\t\t\t <x0:prop>\n\t\t\t\t<x1:calendar-availability xmlns:x1=\"urn:ietf:params:xml:ns:caldav\"/>\n\t\t\t </x0:prop>\n\t\t\t</x0:propfind>`,\n\t})\n\n\tconst xml = await parseXML(response.data)\n\n\tif (!xml) {\n\t\treturn undefined\n\t}\n\n\tconst availability = xml?.multistatus?.response[0]?.propstat?.prop['calendar-availability']\n\tif (!availability) {\n\t\treturn undefined\n\t}\n\n\treturn vavailabilityToSlots(availability)\n}\n\n/**\n * @param {any} slots -\n * @param {any} timezoneId -\n */\nexport async function saveScheduleInboxAvailability(slots, timezoneId) {\n\tconst all = [...Object.keys(slots).flatMap(dayId => slots[dayId].map(slot => ({\n\t\t...slot,\n\t\tday: dayId,\n\t})))]\n\n\tconst vavailability = slotsToVavailability(all, timezoneId)\n\n\tlogger.debug('New availability ical created', {\n\t\tvavailability,\n\t})\n\n\tconst client = getClient('calendars')\n\tawait client.customRequest('inbox', {\n\t\tmethod: 'PROPPATCH',\n\t\tdata: `<?xml version=\"1.0\"?>\n\t\t\t<x0:propertyupdate xmlns:x0=\"DAV:\">\n\t\t\t <x0:set>\n\t\t\t\t<x0:prop>\n\t\t\t\t <x1:calendar-availability xmlns:x1=\"urn:ietf:params:xml:ns:caldav\">${vavailability}</x1:calendar-availability>\n\t\t\t\t</x0:prop>\n\t\t\t </x0:set>\n\t\t\t</x0:propertyupdate>`,\n\t})\n}\n","<template>\n\t<SettingsSection :title=\"$t('dav', 'Availability')\"\n\t\t:description=\"$t('dav', 'If you configure your working hours, other users will see when you are out of office when they book a meeting.')\">\n\t\t<div class=\"time-zone\">\n\t\t\t<strong>\n\t\t\t\t{{ $t('dav', 'Time zone:') }}\n\t\t\t</strong>\n\t\t\t<span class=\"time-zone-text\">\n\t\t\t\t<TimezonePicker v-model=\"timezone\" />\n\t\t\t</span>\n\t\t</div>\n\n\t\t<CalendarAvailability :slots.sync=\"slots\"\n\t\t\t:loading=\"loading\"\n\t\t\t:l10n-to=\"$t('dav', 'to')\"\n\t\t\t:l10n-delete-slot=\"$t('dav', 'Delete slot')\"\n\t\t\t:l10n-empty-day=\"$t('dav', 'No working hours set')\"\n\t\t\t:l10n-add-slot=\"$t('dav', 'Add slot')\"\n\t\t\t:l10n-monday=\"$t('dav', 'Monday')\"\n\t\t\t:l10n-tuesday=\"$t('dav', 'Tuesday')\"\n\t\t\t:l10n-wednesday=\"$t('dav', 'Wednesday')\"\n\t\t\t:l10n-thursday=\"$t('dav', 'Thursday')\"\n\t\t\t:l10n-friday=\"$t('dav', 'Friday')\"\n\t\t\t:l10n-saturday=\"$t('dav', 'Saturday')\"\n\t\t\t:l10n-sunday=\"$t('dav', 'Sunday')\" />\n\n\t\t<Button :disabled=\"loading || saving\"\n\t\t\ttype=\"primary\"\n\t\t\t@click=\"save\">\n\t\t\t{{ $t('dav', 'Save') }}\n\t\t</Button>\n\t</SettingsSection>\n</template>\n\n<script>\nimport { CalendarAvailability } from '@nextcloud/calendar-availability-vue'\nimport {\n\tshowError,\n\tshowSuccess,\n} from '@nextcloud/dialogs'\nimport {\n\tfindScheduleInboxAvailability,\n\tgetEmptySlots,\n\tsaveScheduleInboxAvailability,\n} from '../service/CalendarService'\nimport jstz from 'jstimezonedetect'\nimport Button from '@nextcloud/vue/dist/Components/Button'\nimport SettingsSection from '@nextcloud/vue/dist/Components/SettingsSection'\nimport TimezonePicker from '@nextcloud/vue/dist/Components/TimezonePicker'\n\nexport default {\n\tname: 'Availability',\n\tcomponents: {\n\t\tButton,\n\t\tCalendarAvailability,\n\t\tSettingsSection,\n\t\tTimezonePicker,\n\t},\n\tdata() {\n\t\t// Try to determine the current timezone, and fall back to UTC otherwise\n\t\tconst defaultTimezone = jstz.determine()\n\t\tconst defaultTimezoneId = defaultTimezone ? defaultTimezone.name() : 'UTC'\n\n\t\treturn {\n\t\t\tloading: true,\n\t\t\tsaving: false,\n\t\t\ttimezone: defaultTimezoneId,\n\t\t\tslots: getEmptySlots(),\n\t\t}\n\t},\n\tasync mounted() {\n\t\ttry {\n\t\t\tconst slotData = await findScheduleInboxAvailability()\n\t\t\tif (!slotData) {\n\t\t\t\tconsole.info('no availability is set')\n\t\t\t\tthis.slots = getEmptySlots()\n\t\t\t} else {\n\t\t\t\tconst { slots, timezoneId } = slotData\n\t\t\t\tthis.slots = slots\n\t\t\t\tif (timezoneId) {\n\t\t\t\t\tthis.timezone = timezoneId\n\t\t\t\t}\n\t\t\t\tconsole.info('availability loaded', this.slots, this.timezoneId)\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tconsole.error('could not load existing availability', e)\n\n\t\t\tshowError(t('dav', 'Failed to load availability'))\n\t\t} finally {\n\t\t\tthis.loading = false\n\t\t}\n\t},\n\tmethods: {\n\t\tasync save() {\n\t\t\ttry {\n\t\t\t\tthis.saving = true\n\n\t\t\t\tawait saveScheduleInboxAvailability(this.slots, this.timezone)\n\n\t\t\t\tshowSuccess(t('dav', 'Saved availability'))\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('could not save availability', e)\n\n\t\t\t\tshowError(t('dav', 'Failed to save availability'))\n\t\t\t} finally {\n\t\t\t\tthis.saving = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.availability-day {\n\tpadding: 0 10px 0 10px;\n\tposition: absolute;\n}\n.availability-slots {\n\tdisplay: flex;\n\twhite-space: nowrap;\n}\n.availability-slot {\n\tdisplay: flex;\n\tflex-direction: row;\n\talign-items: center;\n}\n.availability-slot-group {\n\tdisplay: flex;\n\tflex-direction: column;\n}\n::v-deep .mx-input-wrapper {\n\twidth: 85px;\n}\n::v-deep .mx-datepicker {\n\twidth: 97px;\n}\n::v-deep .multiselect {\n\tborder: 1px solid var(--color-border-dark);\n\twidth: 120px;\n}\n.time-zone {\n\tpadding: 32px 12px 12px 0;\n}\n.grid-table {\n\tdisplay: grid;\n\tmargin-bottom: 32px;\n\tgrid-column-gap: 24px;\n\tgrid-row-gap: 6px;\n\tgrid-template-columns: min-content min-content min-content;\n}\n.button {\n\talign-self: flex-end;\n}\n.label-weekday {\n\tposition: relative;\n\tdisplay: inline-flex;\n\tpadding-top: 4px;\n}\n.delete-slot {\n\tbackground-color: transparent;\n\tborder: none;\n\tpadding-bottom: 12px;\n\topacity: .5;\n\t&:hover {\n\t\topacity: 1;\n\t}\n}\n\n.add-another {\n\tbackground-color: transparent;\n\tborder: none;\n\topacity: .5;\n\tdisplay: inline-flex;\n\tpadding: 0;\n\tmargin: 0;\n\tmargin-bottom: 3px;\n\n\t&:hover {\n\t\topacity: 1;\n\t}\n}\n.to-text {\n\tpadding-right: 12px;\n}\n.time-zone-text{\n\tpadding-left: 22px;\n}\n.empty-content {\n\tcolor: var(--color-text-lighter);\n\tmargin-top: 4px;\n}\n\n</style>\n","import mod from \"-!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Availability.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Availability.vue?vue&type=script&lang=js&\"","\n import API from \"!../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/sass-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Availability.vue?vue&type=style&index=0&id=b996f2b8&lang=scss&scoped=true&\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/sass-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Availability.vue?vue&type=style&index=0&id=b996f2b8&lang=scss&scoped=true&\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./Availability.vue?vue&type=template&id=b996f2b8&scoped=true&\"\nimport script from \"./Availability.vue?vue&type=script&lang=js&\"\nexport * from \"./Availability.vue?vue&type=script&lang=js&\"\nimport style0 from \"./Availability.vue?vue&type=style&index=0&id=b996f2b8&lang=scss&scoped=true&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"b996f2b8\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('SettingsSection',{attrs:{\"title\":_vm.$t('dav', 'Availability'),\"description\":_vm.$t('dav', 'If you configure your working hours, other users will see when you are out of office when they book a meeting.')}},[_c('div',{staticClass:\"time-zone\"},[_c('strong',[_vm._v(\"\\n\\t\\t\\t\"+_vm._s(_vm.$t('dav', 'Time zone:'))+\"\\n\\t\\t\")]),_vm._v(\" \"),_c('span',{staticClass:\"time-zone-text\"},[_c('TimezonePicker',{model:{value:(_vm.timezone),callback:function ($$v) {_vm.timezone=$$v},expression:\"timezone\"}})],1)]),_vm._v(\" \"),_c('CalendarAvailability',{attrs:{\"slots\":_vm.slots,\"loading\":_vm.loading,\"l10n-to\":_vm.$t('dav', 'to'),\"l10n-delete-slot\":_vm.$t('dav', 'Delete slot'),\"l10n-empty-day\":_vm.$t('dav', 'No working hours set'),\"l10n-add-slot\":_vm.$t('dav', 'Add slot'),\"l10n-monday\":_vm.$t('dav', 'Monday'),\"l10n-tuesday\":_vm.$t('dav', 'Tuesday'),\"l10n-wednesday\":_vm.$t('dav', 'Wednesday'),\"l10n-thursday\":_vm.$t('dav', 'Thursday'),\"l10n-friday\":_vm.$t('dav', 'Friday'),\"l10n-saturday\":_vm.$t('dav', 'Saturday'),\"l10n-sunday\":_vm.$t('dav', 'Sunday')},on:{\"update:slots\":function($event){_vm.slots=$event}}}),_vm._v(\" \"),_c('Button',{attrs:{\"disabled\":_vm.loading || _vm.saving,\"type\":\"primary\"},on:{\"click\":_vm.save}},[_vm._v(\"\\n\\t\\t\"+_vm._s(_vm.$t('dav', 'Save'))+\"\\n\\t\")])],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import Vue from 'vue'\nimport { translate } from '@nextcloud/l10n'\nimport Availability from './views/Availability'\n\nVue.prototype.$t = translate\n\nconst View = Vue.extend(Availability);\n\n(new View({})).$mount('#settings-personal-availability')\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".availability-day[data-v-b996f2b8]{padding:0 10px 0 10px;position:absolute}.availability-slots[data-v-b996f2b8]{display:flex;white-space:nowrap}.availability-slot[data-v-b996f2b8]{display:flex;flex-direction:row;align-items:center}.availability-slot-group[data-v-b996f2b8]{display:flex;flex-direction:column}[data-v-b996f2b8] .mx-input-wrapper{width:85px}[data-v-b996f2b8] .mx-datepicker{width:97px}[data-v-b996f2b8] .multiselect{border:1px solid var(--color-border-dark);width:120px}.time-zone[data-v-b996f2b8]{padding:32px 12px 12px 0}.grid-table[data-v-b996f2b8]{display:grid;margin-bottom:32px;grid-column-gap:24px;grid-row-gap:6px;grid-template-columns:min-content min-content min-content}.button[data-v-b996f2b8]{align-self:flex-end}.label-weekday[data-v-b996f2b8]{position:relative;display:inline-flex;padding-top:4px}.delete-slot[data-v-b996f2b8]{background-color:rgba(0,0,0,0);border:none;padding-bottom:12px;opacity:.5}.delete-slot[data-v-b996f2b8]:hover{opacity:1}.add-another[data-v-b996f2b8]{background-color:rgba(0,0,0,0);border:none;opacity:.5;display:inline-flex;padding:0;margin:0;margin-bottom:3px}.add-another[data-v-b996f2b8]:hover{opacity:1}.to-text[data-v-b996f2b8]{padding-right:12px}.time-zone-text[data-v-b996f2b8]{padding-left:22px}.empty-content[data-v-b996f2b8]{color:var(--color-text-lighter);margin-top:4px}\", \"\",{\"version\":3,\"sources\":[\"webpack://./apps/dav/src/views/Availability.vue\"],\"names\":[],\"mappings\":\"AAiHA,mCACC,qBAAA,CACA,iBAAA,CAED,qCACC,YAAA,CACA,kBAAA,CAED,oCACC,YAAA,CACA,kBAAA,CACA,kBAAA,CAED,0CACC,YAAA,CACA,qBAAA,CAED,oCACC,UAAA,CAED,iCACC,UAAA,CAED,+BACC,yCAAA,CACA,WAAA,CAED,4BACC,wBAAA,CAED,6BACC,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,gBAAA,CACA,yDAAA,CAED,yBACC,mBAAA,CAED,gCACC,iBAAA,CACA,mBAAA,CACA,eAAA,CAED,8BACC,8BAAA,CACA,WAAA,CACA,mBAAA,CACA,UAAA,CACA,oCACC,SAAA,CAIF,8BACC,8BAAA,CACA,WAAA,CACA,UAAA,CACA,mBAAA,CACA,SAAA,CACA,QAAA,CACA,iBAAA,CAEA,oCACC,SAAA,CAGF,0BACC,kBAAA,CAED,iCACC,iBAAA,CAED,gCACC,+BAAA,CACA,cAAA\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n.availability-day {\\n\\tpadding: 0 10px 0 10px;\\n\\tposition: absolute;\\n}\\n.availability-slots {\\n\\tdisplay: flex;\\n\\twhite-space: nowrap;\\n}\\n.availability-slot {\\n\\tdisplay: flex;\\n\\tflex-direction: row;\\n\\talign-items: center;\\n}\\n.availability-slot-group {\\n\\tdisplay: flex;\\n\\tflex-direction: column;\\n}\\n::v-deep .mx-input-wrapper {\\n\\twidth: 85px;\\n}\\n::v-deep .mx-datepicker {\\n\\twidth: 97px;\\n}\\n::v-deep .multiselect {\\n\\tborder: 1px solid var(--color-border-dark);\\n\\twidth: 120px;\\n}\\n.time-zone {\\n\\tpadding: 32px 12px 12px 0;\\n}\\n.grid-table {\\n\\tdisplay: grid;\\n\\tmargin-bottom: 32px;\\n\\tgrid-column-gap: 24px;\\n\\tgrid-row-gap: 6px;\\n\\tgrid-template-columns: min-content min-content min-content;\\n}\\n.button {\\n\\talign-self: flex-end;\\n}\\n.label-weekday {\\n\\tposition: relative;\\n\\tdisplay: inline-flex;\\n\\tpadding-top: 4px;\\n}\\n.delete-slot {\\n\\tbackground-color: transparent;\\n\\tborder: none;\\n\\tpadding-bottom: 12px;\\n\\topacity: .5;\\n\\t&:hover {\\n\\t\\topacity: 1;\\n\\t}\\n}\\n\\n.add-another {\\n\\tbackground-color: transparent;\\n\\tborder: none;\\n\\topacity: .5;\\n\\tdisplay: inline-flex;\\n\\tpadding: 0;\\n\\tmargin: 0;\\n\\tmargin-bottom: 3px;\\n\\n\\t&:hover {\\n\\t\\topacity: 1;\\n\\t}\\n}\\n.to-text {\\n\\tpadding-right: 12px;\\n}\\n.time-zone-text{\\n\\tpadding-left: 22px;\\n}\\n.empty-content {\\n\\tcolor: var(--color-text-lighter);\\n\\tmargin-top: 4px;\\n}\\n\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","__webpack_require__.amdD = function () {\n\tthrow new Error('define cannot be used indirect');\n};","__webpack_require__.amdO = {};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = function(module) {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","__webpack_require__.j = 3347;","__webpack_require__.b = document.baseURI || self.location.href;\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t3347: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunknextcloud\"] = self[\"webpackChunknextcloud\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","__webpack_require__.nc = undefined;","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [7874], function() { return __webpack_require__(56584); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","getClient","memoize","service","axios","webdav","patch","generateRemoteUrl","getCurrentUser","uid","getLoggerBuilder","setApp","detectUser","build","findScheduleInboxAvailability","client","customRequest","method","data","response","parseXML","xml","undefined","availability","multistatus","propstat","prop","vavailabilityToSlots","saveScheduleInboxAvailability","slots","timezoneId","all","Object","keys","flatMap","dayId","map","slot","day","vavailability","slotsToVavailability","logger","MO","TU","WE","TH","FR","SA","SU","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","_vm","this","_h","$createElement","_c","_self","attrs","$t","staticClass","_v","_s","model","value","callback","$$v","timezone","expression","loading","on","$event","saving","save","Vue","translate","Availability","$mount","___CSS_LOADER_EXPORT___","push","module","id","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","exports","loaded","__webpack_modules__","call","m","amdD","Error","amdO","O","result","chunkIds","fn","priority","notFulfilled","Infinity","i","length","fulfilled","j","every","key","splice","r","n","getter","__esModule","d","a","definition","o","defineProperty","enumerable","get","g","globalThis","Function","e","window","obj","prototype","hasOwnProperty","Symbol","toStringTag","nmd","paths","children","b","document","baseURI","self","location","href","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","chunkLoadingGlobal","forEach","bind","nc","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file
+{"version":3,"file":"dav-settings-personal-availability.js?v=b80f0d65a5bdb5fae1e6","mappings":"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","sources":["webpack:///nextcloud/webpack/runtime/chunk loaded","webpack:///nextcloud/apps/dav/src/dav/client.js","webpack:///nextcloud/apps/dav/src/service/logger.js","webpack:///nextcloud/apps/dav/src/service/CalendarService.js","webpack:///nextcloud/apps/dav/src/service/PreferenceService.js","webpack:///nextcloud/apps/dav/src/views/Availability.vue","webpack:///nextcloud/apps/dav/src/views/Availability.vue?vue&type=script&lang=js&","webpack://nextcloud/./apps/dav/src/views/Availability.vue?a0cc","webpack://nextcloud/./apps/dav/src/views/Availability.vue?aa5a","webpack:///nextcloud/apps/dav/src/views/Availability.vue?vue&type=template&id=90d70a18&scoped=true&","webpack:///nextcloud/apps/dav/src/settings-personal-availability.js","webpack:///nextcloud/apps/dav/src/views/Availability.vue?vue&type=style&index=0&id=90d70a18&lang=scss&scoped=true&","webpack:///nextcloud/webpack/bootstrap","webpack:///nextcloud/webpack/runtime/amd define","webpack:///nextcloud/webpack/runtime/amd options","webpack:///nextcloud/webpack/runtime/compat get default export","webpack:///nextcloud/webpack/runtime/define property getters","webpack:///nextcloud/webpack/runtime/global","webpack:///nextcloud/webpack/runtime/hasOwnProperty shorthand","webpack:///nextcloud/webpack/runtime/make namespace object","webpack:///nextcloud/webpack/runtime/node module decorator","webpack:///nextcloud/webpack/runtime/runtimeId","webpack:///nextcloud/webpack/runtime/jsonp chunk loading","webpack:///nextcloud/webpack/runtime/nonce","webpack:///nextcloud/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","/*\n * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>\n *\n * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport * as webdav from 'webdav'\nimport axios from '@nextcloud/axios'\nimport memoize from 'lodash/fp/memoize'\nimport { generateRemoteUrl } from '@nextcloud/router'\nimport { getCurrentUser } from '@nextcloud/auth'\n\nexport const getClient = memoize((service) => {\n\t// Add this so the server knows it is an request from the browser\n\taxios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'\n\n\t// force our axios\n\tconst patcher = webdav.getPatcher()\n\tpatcher.patch('request', axios)\n\n\treturn webdav.createClient(\n\t\tgenerateRemoteUrl(`dav/${service}/${getCurrentUser().uid}`)\n\t)\n})\n","/*\n * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>\n *\n * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport { getLoggerBuilder } from '@nextcloud/logger'\n\nconst logger = getLoggerBuilder()\n\t.setApp('dav')\n\t.detectUser()\n\t.build()\n\nexport default logger\n","/**\n * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>\n *\n * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport { getClient } from '../dav/client'\nimport logger from './logger'\nimport { parseXML } from 'webdav/dist/node/tools/dav'\n\nimport {\n\tslotsToVavailability,\n\tvavailabilityToSlots,\n} from '@nextcloud/calendar-availability-vue'\n\n/**\n *\n */\nexport function getEmptySlots() {\n\treturn {\n\t\tMO: [],\n\t\tTU: [],\n\t\tWE: [],\n\t\tTH: [],\n\t\tFR: [],\n\t\tSA: [],\n\t\tSU: [],\n\t}\n}\n\n/**\n *\n */\nexport async function findScheduleInboxAvailability() {\n\tconst client = getClient('calendars')\n\n\tconst response = await client.customRequest('inbox', {\n\t\tmethod: 'PROPFIND',\n\t\tdata: `<?xml version=\"1.0\"?>\n\t\t\t<x0:propfind xmlns:x0=\"DAV:\">\n\t\t\t <x0:prop>\n\t\t\t\t<x1:calendar-availability xmlns:x1=\"urn:ietf:params:xml:ns:caldav\"/>\n\t\t\t </x0:prop>\n\t\t\t</x0:propfind>`,\n\t})\n\n\tconst xml = await parseXML(response.data)\n\n\tif (!xml) {\n\t\treturn undefined\n\t}\n\n\tconst availability = xml?.multistatus?.response[0]?.propstat?.prop['calendar-availability']\n\tif (!availability) {\n\t\treturn undefined\n\t}\n\n\treturn vavailabilityToSlots(availability)\n}\n\n/**\n * @param {any} slots -\n * @param {any} timezoneId -\n */\nexport async function saveScheduleInboxAvailability(slots, timezoneId) {\n\tconst all = [...Object.keys(slots).flatMap(dayId => slots[dayId].map(slot => ({\n\t\t...slot,\n\t\tday: dayId,\n\t})))]\n\n\tconst vavailability = slotsToVavailability(all, timezoneId)\n\n\tlogger.debug('New availability ical created', {\n\t\tvavailability,\n\t})\n\n\tconst client = getClient('calendars')\n\tawait client.customRequest('inbox', {\n\t\tmethod: 'PROPPATCH',\n\t\tdata: `<?xml version=\"1.0\"?>\n\t\t\t<x0:propertyupdate xmlns:x0=\"DAV:\">\n\t\t\t <x0:set>\n\t\t\t\t<x0:prop>\n\t\t\t\t <x1:calendar-availability xmlns:x1=\"urn:ietf:params:xml:ns:caldav\">${vavailability}</x1:calendar-availability>\n\t\t\t\t</x0:prop>\n\t\t\t </x0:set>\n\t\t\t</x0:propertyupdate>`,\n\t})\n}\n","/**\n * @copyright 2022 Joas Schilling <coding@schilljs.com>\n *\n * @author Joas Schilling <coding@schilljs.com>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport axios from '@nextcloud/axios'\nimport { generateOcsUrl } from '@nextcloud/router'\n\n/**\n * Enable user status automation based on availability\n */\nexport async function enableUserStatusAutomation() {\n\treturn await axios.post(\n\t\tgenerateOcsUrl('/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {\n\t\t\tappId: 'dav',\n\t\t\tconfigKey: 'user_status_automation',\n\t\t}),\n\t\t{\n\t\t\tconfigValue: 'yes',\n\t\t}\n\t)\n}\n\n/**\n * Disable user status automation based on availability\n */\nexport async function disableUserStatusAutomation() {\n\treturn await axios.delete(\n\t\tgenerateOcsUrl('/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {\n\t\t\tappId: 'dav',\n\t\t\tconfigKey: 'user_status_automation',\n\t\t})\n\t)\n}\n","<template>\n\t<SettingsSection :title=\"$t('dav', 'Availability')\"\n\t\t:description=\"$t('dav', 'If you configure your working hours, other users will see when you are out of office when they book a meeting.')\">\n\t\t<div class=\"time-zone\">\n\t\t\t<strong>\n\t\t\t\t{{ $t('dav', 'Time zone:') }}\n\t\t\t</strong>\n\t\t\t<span class=\"time-zone-text\">\n\t\t\t\t<TimezonePicker v-model=\"timezone\" />\n\t\t\t</span>\n\t\t</div>\n\n\t\t<CalendarAvailability :slots.sync=\"slots\"\n\t\t\t:loading=\"loading\"\n\t\t\t:l10n-to=\"$t('dav', 'to')\"\n\t\t\t:l10n-delete-slot=\"$t('dav', 'Delete slot')\"\n\t\t\t:l10n-empty-day=\"$t('dav', 'No working hours set')\"\n\t\t\t:l10n-add-slot=\"$t('dav', 'Add slot')\"\n\t\t\t:l10n-monday=\"$t('dav', 'Monday')\"\n\t\t\t:l10n-tuesday=\"$t('dav', 'Tuesday')\"\n\t\t\t:l10n-wednesday=\"$t('dav', 'Wednesday')\"\n\t\t\t:l10n-thursday=\"$t('dav', 'Thursday')\"\n\t\t\t:l10n-friday=\"$t('dav', 'Friday')\"\n\t\t\t:l10n-saturday=\"$t('dav', 'Saturday')\"\n\t\t\t:l10n-sunday=\"$t('dav', 'Sunday')\" />\n\n\t\t<CheckboxRadioSwitch :checked.sync=\"automated\">\n\t\t\t{{ $t('dav', 'Automatically set user status to \"Do not distrub\" outside of availability to mute all notifications.') }}\n\t\t</CheckboxRadioSwitch>\n\n\t\t<Button :disabled=\"loading || saving\"\n\t\t\ttype=\"primary\"\n\t\t\t@click=\"save\">\n\t\t\t{{ $t('dav', 'Save') }}\n\t\t</Button>\n\t</SettingsSection>\n</template>\n\n<script>\nimport { CalendarAvailability } from '@nextcloud/calendar-availability-vue'\nimport { loadState } from '@nextcloud/initial-state'\nimport {\n\tshowError,\n\tshowSuccess,\n} from '@nextcloud/dialogs'\nimport {\n\tfindScheduleInboxAvailability,\n\tgetEmptySlots,\n\tsaveScheduleInboxAvailability,\n} from '../service/CalendarService'\nimport {\n\tenableUserStatusAutomation,\n\tdisableUserStatusAutomation,\n} from '../service/PreferenceService'\nimport jstz from 'jstimezonedetect'\nimport Button from '@nextcloud/vue/dist/Components/Button'\nimport CheckboxRadioSwitch from '@nextcloud/vue/dist/Components/CheckboxRadioSwitch'\nimport SettingsSection from '@nextcloud/vue/dist/Components/SettingsSection'\nimport TimezonePicker from '@nextcloud/vue/dist/Components/TimezonePicker'\n\nexport default {\n\tname: 'Availability',\n\tcomponents: {\n\t\tButton,\n\t\tCheckboxRadioSwitch,\n\t\tCalendarAvailability,\n\t\tSettingsSection,\n\t\tTimezonePicker,\n\t},\n\tdata() {\n\t\t// Try to determine the current timezone, and fall back to UTC otherwise\n\t\tconst defaultTimezone = jstz.determine()\n\t\tconst defaultTimezoneId = defaultTimezone ? defaultTimezone.name() : 'UTC'\n\n\t\treturn {\n\t\t\tloading: true,\n\t\t\tsaving: false,\n\t\t\ttimezone: defaultTimezoneId,\n\t\t\tslots: getEmptySlots(),\n\t\t\tautomated: loadState('dav', 'user_status_automation') === 'yes',\n\t\t}\n\t},\n\tasync mounted() {\n\t\ttry {\n\t\t\tconst slotData = await findScheduleInboxAvailability()\n\t\t\tif (!slotData) {\n\t\t\t\tconsole.info('no availability is set')\n\t\t\t\tthis.slots = getEmptySlots()\n\t\t\t} else {\n\t\t\t\tconst { slots, timezoneId } = slotData\n\t\t\t\tthis.slots = slots\n\t\t\t\tif (timezoneId) {\n\t\t\t\t\tthis.timezone = timezoneId\n\t\t\t\t}\n\t\t\t\tconsole.info('availability loaded', this.slots, this.timezoneId)\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tconsole.error('could not load existing availability', e)\n\n\t\t\tshowError(t('dav', 'Failed to load availability'))\n\t\t} finally {\n\t\t\tthis.loading = false\n\t\t}\n\t},\n\tmethods: {\n\t\tasync save() {\n\t\t\ttry {\n\t\t\t\tthis.saving = true\n\n\t\t\t\tawait saveScheduleInboxAvailability(this.slots, this.timezone)\n\t\t\t\tif (this.automated) {\n\t\t\t\t\tawait enableUserStatusAutomation()\n\t\t\t\t} else {\n\t\t\t\t\tawait disableUserStatusAutomation()\n\t\t\t\t}\n\n\t\t\t\tshowSuccess(t('dav', 'Saved availability'))\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('could not save availability', e)\n\n\t\t\t\tshowError(t('dav', 'Failed to save availability'))\n\t\t\t} finally {\n\t\t\t\tthis.saving = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.availability-day {\n\tpadding: 0 10px 0 10px;\n\tposition: absolute;\n}\n.availability-slots {\n\tdisplay: flex;\n\twhite-space: nowrap;\n}\n.availability-slot {\n\tdisplay: flex;\n\tflex-direction: row;\n\talign-items: center;\n}\n.availability-slot-group {\n\tdisplay: flex;\n\tflex-direction: column;\n}\n::v-deep .mx-input-wrapper {\n\twidth: 85px;\n}\n::v-deep .mx-datepicker {\n\twidth: 97px;\n}\n::v-deep .multiselect {\n\tborder: 1px solid var(--color-border-dark);\n\twidth: 120px;\n}\n.time-zone {\n\tpadding: 32px 12px 12px 0;\n}\n.grid-table {\n\tdisplay: grid;\n\tmargin-bottom: 32px;\n\tgrid-column-gap: 24px;\n\tgrid-row-gap: 6px;\n\tgrid-template-columns: min-content min-content min-content;\n}\n.button {\n\talign-self: flex-end;\n}\n.label-weekday {\n\tposition: relative;\n\tdisplay: inline-flex;\n\tpadding-top: 4px;\n}\n.delete-slot {\n\tbackground-color: transparent;\n\tborder: none;\n\tpadding-bottom: 12px;\n\topacity: .5;\n\t&:hover {\n\t\topacity: 1;\n\t}\n}\n\n.add-another {\n\tbackground-color: transparent;\n\tborder: none;\n\topacity: .5;\n\tdisplay: inline-flex;\n\tpadding: 0;\n\tmargin: 0;\n\tmargin-bottom: 3px;\n\n\t&:hover {\n\t\topacity: 1;\n\t}\n}\n.to-text {\n\tpadding-right: 12px;\n}\n.time-zone-text{\n\tpadding-left: 22px;\n}\n.empty-content {\n\tcolor: var(--color-text-lighter);\n\tmargin-top: 4px;\n}\n\n</style>\n","import mod from \"-!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Availability.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Availability.vue?vue&type=script&lang=js&\"","\n import API from \"!../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/sass-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Availability.vue?vue&type=style&index=0&id=90d70a18&lang=scss&scoped=true&\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/sass-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Availability.vue?vue&type=style&index=0&id=90d70a18&lang=scss&scoped=true&\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./Availability.vue?vue&type=template&id=90d70a18&scoped=true&\"\nimport script from \"./Availability.vue?vue&type=script&lang=js&\"\nexport * from \"./Availability.vue?vue&type=script&lang=js&\"\nimport style0 from \"./Availability.vue?vue&type=style&index=0&id=90d70a18&lang=scss&scoped=true&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"90d70a18\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('SettingsSection',{attrs:{\"title\":_vm.$t('dav', 'Availability'),\"description\":_vm.$t('dav', 'If you configure your working hours, other users will see when you are out of office when they book a meeting.')}},[_c('div',{staticClass:\"time-zone\"},[_c('strong',[_vm._v(\"\\n\\t\\t\\t\"+_vm._s(_vm.$t('dav', 'Time zone:'))+\"\\n\\t\\t\")]),_vm._v(\" \"),_c('span',{staticClass:\"time-zone-text\"},[_c('TimezonePicker',{model:{value:(_vm.timezone),callback:function ($$v) {_vm.timezone=$$v},expression:\"timezone\"}})],1)]),_vm._v(\" \"),_c('CalendarAvailability',{attrs:{\"slots\":_vm.slots,\"loading\":_vm.loading,\"l10n-to\":_vm.$t('dav', 'to'),\"l10n-delete-slot\":_vm.$t('dav', 'Delete slot'),\"l10n-empty-day\":_vm.$t('dav', 'No working hours set'),\"l10n-add-slot\":_vm.$t('dav', 'Add slot'),\"l10n-monday\":_vm.$t('dav', 'Monday'),\"l10n-tuesday\":_vm.$t('dav', 'Tuesday'),\"l10n-wednesday\":_vm.$t('dav', 'Wednesday'),\"l10n-thursday\":_vm.$t('dav', 'Thursday'),\"l10n-friday\":_vm.$t('dav', 'Friday'),\"l10n-saturday\":_vm.$t('dav', 'Saturday'),\"l10n-sunday\":_vm.$t('dav', 'Sunday')},on:{\"update:slots\":function($event){_vm.slots=$event}}}),_vm._v(\" \"),_c('CheckboxRadioSwitch',{attrs:{\"checked\":_vm.automated},on:{\"update:checked\":function($event){_vm.automated=$event}}},[_vm._v(\"\\n\\t\\t\"+_vm._s(_vm.$t('dav', 'Automatically set user status to \"Do not distrub\" outside of availability to mute all notifications.'))+\"\\n\\t\")]),_vm._v(\" \"),_c('Button',{attrs:{\"disabled\":_vm.loading || _vm.saving,\"type\":\"primary\"},on:{\"click\":_vm.save}},[_vm._v(\"\\n\\t\\t\"+_vm._s(_vm.$t('dav', 'Save'))+\"\\n\\t\")])],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import Vue from 'vue'\nimport { translate } from '@nextcloud/l10n'\nimport Availability from './views/Availability'\n\nVue.prototype.$t = translate\n\nconst View = Vue.extend(Availability);\n\n(new View({})).$mount('#settings-personal-availability')\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".availability-day[data-v-90d70a18]{padding:0 10px 0 10px;position:absolute}.availability-slots[data-v-90d70a18]{display:flex;white-space:nowrap}.availability-slot[data-v-90d70a18]{display:flex;flex-direction:row;align-items:center}.availability-slot-group[data-v-90d70a18]{display:flex;flex-direction:column}[data-v-90d70a18] .mx-input-wrapper{width:85px}[data-v-90d70a18] .mx-datepicker{width:97px}[data-v-90d70a18] .multiselect{border:1px solid var(--color-border-dark);width:120px}.time-zone[data-v-90d70a18]{padding:32px 12px 12px 0}.grid-table[data-v-90d70a18]{display:grid;margin-bottom:32px;grid-column-gap:24px;grid-row-gap:6px;grid-template-columns:min-content min-content min-content}.button[data-v-90d70a18]{align-self:flex-end}.label-weekday[data-v-90d70a18]{position:relative;display:inline-flex;padding-top:4px}.delete-slot[data-v-90d70a18]{background-color:rgba(0,0,0,0);border:none;padding-bottom:12px;opacity:.5}.delete-slot[data-v-90d70a18]:hover{opacity:1}.add-another[data-v-90d70a18]{background-color:rgba(0,0,0,0);border:none;opacity:.5;display:inline-flex;padding:0;margin:0;margin-bottom:3px}.add-another[data-v-90d70a18]:hover{opacity:1}.to-text[data-v-90d70a18]{padding-right:12px}.time-zone-text[data-v-90d70a18]{padding-left:22px}.empty-content[data-v-90d70a18]{color:var(--color-text-lighter);margin-top:4px}\", \"\",{\"version\":3,\"sources\":[\"webpack://./apps/dav/src/views/Availability.vue\"],\"names\":[],\"mappings\":\"AAkIA,mCACC,qBAAA,CACA,iBAAA,CAED,qCACC,YAAA,CACA,kBAAA,CAED,oCACC,YAAA,CACA,kBAAA,CACA,kBAAA,CAED,0CACC,YAAA,CACA,qBAAA,CAED,oCACC,UAAA,CAED,iCACC,UAAA,CAED,+BACC,yCAAA,CACA,WAAA,CAED,4BACC,wBAAA,CAED,6BACC,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,gBAAA,CACA,yDAAA,CAED,yBACC,mBAAA,CAED,gCACC,iBAAA,CACA,mBAAA,CACA,eAAA,CAED,8BACC,8BAAA,CACA,WAAA,CACA,mBAAA,CACA,UAAA,CACA,oCACC,SAAA,CAIF,8BACC,8BAAA,CACA,WAAA,CACA,UAAA,CACA,mBAAA,CACA,SAAA,CACA,QAAA,CACA,iBAAA,CAEA,oCACC,SAAA,CAGF,0BACC,kBAAA,CAED,iCACC,iBAAA,CAED,gCACC,+BAAA,CACA,cAAA\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n.availability-day {\\n\\tpadding: 0 10px 0 10px;\\n\\tposition: absolute;\\n}\\n.availability-slots {\\n\\tdisplay: flex;\\n\\twhite-space: nowrap;\\n}\\n.availability-slot {\\n\\tdisplay: flex;\\n\\tflex-direction: row;\\n\\talign-items: center;\\n}\\n.availability-slot-group {\\n\\tdisplay: flex;\\n\\tflex-direction: column;\\n}\\n::v-deep .mx-input-wrapper {\\n\\twidth: 85px;\\n}\\n::v-deep .mx-datepicker {\\n\\twidth: 97px;\\n}\\n::v-deep .multiselect {\\n\\tborder: 1px solid var(--color-border-dark);\\n\\twidth: 120px;\\n}\\n.time-zone {\\n\\tpadding: 32px 12px 12px 0;\\n}\\n.grid-table {\\n\\tdisplay: grid;\\n\\tmargin-bottom: 32px;\\n\\tgrid-column-gap: 24px;\\n\\tgrid-row-gap: 6px;\\n\\tgrid-template-columns: min-content min-content min-content;\\n}\\n.button {\\n\\talign-self: flex-end;\\n}\\n.label-weekday {\\n\\tposition: relative;\\n\\tdisplay: inline-flex;\\n\\tpadding-top: 4px;\\n}\\n.delete-slot {\\n\\tbackground-color: transparent;\\n\\tborder: none;\\n\\tpadding-bottom: 12px;\\n\\topacity: .5;\\n\\t&:hover {\\n\\t\\topacity: 1;\\n\\t}\\n}\\n\\n.add-another {\\n\\tbackground-color: transparent;\\n\\tborder: none;\\n\\topacity: .5;\\n\\tdisplay: inline-flex;\\n\\tpadding: 0;\\n\\tmargin: 0;\\n\\tmargin-bottom: 3px;\\n\\n\\t&:hover {\\n\\t\\topacity: 1;\\n\\t}\\n}\\n.to-text {\\n\\tpadding-right: 12px;\\n}\\n.time-zone-text{\\n\\tpadding-left: 22px;\\n}\\n.empty-content {\\n\\tcolor: var(--color-text-lighter);\\n\\tmargin-top: 4px;\\n}\\n\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","__webpack_require__.amdD = function () {\n\tthrow new Error('define cannot be used indirect');\n};","__webpack_require__.amdO = {};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = function(module) {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","__webpack_require__.j = 3347;","__webpack_require__.b = document.baseURI || self.location.href;\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t3347: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunknextcloud\"] = self[\"webpackChunknextcloud\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","__webpack_require__.nc = undefined;","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [7874], function() { return __webpack_require__(86635); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","getClient","memoize","service","axios","webdav","patch","generateRemoteUrl","getCurrentUser","uid","getLoggerBuilder","setApp","detectUser","build","findScheduleInboxAvailability","client","customRequest","method","data","response","parseXML","xml","undefined","availability","multistatus","propstat","prop","vavailabilityToSlots","saveScheduleInboxAvailability","slots","timezoneId","all","Object","keys","flatMap","dayId","map","slot","day","vavailability","slotsToVavailability","logger","enableUserStatusAutomation","generateOcsUrl","appId","configKey","configValue","disableUserStatusAutomation","MO","TU","WE","TH","FR","SA","SU","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","_vm","this","_h","$createElement","_c","_self","attrs","$t","staticClass","_v","_s","model","value","callback","$$v","timezone","expression","loading","on","$event","automated","saving","save","Vue","translate","Availability","$mount","___CSS_LOADER_EXPORT___","push","module","id","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","exports","loaded","__webpack_modules__","call","m","amdD","Error","amdO","O","result","chunkIds","fn","priority","notFulfilled","Infinity","i","length","fulfilled","j","every","key","splice","r","n","getter","__esModule","d","a","definition","o","defineProperty","enumerable","get","g","globalThis","Function","e","window","obj","prototype","hasOwnProperty","Symbol","toStringTag","nmd","paths","children","b","document","baseURI","self","location","href","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","chunkLoadingGlobal","forEach","bind","nc","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file
diff --git a/lib/public/UserStatus/IUserStatus.php b/lib/public/UserStatus/IUserStatus.php
index bf743dea08d..8803b328ad5 100644
--- a/lib/public/UserStatus/IUserStatus.php
+++ b/lib/public/UserStatus/IUserStatus.php
@@ -65,6 +65,18 @@ interface IUserStatus {
public const INVISIBLE = 'invisible';
/**
+ * @var string
+ * @since 25.0.0
+ */
+ public const MESSAGE_CALL = 'call';
+
+ /**
+ * @var string
+ * @since 25.0.0
+ */
+ public const MESSAGE_AVAILABILITY = 'availability';
+
+ /**
* Get the user this status is connected to
*
* @return string