From 2835b3b966dc60ebcf85e7bb77be9d85e24d9920 Mon Sep 17 00:00:00 2001 From: Moritz Strohm <strohm@data-quest.de> Date: Tue, 3 Dec 2024 15:20:59 +0000 Subject: [PATCH] added GUI improvements to schedule, re #4421 Merge request studip/studip!3578 --- app/controllers/calendar/schedule.php | 136 +++++++++++++++++- .../calendar/schedule/_colour_selector.php | 18 +++ app/views/calendar/schedule/course_info.php | 37 ++--- app/views/calendar/schedule/entry.php | 90 +++++++----- app/views/calendar/schedule/settings.php | 64 +++++++++ db/migrations/6.0.13_alter_schedule_table.php | 4 +- .../6.0.35_new_schedule_improvements.php | 75 ++++++++++ lib/classes/calendar/Helper.php | 42 +++++- lib/models/calendar/ScheduleEntry.php | 24 +++- .../assets/stylesheets/scss/calendar.scss | 2 +- .../assets/stylesheets/scss/my_courses.scss | 6 +- .../assets/stylesheets/scss/schedule.scss | 17 +++ resources/assets/stylesheets/studip.scss | 1 + 13 files changed, 436 insertions(+), 80 deletions(-) create mode 100644 app/views/calendar/schedule/_colour_selector.php create mode 100644 app/views/calendar/schedule/settings.php create mode 100644 db/migrations/6.0.35_new_schedule_improvements.php create mode 100644 resources/assets/stylesheets/scss/schedule.scss diff --git a/app/controllers/calendar/schedule.php b/app/controllers/calendar/schedule.php index 8f5e6e533b3..50196608de3 100644 --- a/app/controllers/calendar/schedule.php +++ b/app/controllers/calendar/schedule.php @@ -72,13 +72,13 @@ class Calendar_ScheduleController extends AuthenticatedController _('Neuer Termin'), $this->url_for('calendar/schedule/entry/add'), Icon::create('add'), - ['data-dialog' => ''] + ['data-dialog' => 'size=auto'] ); if ($show_hidden) { $actions->addLink( _('Ausgeblendete Veranstaltungen verstecken'), $this->indexURL(['semester_id' => Request::get('semester_id')]), - Icon::create('visibility-invisible') + Icon::create('visibility-visible') )->asButton(); } else { $actions->addLink( @@ -87,7 +87,7 @@ class Calendar_ScheduleController extends AuthenticatedController 'show_hidden' => true, 'semester_id' => Request::get('semester_id'), ]), - Icon::create('visibility-visible') + Icon::create('visibility-invisible') )->asButton(); } @@ -99,12 +99,40 @@ class Calendar_ScheduleController extends AuthenticatedController ); $actions->addLink( _('Einstellungen'), - $this->url_for('settings/calendar'), + $this->url_for('calendar/schedule/settings'), Icon::create('settings'), ['data-dialog' => 'size=auto;reload-on-close'] ); $sidebar->addWidget($actions); + $schedule_settings = UserConfig::get()->getValue('SCHEDULE_SETTINGS'); + $size = $schedule_settings['size'] ?? 'medium'; + if (Request::submitted('size')) { + $size = Request::option('size'); + if (in_array($size, ['small', 'medium', 'large'])) { + //Set the new size in the schedule settings: + $schedule_settings['size'] = $size; + UserConfig::get()->store('SCHEDULE_SETTINGS', $schedule_settings); + } else { + $size = 'medium'; + } + } + $views = new ViewsWidget(); + $views->setTitle(_('Größe')); + $views->addLink( + _('Klein'), + $this->url_for('calendar/schedule/index', ['size' => 'small']) + )->setActive($size === 'small'); + $views->addLink( + _('Mittel'), + $this->url_for('calendar/schedule/index', ['size' => 'medium']) + )->setActive($size === 'medium'); + $views->addLink( + _('Groß'), + $this->url_for('calendar/schedule/index', ['size' => 'large']) + )->setActive($size === 'large'); + $sidebar->addWidget($views); + $fullcalendar = \Studip\Calendar\Helper::getScheduleFullcalendar( $semester->id ?? '', Request::bool('show_hidden', false) @@ -203,9 +231,23 @@ class Calendar_ScheduleController extends AuthenticatedController ); $event_classes = ['schedule']; - $event_title = $cycle_date->course->getFullName(); + $event_title = $cycle_date->course->getFullName('number-name'); + if ($course_membership) { $event_classes[] = sprintf('course-color-%u', $course_membership->gruppe); + + $lecturer_names = array_map( + fn($lecturer) => $lecturer->user->nachname, + CourseMember::findByCourseAndStatus($course_membership->seminar_id, 'dozent') + ); + sort($lecturer_names); + $event_title = studip_interpolate( + '%{course_name} (%{lecturer_names})', + [ + 'course_name' => $cycle_date->course->getFullName('number-name'), + 'lecturer_names' => implode(', ', $lecturer_names) + ] + ); } elseif ($schedule_course) { $event_classes[] = 'marked-course'; $event_title = studip_interpolate( @@ -274,9 +316,10 @@ class Calendar_ScheduleController extends AuthenticatedController $this->entry->user_id = $GLOBALS['user']->id; if (!Request::submitted('save')) { //Provide good default values: + $this->entry->colour_id = 1; if (Request::submitted('start')) { //String format - $this->entry->dow = Request::int('dow', date('N')); + $this->entry->dow = Request::int('dow',date('N')); $this->entry->setFormattedStart(Request::get('start', date('H:00', strtotime('+1 hour')))); $this->entry->setFormattedEnd(Request::get('end', date('H:00', strtotime('+2 hours')))); } elseif (Request::submitted('begin')) { @@ -284,10 +327,16 @@ class Calendar_ScheduleController extends AuthenticatedController $begin = Request::get('begin'); $end = Request::get('end'); if ($begin && $end) { - $this->entry->dow = date('N', $begin); + $this->entry->dow = intval(date('N', $begin)); $this->entry->setFormattedStart(date('H:i', $begin)); $this->entry->setFormattedEnd(date('H:i', $end)); } + } else { + $begin = time() + 3600; + $end = $begin + 3600; + $this->entry->dow = intval(date('N', $begin)); + $this->entry->setFormattedStart(date('H:00', $begin)); + $this->entry->setFormattedEnd(date('H:00', $end)); } } PageLayout::setTitle(_('Neuer Termin')); @@ -338,6 +387,7 @@ class Calendar_ScheduleController extends AuthenticatedController $this->entry->dow = Request::int('dow', date('N')); $this->entry->setFormattedStart(Request::get('start')); $this->entry->setFormattedEnd(Request::get('end')); + $this->entry->colour_id = Request::get('colour_id') ?? ''; $this->entry->label = Request::get('label', ''); $this->entry->content = Request::get('content', ''); @@ -589,4 +639,76 @@ class Calendar_ScheduleController extends AuthenticatedController } $this->redirect('calendar/schedule/index'); } + + /** + * Shows the settings dialog for the schedule. + */ + public function settings_action() + { + $user_config = UserConfig::get($GLOBALS['user']->id); + $this->schedule_settings = $user_config->getValue('SCHEDULE_SETTINGS'); + + //Provide good defaults: + $default_config = [ + 'start_time' => '08:00', + 'end_time' => '20:00', + 'weekdays' => 5, + 'visible_days' => [1, 2, 3, 4, 5] + ]; + if ( + empty($this->schedule_settings['start_time']) + && empty($this->schedule_settings['end_time']) + && empty($this->schedule_settings['weekdays']) + && empty($this->schedule_settings['visible_days']) + ) { + //Use the defaults: + $this->schedule_settings = $default_config; + } + } + + /** + * Saves the schedule settings from the settings dialog. + */ + public function save_settings_action() + { + CSRFProtection::verifyUnsafeRequest(); + + $start_time = Request::get('start_time', '08:00'); + $end_time = Request::get('end_time', '20:00'); + $weekdays = Request::int('weekdays', 5); + $visible_days = Request::intArray('visible_days'); + if ($start_time >= $end_time) { + PageLayout::postError(_('Die Startuhrzeit muss vor der Enduhrzeit liegen.')); + $this->redirect('calendar/schedule/settings'); + return; + } + if (!in_array($weekdays, [5, 7])) { + PageLayout::postError(_('Der Stundenplan kann nur 5 oder 7 Tage anzeigen.')); + $this->redirect('calendar/schedule/settings'); + return; + } + if (empty($visible_days)) { + PageLayout::postError(_('Es wurde kein Wochentag ausgewählt.')); + $this->redirect('calendar/schedule/settings'); + return; + } + + + $schedule_settings = [ + 'start_time' => $start_time, + 'end_time' => $end_time, + 'weekdays' => $weekdays, + 'visible_days' => $visible_days + ]; + + UserConfig::get($GLOBALS['user']->id)->store('SCHEDULE_SETTINGS', $schedule_settings); + + PageLayout::postSuccess(_('Die Einstellungen wurden gespeichert.')); + if (Request::isDialog()) { + $this->response->add_header('X-Dialog-Close', '1'); + } else { + $this->redirect('calendar/schedule/index'); + } + $this->render_nothing(); + } } diff --git a/app/views/calendar/schedule/_colour_selector.php b/app/views/calendar/schedule/_colour_selector.php new file mode 100644 index 00000000000..34758b2474c --- /dev/null +++ b/app/views/calendar/schedule/_colour_selector.php @@ -0,0 +1,18 @@ +<?php +/** + * @var string $selected_colour_id + */ +?> +<? foreach ($GLOBALS['PERS_TERMIN_KAT'] as $colour_id => $data) : ?> + <td class="colour"> + <input type="radio" name="colour_id" value="<?= htmlReady($colour_id) ?>" + aria-label="<?= sprintf(_('Farbe %s zuordnen'), htmlReady($colour_id)) ?>" + <?= $selected_colour_id === $colour_id ? 'checked' : '' ?> + id="colour-<?= htmlReady($colour_id) ?>"> + <label for="colour-<?= htmlReady($colour_id) ?>" + style="background-color: <?= htmlReady($data['bgcolor']) ?>;"> + <span class="colour-id"></span> + <span class="checked-icon"><?= Icon::create('accept', Icon::ROLE_INFO) ?></span> + </label> + </td> +<? endforeach ?> diff --git a/app/views/calendar/schedule/course_info.php b/app/views/calendar/schedule/course_info.php index 7cfaeae9c10..dd664ec4b48 100644 --- a/app/views/calendar/schedule/course_info.php +++ b/app/views/calendar/schedule/course_info.php @@ -7,7 +7,6 @@ */ ?> <? if ($course) : ?> - <h2><?= htmlReady($course->getFullName()) ?></h2> <form class="default" method="post" data-dialog="reload-on-close" action="<?= $controller->link_for('calendar/schedule/course_info/' . $course->id) ?>"> <?= CSRFProtection::tokenTag() ?> @@ -30,8 +29,10 @@ <fieldset> <legend><?= _('Informationen') ?></legend> <section> - <h3><?= _('Veranstaltungsnummer') ?></h3> - <p><?= htmlReady($course->veranstaltungsnummer) ?></p> + <? if ($course->veranstaltungsnummer) : ?> + <h3><?= _('Veranstaltungsnummer') ?></h3> + <p><?= htmlReady($course->veranstaltungsnummer) ?></p> + <? endif ?> <h3><?= _('Lehrende') ?></h3> <ul class="default"> <? @@ -48,6 +49,22 @@ <h3><?= _('Veranstaltungszeiten') ?></h3> <?= $course->getAllDatesInSemester()->toHtml() ?> </section> + <section> + <? + $enrolment_info = $course->getEnrolmentInformation($GLOBALS['user']->id); + ?> + <? if ($enrolment_info->isEnrolmentAllowed()) : ?> + <a href="<?= URLHelper::getLink('dispatch.php/course/overview', ['cid' => $course->id]) ?>"> + <?= _('Direkt zur Veranstaltung') ?> + <?= Icon::create('link-intern')->asImg(Icon::SIZE_INLINE, ['class' => 'text-bottom']) ?> + </a> + <? else : ?> + <a href="<?= URLHelper::getLink('dispatch.php/course/details', ['sem_id' => $course->id]) ?>"> + <?= _('Direkt zur Veranstaltung') ?> + <?= Icon::create('link-intern')->asImg(Icon::SIZE_INLINE, ['class' => 'text-bottom']) ?> + </a> + <? endif ?> + </section> </fieldset> <div data-dialog-button> <?= \Studip\Button::create( @@ -68,20 +85,6 @@ ['formaction' => $controller->url_for('calendar/schedule/hide_course/' . $course->id)] ) ?> <? endif ?> - <?php - $enrolment_info = $course->getEnrolmentInformation($GLOBALS['user']->id); - ?> - <? if ($enrolment_info->isEnrolmentAllowed()) : ?> - <?= \Studip\LinkButton::create( - _('Direkt zur Veranstaltung'), - URLHelper::getURL('dispatch.php/course/overview', ['cid' => $course->id]) - ) ?> - <? else : ?> - <?= \Studip\LinkButton::create( - _('Direkt zur Veranstaltung'), - URLHelper::getURL('dispatch.php/course/details', ['sem_id' => $course->id]) - ) ?> - <? endif ?> </div> </form> <? endif ?> diff --git a/app/views/calendar/schedule/entry.php b/app/views/calendar/schedule/entry.php index 676f07308c1..561588aa2de 100644 --- a/app/views/calendar/schedule/entry.php +++ b/app/views/calendar/schedule/entry.php @@ -4,48 +4,60 @@ * @var ScheduleEntry $entry The schedule entry to be created/modified. */ ?> -<form class="default" method="post" action="<?= $controller->link_for('calendar/schedule/entry/' . ($entry->isNew() ? 'add' : $entry->id)) ?>" +<form class="default schedule-entry" method="post" + action="<?= $controller->link_for('calendar/schedule/entry/' . ($entry->isNew() ? 'add' : $entry->id)) ?>" data-dialog="reload-on-close"> <?= CSRFProtection::tokenTag() ?> + <fieldset> + <legend><?= _('Farbe') ?></legend> + <table class="default colour-selector"> + <tr> + <?= $this->render_partial( + 'calendar/schedule/_colour_selector', + ['selected_colour_id' => $entry->colour_id] + ) ?> + </tr> + </table> + </fieldset> <fieldset> <legend><?= _('Zeit') ?></legend> - <section class="flex-row"> - <label> - <?= _('Wochentag') ?> - <select name="dow"> - <option value="1" <?= $entry->dow === 1 ? 'selected' : '' ?>> - <?= _('Montag') ?> - </option> - <option value="2" <?= $entry->dow === 2 ? 'selected' : '' ?>> - <?= _('Dienstag') ?> - </option> - <option value="3" <?= $entry->dow === 3 ? 'selected' : '' ?>> - <?= _('Mittwoch') ?> - </option> - <option value="4" <?= $entry->dow === 4 ? 'selected' : '' ?>> - <?= _('Donnerstag') ?> - </option> - <option value="5" <?= $entry->dow === 5 ? 'selected' : '' ?>> - <?= _('Freitag') ?> - </option> - <option value="6" <?= $entry->dow === 6 ? 'selected' : '' ?>> - <?= _('Samstag') ?> - </option> - <option value="7" <?= $entry->dow === 7 ? 'selected' : '' ?>> - <?= _('Sonntag') ?> - </option> - </select> - </label> - <label> - <?= _('Startuhrzeit') ?> - <input type="text" class="has-time-picker" name="start" - value="<?= htmlReady($entry->getFormattedStart()) ?>"> - </label> - <label> - <?= _('Enduhrzeit') ?> - <input type="text" class="has-time-picker" name="end" - value="<?= htmlReady($entry->getFormattedEnd()) ?>"> - </label> + <section class="hgroup nowrap"> + <label> + <?= _('Wochentag') ?> + <select name="dow" class="size-s"> + <option value="1" <?= $entry->dow === 1 ? 'selected' : '' ?>> + <?= _('Montag') ?> + </option> + <option value="2" <?= $entry->dow === 2 ? 'selected' : '' ?>> + <?= _('Dienstag') ?> + </option> + <option value="3" <?= $entry->dow === 3 ? 'selected' : '' ?>> + <?= _('Mittwoch') ?> + </option> + <option value="4" <?= $entry->dow === 4 ? 'selected' : '' ?>> + <?= _('Donnerstag') ?> + </option> + <option value="5" <?= $entry->dow === 5 ? 'selected' : '' ?>> + <?= _('Freitag') ?> + </option> + <option value="6" <?= $entry->dow === 6 ? 'selected' : '' ?>> + <?= _('Samstag') ?> + </option> + <option value="7" <?= $entry->dow === 7 ? 'selected' : '' ?>> + <?= _('Sonntag') ?> + </option> + </select> + </label> + <label> + <?= _('Anfang') ?> + <input type="text" class="has-time-picker size-s" name="start" + value="<?= htmlReady($entry->getFormattedStart()) ?>"> + </label> + <label> + <?= _('Ende') ?> + <input type="text" class="has-time-picker size-s" name="end" + value="<?= htmlReady($entry->getFormattedEnd()) ?>"> + </label> </section> </fieldset> <fieldset> @@ -60,7 +72,7 @@ </label> </fieldset> <div data-dialog-button> - <?= \Studip\Button::create( + <?= \Studip\Button::createAccept( _('Speichern'), 'save', ['formaction' => $controller->url_for('calendar/schedule/save_entry/' . ($entry->isNew() ? 'add' : $entry->id))] diff --git a/app/views/calendar/schedule/settings.php b/app/views/calendar/schedule/settings.php new file mode 100644 index 00000000000..6c03ba60555 --- /dev/null +++ b/app/views/calendar/schedule/settings.php @@ -0,0 +1,64 @@ +<?php +/** + * @var StudipController $controller + * @var array $schedule_settings + */ +?> +<form class="default" method="post" action="<?= $controller->link_for('calendar/schedule/save_settings') ?>" + <?= Request::isDialog() ? 'data-dialog="reload-on-close"' : '' ?>> + <?= CSRFProtection::tokenTag() ?> + <fieldset> + <legend><?= _('Zeiten') ?></legend> + <label> + <?= _('Anfang') ?> + <select name="start_time" aria-label="<?= _('Anfang des Stundenplans') ?>" class="size-s"> + <? for ($i = 0; $i < 24; $i += 1): ?> + <? $value = sprintf('%02u:00', $i); ?> + <option value="<?= htmlReady($value) ?>" + <?= $schedule_settings['start_time'] === $value ? 'selected' : '' ?>> + <?= studip_interpolate('%{time} Uhr', ['time' => $value]) ?> + </option> + <? endfor ?> + </select> + </label> + <label> + <?= _('Ende') ?> + <select name="end_time" aria-label="<?= _('Ende des Stundenplans') ?>" class="size-s"> + <? for ($i = 0; $i < 24; $i += 1): ?> + <? $value = sprintf('%02u:00', $i); ?> + <option value="<?= $value ?>" + <?= $schedule_settings['end_time'] === $value ? 'selected' : '' ?>> + <?= studip_interpolate('%{time} Uhr', ['time' => $value]) ?> + </option> + <? endfor ?> + </select> + </label> + <label> + <input type="radio" name="weekdays" value="7" + <?= $schedule_settings['weekdays'] === 7 ? 'checked' : '' ?>> + <?= _('Alle Wochentage im Stundenplan anzeigen.') ?> + </label> + <label> + <input type="radio" name="weekdays" value="5" + <?= $schedule_settings['weekdays'] === 5 ? 'checked' : '' ?>> + <?= _('Nur Montag bis Freitag im Stundenplan anzeigen.') ?> + </label> + </fieldset> + <fieldset> + <legend><?= _('Wochentage') ?></legend> + <section class="hgroup"> + <? for ($i = 1; $i < 8; $i++) : ?> + <label> + <input type="checkbox" name="visible_days[]" value="<?= $i ?>" + <?= in_array($i, $schedule_settings['visible_days']) ? 'checked' : '' ?>> + <?= getWeekday($i, false) ?> + </label> + <? endfor ?> + </section> + </fieldset> + <div data-dialog-button> + <?= \Studip\Button::createAccept(_('Speichern')) ?> + <?= \Studip\Button::createCancel(_('Abbrechen')) ?> + </div> +</form> + diff --git a/db/migrations/6.0.13_alter_schedule_table.php b/db/migrations/6.0.13_alter_schedule_table.php index d27bf81f5e4..ecd692f4c4e 100644 --- a/db/migrations/6.0.13_alter_schedule_table.php +++ b/db/migrations/6.0.13_alter_schedule_table.php @@ -16,7 +16,7 @@ class AlterScheduleTable extends Migration $db->exec( "ALTER TABLE `schedule_entries` - DROP COLUMN color, + RENAME COLUMN color TO colour_id, CHANGE COLUMN start start_time SMALLINT(6) NOT NULL, CHANGE COLUMN end end_time SMALLINT(6) NOT NULL, CHANGE COLUMN day dow TINYINT(1) NOT NULL, @@ -51,7 +51,7 @@ class AlterScheduleTable extends Migration $db->exec( "ALTER TABLE `schedule_entries` - ADD COLUMN color TINYINT(4) NULL DEFAULT NULL, + RENAME COLUMN colour_id TO color, CHANGE COLUMN start_time start SMALLINT(6) NOT NULL, CHANGE COLUMN end_time end SMALLINT(6) NOT NULL, CHANGE COLUMN dow day TINYINT(1) NOT NULL, diff --git a/db/migrations/6.0.35_new_schedule_improvements.php b/db/migrations/6.0.35_new_schedule_improvements.php new file mode 100644 index 00000000000..2a038b9498e --- /dev/null +++ b/db/migrations/6.0.35_new_schedule_improvements.php @@ -0,0 +1,75 @@ +<?php + + +class NewScheduleImprovements extends Migration +{ + public function description() + { + return 'A bugfix migration to add colours to personal schedule entries again and to migrate schedule configurations.'; + } + + protected function up() + { + $db = DBManager::get(); + $db->exec( + "ALTER TABLE `schedule_entries` + ADD COLUMN IF NOT EXISTS `colour_id` TINYINT(3) NOT NULL DEFAULT 0" + ); + + //Migrate the content of schedule configuration entries: + + $fetch_stmt = $db->prepare( + "SELECT `range_id`, `value` + FROM `config_values` + WHERE `field` = 'SCHEDULE_SETTINGS'" + ); + $update_stmt = $db->prepare( + "UPDATE `config_values` + SET `value` = :new_value, `chdate` = UNIX_TIMESTAMP() + WHERE `field` = 'SCHEDULE_SETTINGS' + AND `range_id` = :range_id" + ); + $delete_stmt = $db->prepare( + "DELETE FROM `config_values` + WHERE `field` = 'SCHEDULE_SETTINGS' + AND `range_id` = :range_id" + ); + + $fetch_stmt->execute(); + while ($row = $fetch_stmt->fetch(PDO::FETCH_ASSOC)) { + $old_config = json_decode($row['value'], true); + if (is_array($old_config)) { + //Convert the configuration: + $new_config = [ + 'start_time' => sprintf('%02u:00', $old_config['glb_start_time']), + 'end_time' => sprintf('%02u:00', $old_config['glb_end_time']), + 'semester_id' => $old_config['semester_id'] + ]; + if (count($old_config['glb_days']) === 7) { + $new_config['weekdays'] = 7; + } else { + $new_config['weekdays'] = 5; + } + //Convert the visible days array: + $visible_days = []; + if (is_array($old_config['glb_days'])) { + foreach ($old_config['glb_days'] as $day) { + if ($day == 0) { + $visible_days[] = 7; + } else { + $visible_days[] = (int) $day; + } + } + } + $new_config['visible_days'] = $visible_days; + $update_stmt->execute([ + 'range_id' => $row['range_id'], + 'new_value' => json_encode($new_config) + ]); + } else { + //Delete the configuration: + $delete_stmt->execute(['range_id' => $old_config['range_id']]); + } + } + } +} diff --git a/lib/classes/calendar/Helper.php b/lib/classes/calendar/Helper.php index 004e2f5047b..8be9891a173 100644 --- a/lib/classes/calendar/Helper.php +++ b/lib/classes/calendar/Helper.php @@ -128,7 +128,31 @@ class Helper if (!$semester_id) { $semester_id = \Semester::findCurrent()?->id ?? ''; } - $calendar_settings = \User::findCurrent()->getConfiguration()->CALENDAR_SETTINGS ?? []; + $schedule_settings = \UserConfig::get($GLOBALS['user']->id)->getValue('SCHEDULE_SETTINGS') ?? []; + $slot_duration = '00:30:00'; + if (!empty($schedule_settings['size']) && in_array($schedule_settings['size'], ['small', 'large'])) { + if ($schedule_settings['size'] === 'small') { + $slot_duration = '01:00:00'; + } elseif ($schedule_settings['size'] === 'large') { + $slot_duration = '00:15:00'; + } + } + + //Determine the value of the hiddenDays config. + $hidden_days = [1, 2, 3, 4, 5, 6, 7]; + $hidden_days = array_diff( + $hidden_days, + $schedule_settings['visible_days'] ?? [1, 2, 3, 4, 5, 6, 7] + ); + + $fullcalendar_hidden_days = []; + foreach ($hidden_days as $day) { + if ($day === 7) { + $fullcalendar_hidden_days[] = 0; + } else { + $fullcalendar_hidden_days[] = $day; + } + } return new \Studip\Fullcalendar( _('Stundenplan'), @@ -136,8 +160,8 @@ class Helper 'editable' => true, 'selectable' => true, 'dialog_size' => 'auto', - 'minTime' => sprintf('%02u:00', $calendar_settings['start'] ?? 8), - 'maxTime' => sprintf('%02u:00', $calendar_settings['end'] ?? 20), + 'minTime' => $schedule_settings['start_time'] ?? '08:00', + 'maxTime' => $schedule_settings['end_time'] ?? '20:00', 'allDaySlot' => false, 'header' => [ 'left' => '', @@ -145,13 +169,19 @@ class Helper ], 'views' => [ 'timeGridWeek' => [ - 'columnHeaderFormat' => ['weekday' => 'long'], - 'weekends' => $calendar_settings['type_week'] === 'LONG', - 'slotDuration' => self::getCalendarSlotDuration('week'), + 'columnHeaderFormat' => ['weekday' => 'short'], + 'weekends' => !empty($schedule_settings['weekdays']) && $schedule_settings['weekdays'] === 7, + 'slotDuration' => $slot_duration ] ], 'defaultView' => 'timeGridWeek', 'defaultDate' => date('Y-m-d'), + 'slotLabelFormat' => [ + 'hour' => 'numeric', + 'minute' => '2-digit', + 'omitZeroMinute' => false + ], + 'hiddenDays' => $fullcalendar_hidden_days, 'timeGridEventMinHeight' => 20, 'eventSources' => [ [ diff --git a/lib/models/calendar/ScheduleEntry.php b/lib/models/calendar/ScheduleEntry.php index f1e23fddaff..638f9e77b13 100644 --- a/lib/models/calendar/ScheduleEntry.php +++ b/lib/models/calendar/ScheduleEntry.php @@ -17,6 +17,7 @@ * @property string $start_time database column * @property string $end_time database column * @property string $dow database column + * @property string $colour_id database column * @property string $label database column * @property string $content database column * @property string $user_id database column @@ -216,7 +217,7 @@ class ScheduleEntry extends SimpleORMap implements Event */ public function getDescription(): string { - return $this->content; + return $this->getValue('content'); } /** @@ -298,13 +299,24 @@ class ScheduleEntry extends SimpleORMap implements Event */ public function toEventData(string $user_id): \Studip\Calendar\EventData { + $title = $this->label; + + $description = $this->getDescription(); + if ($description) { + if ($this->label) { + $title = $this->label . ': ' . $description; + } else { + $title = $description; + } + } + $event_classes = ['schedule-entry']; return new \Studip\Calendar\EventData( $this->getBegin(), $this->getEnd(), - $this->label, - ['schedule-entry'], - '#000000', - '#ffffff', + $title, + $event_classes, + $GLOBALS['PERS_TERMIN_KAT'][$this->colour_id]['fgcolor'] ?? '#000000', + $GLOBALS['PERS_TERMIN_KAT'][$this->colour_id]['bgcolor'] ?? '#ffffff', $this->isWritable($user_id), self::class, $this->id, @@ -317,7 +329,7 @@ class ScheduleEntry extends SimpleORMap implements Event ], [], '', - '#000000', + $GLOBALS['PERS_TERMIN_KAT'][$this->colour_id]['border_color'] ?? '#000000', $this->isAllDayEvent() ); } diff --git a/resources/assets/stylesheets/scss/calendar.scss b/resources/assets/stylesheets/scss/calendar.scss index 0effce153d3..e5bc90b2cd6 100644 --- a/resources/assets/stylesheets/scss/calendar.scss +++ b/resources/assets/stylesheets/scss/calendar.scss @@ -3,7 +3,7 @@ background-color: #fff; color: #000; - border-width: 2px; + border-width: 1px; &:hover { color: #000; diff --git a/resources/assets/stylesheets/scss/my_courses.scss b/resources/assets/stylesheets/scss/my_courses.scss index d47fb58de7b..d288908463d 100644 --- a/resources/assets/stylesheets/scss/my_courses.scss +++ b/resources/assets/stylesheets/scss/my_courses.scss @@ -18,7 +18,8 @@ form.default table.mycourses-group-selector { } } -form.default td.mycourses-group-selector { +form.default td.mycourses-group-selector, +form.default table.colour-selector td.colour { position: relative; background-clip: padding-box; @@ -28,7 +29,8 @@ form.default td.mycourses-group-selector { @extend .sr-only; &:checked + label { - .group-number { + .group-number, + .colour-id { display: none; } .checked-icon { diff --git a/resources/assets/stylesheets/scss/schedule.scss b/resources/assets/stylesheets/scss/schedule.scss new file mode 100644 index 00000000000..d12faf82d10 --- /dev/null +++ b/resources/assets/stylesheets/scss/schedule.scss @@ -0,0 +1,17 @@ +form.default.schedule-entry { + + section.nowrap { + flex-wrap: nowrap; + } + + table.colour-selector td.colour { + label { + width: 1.5em; + height: 1.5em; + + .studip-icon { + height: 1.5em; + } + } + } +} diff --git a/resources/assets/stylesheets/studip.scss b/resources/assets/stylesheets/studip.scss index eb4895ba529..4713c32d896 100644 --- a/resources/assets/stylesheets/studip.scss +++ b/resources/assets/stylesheets/studip.scss @@ -82,6 +82,7 @@ @import "scss/resources"; @import "scss/sidebar"; @import "scss/wizard"; +@import "scss/schedule"; @import "scss/select"; @import "scss/selects"; @import "scss/search"; -- GitLab