diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-14 13:21:16 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-14 13:21:16 +0000 |
commit | 2e582fe0b8b6a8e67982ddb84935db1bd3b401fe (patch) | |
tree | dd511b321f308264952cffb005a4288ea4e478e6 /public | |
parent | Initial commit. (diff) | |
download | icingaweb2-module-graphite-2e582fe0b8b6a8e67982ddb84935db1bd3b401fe.tar.xz icingaweb2-module-graphite-2e582fe0b8b6a8e67982ddb84935db1bd3b401fe.zip |
Adding upstream version 1.2.2.upstream/1.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'public')
-rw-r--r-- | public/css/module.less | 213 | ||||
-rw-r--r-- | public/js/module.js | 112 |
2 files changed, 325 insertions, 0 deletions
diff --git a/public/css/module.less b/public/css/module.less new file mode 100644 index 0000000..bb651e7 --- /dev/null +++ b/public/css/module.less @@ -0,0 +1,213 @@ +div.images { + h3 { + clear: both; + } + + img.svg { + float: left; + border: none; + } + +} + +div.images.object-detail-view { + display: block; + + img.graphiteImg { + width: 100%; + display: block; + } +} + +.timerangepicker-container { + display: flex; + padding: .25em 0; + + .button-link { + line-height: 1.75; + width: 2.25em; + + i { + display: inline-block; + width: 100%; + text-align: center; + } + + i:before { + margin-right: 0; + } + } +} + +form[name=form_timerangepickercommon_graphite] { + display: inline-flex; + flex: 1 1 auto; + width: 0; + max-width: 43.25em; + + &:not(:last-child) { + margin-right: .25em; + } + + select { + min-width: 3.5em; + max-width: 7em; + flex: 1 1 auto; + width: auto; + + &:not(:last-of-type) { + margin-right: .25em; + } + } +} + +form[name=form_timerangepickercustom_graphite] { + min-width: 21em; + + .control-label-group { + text-align: left; + } + + input[type=date] { + min-width: 11em; + } + + input[type=time] { + min-width: 5em; + } +} + +.flyover[id^="graphite-customrange-"] { + display: inline-block; +} + +.grid { + margin-right: -1em; + margin-bottom: -1em; + + .empty-state { + .rounded-corners(); + background-color: @gray-lightest; + margin-right: 1em; + padding: 1em; + text-align: center; + } +} + +.grid-item { + display: inline-block; + border-radius: .25em; + border: 1px solid @gray-lighter; + min-width: 302px; + vertical-align: top; + margin-right: 1em; + margin-bottom: 1em; +} + +.grid-item h2 { + margin-top: 0; + background: @gray-lightest; + border-bottom: 1px solid @gray-lighter; + padding:.25em .5em; + max-width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.grid-item > .images:not(:last-child) { + margin-right: 1em; + display: inline-block; +} + +.grid-item .graphiteImg { + margin-right: 1px; +} + +.grid-item > p { + padding: .5em; + margin-bottom: 0; +} + +p.load-more { + margin-right: 1em; + text-align: right; +} + +// TODO: Remove once ipl-web v0.7.0 is required +.controls:not(.default-layout) { + .box-shadow(0, 0, 0, 1px, @gray-lighter); + + .pagination-control { + float: left; + } + + .sort-control, + .limit-control { + float: right; + margin-left: .5em; + } + + .sort-control { + display: flex; + justify-content: flex-end; + + :not(.form-element) > label { + margin-right: 0; + } + + .control-button { + margin: 0; + } + } + + > :not(:only-child) { + margin-bottom: 0.5em; + } + + .search-suggestions { + margin-bottom: 2.5em; + } + + .search-controls, + .filter { + clear: both; + display: flex; + min-width: 100%; + + .search-bar { + flex: 1 1 auto; + + & ~ .control-button:last-child { + margin-right: -.5em; + } + + & ~ .control-button { + margin-left: .5em; + } + } + } +} + +/* Graph colors */ + +@graphite-graph-bg-color: @body-bg-color; +@graphite-graph-fg-color: @text-color; +@graphite-graph-major-grid-color: @gray-light; +@graphite-graph-minor-grid-color: @graphite-graph-bg-color; + +@light-mode: { + --graphite-graph-bg-color: var(--body-bg-color); + --graphite-graph-fg-color: var(--text-color); + --graphite-graph-major-grid-color: var(--gray-light); + --graphite-graph-minor-grid-color: var(--graphite-graph-bg-color); +}; + +.graphite-graph-color-registry { + display: none; + + background-color: @graphite-graph-bg-color; + color: @graphite-graph-fg-color; + border-top-color: @graphite-graph-major-grid-color; + border-bottom-color: @graphite-graph-minor-grid-color; +} diff --git a/public/js/module.js b/public/js/module.js new file mode 100644 index 0000000..a2a32f2 --- /dev/null +++ b/public/js/module.js @@ -0,0 +1,112 @@ +/* Icinga Web 2 | (c) 2022 Icinga GmbH | GPLv2+ */ + +(function(Icinga) { + + "use strict"; + + class Graphite extends Icinga.EventListener { + constructor(icinga) { + super(icinga); + + this._colorParams = null; + this._resizeTimer = null; + this._onResizeBound = this.onResize.bind(this); + this._onModeChangeBound = this.onModeChange.bind(this); + this._mediaQueryList = window.matchMedia('(prefers-color-scheme: light)'); + + this.on('css-reloaded', 'head', this.onCssReloaded, this); + this.on('rendered', '#main > .container', this.onRendered, this); + window.addEventListener('resize', this._onResizeBound, { passive: true }); + this._mediaQueryList.addEventListener('change', this._onModeChangeBound, { passive: true }); + } + + get colorParams() { + if (this._colorParams === null) { + let colorRegistry = document.querySelector('.graphite-graph-color-registry'); + let registryStyle = window.getComputedStyle(colorRegistry); + + this._colorParams = { + bgcolor: this.rgbToHex(registryStyle.backgroundColor, 'black'), + fgcolor: this.rgbToHex(registryStyle.color, 'white'), + majorGridLineColor: this.rgbToHex(registryStyle.borderTopColor, '0000003F'), + minorGridLineColor: this.rgbToHex(registryStyle.borderBottomColor, 'black') + }; + } + + return this._colorParams; + } + + unbind(emitter) { + super.unbind(emitter); + + window.removeEventListener('resize', this._onResizeBound); + this._mediaQueryList.removeEventListener('change', this._onModeChangeBound); + + this._onResizeBound = null; + this._onModeChangeBound = null; + this._mediaQueryList = null; + } + + onCssReloaded(event) { + let _this = event.data.self; + + _this._colorParams = null; + _this.updateImages(document); + } + + onRendered(event, autorefresh, scripted, autosubmit) { + let _this = event.data.self; + let container = event.target; + + _this.updateImages(container); + } + + onResize() { + // Images are not updated instantly, the user might not yet be finished resizing the window + if (this._resizeTimer !== null) { + clearTimeout(this._resizeTimer); + } + + this._resizeTimer = setTimeout(() => this.updateImages(document), 200); + } + + onModeChange() { + this._colorParams = null; + this.updateImages(document); + } + + updateImages(container) { + container.querySelectorAll('img.graphiteImg[data-actualimageurl]').forEach(img => { + let params = { ...this.colorParams }; // Theming ftw! + params.r = (new Date()).getTime(); // To bypass the browser cache + params.width = img.scrollWidth; // It's either fixed or dependent on parent width + + img.src = this.icinga.utils.addUrlParams(img.dataset.actualimageurl, params); + }); + } + + rgbToHex(rgb, def) { + if (! rgb) { + return def; + } + + let match = rgb.match(/rgba?\((\d+), (\d+), (\d+)(?:, ([\d.]+))?\)/); + if (match === null) { + return def; + } + + let alpha = ''; + if (typeof match[4] !== 'undefined') { + alpha = Math.round(parseFloat(match[4]) * 255).toString(16); + } + + return parseInt(match[1], 10).toString(16).padStart(2, '0') + + parseInt(match[2], 10).toString(16).padStart(2, '0') + + parseInt(match[3], 10).toString(16).padStart(2, '0') + + alpha; + } + } + + Icinga.Behaviors.Graphite = Graphite; + +})(Icinga); |