diff --git a/scss/_logger.scss b/scss/_logger.scss new file mode 100644 index 000000000..bc2da384a --- /dev/null +++ b/scss/_logger.scss @@ -0,0 +1,57 @@ +.logger-toast { + border-radius: 0.5em; + box-shadow: 0 0 8px #888; + padding: 1em; + right: 0; + left: 0; + margin-right: auto; + margin-left: auto; + text-align: center; + position: fixed; + z-index: 999; + display: inline-block; + max-width: 90%; + bottom: 2.5rem; +} + +.logger-primary { + fill: #084298; + color: #084298; + background-color: #cfe2ff; + border-color: #b6d4fe; +} + +.logger-success { + fill: #0f5132; + color: #0f5132; + background-color: #d1e7dd; + border-color: #badbcc; +} + +.logger-info { + fill: #055160; + color: #055160; + background-color: #cff4fc; + border-color: #b6effb; +} + +.logger-warning { + fill: #664d03; + color: #664d03; + background-color: #fff3cd; + border-color: #ffecb5; +} + +.logger-danger { + fill: #842029; + color: #842029; + background-color: #f8d7da; + border-color: #f5c2c7; +} + +.logger-light { + fill: #636464; + color: #636464; + background-color: #fefefe; + border-color: #fdfdfe; +} \ No newline at end of file diff --git a/scss/origo.scss b/scss/origo.scss index adef8d848..3b2003b57 100644 --- a/scss/origo.scss +++ b/scss/origo.scss @@ -49,6 +49,7 @@ @import 'scalepicker'; @import 'embedded-overlay'; @import 'spinner'; + @import 'logger'; } html, diff --git a/src/components/logger.js b/src/components/logger.js new file mode 100644 index 000000000..4b603de2b --- /dev/null +++ b/src/components/logger.js @@ -0,0 +1,109 @@ +import { Icon, Component, Modal } from '../ui'; + +let viewer; +let defaults = { + toast: { + status: 'light', + title: 'Meddelande', + duration: 5000 + }, + modal: { + status: 'light', + title: 'Meddelande', + duration: 0 + } +}; + +function getClass(status) { + let cls; + if (status === 'primary') { + cls = 'logger-primary'; + } else if (status === 'success') { + cls = 'logger-success'; + } else if (status === 'info') { + cls = 'logger-info'; + } else if (status === 'warning') { + cls = 'logger-warning'; + } else if (status === 'danger') { + cls = 'logger-danger'; + } else { + cls = 'logger-light'; + } + return cls; +} + +const createModal = function createModal(options) { + const modalSettings = { ...defaults.modal, ...options }; + const { + title = '', + message = '', + duration, + status + } = modalSettings; + const contentCls = getClass(status); + + let modal = Modal({ + title, + content: message, + target: viewer.getId(), + contentCls + }); + + if (duration && duration > 0) { + setTimeout(() => { + modal.closeModal(); + modal = null; + }, duration); + } +}; + +const createToast = function createToast(options = {}) { + const toastSettings = { ...defaults.toast, ...options }; + const { + status, + duration, + icon, + title = '', + message = '' + } = toastSettings; + + const contentCls = getClass(status); + const toast = document.createElement('div'); + const parentElement = document.getElementById(viewer.getId()); + parentElement.appendChild(toast); + toast.classList.add('logger-toast'); + toast.classList.add(contentCls); + + const content = ` +
+ + ${icon ? Icon({ icon, cls: `${contentCls} icon-medium`, style: 'vertical-align:bottom' }).render() : ''} + + ${title} +
+ ${message} + `; + toast.innerHTML = content; + + setTimeout(() => { + toast.parentNode.removeChild(toast); + }, duration > 0 ? duration : 5000); +}; + +const Logger = function Logger(options = {}) { + defaults = { ...defaults, ...options }; + return Component({ + name: 'logger', + createModal, + createToast, + onAdd(evt) { + viewer = evt.target; + this.render(); + }, + render() { + this.dispatch('render'); + } + }); +}; + +export default Logger; diff --git a/src/ui/modal.js b/src/ui/modal.js index 6ab2a3952..54bf41049 100644 --- a/src/ui/modal.js +++ b/src/ui/modal.js @@ -25,6 +25,7 @@ export default function Modal(options = {}) { contentElement, contentCmp, cls = '', + contentCls = '', isStatic = options.static, target, closeIcon = '#ic_close_24px', @@ -139,7 +140,7 @@ export default function Modal(options = {}) { } return `
${screenEl.render()} -
+
${headerEl.render()} ${contentEl.render()}
diff --git a/src/viewer.js b/src/viewer.js index 49b331477..4dc16a4f8 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -18,6 +18,7 @@ import flattenGroups from './utils/flattengroups'; import getcenter from './geometry/getcenter'; import isEmbedded from './utils/isembedded'; import generateUUID from './utils/generateuuid'; +import Logger from './components/logger'; import permalink from './permalink/permalink'; import Stylewindow from './style/stylewindow'; @@ -54,6 +55,7 @@ const Viewer = function Viewer(targetOption, options = {}) { source = {}, clusterOptions = {}, tileGridOptions = {}, + loggerOptions = {}, url, palette } = options; @@ -105,6 +107,7 @@ const Viewer = function Viewer(targetOption, options = {}) { const footer = Footer({ data: footerData }); + const logger = Logger(loggerOptions); const centerMarker = CenterMarker(); let mapSize; @@ -527,6 +530,10 @@ const Viewer = function Viewer(targetOption, options = {}) { return urlParams; }; + const getLogger = function getLogger() { + return logger; + }; + /** * Internal helper used when urlParams.feature is set and the popup should be displayed. * @param {any} feature @@ -588,6 +595,7 @@ const Viewer = function Viewer(targetOption, options = {}) { this.addComponent(selectionmanager); this.addComponent(featureinfo); this.addComponent(centerMarker); + this.addComponent(logger); this.addControls(); @@ -718,7 +726,8 @@ const Viewer = function Viewer(targetOption, options = {}) { getEmbedded, permalink, generateUUID, - centerMarker + centerMarker, + getLogger }); };