Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom CSS #45

Open
nmoreaud opened this issue Nov 28, 2019 · 7 comments
Open

Custom CSS #45

nmoreaud opened this issue Nov 28, 2019 · 7 comments

Comments

@nmoreaud
Copy link

Could you add an editor to add static CSS to the panel ?
Also, it could be nice to load js files from url (aka CDN, jquery-ui, bootstrap, or other things)
Thanks for your good work

@MarcusCalidus
Copy link
Owner

that's an interesting idea. I'll give thought to that. Thank you.

@MarcusCalidus
Copy link
Owner

You can load any js library you like via following script during onInit() like so:

//this example loads the moment.js library and prints the current timestamp into the browser's console

function injectScript(src) {
    return new Promise((resolve, reject) => {
        const script = document.createElement('script');
        script.async = true;
        script.src = src;
        script.addEventListener('load', resolve);
        script.addEventListener('error', () => reject('Error loading script.'));
        script.addEventListener('abort', () => reject('Script loading aborted.'));
        document.head.appendChild(script);
    });
}

injectScript('https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js')
    .then(() => {
        console.log('Script loaded!');
        console.log(moment().format());
    }).catch(error => {
        console.log(error);
    });

@MarcusCalidus
Copy link
Owner

to inject custom css you can do the following inside onInit()

function addCss(rule) {
  let css = document.createElement('style');
  css.type = 'text/css';
  if (css.styleSheet) css.styleSheet.cssText = rule; // Support for IE
  else css.appendChild(document.createTextNode(rule)); // Support for the rest
  document.getElementsByTagName("head")[0].appendChild(css);
}


// CSS rules
let rule  = '.red {background-color: red}';
    rule += '.blue {background-color: blue}';

addCss(rule);

be aware though, that the above script will add the css node multiple times. One time for every created control. You could tweak the routine to detect if the given node was already added by maybe setting a global variable in window or similar hack.

@nmoreaud
Copy link
Author

Thanks for your response.
I currently use the init function to put all shared generic code between panels, that way I can copy-paste it.
Ex : open modals, tooltips, etc.
I use the same trick as you to add custom CSS.

(function() {
	"use strict";
	
	// generic code (lib)
	
	// All temporary data should be stored in the controller to be able to display multiple panel.
	// Moreover, the front is an SPA, we don't want to share data between pages
	let lib = {};
	ctrl.companyscope = { lib: lib };
		
	lib.isLightColor = function(color) {
		let ctx = document.createElement("canvas").getContext("2d");
		ctx.fillStyle = color;
		let hexColor = ctx.fillStyle.replace("#", "");
		let r = parseInt(hexColor.substr(0,2),16);
		let g = parseInt(hexColor.substr(2,2),16);
		let b = parseInt(hexColor.substr(4,2),16);
		let yiq = ((r*299)+(g*587)+(b*114))/1000;
		return (yiq >= 128);
	};
	
	lib.showModal = function(title, description) {
		// Grafana uses SystemJs to share it's typescript SDK : https://grafana.com/docs/plugins/developing/development/#buildscript
		// We use appEvents pour display a modal : https://github.com/grafana/grafana/blob/e9d5e037e817b57303c4497b42b28ee9403dd65f/public/app/features/alerting/alert_list_ctrl.ts#L64
		System.import('app/core/core').then(function(core) {
			// https://github.com/grafana/grafana/blob/master/public/app/features/alerting/partials/alert_howto.html
			const modalHtml = `
			<div class="modal-body">
				<div class="modal-header">
					<h2 class="modal-header-title">
						<i class="fa fa-info-circle"></i>
						<span class="p-l-1">${title}</span>
					</h2>

					<a class="modal-header-close" ng-click="dismiss();">
						<i class="fa fa-remove"></i>
					</a>
				</div>

				<div class="modal-content">
					<p class="p-a-2 text-center offset-lg-1 col-lg-10">
						${description}
					</p>
				</div>
			</div>
			`;

			core.appEvents.emit('show-modal', {
				modalClass: 'modal--narrow',
				templateHtml: modalHtml,
				model: {}
			});
		});
	};

	lib.zabbixSeverityToColor = function(severity) {
	    if (severity === 'Not classified') {
	        return 'YellowGreen';
	    }
		if (severity === 'Information') {
			return 'MediumTurquoise';
		}
		else if (severity === 'Warning') {
			return 'orange';
		}
		else if (severity === 'Average') {
		    return 'gold';
		}
		else if (severity === 'High' || severity == 'Disaster') {
			return 'red';
		}
		else {
			return 'green';
		}
	};
	
	lib.$tooltip = $('<div class="graph-tooltip">');
	lib.bindTooltipOnSvgHover = function(svgnode, genTooltipHTMLCallback) {
		svgnode.hover(function(e) {
			let html = genTooltipHTMLCallback(e);
			if (html !== null && html !== '') {
				lib.$tooltip
				  .html(html)
				  .place_tt(e.clientX + 20, e.clientY);
			}			
		}, function(e) {
            lib.$tooltip.detach();
		});
	};
	
	lib.makeTooltipsFollowMouse = function() {
		svgnode.onmousemove = function(e) {
			if (document.contains(lib.$tooltip[0])) {
				lib.$tooltip.place_tt(e.clientX + 20, e.clientY);
			}
		};
	};
})();

@MarcusCalidus
Copy link
Owner

I see... so you still think it is necessary to add CSS and 3rdParty Library support inputs?

@nmoreaud
Copy link
Author

I think it would be great addition.
With 3rd party JS support, I could host a lib somewhere and when I update it every panel would be updated as well.
CSS panel/file is just to separate contents, though for big stylesheets it would improve readability.

@MarcusCalidus
Copy link
Owner

acknowledged ... I'll see what I can do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants