From 578cb394967d643f21a4b66bce28fc961fb60829 Mon Sep 17 00:00:00 2001 From: raviks789 <33730024+raviks789@users.noreply.github.com> Date: Fri, 22 Sep 2023 17:22:23 +0200 Subject: [PATCH] Add day mode to the calendar --- library/Notifications/Widget/Calendar.php | 11 +- .../Widget/Calendar/Controls.php | 10 +- .../Notifications/Widget/Calendar/DayGrid.php | 110 ++++++++++++++++++ public/css/calendar.less | 35 ++++++ 4 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 library/Notifications/Widget/Calendar/DayGrid.php diff --git a/library/Notifications/Widget/Calendar.php b/library/Notifications/Widget/Calendar.php index 7e252a91b..d75d271e3 100644 --- a/library/Notifications/Widget/Calendar.php +++ b/library/Notifications/Widget/Calendar.php @@ -7,6 +7,7 @@ use DateTime; use Icinga\Module\Notifications\Widget\Calendar\BaseGrid; use Icinga\Module\Notifications\Widget\Calendar\Controls; +use Icinga\Module\Notifications\Widget\Calendar\DayGrid; use Icinga\Module\Notifications\Widget\Calendar\Entry; use Icinga\Module\Notifications\Widget\Calendar\MonthGrid; use Icinga\Module\Notifications\Widget\Calendar\Util; @@ -31,6 +32,9 @@ class Calendar extends BaseHtmlElement /** @var string Mode to show a specific calendar week */ public const MODE_WEEK = 'week'; + /** @var string Mode to show only the day */ + public const MODE_DAY = 'day'; + protected $tag = 'div'; protected $defaultAttributes = ['class' => 'calendar']; @@ -83,10 +87,11 @@ protected function getModeStart(): DateTime return DateTime::createFromFormat('Y-m-d\TH:i:s', $month . '-01T00:00:00'); case self::MODE_WEEK: - default: $week = $this->getControls()->getValue('week') ?: (new DateTime())->format('Y-\WW'); return (new DateTime())->setTimestamp(strtotime($week)); + default: + return DateTime::createFromFormat('Y-m-d', $this->getControls()->getValue('day')); } } @@ -95,8 +100,10 @@ public function getGrid(): BaseGrid if ($this->grid === null) { if ($this->getControls()->getViewMode() === self::MODE_MONTH) { $this->grid = new MonthGrid($this, $this->getModeStart()); - } else { // $mode === self::MODE_WEEK + } elseif ($this->getControls()->getViewMode() === self::MODE_WEEK) { $this->grid = new WeekGrid($this, $this->getModeStart()); + } else { + $this->grid = new DayGrid($this, $this->getModeStart()); } } diff --git a/library/Notifications/Widget/Calendar/Controls.php b/library/Notifications/Widget/Calendar/Controls.php index c5f1d7c17..407f3eadb 100644 --- a/library/Notifications/Widget/Calendar/Controls.php +++ b/library/Notifications/Widget/Calendar/Controls.php @@ -37,7 +37,6 @@ protected function assemble() ]); break; case Calendar::MODE_WEEK: - default: $this->addElement('input', 'week', [ 'class' => 'autosubmit', 'type' => 'week', @@ -45,10 +44,19 @@ protected function assemble() 'label' => $this->translate('Calendar Week') ]); break; + default: + $this->addElement('input', 'day', [ + 'class' => 'autosubmit', + 'type' => 'date', + 'value' => (new DateTime())->format('Y-m-d'), + 'label' => $this->translate('Date') + ]); + break; } $modeParam = 'mode'; $options = [ + Calendar::MODE_DAY => $this->translate('Day'), Calendar::MODE_WEEK => $this->translate('Week'), Calendar::MODE_MONTH => $this->translate('Month') ]; diff --git a/library/Notifications/Widget/Calendar/DayGrid.php b/library/Notifications/Widget/Calendar/DayGrid.php new file mode 100644 index 000000000..277f88c32 --- /dev/null +++ b/library/Notifications/Widget/Calendar/DayGrid.php @@ -0,0 +1,110 @@ +getGridStart())->add(new DateInterval('P1D')); + } + + protected function getNoOfVisuallyConnectedHours(): int + { + return 24; + } + + protected function getGridArea(int $rowStart, int $rowEnd, int $colStart, int $colEnd): array + { + return [$colStart, $rowStart, $colEnd, $rowEnd]; + } + + protected function createGridSteps(): Traversable + { + $interval = new DateInterval('P1D'); + $hourStartsAt = clone $this->getGridStart(); + for ($i = 0; $i < 24; $i++) { + yield $hourStartsAt; + + $hourStartsAt->add($interval); + } + } + + protected function createHeader(): BaseHtmlElement + { + $header = new HtmlElement('div', Attributes::create(['class' => 'header'])); + + $currentDay = clone $this->getGridStart(); + $interval = new DateInterval('P1D'); + $header->addHtml(new HtmlElement( + 'div', + Attributes::create(['class' => 'column-title']), + new HtmlElement( + 'span', + Attributes::create(['class' => 'day-name']), + Text::create($this->getGridStart()->format('D')) + ), + new HtmlElement( + 'span', + Attributes::create(['class' => 'day-number']), + Text::create($currentDay->format('d')) + ) + )); + + $currentDay->add($interval); + + return $header; + } + + protected function createSidebar(): BaseHtmlElement + { + $sidebar = new HtmlElement('div', Attributes::create(['class' => 'sidebar'])); + + $time = (new DateTime())->setTime(0, 0); + $interval = new DateInterval('PT1H'); + for ($i = 0; $i < 24; $i++) { + $sidebar->addHtml(new HtmlElement( + 'div', + Attributes::create(['class' => 'row-title']), + new HtmlElement( + 'span', + Attributes::create(['class' => 'hour']), + Text::create($time->format('H:i')) + ) + )); + + $time->add($interval); + } + + return $sidebar; + } + + protected function assemble() + { + $this->getAttributes()->add('class', 'day'); + + $this->addHtml( + $this->createHeader(), + $this->createSidebar(), + $this->createGrid(), + $this->createGridOverlay() + ); + } +} diff --git a/public/css/calendar.less b/public/css/calendar.less index c653f2f1c..92156a562 100644 --- a/public/css/calendar.less +++ b/public/css/calendar.less @@ -174,10 +174,39 @@ } } +.calendar-grid.day { + @days: 1; + @hours: 24; + @rowsPerHour: 2; + @columnsPerDay: 28; + + .sidebar { + grid-template-rows: repeat(@hours, 1fr); + } + + .grid, + .overlay { + display: grid; + grid-template-rows: repeat(@hours * @rowsPerHour, 1fr); + grid-template-columns: repeat(@days * @columnsPerDay, minmax(2em, 1fr)); + } + + .grid, + .overlay { + border-left: none; + } + + .step { + grid-column-end: span @columnsPerDay; + grid-row-end: span @rowsPerHour; + } +} + .calendar-grid { display: grid; &.week, + &.day, &.month { .header { grid-area: ~"1 / 2 / 2 / 3"; @@ -201,6 +230,10 @@ grid-template-columns: 4em minmax(0, 1fr); grid-template-rows: 1.5em minmax(0, 1fr); } + &.day { + grid-template-columns: 6em minmax(0, 1fr); + grid-template-rows: 2.5em minmax(0, 1fr); + } .overlay { pointer-events: none; @@ -214,9 +247,11 @@ /* Design */ .calendar-controls { + input[type="date"], input[type="month"], input[type="week"] { background-color: @low-sat-blue; + width: auto; } .view-mode-switcher label {