Skip to content

Commit c7516f9

Browse files
Introduce ViewModeSwitcher
Migrate icingadb-web's `ViewModeSwitcher` and its styles.
1 parent 2e096a4 commit c7516f9

3 files changed

Lines changed: 254 additions & 0 deletions

File tree

asset/css/controls.less

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,12 @@
127127
}
128128

129129
> .sort-control,
130+
> .view-mode-switcher,
130131
> .limit-control {
131132
float: right;
132133
}
133134

135+
> .view-mode-switcher,
134136
> .limit-control {
135137
margin-right: .5em;
136138
}

asset/css/view-mode-switcher.less

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
.view-mode-switcher {
2+
display: flex;
3+
4+
input {
5+
display: none;
6+
}
7+
8+
label {
9+
color: var(--control-color, @control-color);
10+
line-height: 1;
11+
background: var(--low-sat-blue, @low-sat-blue);
12+
padding: 14/16*.25em 14/16*.5em;
13+
font-size: 16/12em;
14+
height: 24/16em; // desired pixel height / font-size
15+
cursor: pointer;
16+
17+
&:first-of-type {
18+
border-top-left-radius: 0.25em;
19+
border-bottom-left-radius: 0.25em;
20+
}
21+
22+
&:last-of-type {
23+
border-top-right-radius: 0.25em;
24+
border-bottom-right-radius: 0.25em;
25+
}
26+
27+
&:not(:last-of-type) {
28+
border-right: 1px solid var(--low-sat-blue-dark, @low-sat-blue-dark);
29+
}
30+
31+
i {
32+
// fix height for Chrome
33+
display: block;
34+
}
35+
}
36+
37+
input[checked] + label {
38+
background-color: var(--control-color, @control-color);
39+
color: var(--text-color-on-icinga-blue, @text-color-on-icinga-blue);
40+
cursor: default;
41+
}
42+
}

