@geogirafe/lib-geoportal
Version:
GeoGirafe is a flexible application to build online geoportals.
235 lines (234 loc) • 8.58 kB
JavaScript
import OlGeomGeometry from 'ol/geom/Geometry';
import ConfigManager from '../../../tools/configuration/configmanager';
import FeatureToGridDataById from '../../../tools/featuretogriddatabyid';
import I18nManager from '../../../tools/i18n/i18nmanager';
import FormatGridGeomValue from './formatgridgeomvalue';
import { TabulatorFull as Tabulator } from 'tabulator-tables';
import StateManager from '../../../tools/state/statemanager';
import { getUid } from 'ol/util';
import { getColumnAlias } from '../../../tools/utils/aliases';
export default class SelectionTabulatorManager {
constructor() {
Object.defineProperty(this, "formatGridGeomValue", {
enumerable: true,
configurable: true,
writable: true,
value: new FormatGridGeomValue()
});
Object.defineProperty(this, "configManager", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "featureToGridData", {
enumerable: true,
configurable: true,
writable: true,
value: new FeatureToGridDataById({ keepGeomProperty: true })
});
Object.defineProperty(this, "stateManager", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "idTab", {
enumerable: true,
configurable: true,
writable: true,
value: {}
});
Object.defineProperty(this, "tabHeaders", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
Object.defineProperty(this, "table", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "element", {
enumerable: true,
configurable: true,
writable: true,
value: ''
});
Object.defineProperty(this, "data", {
enumerable: true,
configurable: true,
writable: true,
value: {}
});
this.configManager = ConfigManager.getInstance();
this.stateManager = StateManager.getInstance();
}
/**
* Set the HTML element to be used by the grid.
*/
setElement(htmlElement) {
this.element = htmlElement;
}
/**
* Replace the data of the current grid with the data of the specified tab.
*/
replaceData(id) {
const columns = this.columnsToGridColumns(id, this.data[id].columns);
this.table?.setColumns(columns);
this.table?.replaceData(this.data[id].notOlProperties);
}
/**
* Activates a tab matching the given id.
*/
activateTab(id) {
this.tabHeaders?.forEach((tabHeader) => (tabHeader.active = false));
const visibleTabHeader = this.tabHeaders?.find((tabHeader) => tabHeader.id === id);
if (!visibleTabHeader) {
return;
}
visibleTabHeader.active = true;
}
/**
* Creates (replace) the Tabulator grid based on the provided tab id and related data and features.
*/
displayGrid(id) {
if (!this.element) {
return;
}
this.table = new Tabulator(this.element, {
data: this.data[id].notOlProperties,
columns: this.columnsToGridColumns(id, this.data[id].columns),
selectableRows: true,
layout: 'fitColumns',
locale: true,
maxHeight: '750',
headerSortElement: function (_, dir) {
switch (dir) {
case 'asc':
return '<img alt="sort-up-icon" src="icons/sort-up.svg" />';
case 'desc':
return '<img alt="sort-down-icon" src="icons/sort-down.svg" />';
default:
return '<img alt="sort-icon" src="icons/sort.svg" />';
}
}
});
this.table?.on('rowSelectionChanged', (selection) => {
// True if at least one row is selected.
this.stateManager.state.selection.gridSelected = selection.length > 0;
// Create a Map of features by their UIDs
const featureMap = new Map();
this.data[id].features.forEach((feature) => {
const uid = getUid(feature.getGeometry());
featureMap.set(uid, feature);
});
// Highlight selected features on the map.
const highlightedGeometries = selection
.map((row) => featureMap.get(getUid(row.geom ?? row.the_geom ?? row.geometry)))
.filter((feature) => feature !== undefined);
this.stateManager.state.selection.highlightedFeatures = highlightedGeometries;
});
}
/**
* Transforms the given features into grid data and sets tab headers.
* The grid data are completely replaced.
*/
featuresToGridData(features) {
this.idTab = {};
const gridDataById = this.featureToGridData.toGridDataById(features);
// Create tabs and collect data.
Object.keys(gridDataById).forEach((id) => this.gridDataToGridTab(id, gridDataById[id]));
// Create tabs headers
this.tabHeaders = Object.keys(this.idTab).map((key) => {
return {
id: key,
text: I18nManager.getInstance().getTranslation(key),
active: false
};
});
this.data = this.filterEmptyColumnsOnData(gridDataById);
}
/**
* Converts grid data to grid tab format and adds it to the idTab object.
* @private
*/
gridDataToGridTab(id, gridData) {
if (id in this.idTab) {
// Already in ? Don't add a new one.
return;
}
this.idTab[id] = {
columns: gridData.columns.map((column) => this.createGridColumn(id, column)),
data: gridData.data.map((data) => this.createGridData(data)),
features: gridData.features
};
}
columnsToGridColumns(idTable, columns) {
const columnDefinition = [];
columns.forEach((column) => {
const columnAlias = getColumnAlias(idTable, column);
columnDefinition.push({
title: I18nManager.getInstance().getTranslation(columnAlias),
field: column,
formatter: 'html'
});
});
columnDefinition.forEach((column) => {
if (column.field === 'the_geom' || column.field === 'geom' || column.field === 'geometry') {
column.formatter = (cell) => {
return this.formatGridGeomValue.getGeometryIcons(cell.getValue(), this.getLocale()) ?? cell.getValue();
};
}
});
return columnDefinition;
}
filterEmptyColumnsOnData(data) {
for (const [_, entry] of Object.entries(data)) {
const columns = entry.columns;
const notOlProperties = entry.notOlProperties;
for (const [_, row] of Object.entries(notOlProperties)) {
for (const [key, _] of Object.entries(row)) {
if (!columns.some((column) => column === key)) {
delete row[key];
}
}
}
}
return data;
}
/**
* @returns A newly created grid column object.
* @private
*/
createGridColumn(idTable, idColumn) {
const columnAlias = getColumnAlias(idTable, idColumn);
return {
id: idColumn,
name: I18nManager.getInstance().getTranslation(columnAlias)
};
}
/**
* Creates grid data by mapping values (simple values, or transformed values in case of HTML).
* @returns The grid data array.
* @private
*/
createGridData(values) {
return values.map((value) => value instanceof OlGeomGeometry ? this.formatGridGeomValue.getGeometryIcons(value, this.getLocale()) : value);
}
/**
* @returns The locale specified in the configuration.
* @private
*/
getLocale() {
return this.configManager.Config.general.locale;
}
blockRedraw() {
this.table?.blockRedraw();
}
restoreRedraw() {
this.table?.restoreRedraw();
}
}