zenit-sdk 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-OOK4DBG5.mjs → chunk-URDEEWUZ.mjs} +330 -16
- package/dist/chunk-URDEEWUZ.mjs.map +1 -0
- package/dist/{index-DvcYGhqj.d.mts → index-BSljZaYk.d.mts} +13 -0
- package/dist/{index-DvcYGhqj.d.ts → index-BSljZaYk.d.ts} +13 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +333 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10 -5
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +324 -10
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-OOK4DBG5.mjs.map +0 -1
package/dist/react/index.js
CHANGED
|
@@ -298,6 +298,26 @@ var import_react_leaflet = require("react-leaflet");
|
|
|
298
298
|
var import_leaflet = __toESM(require("leaflet"));
|
|
299
299
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
300
300
|
var POINT_GEOMETRY_TYPES = /* @__PURE__ */ new Set(["Point", "MultiPoint"]);
|
|
301
|
+
function normalizeBboxFromData(data) {
|
|
302
|
+
const bboxCandidate = data.bbox;
|
|
303
|
+
if (!Array.isArray(bboxCandidate) || bboxCandidate.length < 4) return null;
|
|
304
|
+
const [minLon, minLat, maxLon, maxLat] = bboxCandidate;
|
|
305
|
+
const values = [minLon, minLat, maxLon, maxLat].map((value) => Number(value));
|
|
306
|
+
if (values.every((value) => Number.isFinite(value))) {
|
|
307
|
+
return values;
|
|
308
|
+
}
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
function buildIdsSample(features) {
|
|
312
|
+
return features.slice(0, 10).map((feature) => {
|
|
313
|
+
const typedFeature = feature;
|
|
314
|
+
if (typedFeature.id !== void 0 && typedFeature.id !== null) {
|
|
315
|
+
return String(typedFeature.id);
|
|
316
|
+
}
|
|
317
|
+
const featureId = typedFeature.properties?.featureId;
|
|
318
|
+
return featureId !== void 0 && featureId !== null ? String(featureId) : "";
|
|
319
|
+
}).join(",");
|
|
320
|
+
}
|
|
301
321
|
function getGeometryType(feature) {
|
|
302
322
|
const t = feature?.geometry?.type;
|
|
303
323
|
return typeof t === "string" ? t : null;
|
|
@@ -333,6 +353,18 @@ var LayerGeoJson = ({
|
|
|
333
353
|
const features = data.features ?? [];
|
|
334
354
|
const fillFeatures = features.filter(isNonPointGeometry);
|
|
335
355
|
const pointFeatures = features.filter(isPointGeometry);
|
|
356
|
+
const dataVersionRef = (0, import_react.useRef)(0);
|
|
357
|
+
const prevSignatureRef = (0, import_react.useRef)("");
|
|
358
|
+
const firstId = features.length > 0 ? String(features[0]?.id ?? "") : "";
|
|
359
|
+
const lastId = features.length > 0 ? String(features[features.length - 1]?.id ?? "") : "";
|
|
360
|
+
const bbox = normalizeBboxFromData(data);
|
|
361
|
+
const idsSample = buildIdsSample(features);
|
|
362
|
+
const signature = bbox ? `${layerId}|${features.length}|${firstId}|${lastId}|${idsSample}|${bbox[0]}|${bbox[1]}|${bbox[2]}|${bbox[3]}` : `${layerId}|${features.length}|${firstId}|${lastId}|${idsSample}`;
|
|
363
|
+
const signatureToken = signature.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
364
|
+
if (prevSignatureRef.current !== signature) {
|
|
365
|
+
dataVersionRef.current += 1;
|
|
366
|
+
prevSignatureRef.current = signature;
|
|
367
|
+
}
|
|
336
368
|
const fillData = fillFeatures.length > 0 ? buildFeatureCollection(fillFeatures) : null;
|
|
337
369
|
const pointsData = pointFeatures.length > 0 ? buildFeatureCollection(pointFeatures) : null;
|
|
338
370
|
const clusterLayerRef = (0, import_react.useRef)(null);
|
|
@@ -385,7 +417,7 @@ var LayerGeoJson = ({
|
|
|
385
417
|
onPolygonLabel?.(feature, layer);
|
|
386
418
|
}
|
|
387
419
|
},
|
|
388
|
-
`fill-${layerId}`
|
|
420
|
+
`fill-${layerId}-${signatureToken}-v${dataVersionRef.current}`
|
|
389
421
|
),
|
|
390
422
|
pointsData && !canCluster && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
391
423
|
import_react_leaflet.GeoJSON,
|
|
@@ -398,7 +430,7 @@ var LayerGeoJson = ({
|
|
|
398
430
|
}),
|
|
399
431
|
onEachFeature
|
|
400
432
|
},
|
|
401
|
-
`points-${layerId}`
|
|
433
|
+
`points-${layerId}-${signatureToken}-v${dataVersionRef.current}`
|
|
402
434
|
)
|
|
403
435
|
] });
|
|
404
436
|
};
|
|
@@ -958,6 +990,18 @@ var LocationControl = ({ position = "bottomleft", zoom = 16 }) => {
|
|
|
958
990
|
// src/react/map/map-handlers.tsx
|
|
959
991
|
var import_react4 = require("react");
|
|
960
992
|
var import_react_leaflet3 = require("react-leaflet");
|
|
993
|
+
var MapInvalidator = ({ trigger }) => {
|
|
994
|
+
const map = (0, import_react_leaflet3.useMap)();
|
|
995
|
+
const lastTrigger = (0, import_react4.useRef)(void 0);
|
|
996
|
+
(0, import_react4.useEffect)(() => {
|
|
997
|
+
if (lastTrigger.current === trigger) return;
|
|
998
|
+
lastTrigger.current = trigger;
|
|
999
|
+
requestAnimationFrame(() => {
|
|
1000
|
+
map.invalidateSize();
|
|
1001
|
+
});
|
|
1002
|
+
}, [map, trigger]);
|
|
1003
|
+
return null;
|
|
1004
|
+
};
|
|
961
1005
|
function computeBBoxFromGeojson(geojson) {
|
|
962
1006
|
if (!geojson || !Array.isArray(geojson.features)) return null;
|
|
963
1007
|
const coords = [];
|
|
@@ -1186,6 +1230,8 @@ var ZenitMap = (0, import_react5.forwardRef)(({
|
|
|
1186
1230
|
const [loadingMap, setLoadingMap] = (0, import_react5.useState)(false);
|
|
1187
1231
|
const [mapError, setMapError] = (0, import_react5.useState)(null);
|
|
1188
1232
|
const [mapInstance, setMapInstance] = (0, import_react5.useState)(null);
|
|
1233
|
+
const [layerGeojsonOverrides, setLayerGeojsonOverrides] = (0, import_react5.useState)({});
|
|
1234
|
+
const originalGeojsonByLayerIdRef = (0, import_react5.useRef)({});
|
|
1189
1235
|
const [panesReady, setPanesReady] = (0, import_react5.useState)(false);
|
|
1190
1236
|
const [currentZoom, setCurrentZoom] = (0, import_react5.useState)(initialZoom ?? DEFAULT_ZOOM);
|
|
1191
1237
|
const [isPopupOpen, setIsPopupOpen] = (0, import_react5.useState)(false);
|
|
@@ -1471,13 +1517,27 @@ var ZenitMap = (0, import_react5.forwardRef)(({
|
|
|
1471
1517
|
(0, import_react5.useEffect)(() => {
|
|
1472
1518
|
setCurrentZoom(zoom);
|
|
1473
1519
|
}, [zoom]);
|
|
1520
|
+
(0, import_react5.useEffect)(() => {
|
|
1521
|
+
if (!layerGeojson) return;
|
|
1522
|
+
layers.forEach((layer) => {
|
|
1523
|
+
const layerKey = String(layer.mapLayer.layerId);
|
|
1524
|
+
const incoming = layerGeojson[layer.mapLayer.layerId] ?? layerGeojson[layerKey] ?? null;
|
|
1525
|
+
if (incoming && !originalGeojsonByLayerIdRef.current[layerKey]) {
|
|
1526
|
+
originalGeojsonByLayerIdRef.current[layerKey] = incoming;
|
|
1527
|
+
}
|
|
1528
|
+
});
|
|
1529
|
+
}, [layerGeojson, layers]);
|
|
1474
1530
|
const decoratedLayers = (0, import_react5.useMemo)(() => {
|
|
1475
|
-
return layers.map((layer) =>
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1531
|
+
return layers.map((layer) => {
|
|
1532
|
+
const layerKey = String(layer.mapLayer.layerId);
|
|
1533
|
+
const override = layerGeojsonOverrides[layerKey];
|
|
1534
|
+
return {
|
|
1535
|
+
...layer,
|
|
1536
|
+
effective: effectiveStates.find((state) => state.layerId === layer.mapLayer.layerId),
|
|
1537
|
+
data: override ?? layerGeojson?.[layer.mapLayer.layerId] ?? layerGeojson?.[layerKey] ?? null
|
|
1538
|
+
};
|
|
1539
|
+
});
|
|
1540
|
+
}, [effectiveStates, layerGeojson, layerGeojsonOverrides, layers]);
|
|
1481
1541
|
const orderedLayers = (0, import_react5.useMemo)(() => {
|
|
1482
1542
|
return [...decoratedLayers].filter((layer) => layer.effective?.visible && layer.data).sort((a, b) => a.displayOrder - b.displayOrder);
|
|
1483
1543
|
}, [decoratedLayers]);
|
|
@@ -1706,6 +1766,24 @@ var ZenitMap = (0, import_react5.forwardRef)(({
|
|
|
1706
1766
|
};
|
|
1707
1767
|
mapInstance.fitBounds(bounds, fitOptions);
|
|
1708
1768
|
},
|
|
1769
|
+
fitToBbox: (bbox, padding) => {
|
|
1770
|
+
if (!mapInstance) return;
|
|
1771
|
+
if (typeof bbox.minLat !== "number" || typeof bbox.minLon !== "number" || typeof bbox.maxLat !== "number" || typeof bbox.maxLon !== "number" || !Number.isFinite(bbox.minLat) || !Number.isFinite(bbox.minLon) || !Number.isFinite(bbox.maxLat) || !Number.isFinite(bbox.maxLon)) {
|
|
1772
|
+
console.warn("[ZenitMap.fitToBbox] Invalid bbox", bbox);
|
|
1773
|
+
return;
|
|
1774
|
+
}
|
|
1775
|
+
const resolvedPadding = padding ?? (isMobile ? 40 : 24);
|
|
1776
|
+
const bounds = import_leaflet4.default.latLngBounds([bbox.minLat, bbox.minLon], [bbox.maxLat, bbox.maxLon]);
|
|
1777
|
+
mapInstance.fitBounds(bounds, { padding: [resolvedPadding, resolvedPadding], animate: true });
|
|
1778
|
+
},
|
|
1779
|
+
fitToGeoJson: (fc, padding) => {
|
|
1780
|
+
if (!mapInstance) return;
|
|
1781
|
+
if (!fc?.features?.length) return;
|
|
1782
|
+
const bounds = import_leaflet4.default.geoJSON(fc).getBounds();
|
|
1783
|
+
if (!bounds.isValid()) return;
|
|
1784
|
+
const resolvedPadding = padding ?? (isMobile ? 40 : 24);
|
|
1785
|
+
mapInstance.fitBounds(bounds, { padding: [resolvedPadding, resolvedPadding], animate: true });
|
|
1786
|
+
},
|
|
1709
1787
|
setView: (coordinates, zoom2) => {
|
|
1710
1788
|
if (!mapInstance) return;
|
|
1711
1789
|
mapInstance.setView([coordinates.lat, coordinates.lon], zoom2 ?? mapInstance.getZoom(), {
|
|
@@ -1730,8 +1808,25 @@ var ZenitMap = (0, import_react5.forwardRef)(({
|
|
|
1730
1808
|
highlightFeature: (layerId, featureId) => {
|
|
1731
1809
|
upsertUiOverride(layerId, { overrideVisible: true, overrideOpacity: 1 });
|
|
1732
1810
|
},
|
|
1811
|
+
updateLayerGeoJson: (layerId, featureCollection) => {
|
|
1812
|
+
const layerKey = String(layerId);
|
|
1813
|
+
setLayerGeojsonOverrides((prev) => ({ ...prev, [layerKey]: featureCollection }));
|
|
1814
|
+
},
|
|
1815
|
+
restoreLayerGeoJson: (layerId) => {
|
|
1816
|
+
const layerKey = String(layerId);
|
|
1817
|
+
const original = originalGeojsonByLayerIdRef.current[layerKey];
|
|
1818
|
+
setLayerGeojsonOverrides((prev) => {
|
|
1819
|
+
const next = { ...prev };
|
|
1820
|
+
if (original) {
|
|
1821
|
+
next[layerKey] = original;
|
|
1822
|
+
} else {
|
|
1823
|
+
delete next[layerKey];
|
|
1824
|
+
}
|
|
1825
|
+
return next;
|
|
1826
|
+
});
|
|
1827
|
+
},
|
|
1733
1828
|
getMapInstance: () => mapInstance
|
|
1734
|
-
}), [effectiveStates, mapInstance]);
|
|
1829
|
+
}), [effectiveStates, isMobile, mapInstance]);
|
|
1735
1830
|
if (loadingMap) {
|
|
1736
1831
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { padding: 16, height, width }, children: "Cargando mapa..." });
|
|
1737
1832
|
}
|
|
@@ -1784,6 +1879,7 @@ var ZenitMap = (0, import_react5.forwardRef)(({
|
|
|
1784
1879
|
),
|
|
1785
1880
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_leaflet4.ZoomControl, { position: "topright" }),
|
|
1786
1881
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MapInstanceBridge, { onReady: handleMapReady }),
|
|
1882
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MapInvalidator, { trigger: mapId }),
|
|
1787
1883
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1788
1884
|
BBoxZoomHandler,
|
|
1789
1885
|
{
|
|
@@ -2001,7 +2097,9 @@ var ZenitLayerManager = ({
|
|
|
2001
2097
|
showUploadTab = true,
|
|
2002
2098
|
showLayerVisibilityIcon = true,
|
|
2003
2099
|
layerFeatureCounts,
|
|
2004
|
-
mapLayers
|
|
2100
|
+
mapLayers,
|
|
2101
|
+
onApplyLayerFilter,
|
|
2102
|
+
onClearLayerFilter
|
|
2005
2103
|
}) => {
|
|
2006
2104
|
const [map, setMap] = (0, import_react6.useState)(null);
|
|
2007
2105
|
const [loadingMap, setLoadingMap] = (0, import_react6.useState)(false);
|
|
@@ -2009,6 +2107,15 @@ var ZenitLayerManager = ({
|
|
|
2009
2107
|
const [layers, setLayers] = (0, import_react6.useState)([]);
|
|
2010
2108
|
const [activeTab, setActiveTab] = (0, import_react6.useState)("layers");
|
|
2011
2109
|
const [panelVisible, setPanelVisible] = (0, import_react6.useState)(true);
|
|
2110
|
+
const [selectedFilterLayerId, setSelectedFilterLayerId] = (0, import_react6.useState)("");
|
|
2111
|
+
const [selectedFilterField, setSelectedFilterField] = (0, import_react6.useState)("");
|
|
2112
|
+
const [selectedFilterValue, setSelectedFilterValue] = (0, import_react6.useState)("");
|
|
2113
|
+
const [catalogByLayerField, setCatalogByLayerField] = (0, import_react6.useState)({});
|
|
2114
|
+
const [loadingCatalog, setLoadingCatalog] = (0, import_react6.useState)(false);
|
|
2115
|
+
const [applyingFilter, setApplyingFilter] = (0, import_react6.useState)(false);
|
|
2116
|
+
const [filterError, setFilterError] = (0, import_react6.useState)(null);
|
|
2117
|
+
const [appliedFilter, setAppliedFilter] = (0, import_react6.useState)(null);
|
|
2118
|
+
const catalogAbortRef = (0, import_react6.useRef)(null);
|
|
2012
2119
|
const lastEmittedStatesRef = (0, import_react6.useRef)(null);
|
|
2013
2120
|
const isControlled = Array.isArray(layerStates) && typeof onLayerStatesChange === "function";
|
|
2014
2121
|
const baseStates = (0, import_react6.useMemo)(
|
|
@@ -2202,6 +2309,139 @@ var ZenitLayerManager = ({
|
|
|
2202
2309
|
return String(a.mapLayer.layerId).localeCompare(String(b.mapLayer.layerId));
|
|
2203
2310
|
});
|
|
2204
2311
|
}, [effectiveStates, layers, resolveFeatureCount]);
|
|
2312
|
+
const filterableLayers = (0, import_react6.useMemo)(() => {
|
|
2313
|
+
return decoratedLayers.filter((entry) => {
|
|
2314
|
+
const prefilters = entry.mapLayer.layerConfig?.prefilters;
|
|
2315
|
+
return !!prefilters && Object.keys(prefilters).length > 0;
|
|
2316
|
+
});
|
|
2317
|
+
}, [decoratedLayers]);
|
|
2318
|
+
const selectedFilterLayer = (0, import_react6.useMemo)(
|
|
2319
|
+
() => filterableLayers.find((layer) => String(layer.mapLayer.layerId) === selectedFilterLayerId) ?? null,
|
|
2320
|
+
[filterableLayers, selectedFilterLayerId]
|
|
2321
|
+
);
|
|
2322
|
+
const filterFields = (0, import_react6.useMemo)(() => {
|
|
2323
|
+
const prefilters = selectedFilterLayer?.mapLayer.layerConfig?.prefilters;
|
|
2324
|
+
return prefilters ? Object.keys(prefilters) : [];
|
|
2325
|
+
}, [selectedFilterLayer]);
|
|
2326
|
+
const activeCatalogKey = selectedFilterLayer ? `${selectedFilterLayer.mapLayer.layerId}:${selectedFilterField}` : null;
|
|
2327
|
+
const activeCatalogValues = activeCatalogKey ? catalogByLayerField[activeCatalogKey] ?? [] : [];
|
|
2328
|
+
const extractCatalogValues = import_react6.default.useCallback((catalogData, field) => {
|
|
2329
|
+
const values = /* @__PURE__ */ new Set();
|
|
2330
|
+
const pushValue = (value) => {
|
|
2331
|
+
if (value === null || value === void 0) return;
|
|
2332
|
+
const normalized = String(value).trim();
|
|
2333
|
+
if (normalized) values.add(normalized);
|
|
2334
|
+
};
|
|
2335
|
+
if (catalogData && typeof catalogData === "object") {
|
|
2336
|
+
const maybeRecord = catalogData;
|
|
2337
|
+
const directField = maybeRecord[field];
|
|
2338
|
+
if (Array.isArray(directField)) {
|
|
2339
|
+
directField.forEach(pushValue);
|
|
2340
|
+
}
|
|
2341
|
+
const items = maybeRecord.items;
|
|
2342
|
+
if (Array.isArray(items)) {
|
|
2343
|
+
items.forEach((item) => {
|
|
2344
|
+
if (!item || typeof item !== "object") return;
|
|
2345
|
+
const row = item;
|
|
2346
|
+
const rowField = row.field;
|
|
2347
|
+
if (String(rowField ?? "").toUpperCase() === field.toUpperCase() && Array.isArray(row.values)) {
|
|
2348
|
+
row.values.forEach(pushValue);
|
|
2349
|
+
}
|
|
2350
|
+
});
|
|
2351
|
+
}
|
|
2352
|
+
const features = maybeRecord.features;
|
|
2353
|
+
if (Array.isArray(features)) {
|
|
2354
|
+
features.forEach((feature) => {
|
|
2355
|
+
if (!feature || typeof feature !== "object") return;
|
|
2356
|
+
const properties = feature.properties;
|
|
2357
|
+
if (properties && field in properties) {
|
|
2358
|
+
pushValue(properties[field]);
|
|
2359
|
+
}
|
|
2360
|
+
});
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
return [...values].sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
|
|
2364
|
+
}, []);
|
|
2365
|
+
(0, import_react6.useEffect)(() => {
|
|
2366
|
+
if (!filterableLayers.length) {
|
|
2367
|
+
setSelectedFilterLayerId("");
|
|
2368
|
+
return;
|
|
2369
|
+
}
|
|
2370
|
+
if (!selectedFilterLayerId || !filterableLayers.some((layer) => String(layer.mapLayer.layerId) === selectedFilterLayerId)) {
|
|
2371
|
+
setSelectedFilterLayerId(String(filterableLayers[0].mapLayer.layerId));
|
|
2372
|
+
}
|
|
2373
|
+
}, [filterableLayers, selectedFilterLayerId]);
|
|
2374
|
+
(0, import_react6.useEffect)(() => {
|
|
2375
|
+
if (!filterFields.length) {
|
|
2376
|
+
setSelectedFilterField("");
|
|
2377
|
+
return;
|
|
2378
|
+
}
|
|
2379
|
+
if (!selectedFilterField || !filterFields.includes(selectedFilterField)) {
|
|
2380
|
+
setSelectedFilterField(filterFields[0]);
|
|
2381
|
+
setSelectedFilterValue("");
|
|
2382
|
+
}
|
|
2383
|
+
}, [filterFields, selectedFilterField]);
|
|
2384
|
+
(0, import_react6.useEffect)(() => {
|
|
2385
|
+
if (activeTab !== "filters") return;
|
|
2386
|
+
if (!selectedFilterLayer || !selectedFilterField || !activeCatalogKey) return;
|
|
2387
|
+
if (catalogByLayerField[activeCatalogKey]) return;
|
|
2388
|
+
catalogAbortRef.current?.abort();
|
|
2389
|
+
const controller = new AbortController();
|
|
2390
|
+
catalogAbortRef.current = controller;
|
|
2391
|
+
setLoadingCatalog(true);
|
|
2392
|
+
setFilterError(null);
|
|
2393
|
+
client.layers.getLayerFeaturesCatalog(selectedFilterLayer.mapLayer.layerId).then((response) => {
|
|
2394
|
+
if (controller.signal.aborted) return;
|
|
2395
|
+
const values = extractCatalogValues(response.data, selectedFilterField);
|
|
2396
|
+
setCatalogByLayerField((prev) => ({ ...prev, [activeCatalogKey]: values }));
|
|
2397
|
+
}).catch((error) => {
|
|
2398
|
+
if (controller.signal.aborted) return;
|
|
2399
|
+
const message = error instanceof Error ? error.message : "No se pudo cargar el cat\xE1logo";
|
|
2400
|
+
setFilterError(message);
|
|
2401
|
+
}).finally(() => {
|
|
2402
|
+
if (!controller.signal.aborted) setLoadingCatalog(false);
|
|
2403
|
+
});
|
|
2404
|
+
return () => {
|
|
2405
|
+
controller.abort();
|
|
2406
|
+
};
|
|
2407
|
+
}, [activeCatalogKey, activeTab, catalogByLayerField, client.layers, extractCatalogValues, selectedFilterField, selectedFilterLayer]);
|
|
2408
|
+
const handleApplyFilter = import_react6.default.useCallback(async () => {
|
|
2409
|
+
if (!selectedFilterLayer || !selectedFilterField || !selectedFilterValue || !onApplyLayerFilter) return;
|
|
2410
|
+
setApplyingFilter(true);
|
|
2411
|
+
setFilterError(null);
|
|
2412
|
+
try {
|
|
2413
|
+
await onApplyLayerFilter({
|
|
2414
|
+
layerId: selectedFilterLayer.mapLayer.layerId,
|
|
2415
|
+
field: selectedFilterField,
|
|
2416
|
+
value: selectedFilterValue
|
|
2417
|
+
});
|
|
2418
|
+
setAppliedFilter({
|
|
2419
|
+
layerId: selectedFilterLayer.mapLayer.layerId,
|
|
2420
|
+
field: selectedFilterField,
|
|
2421
|
+
value: selectedFilterValue
|
|
2422
|
+
});
|
|
2423
|
+
} catch (error) {
|
|
2424
|
+
const message = error instanceof Error ? error.message : "No se pudo aplicar el filtro";
|
|
2425
|
+
setFilterError(message);
|
|
2426
|
+
} finally {
|
|
2427
|
+
setApplyingFilter(false);
|
|
2428
|
+
}
|
|
2429
|
+
}, [onApplyLayerFilter, selectedFilterField, selectedFilterLayer, selectedFilterValue]);
|
|
2430
|
+
const handleClearFilter = import_react6.default.useCallback(async () => {
|
|
2431
|
+
if (!selectedFilterLayer) return;
|
|
2432
|
+
setApplyingFilter(true);
|
|
2433
|
+
setFilterError(null);
|
|
2434
|
+
try {
|
|
2435
|
+
await onClearLayerFilter?.({ layerId: selectedFilterLayer.mapLayer.layerId, field: selectedFilterField || void 0 });
|
|
2436
|
+
setSelectedFilterValue("");
|
|
2437
|
+
setAppliedFilter(null);
|
|
2438
|
+
} catch (error) {
|
|
2439
|
+
const message = error instanceof Error ? error.message : "No se pudo limpiar el filtro";
|
|
2440
|
+
setFilterError(message);
|
|
2441
|
+
} finally {
|
|
2442
|
+
setApplyingFilter(false);
|
|
2443
|
+
}
|
|
2444
|
+
}, [onClearLayerFilter, selectedFilterField, selectedFilterLayer]);
|
|
2205
2445
|
const resolveLayerStyle = import_react6.default.useCallback(
|
|
2206
2446
|
(layerId) => {
|
|
2207
2447
|
const layerKey = String(layerId);
|
|
@@ -2540,6 +2780,18 @@ var ZenitLayerManager = ({
|
|
|
2540
2780
|
"Subir"
|
|
2541
2781
|
]
|
|
2542
2782
|
}
|
|
2783
|
+
),
|
|
2784
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
2785
|
+
"button",
|
|
2786
|
+
{
|
|
2787
|
+
type: "button",
|
|
2788
|
+
className: `zlm-tab${activeTab === "filters" ? " is-active" : ""}`,
|
|
2789
|
+
onClick: () => setActiveTab("filters"),
|
|
2790
|
+
children: [
|
|
2791
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react.Layers, { size: 16 }),
|
|
2792
|
+
"Filtros"
|
|
2793
|
+
]
|
|
2794
|
+
}
|
|
2543
2795
|
)
|
|
2544
2796
|
]
|
|
2545
2797
|
}
|
|
@@ -2547,6 +2799,68 @@ var ZenitLayerManager = ({
|
|
|
2547
2799
|
] }),
|
|
2548
2800
|
panelVisible && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { padding: "12px 10px 18px", overflowY: "auto", flex: 1, minHeight: 0 }, children: [
|
|
2549
2801
|
activeTab === "layers" && renderLayerCards(),
|
|
2802
|
+
activeTab === "filters" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "zlm-filter-panel", style: { display: "flex", flexDirection: "column", gap: 10, background: "#fff", border: "1px solid #e2e8f0", borderRadius: 12, padding: 12 }, children: !filterableLayers.length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { color: "#64748b", fontSize: 13 }, children: "No hay filtros disponibles para las capas de este mapa." }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
2803
|
+
filterableLayers.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { style: { display: "flex", flexDirection: "column", gap: 6, fontSize: 12, color: "#475569" }, children: [
|
|
2804
|
+
"Capa",
|
|
2805
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("select", { className: "zlm-filter-select", value: selectedFilterLayerId, onChange: (e) => setSelectedFilterLayerId(e.target.value), children: filterableLayers.map((layer) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: String(layer.mapLayer.layerId), children: layer.layerName ?? `Capa ${layer.mapLayer.layerId}` }, String(layer.mapLayer.layerId))) })
|
|
2806
|
+
] }),
|
|
2807
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { style: { display: "flex", flexDirection: "column", gap: 6, fontSize: 12, color: "#475569" }, children: [
|
|
2808
|
+
"Campo",
|
|
2809
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("select", { className: "zlm-filter-select", value: selectedFilterField, onChange: (e) => {
|
|
2810
|
+
setSelectedFilterField(e.target.value);
|
|
2811
|
+
setSelectedFilterValue("");
|
|
2812
|
+
}, children: filterFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: field, children: field }, field)) })
|
|
2813
|
+
] }),
|
|
2814
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { style: { display: "flex", flexDirection: "column", gap: 6, fontSize: 12, color: "#475569" }, children: [
|
|
2815
|
+
"Valor",
|
|
2816
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
2817
|
+
"select",
|
|
2818
|
+
{
|
|
2819
|
+
className: "zlm-filter-select",
|
|
2820
|
+
value: selectedFilterValue,
|
|
2821
|
+
onChange: (e) => {
|
|
2822
|
+
const value = e.target.value;
|
|
2823
|
+
setSelectedFilterValue(value);
|
|
2824
|
+
},
|
|
2825
|
+
children: [
|
|
2826
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "", children: "Seleccionar\u2026" }),
|
|
2827
|
+
activeCatalogValues.map((value) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value, children: value }, value))
|
|
2828
|
+
]
|
|
2829
|
+
}
|
|
2830
|
+
)
|
|
2831
|
+
] }),
|
|
2832
|
+
loadingCatalog && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { color: "#64748b", fontSize: 12 }, children: "Cargando cat\xE1logo\u2026" }),
|
|
2833
|
+
!loadingCatalog && selectedFilterField && activeCatalogValues.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { color: "#64748b", fontSize: 12 }, children: "No hay cat\xE1logo disponible para este filtro." }),
|
|
2834
|
+
filterError && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { color: "#b91c1c", fontSize: 12 }, children: filterError }),
|
|
2835
|
+
appliedFilter && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "zlm-badge", style: { alignSelf: "flex-start" }, children: [
|
|
2836
|
+
"Activo: ",
|
|
2837
|
+
appliedFilter.field,
|
|
2838
|
+
" = ",
|
|
2839
|
+
appliedFilter.value
|
|
2840
|
+
] }),
|
|
2841
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "zlm-filter-actions", style: { display: "flex", gap: 8 }, children: [
|
|
2842
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2843
|
+
"button",
|
|
2844
|
+
{
|
|
2845
|
+
type: "button",
|
|
2846
|
+
className: "zlm-panel-toggle",
|
|
2847
|
+
disabled: !selectedFilterValue || applyingFilter || !onApplyLayerFilter,
|
|
2848
|
+
onClick: handleApplyFilter,
|
|
2849
|
+
children: applyingFilter ? "Aplicando\u2026" : "Aplicar"
|
|
2850
|
+
}
|
|
2851
|
+
),
|
|
2852
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2853
|
+
"button",
|
|
2854
|
+
{
|
|
2855
|
+
type: "button",
|
|
2856
|
+
className: "zlm-panel-toggle",
|
|
2857
|
+
disabled: applyingFilter,
|
|
2858
|
+
onClick: handleClearFilter,
|
|
2859
|
+
children: "Limpiar"
|
|
2860
|
+
}
|
|
2861
|
+
)
|
|
2862
|
+
] })
|
|
2863
|
+
] }) }),
|
|
2550
2864
|
showUploadTab && activeTab === "upload" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { color: "#475569", fontSize: 13 }, children: "Pr\xF3ximamente podr\xE1s subir capas desde este panel." })
|
|
2551
2865
|
] })
|
|
2552
2866
|
] });
|