src/Control/ViewModeSwitcher.php

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
<?php
2+
3+
namespace ipl\Web\Control;
4+
5+
use ipl\Html\Attributes;
6+
use ipl\Html\Form;
7+
use ipl\Html\FormElement\HiddenElement;
8+
use ipl\Html\FormElement\InputElement;
9+
use ipl\Html\HtmlElement;
10+
use ipl\Web\Common\FormUid;
11+
use ipl\Web\Widget\IcingaIcon;
12+
13+
class ViewModeSwitcher extends Form
14+
{
15+
use FormUid;
16+
17+
protected $defaultAttributes = [
18+
'class' => 'view-mode-switcher',
19+
'name' => 'view-mode-switcher'
20+
];
21+
22+
/** @var string Default view mode */
23+
public const DEFAULT_VIEW_MODE = 'common';
24+
25+
/** @var string Default view mode param */
26+
public const DEFAULT_VIEW_MODE_PARAM = 'view';
27+
28+
/** @var array<string, string> View mode-icon pairs */
29+
public static array $viewModes = [
30+
'minimal' => 'minimal',
31+
'common' => 'default',
32+
'detailed' => 'detailed'
33+
];
34+
35+
protected ?string $defaultViewMode = null;
36+
37+
/** @var string */
38+
protected $method = 'POST';
39+
40+
/** @var callable */
41+
protected $protector;
42+
43+
protected string $viewModeParam = self::DEFAULT_VIEW_MODE_PARAM;
44+
45+
/**
46+
* Get the default mode
47+
*
48+
* @return string
49+
*/
50+
public function getDefaultViewMode(): string
51+
{
52+
return $this->defaultViewMode ?: static::DEFAULT_VIEW_MODE;
53+
}
54+
55+
/**
56+
* Set the default view mode
57+
*
58+
* @param string $defaultViewMode
59+
*
60+
* @return $this
61+
*/
62+
public function setDefaultViewMode(string $defaultViewMode): static
63+
{
64+
$this->defaultViewMode = $defaultViewMode;
65+
66+
return $this;
67+
}
68+
69+
/**
70+
* Get the view mode URL parameter
71+
*
72+
* @return string
73+
*/
74+
public function getViewModeParam(): string
75+
{
76+
return $this->viewModeParam;
77+
}
78+
79+
/**
80+
* Set the view mode URL parameter
81+
*
82+
* @param string $viewModeParam
83+
*
84+
* @return $this
85+
*/
86+
public function setViewModeParam(string $viewModeParam): static
87+
{
88+
$this->viewModeParam = $viewModeParam;
89+
90+
return $this;
91+
}
92+
93+
/**
94+
* Get the view mode
95+
*
96+
* @return string
97+
*/
98+
public function getViewMode(): string
99+
{
100+
$viewMode = $this->getPopulatedValue($this->getViewModeParam(), $this->getDefaultViewMode());
101+
102+
// View mode stays null if explicitly populated with null.
103+
if ($viewMode !== null && array_key_exists($viewMode, static::$viewModes)) {
104+
return $viewMode;
105+
}
106+
107+
return $this->getDefaultViewMode();
108+
}
109+
110+
/**
111+
* Set the view mode
112+
*
113+
* @param string $name
114+
*
115+
* @return $this
116+
*/
117+
public function setViewMode(string $name): static
118+
{
119+
$this->populate([$this->getViewModeParam() => $name]);
120+
121+
return $this;
122+
}
123+
124+
/**
125+
* Set callback to protect ids with
126+
*
127+
* @param callable $protector
128+
*
129+
* @return $this
130+
*/
131+
public function setIdProtector(callable $protector): static
132+
{
133+
$this->protector = $protector;
134+
135+
return $this;
136+
}
137+
138+
private function protectId($id)
139+
{
140+
if (is_callable($this->protector)) {
141+
return call_user_func($this->protector, $id);
142+
}
143+
144+
return $id;
145+
}
146+
147+
protected function assemble(): void
148+
{
149+
$viewModeParam = $this->getViewModeParam();
150+
151+
$this->addElement($this->createUidElement());
152+
$this->addElement(new HiddenElement($viewModeParam));
153+
154+
foreach (static::$viewModes as $viewMode => $icon) {
155+
$protectedId = $this->protectId('view-mode-switcher-' . $icon);
156+
$input = new InputElement($viewModeParam, [
157+
'class' => 'autosubmit',
158+
'id' => $protectedId,
159+
'name' => $viewModeParam,
160+
'type' => 'radio',
161+
'value' => $viewMode
162+
]);
163+
$input->getAttributes()->registerAttributeCallback('checked', function () use ($viewMode) {
164+
return $viewMode === $this->getViewMode();
165+
});
166+
167+
$label = new HtmlElement(
168+
'label',
169+
Attributes::create([
170+
'for' => $protectedId
171+
]),
172+
new IcingaIcon($icon)
173+
);
174+
$label->getAttributes()->registerAttributeCallback('title', function () use ($viewMode) {
175+
return $this->getTitle($viewMode);
176+
});
177+
178+
$this->addHtml($input, $label);
179+
}
180+
}
181+
182+
/**
183+
* Return the title for the view mode when it is active and inactive
184+
*
185+
* @param string $viewMode
186+
*
187+
* @return string Title for the view mode when it is active and inactive
188+
*/
189+
protected function getTitle(string $viewMode): string
190+
{
191+
$active = null;
192+
$inactive = null;
193+
switch ($viewMode) {
194+
case 'minimal':
195+
$active = t('Minimal view active');
196+
$inactive = t('Switch to minimal view');
197+
break;
198+
case 'common':
199+
$active = t('Common view active');
200+
$inactive = t('Switch to common view');
201+
break;
202+
case 'detailed':
203+
$active = t('Detailed view active');
204+
$inactive = t('Switch to detailed view');
205+
break;
206+
}
207+
208+
return $viewMode === $this->getViewMode() ? $active : $inactive;
209+
}
210+
}

0 commit comments

Comments
 (0)