Skip to content

Commit

Permalink
Schedule detail: Introduce Timescale
Browse files Browse the repository at this point in the history
  • Loading branch information
sukhwinder33445 committed Mar 4, 2025
1 parent 41595b9 commit 48cb522
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 1 deletion.
93 changes: 93 additions & 0 deletions library/Notifications/Widget/TimeGrid/Timescale.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

/* Icinga Notifications Web | (c) 2025 Icinga GmbH | GPLv2 */

namespace Icinga\Module\Notifications\Widget\TimeGrid;

use DateTime;
use IntlDateFormatter;
use ipl\Html\Attributes;
use ipl\Html\BaseHtmlElement;
use ipl\Html\HtmlElement;
use ipl\Html\Text;
use ipl\I18n\Translation;
use ipl\Web\Style;
use Locale;

/**
* Creates a localized timescale for the TimeGrid
*/
class Timescale extends BaseHtmlElement
{
use Translation;

protected $tag = 'div';

protected $defaultAttributes = ['class' => 'timescale'];

/** @var int The number of days shown */
protected $days;

/** @var Style */
protected $style;

/**
* Create a new Timescale
*
* @param int $days
* @param Style $style
*/
public function __construct(int $days, Style $style)
{
$this->days = $days;
$this->style = $style;
}

public function assemble(): void
{
switch (true) {
case $this->days === 1:
$timestampPerDay = 24;
break;
case $this->days <= 7:
$timestampPerDay = 3;
break;
case $this->days <= 14:
$timestampPerDay = 2;
break;
default:
$timestampPerDay = 1;
}

$this->style->addFor($this, ['--timestampsPerDay' => $timestampPerDay * 2]); // *2 for .ticks

$dateFormatter = new IntlDateFormatter(
Locale::getDefault(),
IntlDateFormatter::NONE,
IntlDateFormatter::SHORT
);

$timeIntervals = 24 / $timestampPerDay;

$time = new DateTime();
$dayTimestamps = [];
for ($i = 0; $i < $timestampPerDay; $i++) {
// am-pm is separated by non-breaking whitespace
$parts = preg_split('/\s/u', $dateFormatter->format($time->setTime($i * $timeIntervals, 0)));

$stamp = [new HtmlElement('span', null, new Text($parts[0]))];
if (isset($parts[1])) {
$stamp[] = new HtmlElement('span', null, new Text($parts[1]));
}

$dayTimestamps[] = new HtmlElement('span', new Attributes(['class' => 'timestamp']), ...$stamp);
$dayTimestamps[] = new HtmlElement('span', new Attributes(['class' => 'ticks']));
}

$allTimestamps = array_merge(...array_fill(0, $this->days, $dayTimestamps));
// clone is required because $allTimestamps contains references of same object
$allTimestamps[] = (clone $allTimestamps[0])->addAttributes(['class' => 'midnight']); // extra stamp of 12AM

$this->addHtml(...$allTimestamps);
}
}
4 changes: 4 additions & 0 deletions library/Notifications/Widget/Timeline.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Icinga\Module\Notifications\Widget\TimeGrid\DynamicGrid;
use Icinga\Module\Notifications\Widget\TimeGrid\EntryProvider;
use Icinga\Module\Notifications\Widget\TimeGrid\GridStep;
use Icinga\Module\Notifications\Widget\TimeGrid\Timescale;
use Icinga\Module\Notifications\Widget\Timeline\Entry;
use Icinga\Module\Notifications\Widget\Timeline\MinimalGrid;
use Icinga\Module\Notifications\Widget\Timeline\Rotation;
Expand Down Expand Up @@ -316,6 +317,9 @@ protected function assemble()
Text::create($this->translate('Result'))
)
);

$this->getGrid()
->addHtml(new Timescale($this->days, $this->getStyle()));
}

$this->addHtml(
Expand Down
53 changes: 52 additions & 1 deletion public/css/timeline.less
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
.timeline {
display: flex;
flex-direction: column;
overflow: hidden;

.time-grid {
--sidebarWidth: 12em;
--stepRowHeight: 4em;
--primaryRowHeight: 4em;
position: relative;
margin-right: 1em; // make midnight timestamp visible

.time-grid-header {
box-sizing: border-box;
Expand Down Expand Up @@ -65,10 +67,54 @@
display: block;
border-top: 1px solid black;
position: absolute;
bottom: var(--stepRowHeight);
bottom: ~"calc(var(--stepRowHeight) + 3em)"; // 3em .timescale height
right: 0;
left: 0;
}

.timescale {
display: grid;
grid-template-columns: repeat(~"calc(var(--primaryColumns) * var(--timestampsPerDay))", 1fr);
border-left: 1px solid @gray-lighter; // this is required to maintain the grid layout
grid-area: ~"4 / 2 / 4 / 3";
height: 3em;

.ticks {
position: relative;
border-right: 1px solid @gray-lighter;
border-left: 1px solid @gray-lighter;

&:after { // overlaps the unnecessary part of border-left
content: '';
position: absolute;
top: 0.25em;
left: -10%;
width: .25em;
height: 100%;
background: @body-bg-color;
}
}

.timestamp {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 0.5em;
padding-top: 0.5em;
font-size: .5em;
position: relative;
left: -50%;

&.midnight {
left: 50%;
}
}

span:nth-last-of-type(2), // last .ticks before .midnight
.midnight {
grid-area: ~"1 / -2 / 1 / -1";
}
}
}
}

Expand Down Expand Up @@ -134,6 +180,11 @@
font-size: .75em;
opacity: .8;
}

.timescale .timestamp {
color: @gray-semilight;
background: @body-bg-color;
}
}

.timeline.minimal-layout .empty-notice {
Expand Down

0 comments on commit 48cb522

Please sign in to comment.