diff --git a/application/controllers/StaticController.php b/application/controllers/StaticController.php new file mode 100644 index 00000000..882184ec --- /dev/null +++ b/application/controllers/StaticController.php @@ -0,0 +1,57 @@ +_helper->viewRenderer->setNoRender(true); + $this->_helper->layout()->disableLayout(); + } + + public function indexAction() + { + $moduleRoot = $this->Module()->getBaseDir(); + + $file = $this->getParam('file'); + $filePath = realpath($moduleRoot . '/public/' . rawurldecode($file)); + + if ($filePath === false) { + $this->httpNotFound('%s does not exist', $filePath); + } + + $s = stat($filePath); + $eTag = sprintf('%x-%x-%x', $s['ino'], $s['size'], (float) str_pad($s['mtime'], 16, '0')); + + $this->getResponse()->setHeader( + 'Cache-Control', + 'public, max-age=1814400, stale-while-revalidate=604800', + true + ); + + if ($this->getRequest()->getServer('HTTP_IF_NONE_MATCH') === $eTag) { + $this->getResponse() + ->setHttpResponseCode(304); + } else { + $this->getResponse() + ->setHeader('ETag', $eTag) + ->setHeader('Content-Type', mime_content_type($filePath), true) + ->setHeader('Last-Modified', gmdate('D, d M Y H:i:s', $s['mtime']) . ' GMT'); + + readfile($filePath); + } + } +} diff --git a/configuration.php b/configuration.php index 153eec31..7085c651 100644 --- a/configuration.php +++ b/configuration.php @@ -88,6 +88,7 @@ namespace Icinga\Module\Icingadb $this->provideCssFile('lists.less'); $this->provideCssFile('mixins.less'); $this->provideCssFile('widgets.less'); + $this->provideCssFile('icinga-icons.less'); $this->provideJsFile('action-list.js'); $this->provideJsFile('migrate.js'); diff --git a/library/Icingadb/Widget/IcingaIcon.php b/library/Icingadb/Widget/IcingaIcon.php new file mode 100644 index 00000000..fd93e474 --- /dev/null +++ b/library/Icingadb/Widget/IcingaIcon.php @@ -0,0 +1,29 @@ +. The given + * name will be used as automatically added CSS class for the icon element in the format 'iicon-$name'. In addition, + * the CSS class 'icon' will be automatically added too. + * + * @param string $name The name of the icon + * @param Attributes|array $attributes The HTML attributes for the element + */ + public function __construct($name, $attributes = null) + { + $this + ->getAttributes() + ->add('class', ['icon', "iicon-$name"]) + ->add($attributes); + } +} diff --git a/library/Icingadb/Widget/ViewModeSwitcher.php b/library/Icingadb/Widget/ViewModeSwitcher.php index 5a8a5c74..7d8712f1 100644 --- a/library/Icingadb/Widget/ViewModeSwitcher.php +++ b/library/Icingadb/Widget/ViewModeSwitcher.php @@ -5,7 +5,6 @@ namespace Icinga\Module\Icingadb\Widget; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; use ipl\Web\Url; -use ipl\Web\Widget\Icon; use ipl\Web\Widget\Link; class ViewModeSwitcher extends BaseHtmlElement @@ -14,9 +13,9 @@ class ViewModeSwitcher extends BaseHtmlElement /** @var array View mode-icon pairs */ public static $viewModes = [ - 'minimal' => 'chat-empty', - 'common' => 'th-list', - 'detailed' => 'chat' + 'minimal' => 'minimal', + 'common' => 'default', + 'detailed' => 'detailed' ]; /** @var Url */ @@ -76,7 +75,7 @@ class ViewModeSwitcher extends BaseHtmlElement foreach (static::$viewModes as $viewMode => $icon) { $url = $this->url->with($viewModeParam, $viewMode); - $link = Html::tag('li', new Link(new Icon($icon), $url)); + $link = Html::tag('li', new Link(new IcingaIcon($icon), $url)); if ($viewMode === $currentViewMode) { $link->getAttributes()->add('class', 'active'); diff --git a/public/css/icinga-icons.less b/public/css/icinga-icons.less new file mode 100644 index 00000000..770f72da --- /dev/null +++ b/public/css/icinga-icons.less @@ -0,0 +1,43 @@ +@font-face { + font-family: 'Icinga-Icons'; + src: url('../icingadb/static?file=font/Icinga-Icons.eot'); + src: url('../icingadb/static?file=font/Icinga-Icons.eot') format('embedded-opentype'), + url('../icingadb/static?file=font/Icinga-Icons.ttf') format('truetype'), + url('../icingadb/static?file=font/Icinga-Icons.woff') format('woff'), + url('../icingadb/static?file=font/Icinga-Icons.svg') format('svg'); + font-weight: normal; + font-style: normal; + font-display: block; +} + +[class^="iicon-"]:before, [class*=" iicon-"]:before { + /* use !important to prevent issues with browser extensions that change fonts */ + font-family: 'Icinga-Icons' !important; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1em; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + + display: inline-block; + text-decoration: inherit; + width: 1em; + margin-right: .2em; + text-align: center; +} + +.iicon-minimal:before { + content: "\e900"; +} +.iicon-detailed:before { + content: "\e901"; +} +.iicon-default:before { + content: "\e902"; +} diff --git a/public/css/module.less b/public/css/module.less index 39acdcde..556e6345 100644 --- a/public/css/module.less +++ b/public/css/module.less @@ -68,8 +68,12 @@ a { display: block; height: 100%; - padding: 0.5em 1em; + padding: .3em .6em; width: 100%; + + .icon:before { + font-size: 16px; // Pixels, because the glyphs get blurry otherwise + } } } } diff --git a/public/font/Icinga-Icons.eot b/public/font/Icinga-Icons.eot new file mode 100644 index 00000000..b492a29c Binary files /dev/null and b/public/font/Icinga-Icons.eot differ diff --git a/public/font/Icinga-Icons.svg b/public/font/Icinga-Icons.svg new file mode 100644 index 00000000..697a9514 --- /dev/null +++ b/public/font/Icinga-Icons.svg @@ -0,0 +1,13 @@ + + + +Generated by IcoMoon + + + + + + + + + \ No newline at end of file diff --git a/public/font/Icinga-Icons.ttf b/public/font/Icinga-Icons.ttf new file mode 100644 index 00000000..192416e1 Binary files /dev/null and b/public/font/Icinga-Icons.ttf differ diff --git a/public/font/Icinga-Icons.woff b/public/font/Icinga-Icons.woff new file mode 100644 index 00000000..f7617298 Binary files /dev/null and b/public/font/Icinga-Icons.woff differ