diff --git a/lib/ui/layers/panels/dataviews.mjs b/lib/ui/layers/panels/dataviews.mjs
index 03ed3cf7d2..ad3a686291 100644
--- a/lib/ui/layers/panels/dataviews.mjs
+++ b/lib/ui/layers/panels/dataviews.mjs
@@ -24,62 +24,53 @@ The dataviews method returns a drawer with checkbox elements for each dataview o
The dataviews will be decorated with the `mapp.ui.Dataview()` method.
@param {layer} layer The decorated mapp layer object.
-@property {Object} dataviews The layer dataviews.
+@property {Object} layer.dataviews The layer dataviews.
@return {HTMLElement}
*/
-
export default function dataviews(layer) {
+ const content = [];
- // Return if on mobile as dataviews are not supported.
- if (mapp.utils.mobile()) return;
-
- // Create chkbox controls for each dataview entry.
- const dataviewChkboxes = Object.entries(layer.dataviews).map(entry => {
-
- // The layer.dataviews{} object may include a hide flag.
- if (typeof entry[1] !== 'object') return;
-
- // Assign key, host, and layer to dataview object.
- const dataview = Object.assign(entry[1],
- {
- key: entry[0],
- host: layer.mapview.host,
- layer,
- })
+ for (const [key, dataview] of Object.entries(layer.dataviews)) {
+ // The dataview entry may be a flag.
+ if (typeof dataview === 'string' || dataview === true) continue;
- // Prevent altering the dataview target in JSON
- dataview._target ??= dataview.target
+ Object.assign(dataview, {
+ key,
+ layer,
+ host: layer.mapview.host,
+ });
// Find tabview element from data-id attribute.
- dataview.tabview = document.querySelector(`[data-id=${dataview._target}]`)
+ dataview.tabview = document.querySelector(`[data-id=${dataview.target}]`);
// Return if the named tabview is not found in document.
- if (!dataview.tabview) return;
+ if (dataview.tabview) {
+ // Return if on mobile as dataviews are not supported.
+ if (mapp.utils.mobile()) return;
+
+ dataview.show ??= () => {
+ // Create tab after dataview creation is complete.
+ dataview.tabview.dispatchEvent(
+ new CustomEvent('addTab', { detail: dataview }),
+ );
+
+ // Show the dataview tab.
+ dataview.show();
+ };
+
+ dataview.hide ??= () => {
+ dataview.display = false;
+ dataview.remove();
+ };
+ }
// Assign target html element for dataview.
- dataview.target = mapp.utils.html.node`
`
+ dataview.target = mapp.utils.html.node`
+
`;
// Assign label for dataview.chkbox
- dataview.label ??= dataview.title || dataview.key
-
- dataview.show ??= () => {
-
- // Create tab after dataview creation is complete.
- dataview.tabview.dispatchEvent(new CustomEvent('addTab', {
- detail: dataview
- }))
-
- // Show the dataview tab.
- dataview.show()
- }
-
- dataview.hide ??= () => {
-
- dataview.display = false
-
- dataview.remove()
- }
+ dataview.label ??= dataview.title || dataview.key;
// Create checkbox control for dataview.
dataview.chkbox = mapp.ui.elements.chkbox({
@@ -88,28 +79,27 @@ export default function dataviews(layer) {
checked: !!dataview.display,
disabled: dataview.disabled,
onchange: (checked) => {
+ dataview.display = checked;
- dataview.display = checked
-
- dataview.display
- ? dataview.show()
- : dataview.hide()
- }
- })
+ dataview.display ? dataview.show() : dataview.hide();
+ },
+ });
if (mapp.ui.Dataview(dataview) instanceof Error) return;
// Display dataview if layer and dv have display flag.
- layer.display
- && dataview.display
- && dataview.show()
+ layer.display && dataview.display && dataview.show();
layer.showCallbacks.push(() => {
- dataview.display && dataview.show()
- })
+ dataview.display && dataview.show();
+ });
- return dataview.chkbox
- })
+ content.push(dataview.chkbox);
+
+ if (!dataview.tabview) {
+ content.push(dataview.target);
+ }
+ }
// The dataviews are created but no panel is returned.
if (layer.dataviews.hide) return;
@@ -121,8 +111,8 @@ export default function dataviews(layer) {
header: mapp.utils.html`
${mapp.dictionary.layer_dataview_header}
`,
- content: mapp.utils.html`${dataviewChkboxes.filter(dv => !!dv)}`
- })
+ content,
+ });
- return drawer
+ return drawer;
}
diff --git a/lib/ui/layers/view.mjs b/lib/ui/layers/view.mjs
index ea1686c0d9..e8b3350103 100644
--- a/lib/ui/layers/view.mjs
+++ b/lib/ui/layers/view.mjs
@@ -260,6 +260,11 @@ function changeEnd(layer) {
// Collapse drawer and disable layer.view.
layer.view.querySelector('.layer-view.drawer').classList.remove('expanded')
+ const expandedDrawer = layer.view.querySelectorAll('.layer-view.drawer .expanded');
+
+ // Collapse any expanded elements within layer.view drawer.
+ [...expandedDrawer].forEach(drawer => drawer.classList.remove('expanded'))
+
// Disable layer display toggle.
layer.displayToggle instanceof HTMLElement && layer.displayToggle.classList.add('disabled')
diff --git a/lib/ui/locations/entries/dataview.mjs b/lib/ui/locations/entries/dataview.mjs
index 3a874090dd..baffdca52c 100644
--- a/lib/ui/locations/entries/dataview.mjs
+++ b/lib/ui/locations/entries/dataview.mjs
@@ -49,35 +49,29 @@ The dataview checkbox and locationViewTarget elements will be returned if availa
@property {boolean} [entry.display] The dataview display flag.
@property {Function} [entry.show] The dataview show method.
@property {Function} [entry.hide] The dataview hide method.
-@property {HTMLElement} [entry.locationViewTarget] Dataview target for display in location.view.
@return {HTMLElement} Location view dataview and checkbox.
*/
export default function dataview(entry) {
-
if (entry.value !== undefined) {
- entry.data = entry.value
+ entry.data = entry.value;
if (entry.data?.length === 0) {
-
- entry.data = null
+ entry.data = null;
}
- }
+ }
if (entry.data === null) {
-
// The entry must be disabled if the query has run with querycheck:true and the data is null.
// This is to prevent the query running over and over again getting the same result.
entry._display ??= entry.display;
delete entry.display;
-
} else {
entry.display ??= entry._display;
}
if (entry.label) {
-
// Create checkbox if a label is provided.
entry.chkbox = mapp.ui.elements.chkbox({
data_id: entry.key,
@@ -100,7 +94,6 @@ export default function dataview(entry) {
typeof entry.target === 'string' &&
document.getElementById(entry.target)
) {
-
// Assign element by ID as target.
entry.target = document.getElementById(entry.target);
@@ -113,7 +106,6 @@ export default function dataview(entry) {
// Dataview has already been created. e.g. after the location (view) is updated, and it is not dynamic.
if (entry.update && !entry.dynamic) {
-
if (entry.display) entry.show?.();
// Return elements to location view.
@@ -145,10 +137,9 @@ export default function dataview(entry) {
entry.tabview.dispatchEvent(
new CustomEvent('addTab', {
detail: entry,
- })
+ }),
);
} else if (!entry.tabview) {
-
// Dataview will be rendered into location view.
const location_class = `location ${entry.key || entry.query}`;
diff --git a/public/css/elements/_drawer.css b/public/css/elements/_drawer.css
index 5e339a5647..5199d03536 100644
--- a/public/css/elements/_drawer.css
+++ b/public/css/elements/_drawer.css
@@ -21,7 +21,7 @@
}
&.expandable:not(.expanded)>*:not(.header) {
- display: none;
+ display: none !important;
}
&.expanded>.header>.mask-icon.expander {
diff --git a/public/css/ui.css b/public/css/ui.css
index 1da042b0b7..6a3842e314 100644
--- a/public/css/ui.css
+++ b/public/css/ui.css
@@ -1203,7 +1203,7 @@ dialog {
mask-image: url('data:image/svg+xml,');
}
&.expandable:not(.expanded) > *:not(.header) {
- display: none;
+ display: none !important;
}
&.expanded > .header > .mask-icon.expander {
-webkit-mask-image: url('data:image/svg+xml,');
diff --git a/tests/assets/dataviews/dataviews_panel.json b/tests/assets/dataviews/dataviews_panel.json
new file mode 100644
index 0000000000..4b16bef149
--- /dev/null
+++ b/tests/assets/dataviews/dataviews_panel.json
@@ -0,0 +1,65 @@
+{
+ "dataviews": {
+ "test": {
+ "target": "tabview",
+ "dataview": "Json",
+ "query": "stores",
+ "display": true,
+ "queryparams": {
+ "table": true,
+ "layer": "stores",
+ "limit": 10
+ },
+ "toolbar": {
+ "queryparams": {
+ "limit": {
+ "type": "numeric"
+ }
+ }
+ },
+ "table": {
+ "frozenRows": 1,
+ "selectable": true,
+ "columns": [
+ {
+ "field": "name",
+ "width": 300,
+ "title": "Name"
+ }
+ ]
+ }
+ },
+ "stores": {
+ "display": true,
+ "target": "tabview",
+ "query": "stores",
+ "viewport": true,
+ "dataview": "Json",
+ "table": {
+ "selectable": true,
+ "pagination": true,
+ "columns": [
+ {
+ "field": "name",
+ "width": 300,
+ "title": "Name"
+ }
+ ]
+ }
+ },
+ "json": {
+ "display": true,
+ "label": "Json",
+ "dataview": "Json",
+ "query": "select_arr",
+ "toolbar": {
+ "jsonfile": true
+ },
+ "template": {
+ "key": "select_arr",
+ "template": "SELECT array[1, 2, 3]",
+ "value_only": true
+ }
+ }
+ }
+}
diff --git a/tests/lib/ui/layers/_layers.test.mjs b/tests/lib/ui/layers/_layers.test.mjs
index 99f59690cd..f6c406ea7c 100644
--- a/tests/lib/ui/layers/_layers.test.mjs
+++ b/tests/lib/ui/layers/_layers.test.mjs
@@ -1,5 +1,6 @@
import { filters } from './filters.test.mjs';
import { filter } from './panels/filter.test.mjs';
+import { dataviews } from './panels/dataviews.test.mjs';
import { view } from './view.test.mjs';
export const layers = {
@@ -7,6 +8,7 @@ export const layers = {
filters,
panels: {
filter,
+ dataviews,
},
view,
};
diff --git a/tests/lib/ui/layers/panels/dataviews.test.mjs b/tests/lib/ui/layers/panels/dataviews.test.mjs
new file mode 100644
index 0000000000..65a5814f6d
--- /dev/null
+++ b/tests/lib/ui/layers/panels/dataviews.test.mjs
@@ -0,0 +1,34 @@
+import dataviews_panel from '../../../../assets/dataviews/dataviews_panel.json';
+export function dataviews(mapview) {
+ codi.describe(
+ {
+ name: 'Panel Filter test:',
+ id: 'ui_layers_panel_dataviews',
+ parentId: 'ui_layers',
+ },
+ () => {
+ codi.it(
+ {
+ name: 'Create dataview panel',
+ parentId: 'ui_layers_panel_dataviews',
+ },
+ () => {
+ const dataviews = JSON.parse(JSON.stringify(dataviews_panel));
+
+ const layer = {
+ mapview: mapview,
+ dataviews: dataviews.dataviews,
+ showCallbacks: [],
+ };
+
+ const drawer = ui.layers.panels.dataviews(layer);
+
+ codi.assertTrue(
+ drawer.childNodes.length > 0,
+ 'Ensure that we have children being added into the panel',
+ );
+ },
+ );
+ },
+ );
+}
diff --git a/tests/lib/ui/locations/entries/dataview.test.mjs b/tests/lib/ui/locations/entries/dataview.test.mjs
new file mode 100644
index 0000000000..108115cb86
--- /dev/null
+++ b/tests/lib/ui/locations/entries/dataview.test.mjs
@@ -0,0 +1,40 @@
+export function dataview(mapview) {
+ codi.describe(
+ {
+ name: 'Dataview test',
+ id: 'ui_locations_entries_dataview',
+ parentId: 'ui_locations_entries',
+ },
+ () => {
+ codi.it(
+ {
+ name: 'basic',
+ id: 'ui_locations_entries_dataview_basic',
+ parentId: 'ui_locations_entries_dataview',
+ },
+ () => {
+ const expected = '';
+ const entry = {
+ key: 'test-dataview',
+ dataview: 'Json',
+ layer: {
+ mapview: mapview,
+ },
+ data: { test: true },
+ location: {
+ layer: {},
+ },
+ };
+
+ const result = ui.locations.entries.dataview(entry);
+
+ codi.assertEqual(
+ result[3],
+ expected,
+ 'We expect to get a basic dataview div returned',
+ );
+ },
+ );
+ },
+ );
+}