Skip to content

Commit

Permalink
Merge pull request #4946 from camptocamp/GEO-1965
Browse files Browse the repository at this point in the history
Add WMS layer support for the disclaimer service
  • Loading branch information
fredj committed Jun 25, 2019
2 parents 247533e + 5d2cacc commit f203c01
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 58 deletions.
115 changes: 79 additions & 36 deletions contribs/gmf/src/disclaimer/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,6 @@ const module = angular.module('gmfDisclaimer', [
]);


/**
*
* @param {import("ol/layer/Base.js").default} layer Layer
* @param {function(string):void} func Function
*/
function forEachDisclaimer(layer, func) {
const disclaimers = layer.get('disclaimers');
if (disclaimers && Array.isArray(disclaimers)) {
disclaimers.forEach(func);
}
}


/**
* Used metadata:
*
Expand Down Expand Up @@ -219,30 +206,23 @@ DisclaimerController.prototype.registerLayer_ = function(layer) {

if (this.layerVisibility) {
// Show disclaimer messages for this layer
forEachDisclaimer(layer, (disclaimer) => {
if (layer.getVisible()) {
this.showDisclaimerMessage_(disclaimer);
}
});
if (layer.getVisible()) {
this.update_(layer);
} else {
this.closeAll_(layer);
}

const listenerKey = olEvents.listen(layer, 'change:visible', (event) => {
const layer = event.target;
const listenerKey = olEvents.listen(layer, 'change', (event) => {
if (layer.getVisible()) {
forEachDisclaimer(layer, (disclaimer) => {
this.showDisclaimerMessage_(disclaimer);
});
this.update_(layer);
} else {
forEachDisclaimer(layer, (disclaimer) => {
this.closeDisclaimerMessage_(disclaimer);
});
this.closeAll_(layer);
}
});
this.eventHelper_.addListenerKey(layerUid, listenerKey);
} else {
// Show disclaimer messages for this layer
forEachDisclaimer(layer, (disclaimer) => {
this.showDisclaimerMessage_(disclaimer);
});
this.showAll_(layer);
}
}
};
Expand All @@ -265,11 +245,8 @@ DisclaimerController.prototype.unregisterLayer_ = function(layer) {
layer.getLayers().forEach(layer => this.unregisterLayer_(layer));

} else {

// Close disclaimer messages for this layer
forEachDisclaimer(layer, (disclaimer) => {
this.closeDisclaimerMessage_(disclaimer);
});
// Close all disclaimer messages for this layer
this.closeAll_(layer);
}

};
Expand All @@ -281,10 +258,11 @@ DisclaimerController.prototype.$onDestroy = function() {


/**
* @param {string} layerUid Layer identifier.
* @param {string} msg Disclaimer message.
* @private
*/
DisclaimerController.prototype.showDisclaimerMessage_ = function(msg) {
DisclaimerController.prototype.showDisclaimerMessage_ = function(layerUid, msg) {
msg = this.gettextCatalog_.getString(msg);
if (this.external) {
if (this.msgs_.indexOf(msg) < 0) {
Expand All @@ -296,6 +274,7 @@ DisclaimerController.prototype.showDisclaimerMessage_ = function(msg) {
this.disclaimer_.alert({
popup: this.popup,
msg: msg,
layerUid: layerUid,
target: this.element_,
type: MessageType.WARNING
});
Expand All @@ -304,10 +283,73 @@ DisclaimerController.prototype.showDisclaimerMessage_ = function(msg) {


/**
* @param {import("ol/layer/Base.js").default} layer Layer
* @private
*/
DisclaimerController.prototype.closeAll_ = function(layer) {
const disclaimers = layer.get('disclaimers');
if (disclaimers) {
const layerUid = olUtilGetUid(layer);
for (const key in disclaimers) {
const uid = `${layerUid}-${key}`;
this.closeDisclaimerMessage_(uid, disclaimers[key]);
}
}
};


/**
* @param {import("ol/layer/Base.js").default} layer Layer
* @private
*/
DisclaimerController.prototype.showAll_ = function(layer) {
const disclaimers = layer.get('disclaimers');
if (disclaimers) {
const layerUid = olUtilGetUid(layer);
for (const key in disclaimers) {
const uid = `${layerUid}-${key}`;
this.showDisclaimerMessage_(uid, disclaimers[key]);
}
}
};


/**
* @param {import("ol/layer/Base.js").default} layer Layer
* @private
*/
DisclaimerController.prototype.update_ = function(layer) {
const disclaimers = layer.get('disclaimers');
if (disclaimers) {
if ('all' in disclaimers) {
// the disclaimer is for all the layers, WMS or WMTS.
console.assert(Object.keys(disclaimers).length === 1);
this.showAll_(layer);
} else {
const layerWMS = /** @type {import("ol/layer/Layer.js").default} */ (layer);
const sourceWMS = /** @type {import("ol/source/ImageWMS.js").default} */ (layerWMS.getSource());
if (sourceWMS.getParams) {
const layers = sourceWMS.getParams()['LAYERS'];
const layerUid = olUtilGetUid(layer);
for (const key in disclaimers) {
const uid = `${layerUid}-${key}`;
if (layers.indexOf(key) !== -1) {
this.showDisclaimerMessage_(uid, disclaimers[key]);
} else {
this.closeDisclaimerMessage_(uid, disclaimers[key]);
}
}
}
}
}
};

/**
* @param {string} layerUid Layer identifier.
* @param {string} msg Disclaimer message.
* @private
*/
DisclaimerController.prototype.closeDisclaimerMessage_ = function(msg) {
DisclaimerController.prototype.closeDisclaimerMessage_ = function(layerUid, msg) {
msg = this.gettextCatalog_.getString(msg);
if (this.external) {
this.visibility = false;
Expand All @@ -317,6 +359,7 @@ DisclaimerController.prototype.closeDisclaimerMessage_ = function(msg) {
this.disclaimer_.close({
popup: this.popup,
msg: msg,
layerUid: layerUid,
target: this.element_,
type: MessageType.WARNING
});
Expand Down
12 changes: 9 additions & 3 deletions contribs/gmf/src/layertree/SyncLayertreeMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ SyncLayertreeMap.prototype.createWMTSLayer_ = function(gmfLayerWMTS) {

/**
* Update properties of a layer with the node of a given leafNode.
* @param {import('gmf/themes.js').GmfLayer} leafNode a leaf node.
* @param {import('gmf/themes.js').GmfLayer|import('gmf/themes.js').GmfLayerWMS} leafNode a leaf node.
* @param {import("ol/layer/Base.js").default} layer A layer.
* @private
*/
Expand All @@ -356,8 +356,14 @@ SyncLayertreeMap.prototype.updateLayerReferences_ = function(leafNode, layer) {

const disclaimer = leafNode.metadata.disclaimer;
if (disclaimer) {
const disclaimers = layer.get('disclaimers') || [];
disclaimers.push(leafNode.metadata.disclaimer);
const disclaimers = layer.get('disclaimers') || {};

// 'all' means that the disclaimer is for all the layer.
let layers = 'all';
if ('layers' in leafNode) {
layers = /** @type {import('gmf/themes.js').GmfLayerWMS} */ (leafNode).layers;
}
disclaimers[layers] = leafNode.metadata.disclaimer;
layer.set('disclaimers', disclaimers);
}
};
Expand Down
93 changes: 75 additions & 18 deletions src/message/Disclaimer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ import ngeoMessageMessage, {MessageType} from 'ngeo/message/Message.js';
import 'ngeo/sass/font.scss';


/**
* A message to display by the disclaimer service.
*
* @typedef {Object} Message
* @property {number} [delay=7000] The delay in milliseconds the message is shown
* @property {boolean} [popup=false] Whether the message should be displayed inside a popup window or not.
* @property {string} msg The message text to display.
* @property {string} [layerUid] The OpenLayers layer identifier.
* @property {JQuery|Element|string} [target] The target element (or selector to get the element) in which
* to display the message. If not defined, then the default target of the notification service is used.
* @property {string} [type='info'] The type of message.
*/


/**
* Provides methods to display any sort of messages, disclaimers, errors,
* etc. Requires Bootstrap library (both CSS and JS) to display the alerts
Expand Down Expand Up @@ -55,12 +69,24 @@ export class MessageDisclaimerService extends ngeoMessageMessage {
* @private
*/
this.messages_ = {};

/**
* @type {Object<string, number>}
* @private
*/
this.messagesConsumerCount_ = {};

/**
* @type {Object<string, boolean>}
* @private
*/
this.uids_ = {};
}

/**
* Show disclaimer message string or object or list of disclaimer message
* strings or objects.
* @param {string|import('ngeo/message/Message.js').Message|Array.<string|import('ngeo/message/Message.js').Message>}
* @param {string|Message|Array.<string|Message>}
* object A message or list of messages as text or configuration objects.
*/
alert(object) {
Expand All @@ -70,17 +96,17 @@ export class MessageDisclaimerService extends ngeoMessageMessage {
/**
* Close disclaimer message string or object or list of disclaimer message
* strings or objects.
* @param {string|import('ngeo/message/Message.js').Message|Array.<string|import('ngeo/message/Message.js').Message>}
* @param {string|Message|Array.<string|Message>}
* object A message or list of messages as text or configuration objects.
*/
close(object) {
const msgObjects = this.getMessageObjects(object);
msgObjects.forEach(this.closeMessage_, this);
msgObjects.forEach((message) => this.closeMessage_(message));
}

/**
* Show the message.
* @param {import('ngeo/message/Message.js').Message} message Message.
* @param {Message} message Message.
* @protected
* @override
*/
Expand All @@ -89,15 +115,15 @@ export class MessageDisclaimerService extends ngeoMessageMessage {
const type = message.type;
console.assert(typeof type == 'string', 'Type should be set.');

// No need to do anything if message already exist.
// No need to do anything if message already displayed.
const uid = this.getMessageUid_(message);
if (this.messages_[uid] !== undefined) {
if (this.uids_[uid]) {
return;
}

const showInPopup = message.popup === true;
this.uids_[uid] = true;

if (showInPopup) {
if (message.popup === true) {
// display the message in a popup, i.e. using the ngeo create popup
const popup = this.createPopup_();
const content = this.sce_.trustAsHtml(message.msg);
Expand All @@ -108,7 +134,7 @@ export class MessageDisclaimerService extends ngeoMessageMessage {
});

// Watch the open property
popup.scope.$watch('open', (newVal, oldVal) => {
popup.scope.$watch('open', newVal => {
if (!newVal) {
this.closeMessage_(message);
}
Expand All @@ -117,6 +143,14 @@ export class MessageDisclaimerService extends ngeoMessageMessage {
this.messages_[uid] = popup;

} else {
// get an already displayed compatible message.
const compatibleMessageUid = this.getCompatibleMessageUid_(message);
if (this.messages_[compatibleMessageUid]) {
// we already have a message
this.messagesConsumerCount_[compatibleMessageUid]++;
return;
}

// display the message using a bootstrap dismissible alert
const classNames = ['alert', 'fade', 'alert-dismissible', 'show'];
switch (type) {
Expand Down Expand Up @@ -158,36 +192,58 @@ export class MessageDisclaimerService extends ngeoMessageMessage {

// Listen when the message gets closed to cleanup the cache of messages
el.on('closed.bs.alert', () => {
this.closeMessage_(message);
this.closeMessage_(message, true);
});

this.messages_[uid] = el;
this.messages_[compatibleMessageUid] = el;
this.messagesConsumerCount_[compatibleMessageUid] = 1;
}
}

/**
* @param {import('ngeo/message/Message.js').Message} message Message.
* @param {Message} message Message.
* @return {string} The uid.
* @private
*/
getMessageUid_(message) {
return `${message.msg}-${message.type}-${message.layerUid}`;
}

/**
* @param {Message} message Message.
* @return {string} The uid.
* @private
*/
getCompatibleMessageUid_(message) {
return `${message.msg}-${message.type}`;
}

/**
* Close the message.
* @param {import('ngeo/message/Message.js').Message} message Message.
* @param {Message} message Message.
* @param {boolean} force Force close the message.
* @protected
*/
closeMessage_(message) {
closeMessage_(message, force = false) {
const uid = this.getMessageUid_(message);
const obj = this.messages_[uid];

// (1) No need to do anything if message doesn't exist
if (obj === undefined) {
if (!this.uids_[uid]) {
return;
}
delete this.uids_[uid];
const compatibleMessageUid = this.getCompatibleMessageUid_(message);
if (force) {
this.messagesConsumerCount_[compatibleMessageUid] = 0;
} else {
this.messagesConsumerCount_[compatibleMessageUid]--;
}
if (this.messagesConsumerCount_[compatibleMessageUid] > 0) {
// the message is still used
return;
}

const obj = this.messages_[compatibleMessageUid];

// (2) Close message (popup or alert)
if (obj instanceof MessagePopup) {
// (2.1) Close popup, if not already closed
Expand All @@ -205,7 +261,8 @@ export class MessageDisclaimerService extends ngeoMessageMessage {
}

// (3) Remove message from cache since it's closed now.
delete this.messages_[uid];
delete this.messages_[compatibleMessageUid];
delete this.messagesConsumerCount_[compatibleMessageUid];
}
}

Expand Down

0 comments on commit f203c01

Please sign in to comment.