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

FeaturesTable improvements #4922

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 30 additions & 21 deletions assets/src/components/FeaturesTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default class FeaturesTable extends HTMLElement {
// Sorting attribute and direction
this.sortingField = this.getAttribute('sortingField');
const sortingOrder = this.getAttribute('sortingOrder');
this.sortingOrder = (sortingOrder !== null && ['asc', 'desc'].includes(sortingOrder)) ? this.sortingField : 'asc';
this.sortingOrder = (sortingOrder !== null && ['asc', 'desc'].includes(sortingOrder)) ? sortingOrder : 'asc';

// open popup ?
this.openPopup = (this.layerConfig && this.layerConfig.popup);
Expand Down Expand Up @@ -106,7 +106,7 @@ export default class FeaturesTable extends HTMLElement {

// If an error occurred, replace empty content with error
if (displayExpressions.status != 'success') {
this.querySelector('div.lizmap-features-table-container').innerHTML = `<p style="padding: 3px;">
this.querySelector('table.lizmap-features-table-container').innerHTML = `<p style="padding: 3px;">
${displayExpressions.error}
</p>`;
}
Expand Down Expand Up @@ -176,7 +176,7 @@ export default class FeaturesTable extends HTMLElement {

// If there is not features, add empty content in the container
if (this.features.length === 0) {
this.querySelector('div.lizmap-features-table-container').innerHTML = '&nbsp;';
this.querySelector('table.lizmap-features-table-container').innerHTML = '&nbsp;';
}

// Add drag & drop capabilities if option is set
Expand Down Expand Up @@ -204,6 +204,7 @@ export default class FeaturesTable extends HTMLElement {
* @param {number} lineId Line number of the item in the features table
*/
onItemClick(event, feature) {

if (!this.openPopup) {return true;}

// Check if the item was active
Expand All @@ -213,19 +214,22 @@ export default class FeaturesTable extends HTMLElement {
const activeItemTitle = `${this.openPopup ? lizDict['featuresTable.item.active.hover']: ''}`;
const defaultItemTitle = `${this.openPopup ? lizDict['featuresTable.item.hover'] + '.': ''} ${this.itemsDraggable == 'yes' ? lizDict['featuresTable.item.draggable.hover'] + '.' : ''}`;

// Fix event.target depending on which HTML tag we click on
const eventTarget = event.currentTarget;

if (!itemWasActive) {

// Set the features table properties
const lineId = parseInt(event.target.dataset.lineId);
const lineId = parseInt(eventTarget.dataset.lineId);
this.activeItemFeatureId = feature.properties.feature_id;
this.activeItemLineNumber = lineId;

// Get popup data and display it
mainLizmap.featuresTable.openPopup(
event.target.dataset.layerId,
eventTarget.dataset.layerId,
feature,
this.uniqueField,
event.target.parentElement.parentElement.querySelector('div.lizmap-features-table-item-popup'),
eventTarget.parentElement.parentElement.querySelector('div.lizmap-features-table-item-popup'),
function(aLayerId, aFeature, aTarget) {
// Add bootstrap classes to the popup tables
const popupTable = aTarget.querySelector('table.lizmapPopupTable');
Expand All @@ -241,14 +245,14 @@ export default class FeaturesTable extends HTMLElement {

// Remove popup-displayed for all other items
// And restore previous title
var items = featuresTableDiv.querySelectorAll('div.lizmap-features-table-container div.lizmap-features-table-item.popup-displayed');
var items = featuresTableDiv.querySelectorAll('table.lizmap-features-table-container tr.lizmap-features-table-item.popup-displayed');
Array.from(items).forEach(item => {
item.classList.remove('popup-displayed');
item.setAttribute('title', defaultItemTitle);
});

// Add class to the active item
const childSelector = `div.lizmap-features-table-item[data-feature-id="${feature.properties.feature_id}"]`;
const childSelector = `tr.lizmap-features-table-item[data-feature-id="${feature.properties.feature_id}"]`;
const activeItem = featuresTableDiv.querySelector(childSelector);
if (activeItem) activeItem.classList.add('popup-displayed');

Expand All @@ -268,9 +272,9 @@ export default class FeaturesTable extends HTMLElement {
this.activeItemFeatureId = null;
this.activeItemLineNumber = null;

event.target.classList.remove('popup-displayed');
event.target.setAttribute('title', defaultItemTitle);
event.target.closest('div.lizmap-features-table').classList.remove('popup-displayed');
eventTarget.classList.remove('popup-displayed');
eventTarget.setAttribute('title', defaultItemTitle);
eventTarget.closest('div.lizmap-features-table').classList.remove('popup-displayed');
}
}

Expand All @@ -282,7 +286,7 @@ export default class FeaturesTable extends HTMLElement {
*/
addDragAndDropCapabilities() {
// Add drag and drop events to table items
const items = this.querySelectorAll('div.lizmap-features-table-container div.lizmap-features-table-item');
const items = this.querySelectorAll('table.lizmap-features-table-container tr.lizmap-features-table-item');
if (!items) return;

Array.from(items).forEach(item => {
Expand Down Expand Up @@ -359,7 +363,7 @@ export default class FeaturesTable extends HTMLElement {

// Send event
const movedFeatureId = dropped.dataset.featureId;
const newItem = item.parentElement.querySelector(`div.lizmap-features-table-item[data-feature-id="${movedFeatureId}"]`);
const newItem = item.parentElement.querySelector(`tr.lizmap-features-table-item[data-feature-id="${movedFeatureId}"]`);
/**
* When the user has dropped an item in a new position
* @event features.table.item.dragged
Expand Down Expand Up @@ -407,30 +411,30 @@ export default class FeaturesTable extends HTMLElement {
@click=${event => {
// Click on the previous item
const lineNumber = this.activeItemLineNumber - 1;
const featureDiv = this.querySelector(`div.lizmap-features-table-item[data-line-id="${lineNumber}"]`);
const featureDiv = this.querySelector(`tr.lizmap-features-table-item[data-line-id="${lineNumber}"]`);
if (featureDiv) featureDiv.click();
}}></button>
<button class="btn btn-mini next-popup"
title="${lizDict['featuresTable.toolbar.next']}"
@click=${event => {
// Click on the next item
const lineNumber = this.activeItemLineNumber + 1;
const featureDiv = this.querySelector(`div.lizmap-features-table-item[data-line-id="${lineNumber}"]`);
const featureDiv = this.querySelector(`tr.lizmap-features-table-item[data-line-id="${lineNumber}"]`);
if (featureDiv) featureDiv.click();
}}></button>
<button class="btn btn-mini close-popup"
title="${lizDict['featuresTable.toolbar.close']}"
@click=${event => {
// Click on the active line to deactivate it
if (this.activeItemFeatureId === null) return;
const featureDiv = this.querySelector(`div.lizmap-features-table-item[data-feature-id="${this.activeItemFeatureId}"]`);
const featureDiv = this.querySelector(`tr.lizmap-features-table-item[data-feature-id="${this.activeItemFeatureId}"]`);
featureDiv.click();
}}></button>
</div>
<div class="lizmap-features-table-container">
<table class="lizmap-features-table-container">
${this.features.map((feature, idx) =>
html`
<div
<tr
class="lizmap-features-table-item ${this.openPopup ? 'has-action' : ''}"
data-layer-id="${this.layerId}"
data-feature-id="${feature.properties.feature_id}"
Expand All @@ -439,11 +443,16 @@ export default class FeaturesTable extends HTMLElement {
@click=${event => {
this.onItemClick(event, feature);
}}
>${feature.properties.display_expression}
</div>
>
<td
class="lizmap-features-table-item"
>
${feature.properties.display_expression}
</td>
</tr>
`
)}
</div>
</table>
<div class="lizmap-features-table-item-popup"></div>
</div>
`;
Expand Down
23 changes: 14 additions & 9 deletions lizmap/www/assets/css/map.css
Original file line number Diff line number Diff line change
Expand Up @@ -3603,7 +3603,7 @@ lizmap-features-table h4 {
div.lizmap-features-table {
position: relative;
}
div.lizmap-features-table-container {
table.lizmap-features-table-container {
border: 1px solid var(--color-contrasted-elements);
font-size: 0.9em;
margin: 0px 10px 0px 10px;
Expand All @@ -3613,10 +3613,10 @@ div.lizmap-features-table-container {
}

/* Feature item */
div.lizmap-features-table-container div.lizmap-features-table-item {
padding: 5px;
table.lizmap-features-table-container tr.lizmap-features-table-item {
border-top: 1px solid var(--color-contrasted-elements);
position: relative;
display: block;
/* Invert colors on hover & focus */
&:hover, &:focus, &:active, &.popup-displayed {
background-color: var(--color-contrasted-elements);
Expand All @@ -3628,16 +3628,21 @@ div.lizmap-features-table-container div.lizmap-features-table-item {
}
}
/* Pointer cursor */
div.lizmap-features-table-container div.lizmap-features-table-item.has-action {
table.lizmap-features-table-container tr.lizmap-features-table-item.has-action {
cursor: pointer;
}

/* Column in feature item row */
td.lizmap-features-table-item {
padding: 5px;
}

/* Hide other children if only one child feature is active */
div.lizmap-features-table.popup-displayed div.lizmap-features-table-container div.lizmap-features-table-item {
div.lizmap-features-table.popup-displayed table.lizmap-features-table-container tr.lizmap-features-table-item {
display: none;
}
/* In this context, display only the active child item */
div.lizmap-features-table.popup-displayed div.lizmap-features-table-container div.lizmap-features-table-item.popup-displayed {
div.lizmap-features-table.popup-displayed table.lizmap-features-table-container tr.lizmap-features-table-item.popup-displayed {
display: block;
}
/* Toolbar visible when popup is visible */
Expand Down Expand Up @@ -3686,17 +3691,17 @@ div.lizmap-features-table-toolbar button.next-popup {


/* Popup div, visible only if popup-dsplayed class is present for it preceeding sibling */
div.lizmap-features-table div.lizmap-features-table-container + div.lizmap-features-table-item-popup {
div.lizmap-features-table table.lizmap-features-table-container + div.lizmap-features-table-item-popup {
display: none;
min-height: 200px;
min-width: 200px;
overflow: auto;
}
div.lizmap-features-table.popup-displayed div.lizmap-features-table-container + div.lizmap-features-table-item-popup {
div.lizmap-features-table.popup-displayed table.lizmap-features-table-container + div.lizmap-features-table-item-popup {
display: block;
}
/* Hide title of the popup, since it is already visible above */
div.lizmap-features-table.popup-displayed div.lizmap-features-table-container + div.lizmap-features-table-item-popup h4.lizmapPopupTitle {
div.lizmap-features-table.popup-displayed table.lizmap-features-table-container + div.lizmap-features-table-item-popup h4.lizmapPopupTitle {
display: none;
}
.hide {
Expand Down
32 changes: 27 additions & 5 deletions tests/end2end/playwright/lizmap-features-table.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,26 @@ test.describe('Display lizmap-features-table component in popup from QGIS toolti
await expect(lizmapFeaturesTable.locator("h4")).toHaveText("child sub-districts");

// Check items count
await expect(lizmapFeaturesTable.locator("div.lizmap-features-table-container div.lizmap-features-table-item")).toHaveCount(10);
await expect(lizmapFeaturesTable.locator("table.lizmap-features-table-container tr.lizmap-features-table-item")).toHaveCount(10);

// Get first item and check it
let firstItem = lizmapFeaturesTable.locator("div.lizmap-features-table-container div.lizmap-features-table-item").first();
let firstItem = lizmapFeaturesTable.locator("table.lizmap-features-table-container tr.lizmap-features-table-item").first();
await expect(firstItem).toHaveAttribute('data-line-id', '1');
await expect(firstItem).toHaveAttribute('data-feature-id', '10');
await expect(firstItem).toHaveAttribute('data-feature-id', '17');

// Click on first item and check sub-popup
firstItem.click();
await expect(lizmapFeaturesTable.locator('div.lizmap-features-table')).toHaveClass(/popup-displayed/);
await expect(firstItem).toHaveClass(/popup-displayed/);
let popupContainer = lizmapFeaturesTable.locator('div.lizmap-features-table-item-popup');
await expect(popupContainer).toBeVisible();
await expect(popupContainer.locator('table.lizmapPopupTable tbody tr:first-child td')).toHaveText('10');
await expect(popupContainer.locator('table.lizmapPopupTable tbody tr:first-child td')).toHaveText('17');

// Next item
let nextItemButton = lizmapFeaturesTable.locator('div.lizmap-features-table-toolbar button.next-popup');
nextItemButton.click();
await expect(popupContainer).toBeVisible();
await expect(popupContainer.locator('table.lizmapPopupTable tbody tr:first-child td')).toHaveText('8');
await expect(popupContainer.locator('table.lizmapPopupTable tbody tr:first-child td')).toHaveText('9');

// Close Item
let closeItemButton = lizmapFeaturesTable.locator('div.lizmap-features-table-toolbar button.close-popup');
Expand All @@ -62,6 +62,28 @@ test.describe('Display lizmap-features-table component in popup from QGIS toolti
await expect(lizmapFeaturesTable.locator('div.lizmap-features-table')).not.toHaveClass(/popup-displayed/);
await expect(firstItem).not.toHaveClass(/popup-displayed/);

// Drag and Drop Item
await page.locator('table.lizmap-features-table-container').hover({
position: {
x: 141,
y: 257
}
});
await page.mouse.down();
await page.locator('table.lizmap-features-table-container').hover({
position: {
x: 141,
y: 12
}
});
await page.mouse.up();

await expect(firstItem).toHaveAttribute('data-line-id', '1');
await expect(firstItem).toHaveAttribute('data-feature-id', '10');

let lastItem = lizmapFeaturesTable.locator("table.lizmap-features-table-container tr.lizmap-features-table-item").last();
await expect(lastItem).toHaveAttribute('data-line-id', '10');
await expect(lastItem).toHaveAttribute('data-feature-id', '8');


//clear screen
Expand Down
Loading