diff --git a/appinfo/routes.php b/appinfo/routes.php index ea0d3c27f2..a2137f9e13 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -58,6 +58,6 @@ ['name' => 'email#sendEmailPublicLink', 'url' => '/v1/public/sendmail', 'verb' => 'POST'], ], 'resources' => [ - 'appointmentConfig' => ['url' => 'v1/appointment_configs'] + 'appointmentConfig' => ['url' => '/v1/appointment_configs'] ] ]; diff --git a/css/app-modal.scss b/css/app-modal.scss new file mode 100644 index 0000000000..b4ea5bd8a1 --- /dev/null +++ b/css/app-modal.scss @@ -0,0 +1,76 @@ +/** + * Calendar App + * + * @copyright 2021 Richard Steinmetz + * + * @author Richard Steinmetz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 library. If not, see . + * + */ + +.appointment-config-modal { + overflow: auto; + padding: 2vw; + max-width: 900px; + + // Subtract padding twice from max height of modal + max-height: calc(90vh - 4vw); + + &__form { + display: flex; + flex-direction: column; + width: 100%; + + fieldset { + padding: 20px 0; + + header { + font-size: 16px; + margin-bottom: 3px; + } + } + + .availability-select, .calendar-select { + display: flex; + flex-direction: column; + } + + &__row { + &--wrapped { + display: flex; + flex-wrap: wrap; + gap: 10px 50px; + + > div { + flex: 1 200px; + } + } + } + + &__row + &__row { + margin-top: 10px; + } + + // Fix calendar picker styling + .multiselect__tags { + height: unset !important; + margin: 0 !important; + } + } + + &__submit-button { + margin-top: 20px; + } +} diff --git a/css/app-navigation.scss b/css/app-navigation.scss index fe546e0d4f..aabdc2f5d9 100644 --- a/css/app-navigation.scss +++ b/css/app-navigation.scss @@ -8,6 +8,7 @@ * @author Raghu Nayyar * @author Georg Ehrke * @author John Molakvoæ + * @author Richard Steinmetz * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -308,5 +309,11 @@ } } } + + .appointment-config-list { + .app-navigation-caption { + margin-top: 22px; + } + } } } diff --git a/css/calendar.scss b/css/calendar.scss index f8ebf8d1b1..ae20147350 100644 --- a/css/calendar.scss +++ b/css/calendar.scss @@ -22,6 +22,7 @@ @import 'app-navigation.scss'; @import 'app-sidebar.scss'; @import 'app-settings.scss'; +@import 'app-modal.scss'; @import 'freebusy.scss'; @import 'fullcalendar.scss'; @import 'global.scss'; diff --git a/lib/Controller/AppointmentConfigController.php b/lib/Controller/AppointmentConfigController.php index 7db543d3c2..3ba64c503e 100644 --- a/lib/Controller/AppointmentConfigController.php +++ b/lib/Controller/AppointmentConfigController.php @@ -100,17 +100,17 @@ public function show(int $id): JsonResponse { * @param int $followupDuration * @param int $timeToNextSlot * @param int|null $dailyMax - * @param string[] $freebusyUris + * @param string[]|null $freebusyUris * @param int|null $start * @param int|null $end * @return JsonResponse */ public function create( - string $name, - string $description, - string $location, - string $visibility, - string $targetCalendarUri, + string $name, + string $description, + string $location, + string $visibility, + string $targetCalendarUri, ?string $availability, int $length, int $increment, @@ -118,7 +118,7 @@ public function create( int $followupDuration = 0, int $timeToNextSlot = 0, ?int $dailyMax = null, - array $freebusyUris = null, + ?array $freebusyUris = null, ?int $start = null, ?int $end = null): JsonResponse { @@ -160,14 +160,14 @@ public function create( * @param string $location * @param string $visibility * @param string $targetCalendarUri - * @param string $availability + * @param string|null $availability * @param int $length * @param int $increment * @param int $preparationDuration * @param int $followupDuration - * @param int $buffer + * @param int $timeToNextSlot * @param int|null $dailyMax - * @param string|null $freebusyUris + * @param string[] $freebusyUris * @param int|null $start * @param int|null $end * @return JsonResponse @@ -179,14 +179,14 @@ public function update( string $location, string $visibility, string $targetCalendarUri, - string $availability, + ?string $availability, int $length, int $increment, int $preparationDuration = 0, int $followupDuration = 0, - int $buffer = 0, + int $timeToNextSlot = 0, ?int $dailyMax = null, - ?string $freebusyUris = null, + ?array $freebusyUris = null, ?int $start = null, ?int $end = null): JsonResponse { if ($this->userId === null) { @@ -210,9 +210,9 @@ public function update( $appointmentConfig->setIncrement($increment); $appointmentConfig->setPreparationDuration($preparationDuration); $appointmentConfig->setFollowupDuration($followupDuration); - $appointmentConfig->setTimeBeforeNextSlot($buffer); + $appointmentConfig->setTimeBeforeNextSlot($timeToNextSlot); $appointmentConfig->setDailyMax($dailyMax); - $appointmentConfig->setCalendarFreebusyUris($freebusyUris); + $appointmentConfig->setCalendarFreeBusyUrisAsArray($freebusyUris ?? []); $appointmentConfig->setStart($start); $appointmentConfig->setEnd($end); diff --git a/lib/Controller/ViewController.php b/lib/Controller/ViewController.php index affb65bb48..9f8b930732 100644 --- a/lib/Controller/ViewController.php +++ b/lib/Controller/ViewController.php @@ -23,59 +23,44 @@ */ namespace OCA\Calendar\Controller; +use OCA\Calendar\Service\Appointments\AppointmentConfigService; use OCP\App\IAppManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Services\IInitialState; use OCP\IConfig; -use OCP\IInitialStateService; use OCP\IRequest; -/** - * Class ViewController - * - * @package OCA\Calendar\Controller - */ class ViewController extends Controller { - /** - * @var IConfig - */ + /** @var IConfig */ private $config; - /** - * @var string - */ - private $userId; + /** @var AppointmentConfigService */ + private $appointmentConfigService; - /** - * @var IInitialStateService - */ + /** @var IInitialState */ private $initialStateService; - /** - * @var IAppManager - */ + /** @var IAppManager */ private $appManager; - /** - * @param string $appName - * @param IRequest $request an instance of the request - * @param IConfig $config - * @param IInitialStateService $initialStateService - * @param IAppManager $appManager - * @param string $userId - */ + /** @var string */ + private $userId; + public function __construct(string $appName, IRequest $request, IConfig $config, - IInitialStateService $initialStateService, + AppointmentConfigService $appointmentConfigService, + IInitialState $initialStateService, IAppManager $appManager, ?string $userId) { parent::__construct($appName, $request); $this->config = $config; - $this->userId = $userId; + $this->appointmentConfigService = $appointmentConfigService; $this->initialStateService = $initialStateService; $this->appManager = $appManager; + $this->userId = $userId; } /** @@ -113,20 +98,24 @@ public function index():TemplateResponse { $talkApiVersion = version_compare($this->appManager->getAppVersion('spreed'), '12.0.0', '>=') ? 'v4' : 'v1'; $tasksEnabled = $this->appManager->isEnabledForUser('tasks'); - $this->initialStateService->provideInitialState($this->appName, 'app_version', $appVersion); - $this->initialStateService->provideInitialState($this->appName, 'event_limit', $eventLimit); - $this->initialStateService->provideInitialState($this->appName, 'first_run', $firstRun); - $this->initialStateService->provideInitialState($this->appName, 'initial_view', $initialView); - $this->initialStateService->provideInitialState($this->appName, 'show_weekends', $showWeekends); - $this->initialStateService->provideInitialState($this->appName, 'show_week_numbers', $showWeekNumbers); - $this->initialStateService->provideInitialState($this->appName, 'skip_popover', $skipPopover); - $this->initialStateService->provideInitialState($this->appName, 'talk_enabled', $talkEnabled); - $this->initialStateService->provideInitialState($this->appName, 'talk_api_version', $talkApiVersion); - $this->initialStateService->provideInitialState($this->appName, 'timezone', $timezone); - $this->initialStateService->provideInitialState($this->appName, 'slot_duration', $slotDuration); - $this->initialStateService->provideInitialState($this->appName, 'default_reminder', $defaultReminder); - $this->initialStateService->provideInitialState($this->appName, 'show_tasks', $showTasks); - $this->initialStateService->provideInitialState($this->appName, 'tasks_enabled', $tasksEnabled); + $this->initialStateService->provideInitialState('app_version', $appVersion); + $this->initialStateService->provideInitialState('event_limit', $eventLimit); + $this->initialStateService->provideInitialState('first_run', $firstRun); + $this->initialStateService->provideInitialState('initial_view', $initialView); + $this->initialStateService->provideInitialState('show_weekends', $showWeekends); + $this->initialStateService->provideInitialState('show_week_numbers', $showWeekNumbers); + $this->initialStateService->provideInitialState('skip_popover', $skipPopover); + $this->initialStateService->provideInitialState('talk_enabled', $talkEnabled); + $this->initialStateService->provideInitialState('talk_api_version', $talkApiVersion); + $this->initialStateService->provideInitialState('timezone', $timezone); + $this->initialStateService->provideInitialState('slot_duration', $slotDuration); + $this->initialStateService->provideInitialState('default_reminder', $defaultReminder); + $this->initialStateService->provideInitialState('show_tasks', $showTasks); + $this->initialStateService->provideInitialState('tasks_enabled', $tasksEnabled); + $this->initialStateService->provideInitialState( + 'appointmentConfigs', + $this->appointmentConfigService->getAllAppointmentConfigurations($this->userId), + ); return new TemplateResponse($this->appName, 'main'); } diff --git a/src/components/AppNavigation/AppointmentConfigList.vue b/src/components/AppNavigation/AppointmentConfigList.vue new file mode 100644 index 0000000000..33b959f83c --- /dev/null +++ b/src/components/AppNavigation/AppointmentConfigList.vue @@ -0,0 +1,138 @@ + + + + + diff --git a/src/components/AppNavigation/AppointmentConfigList/AppointmentConfigListItem.vue b/src/components/AppNavigation/AppointmentConfigList/AppointmentConfigListItem.vue new file mode 100644 index 0000000000..b462e9aebc --- /dev/null +++ b/src/components/AppNavigation/AppointmentConfigList/AppointmentConfigListItem.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/src/components/AppointmentConfigModal.vue b/src/components/AppointmentConfigModal.vue new file mode 100644 index 0000000000..06a6f53788 --- /dev/null +++ b/src/components/AppointmentConfigModal.vue @@ -0,0 +1,224 @@ + + +