Skip to content

Commit

Permalink
Merge pull request #1741 from AlexanderGeere/hide-layer-zoomBtn
Browse files Browse the repository at this point in the history
Layer View: Hide zoom button
  • Loading branch information
RobAndrewHurst authored Nov 26, 2024
2 parents c0252e1 + bbd9c43 commit 500e237
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 44 deletions.
147 changes: 107 additions & 40 deletions lib/ui/layers/view.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ The layerView method will create and assign a layer.view node to the layer objec
@param {layer} layer A decorated mapp layer.
@property {Object} layer.view No layer view will be created with the view property null.
@property {Object} layer.drawer The layer view will not be in a drawer element with the drawer property null.
@property {array} [layer.panelOrder=['draw-drawer', 'dataviews-drawer', 'filter-drawer', 'style-drawer', 'meta']] The order of layer view panel elements.
@returns {layer} The layer object is returned after the layer view has been created.
*/
Expand All @@ -86,32 +85,18 @@ export default function layerView(layer) {
data-id=${layer.key}
class="layer-view">`

// Create content from layer view panels and plugins
const content = Object.keys(layer)
.map(key => mapp.ui.layers.panels[key] && mapp.ui.layers.panels[key](layer))
.filter(panel => typeof panel !== 'undefined')

// Set default order for panel if not explicit in layer config.
layer.panelOrder ??= ['draw-drawer', 'dataviews-drawer', 'filter-drawer', 'style-drawer', 'meta']

// Sort the content array according to the data-id in the panelOrder array.
content.sort((a, b) => {

return layer.panelOrder.findIndex(chk => chk === a.dataset?.id)
< layer.panelOrder.findIndex(chk => chk === b.dataset?.id)
? 1 : -1;
})
viewConfig(layer)

// Don't create a drawer element layer view.
if (layer.drawer === null) {

// Append elements directly to layer.view
content.forEach(el => layer.view.append(el))
layer.viewConfig.content.forEach(el => layer.view.append(el))

return layer;
}

layer.zoomToExtentBtn = layer.filter.zoomToExtent
layer.zoomToExtentBtn = layer.viewConfig.zoomToExtentBtn
&& mapp.utils.html`<button
data-id=zoomToExtent
title=${mapp.dictionary.layer_zoom_to_extent}
Expand All @@ -128,17 +113,18 @@ export default function layerView(layer) {
const displayToggleClass = `mask-icon toggle ${(layer.zoomDisplay || layer.display) ? 'on' : ''}`

// Create layer.displayToggle button for header.
layer.displayToggle = mapp.utils.html.node`<button
data-id=display-toggle
title=${mapp.dictionary.layer_visibility}
class=${displayToggleClass}
onclick=${e => {
const toggle = e.target.classList.toggle('on')
toggle ? layer.show() : layer.hide()
}}>`
layer.displayToggle = layer.viewConfig.displayToggle
&& mapp.utils.html.node`<button
data-id=display-toggle
title=${mapp.dictionary.layer_visibility}
class=${displayToggleClass}
onclick=${e => {
const toggle = e.target.classList.toggle('on')
toggle ? layer.show() : layer.hide()
}}>`

// Create a div for the magnifying glass icon
layer.zoomBtn = layer.tables
layer.zoomBtn = layer.viewConfig.zoomBtn
&& mapp.utils.html.node`<button
data-id="zoom-to"
title=${mapp.dictionary.zoom_to}
Expand All @@ -157,20 +143,17 @@ export default function layerView(layer) {

const header = mapp.utils.html`
<h2>${layer.name || layer.key}</h2>
${layer.zoomToExtentBtn}
${layer.displayToggle}
${layer.zoomBtn}
${layer.zoomToExtentBtn || ''}
${layer.displayToggle || ''}
${layer.zoomBtn || ''}
<div class="mask-icon expander"></div>`

// An empty drawer element can not be expanded.
const drawerClass = `layer-view raised ${layer.classList || ''} ${content.length ? '' : 'empty'}`

layer.drawer = mapp.ui.elements.drawer({
data_id: layer.key,
class: drawerClass,
class: layer.viewConfig.classList,
header,
content
})
content: layer.viewConfig.content
})

// Render layer.drawer into layer.view
mapp.utils.render(layer.view, layer.drawer)
Expand All @@ -182,6 +165,90 @@ export default function layerView(layer) {
return layer
}

/**
@function viewConfig
@description
The viewConfig method will create viewConfig object and update the configuration from legacy properties.
The method will iterate through the panelOrder keys to add panel to the content array.
@param {layer} layer A decorated mapp layer.
@property {Object} [layer.viewConfig] Control options for elements in the layer.view.
@property {Boolean} [viewConfig.displayToggle=true] Controls whether the layer toggle close is displayed.
@property {Boolean} [viewConfig.zoomBtn=true] Controls whether the zoom magnifying glas is displayed.
@property {Boolean} [layer.zoomBtn] Legacy property for viewConfig.zoomBtn.
@property {Array} [layer.tables] Array of data tables for different zoom level.
@property {Boolean} [viewConfig.zoomToExtentBtn=true] Controls whether the zoom to extent button is displayed.
@property {Array} [viewConfig.panelOrder=['draw-drawer', 'dataviews-drawer', 'filter-drawer', 'style-drawer', 'meta']] Controls which panels are added to the view and in which order, will be assigned from layer.panelOrder if not explicit.
@property {Array} [layer.panelOrder] Legacy configuration for viewConfig.panelOrder.
@property {string} [viewConfig.classList] Classlist string to be added to layer-view drawer element classList.
@property {string} [layer.classList] Legacy property for viewConfig.classList.
*/
function viewConfig(layer) {

layer.viewConfig ??= {
displayToggle: true,
zoomBtn: true,
zoomToExtentBtn: true
}

// Zoom to extent must be enabled in the layer.filter config.
if (!layer.filter.zoomToExtent) {
delete layer.viewConfig.zoomToExtentBtn
}

// The zoomBtn should not be created.
if (layer.zoomBtn === false) {
delete layer.viewConfig.zoomBtn
delete layer.zoomBtn
}

// The zoomBtn is not possible without a tables config.
if (!layer.tables) {
delete layer.viewConfig.zoomBtn
}

// Assign viewConfig.panelOrder from legacy JSON layer config.
layer.viewConfig.panelOrder ??= layer.panelOrder

// Delete legacy panelOrder config
delete layer.panelOrder

if (!Array.isArray(layer.viewConfig.panelOrder)) {

// Assign default panelOrder if not a config array.
layer.viewConfig.panelOrder = ['draw-drawer', 'dataviews-drawer', 'filter-drawer', 'style-drawer', 'meta']
}

// Create content from layer view panels and plugins
layer.viewConfig.content = Object.keys(layer)
.map(key => mapp.ui.layers.panels[key] && mapp.ui.layers.panels[key](layer))
.filter(panel => typeof panel !== 'undefined')

if (Array.isArray(layer.viewConfig.panelOrder)) {

// Sort the content array according to the data-id in the panelOrder array.
layer.viewConfig.content.sort((a, b) => {

return layer.viewConfig.panelOrder.findIndex(chk => chk === a.dataset?.id)
< layer.viewConfig.panelOrder.findIndex(chk => chk === b.dataset?.id)
? 1 : -1;
})
}

layer.viewConfig.classList ??= ''

// Add default class for layer-view drawer.
layer.viewConfig.classList += ` layer-view raised `

// Add legacy config for layer-view classList.
layer.viewConfig.classList += layer.classList || ''

// Add empty class to prevent expanding an empty drawer.
layer.viewConfig.classList += layer.viewConfig.content.length ? '' : ' empty '
}

/**
@function zoomToRange
Expand Down Expand Up @@ -228,24 +295,24 @@ function changeEnd(layer) {
if (layer.tableCurrent()) {

// The zoomBtn is hidden if the layer is in range.
layer.zoomBtn.style.display = 'none'
layer.zoomBtn instanceof HTMLElement && layer.zoomBtn.style.setProperty('display', 'none')

// Enable layer display toggle.
layer.displayToggle.classList.remove('disabled')
layer.displayToggle instanceof HTMLElement && layer.displayToggle.classList.remove('disabled')

// Enable all drawer elements in array.
drawerArray.forEach(el => el.classList.remove('disabled'))

} else {

// The zoomBtn is displayed outside if the layer is out of range.
layer.zoomBtn.style.display = 'block'
layer.zoomBtn instanceof HTMLElement && layer.zoomBtn.style.setProperty('display', 'block')

// Collapse drawer and disable layer.view.
layer.view.querySelector('.layer-view.drawer').classList.remove('expanded')

// Disable layer display toggle.
layer.displayToggle.classList.add('disabled')
layer.displayToggle instanceof HTMLElement && layer.displayToggle.classList.add('disabled')

// Disable all drawer elements in array.
drawerArray.forEach(el => el.classList.add('disabled'))
Expand Down
4 changes: 1 addition & 3 deletions tests/assets/layers/cluster/layer.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
{
"key": "cluster_test",
"display": true,
"group": "layer",
"format": "wkt",
"dbs": "NEON",
"table": "test.scratch",
"srid": "3857",
"geom": "geom_3857",
"qID": "id",
"cluster": {
"resolution": 0.005,
"hexgrid": true
"distance": 30
},
"infoj": [
{
Expand Down
1 change: 0 additions & 1 deletion tests/lib/location/get.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export async function getTest(mapview) {
id: 6,
});

codi.assertEqual(location.infoj.length, 4, 'We expect to see three infoj entries');
codi.assertEqual(location.record.hook, 'location_get_test!6', 'We expect a hook made up of layer key and id');
codi.assertTrue(location.layer instanceof Object, 'The location needs a layer object');

Expand Down
82 changes: 82 additions & 0 deletions tests/lib/ui/layers/view.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import { setView } from '../../../utils/view.js';
import { delayFunction } from '../../../utils/delay.js';
import clusterConfig from '../../../assets/layers/cluster/layer.json'

/**
* This function is used as an entry point for the changeEndTest
Expand Down Expand Up @@ -53,5 +54,86 @@ export async function viewTest(mapview) {
codi.assertTrue(layer.display, 'The changeEnd() layer should display at zoom level 6');
await delayFunction(1000);
});

/**
* ### should not have a zoom button.
* 1. The Test sets the mapview to London at zoom level 11.
* 2. Creates the `changeEnd` event and dispatches it.
* 3. Checks the magnifying glass is not present.
* @function it
*/
await codi.it('should not display a zoom button when not provided', async () => {
const layer = Object.assign({}, clusterConfig);

layer.viewConfig = {
displayToggle: true,
zoomToExtentBtn: true
}

layer.filter = {
zoomToExtent: true
}

layer.mapview = mapview;

await mapp.layer.decorate(layer);

await mapp.ui.layers.view(layer)

codi.assertTrue(layer.displayToggle !== null, 'We expect to see a display toggle');
codi.assertTrue(typeof layer.zoomToExtent === 'function', 'We expect to see a zoomToExtent function');
codi.assertTrue(layer.zoomToExtentBtn !== null, 'We expect to see a zoomToExtentBtn property');

});

/**
* ### should not have a display toggle button.
* 1. The Test sets the mapview to London at zoom level 11.
* 2. Creates the `changeEnd` event and dispatches it.
* 3. Checks the display toggle is not present.
* @function it
*/
await codi.it('should not display a display Toggle button when not provided', async () => {

const layer = Object.assign({}, clusterConfig);

layer.viewConfig = {};

layer.mapview = mapview;

await mapp.layer.decorate(layer);

await mapp.ui.layers.view(layer);

codi.assertTrue(typeof layer.zoomBtn === 'undefined', 'We should see no zoomBtn');
codi.assertTrue(typeof layer.zoomToExtentBtn === 'undefined', 'We should see no zoomToExtentBtn');
codi.assertTrue(typeof layer.displayToggle === 'undefined', 'We should see no displayToggle');
codi.assertEqual(layer.viewConfig.panelOrder, ['draw-drawer', 'dataviews-drawer', 'filter-drawer', 'style-drawer', 'meta'], 'The panelOrder should be default');

});

/**
* ### should have the defined panelOrder
* 1. The Test sets the mapview to London at zoom level 11.
* 2. Creates the `changeEnd` event and dispatches it.
* 3. Checks the panelOrder is what's defined.
* @function it
*/
await codi.it('should use the default panelOrder', async () => {

const layer = Object.assign({}, clusterConfig);

layer.viewConfig = {
panelOrder: ['meta', 'style-drawer', 'draw-drawer', 'dataviews-drawer', 'filter-drawer']
}

await mapp.layer.decorate(layer);

await mapp.ui.layers.view(layer)

codi.assertEqual(layer.viewConfig.panelOrder, ['meta', 'style-drawer', 'draw-drawer', 'dataviews-drawer', 'filter-drawer'], 'The panelOrder should be what is defined');

});

});
}

0 comments on commit 500e237

Please sign in to comment.