@metastringfoundation/map-list 0.1.1 → 0.1.3
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/components/Handler/MapComparisonControl.d.ts +7 -0
- package/dist/components/Handler/MapComparisonControl.d.ts.map +1 -0
- package/dist/components/Handler/MapComparisonControl.js +8 -0
- package/dist/components/core/button.js +1 -1
- package/dist/components/core/input.d.ts.map +1 -1
- package/dist/components/core/input.js +1 -1
- package/dist/components/dualMap/MapLayerCard.d.ts +8 -0
- package/dist/components/dualMap/MapLayerCard.d.ts.map +1 -0
- package/dist/components/dualMap/MapLayerCard.js +68 -0
- package/dist/components/dualMap/index.d.ts +2 -1
- package/dist/components/dualMap/index.d.ts.map +1 -1
- package/dist/components/dualMap/index.js +219 -56
- package/dist/components/map/compare-sidebar.d.ts +2 -0
- package/dist/components/map/compare-sidebar.d.ts.map +1 -0
- package/dist/components/map/compare-sidebar.js +34 -0
- package/dist/components/map/compare.d.ts +2 -0
- package/dist/components/map/compare.d.ts.map +1 -0
- package/dist/components/map/compare.js +42 -0
- package/dist/components/map/index.d.ts.map +1 -1
- package/dist/components/map/index.js +14 -1
- package/dist/components/map/layers/grid/index.d.ts.map +1 -1
- package/dist/components/map/layers/grid/index.js +11 -1
- package/dist/components/map/layers/index.d.ts.map +1 -1
- package/dist/components/map/layers/index.js +0 -1
- package/dist/components/map/layers/raster/index.d.ts.map +1 -1
- package/dist/components/map/layers/raster/index.js +5 -3
- package/dist/components/map/layers/vector/index.d.ts.map +1 -1
- package/dist/components/map/layers/vector/index.js +25 -2
- package/dist/components/map/search.d.ts +2 -0
- package/dist/components/map/search.d.ts.map +1 -0
- package/dist/components/map/search.js +122 -0
- package/dist/components/map-comparison/attribute-selector.d.ts +11 -0
- package/dist/components/map-comparison/attribute-selector.d.ts.map +1 -0
- package/dist/components/map-comparison/attribute-selector.js +10 -0
- package/dist/components/map-comparison/comparison-panel.d.ts +2 -0
- package/dist/components/map-comparison/comparison-panel.d.ts.map +1 -0
- package/dist/components/map-comparison/comparison-panel.js +45 -0
- package/dist/components/map-comparison/comparison-stats.d.ts +2 -0
- package/dist/components/map-comparison/comparison-stats.d.ts.map +1 -0
- package/dist/components/map-comparison/comparison-stats.js +35 -0
- package/dist/components/map-comparison/comparison-view.d.ts +2 -0
- package/dist/components/map-comparison/comparison-view.d.ts.map +1 -0
- package/dist/components/map-comparison/comparison-view.js +152 -0
- package/dist/components/map-comparison/comparison-wrapper.d.ts +8 -0
- package/dist/components/map-comparison/comparison-wrapper.d.ts.map +1 -0
- package/dist/components/map-comparison/comparison-wrapper.js +26 -0
- package/dist/components/map-comparison/index.d.ts +3 -0
- package/dist/components/map-comparison/index.d.ts.map +1 -0
- package/dist/components/map-comparison/index.js +165 -0
- package/dist/components/map-comparison/types.d.ts +30 -0
- package/dist/components/map-comparison/types.d.ts.map +1 -0
- package/dist/components/map-comparison/types.js +2 -0
- package/dist/components/map-comparison/use-map-comparison.d.ts +18 -0
- package/dist/components/map-comparison/use-map-comparison.d.ts.map +1 -0
- package/dist/components/map-comparison/use-map-comparison.js +139 -0
- package/dist/components/sidebar/common/attribute-compare-addon.d.ts +7 -0
- package/dist/components/sidebar/common/attribute-compare-addon.d.ts.map +1 -0
- package/dist/components/sidebar/common/attribute-compare-addon.js +36 -0
- package/dist/components/sidebar/common/layer-item-style.d.ts.map +1 -1
- package/dist/components/sidebar/common/layer-item-style.js +46 -1
- package/dist/components/sidebar/common/layer-item.d.ts.map +1 -1
- package/dist/components/sidebar/common/layer-item.js +1 -2
- package/dist/components/sidebar/common/opacity-handler-addon.d.ts +5 -2
- package/dist/components/sidebar/common/opacity-handler-addon.d.ts.map +1 -1
- package/dist/components/sidebar/common/opacity-handler-addon.js +101 -4
- package/dist/components/sidebar/common/style-legend.d.ts.map +1 -1
- package/dist/components/sidebar/common/style-legend.js +1 -2
- package/dist/components/sidebar/comparison/index.d.ts +4 -0
- package/dist/components/sidebar/comparison/index.d.ts.map +1 -0
- package/dist/components/sidebar/comparison/index.js +34 -0
- package/dist/components/sidebar/search/attribute-comparison.d.ts +10 -0
- package/dist/components/sidebar/search/attribute-comparison.d.ts.map +1 -0
- package/dist/components/sidebar/search/attribute-comparison.js +137 -0
- package/dist/components/sidebar/search/index.d.ts +2 -0
- package/dist/components/sidebar/search/index.d.ts.map +1 -0
- package/dist/components/sidebar/search/index.js +29 -0
- package/dist/components/sidebar/selected/index.d.ts.map +1 -1
- package/dist/components/sidebar/selected/index.js +4 -1
- package/dist/components/sidebar/tabs.js +2 -2
- package/dist/hooks/use-layers.d.ts +8 -0
- package/dist/hooks/use-layers.d.ts.map +1 -1
- package/dist/hooks/use-layers.js +101 -1
- package/dist/hooks/use-polygon-data.d.ts +34 -0
- package/dist/hooks/use-polygon-data.d.ts.map +1 -0
- package/dist/hooks/use-polygon-data.js +74 -0
- package/dist/index.css +659 -30
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -36
- package/dist/services/naksha.d.ts.map +1 -1
- package/dist/services/naksha.js +16 -158
- package/dist/services/polygon.d.ts +36 -0
- package/dist/services/polygon.d.ts.map +1 -0
- package/dist/services/polygon.js +67 -0
- package/dist/utils/naksha.d.ts.map +1 -1
- package/dist/utils/naksha.js +4 -2
- package/package.json +16 -15
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
|
+
// @ts-nocheck
|
|
8
|
+
const react_1 = require("react");
|
|
9
|
+
const use_layers_1 = __importDefault(require("../../hooks/use-layers"));
|
|
10
|
+
const core_1 = require("../core");
|
|
11
|
+
const constants_1 = require("../../static/constants");
|
|
12
|
+
const naksha_1 = require("../../utils/naksha");
|
|
13
|
+
const LayerCard = ({ layer, selectedAttributes, isLoadingAttributes, onDropdownToggle, onAttributeToggle }) => {
|
|
14
|
+
const [isDropdownOpen, setIsDropdownOpen] = (0, react_1.useState)(false);
|
|
15
|
+
const attributes = (0, react_1.useMemo)(() => {
|
|
16
|
+
const propertyMap = layer.data?.propertyMap || {};
|
|
17
|
+
return Object.entries(propertyMap).map(([key, displayName]) => ({
|
|
18
|
+
key,
|
|
19
|
+
displayName: displayName || key,
|
|
20
|
+
}));
|
|
21
|
+
}, [layer.data?.propertyMap]);
|
|
22
|
+
const selectedCount = selectedAttributes.size;
|
|
23
|
+
const totalCount = attributes.length;
|
|
24
|
+
const handleDropdownClick = () => {
|
|
25
|
+
const wasOpen = isDropdownOpen;
|
|
26
|
+
const newState = !isDropdownOpen;
|
|
27
|
+
setIsDropdownOpen(newState);
|
|
28
|
+
// Fetch data when opening the dropdown (was closed, now opening)
|
|
29
|
+
if (newState && !wasOpen) {
|
|
30
|
+
onDropdownToggle();
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const formatDate = (dateString) => {
|
|
34
|
+
if (!dateString)
|
|
35
|
+
return null;
|
|
36
|
+
try {
|
|
37
|
+
return new Date(dateString).toLocaleDateString();
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "p-3 border-b border-gray-200 bg-white hover:bg-gray-50 transition-colors", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex gap-3 mb-3", children: [(0, jsx_runtime_1.jsx)("img", { className: "flex shrink-0 overflow-hidden h-16 w-16 object-cover border border-gray-300 rounded shadow-sm", src: layer.thumbnail || constants_1.FALLBACK_THUMB, alt: layer.title }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("h3", { className: "font-semibold text-gray-900 mb-1 leading-tight truncate", title: layer.title, children: layer.title }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-gray-600 line-clamp-2 mb-2", title: layer.description, children: layer.description || "No description available" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap gap-x-3 gap-y-1 text-sm text-gray-500", children: [layer.createdBy && ((0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-1", children: [(0, jsx_runtime_1.jsx)("span", { className: "font-medium", children: "By:" }), (0, jsx_runtime_1.jsx)("span", { children: layer.createdBy })] })), formatDate(layer.createdDate) && ((0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-1", children: [(0, jsx_runtime_1.jsx)("span", { className: "font-medium", children: "Date:" }), (0, jsx_runtime_1.jsx)("span", { children: formatDate(layer.createdDate) })] })), layer.license && ((0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-1", children: [(0, jsx_runtime_1.jsx)("span", { className: "font-medium", children: "License:" }), (0, jsx_runtime_1.jsx)("span", { children: layer.license })] })), layer.tags && layer.tags.length > 0 && ((0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-1", children: [(0, jsx_runtime_1.jsx)("span", { className: "font-medium", children: "Tags:" }), (0, jsx_runtime_1.jsxs)("span", { children: [layer.tags.slice(0, 2).join(", "), layer.tags.length > 2 ? "..." : ""] })] }))] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "mt-2", children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", onClick: handleDropdownClick, className: "w-full flex items-center justify-between px-3 py-2 text-sm font-medium text-gray-700 bg-gray-50 hover:bg-gray-100 border border-gray-300 rounded transition-colors", children: [(0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("span", { children: "Attributes" }), selectedCount > 0 && ((0, jsx_runtime_1.jsxs)("span", { className: "px-1.5 py-0.5 bg-green-100 text-green-700 rounded text-sm font-semibold", children: [selectedCount, "/", totalCount] }))] }), isDropdownOpen ? (0, jsx_runtime_1.jsx)(core_1.UpIcon, {}) : (0, jsx_runtime_1.jsx)(core_1.DownIcon, {})] }), isDropdownOpen && ((0, jsx_runtime_1.jsx)("div", { className: "mt-2 border border-gray-300 rounded bg-white max-h-64 overflow-y-auto shadow-sm scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-gray-100", children: isLoadingAttributes ? ((0, jsx_runtime_1.jsx)("div", { className: "px-3 py-4 text-sm text-gray-500 italic text-center", children: "Loading attributes..." })) : attributes.length > 0 ? (attributes.map((attr) => ((0, jsx_runtime_1.jsxs)("label", { className: "flex items-center gap-2 px-3 py-2 hover:bg-gray-50 cursor-pointer border-b border-gray-100 last:border-b-0 transition-colors", children: [(0, jsx_runtime_1.jsx)(core_1.CheckboxInput, { name: `${layer.id}-${attr.key}`, checked: selectedAttributes.has(attr.key), onChange: () => {
|
|
44
|
+
onAttributeToggle(attr.key);
|
|
45
|
+
}, style: { accentColor: '#16a34a' } }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm text-gray-700 flex-1", children: attr.displayName })] }, attr.key)))) : ((0, jsx_runtime_1.jsx)("div", { className: "px-3 py-4 text-sm text-gray-500 italic text-center", children: "No attributes available for this layer" })) }))] })] }));
|
|
46
|
+
};
|
|
47
|
+
const MapComparison = () => {
|
|
48
|
+
const { layer, mp } = (0, use_layers_1.default)();
|
|
49
|
+
const [isOpen, setIsOpen] = (0, react_1.useState)(false);
|
|
50
|
+
const [searchTerm, setSearchTerm] = (0, react_1.useState)("");
|
|
51
|
+
const [compareSelectedLayers, setCompareSelectedLayers] = (0, react_1.useState)(new Set());
|
|
52
|
+
const [selectedAttributes, setSelectedAttributes] = (0, react_1.useState)({});
|
|
53
|
+
const [loadingAttributes, setLoadingAttributes] = (0, react_1.useState)({});
|
|
54
|
+
const [layersWithData, setLayersWithData] = (0, react_1.useState)({});
|
|
55
|
+
const fetchingRef = (0, react_1.useRef)(new Set());
|
|
56
|
+
const toggleOpen = () => setIsOpen(!isOpen);
|
|
57
|
+
// Filter layers based on search term
|
|
58
|
+
const filteredLayers = (0, react_1.useMemo)(() => {
|
|
59
|
+
if (!searchTerm.trim()) {
|
|
60
|
+
return layer.all;
|
|
61
|
+
}
|
|
62
|
+
const term = searchTerm.toLowerCase();
|
|
63
|
+
return layer.all.filter((l) => {
|
|
64
|
+
return (l.title?.toLowerCase().includes(term) ||
|
|
65
|
+
l.description?.toLowerCase().includes(term) ||
|
|
66
|
+
l.createdBy?.toLowerCase().includes(term) ||
|
|
67
|
+
l.tags?.some((tag) => tag.toLowerCase().includes(term)));
|
|
68
|
+
});
|
|
69
|
+
}, [layer.all, searchTerm]);
|
|
70
|
+
const handleCompareToggle = (layerId) => {
|
|
71
|
+
setCompareSelectedLayers((prev) => {
|
|
72
|
+
const newSet = new Set(prev);
|
|
73
|
+
if (newSet.has(layerId)) {
|
|
74
|
+
newSet.delete(layerId);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
newSet.add(layerId);
|
|
78
|
+
}
|
|
79
|
+
return newSet;
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
const fetchLayerAttributes = async (layerId) => {
|
|
83
|
+
const layerItem = layer.all.find((l) => l.id === layerId);
|
|
84
|
+
if (!layerItem)
|
|
85
|
+
return;
|
|
86
|
+
// Skip if already fetched or currently loading
|
|
87
|
+
if (layersWithData[layerId] || fetchingRef.current.has(layerId))
|
|
88
|
+
return;
|
|
89
|
+
// If layer already has propertyMap, use it directly
|
|
90
|
+
if (layerItem.data?.propertyMap && Object.keys(layerItem.data.propertyMap).length > 0) {
|
|
91
|
+
setLayersWithData((prev) => ({
|
|
92
|
+
...prev,
|
|
93
|
+
[layerId]: layerItem,
|
|
94
|
+
}));
|
|
95
|
+
setSelectedAttributes((prev) => ({
|
|
96
|
+
...prev,
|
|
97
|
+
[layerId]: new Set(),
|
|
98
|
+
}));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
fetchingRef.current.add(layerId);
|
|
102
|
+
setLoadingAttributes((prev) => ({ ...prev, [layerId]: true }));
|
|
103
|
+
try {
|
|
104
|
+
const layerData = await (0, naksha_1.getLayerStyle)(layerItem, 0, // styleIndex
|
|
105
|
+
mp.nakshaApiEndpoint, mp.geoserver);
|
|
106
|
+
const updatedLayer = {
|
|
107
|
+
...layerItem,
|
|
108
|
+
data: layerData,
|
|
109
|
+
};
|
|
110
|
+
setLayersWithData((prev) => ({
|
|
111
|
+
...prev,
|
|
112
|
+
[layerId]: updatedLayer,
|
|
113
|
+
}));
|
|
114
|
+
setSelectedAttributes((prev) => ({
|
|
115
|
+
...prev,
|
|
116
|
+
[layerId]: new Set(),
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
console.error("Error fetching layer attributes:", error);
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
fetchingRef.current.delete(layerId);
|
|
124
|
+
setLoadingAttributes((prev) => ({ ...prev, [layerId]: false }));
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const handleAttributeToggle = (layerId, attributeKey) => {
|
|
128
|
+
setSelectedAttributes((prev) => {
|
|
129
|
+
const layerAttributes = prev[layerId] || new Set();
|
|
130
|
+
const newSet = new Set(layerAttributes);
|
|
131
|
+
if (newSet.has(attributeKey)) {
|
|
132
|
+
newSet.delete(attributeKey);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
newSet.add(attributeKey);
|
|
136
|
+
// Auto-check the main compare checkbox when any attribute is selected
|
|
137
|
+
if (!compareSelectedLayers.has(layerId)) {
|
|
138
|
+
setCompareSelectedLayers((prevCompare) => {
|
|
139
|
+
const newCompareSet = new Set(prevCompare);
|
|
140
|
+
newCompareSet.add(layerId);
|
|
141
|
+
return newCompareSet;
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
...prev,
|
|
147
|
+
[layerId]: newSet,
|
|
148
|
+
};
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
const handleCompare = () => {
|
|
152
|
+
// TODO: Implement comparison logic
|
|
153
|
+
console.log("Comparing layers:", Array.from(compareSelectedLayers));
|
|
154
|
+
console.log("Selected attributes:", selectedAttributes);
|
|
155
|
+
// This will trigger the actual comparison functionality
|
|
156
|
+
};
|
|
157
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("button", { onClick: toggleOpen, type: "button", className: "absolute left-4 top-[60px] z-10 bg-white rounded-lg shadow-lg flex items-center gap-2 font-medium hover:bg-gray-50 transition-colors border border-gray-200 px-4 py-3", children: [(0, jsx_runtime_1.jsxs)("svg", { width: "18", height: "18", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", viewBox: "0 0 24 24", className: "text-green-600", children: [(0, jsx_runtime_1.jsx)("path", { d: "M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" }), (0, jsx_runtime_1.jsx)("line", { x1: "12", y1: "2", x2: "12", y2: "22" }), (0, jsx_runtime_1.jsx)("line", { x1: "2", y1: "12", x2: "22", y2: "12" })] }), (0, jsx_runtime_1.jsx)("span", { children: "Compare" })] }), isOpen && ((0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 flex items-center justify-center z-50 p-4", children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-white rounded-lg shadow-2xl w-full max-w-3xl h-[85vh] flex flex-col overflow-hidden border border-gray-200", children: [(0, jsx_runtime_1.jsx)("div", { className: "px-6 py-4 border-b border-gray-200 bg-gray-50", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 shrink-0", children: [(0, jsx_runtime_1.jsxs)("svg", { width: "20", height: "20", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", viewBox: "0 0 24 24", className: "text-green-600", children: [(0, jsx_runtime_1.jsx)("path", { d: "M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" }), (0, jsx_runtime_1.jsx)("line", { x1: "12", y1: "2", x2: "12", y2: "22" }), (0, jsx_runtime_1.jsx)("line", { x1: "2", y1: "12", x2: "22", y2: "12" })] }), (0, jsx_runtime_1.jsx)("h2", { className: "text-xl font-semibold text-gray-800 whitespace-nowrap", children: "Map Comparison" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 flex-1 min-w-0 max-w-md", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 min-w-0", children: (0, jsx_runtime_1.jsx)(core_1.SearchInput, { placeholder: "Search layers...", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value) }) }), (0, jsx_runtime_1.jsx)("button", { onClick: toggleOpen, type: "button", className: "flex items-center justify-center w-8 h-8 bg-red-100 hover:bg-red-200 text-red-800 rounded transition-colors shrink-0", title: "Close", children: (0, jsx_runtime_1.jsxs)("svg", { width: "18", height: "18", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", viewBox: "0 0 24 24", children: [(0, jsx_runtime_1.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), (0, jsx_runtime_1.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })] })] }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 min-h-0 overflow-y-auto bg-white", children: filteredLayers.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center h-full min-h-[400px] p-8 text-center text-gray-500", children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { className: "mb-2 text-base", children: searchTerm ? "No layers found" : "No layers available" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm", children: searchTerm
|
|
158
|
+
? "Try adjusting your search terms"
|
|
159
|
+
: "Layers will appear here when available" })] }) })) : (filteredLayers.map((layerItem) => {
|
|
160
|
+
// Use fetched layer data if available, otherwise use original
|
|
161
|
+
const layerData = layersWithData[layerItem.id] || layerItem;
|
|
162
|
+
return ((0, jsx_runtime_1.jsx)(LayerCard, { layer: layerData, isLoadingAttributes: loadingAttributes[layerItem.id] || false, selectedAttributes: selectedAttributes[layerItem.id] || new Set(), onDropdownToggle: () => fetchLayerAttributes(layerItem.id), onAttributeToggle: (attributeKey) => handleAttributeToggle(layerItem.id, attributeKey) }, layerItem.id));
|
|
163
|
+
})) }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-end gap-3 px-6 py-4 border-t border-gray-200 bg-gray-50", children: (0, jsx_runtime_1.jsx)("button", { onClick: handleCompare, type: "button", className: "px-5 py-2.5 text-white bg-green-600 hover:bg-green-700 rounded-md transition-colors font-medium text-sm shadow-sm", children: "Compare" }) })] }) }))] }));
|
|
164
|
+
};
|
|
165
|
+
exports.default = MapComparison;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { GeoserverLayer } from "../../interfaces";
|
|
2
|
+
export type ComparisonMode = "side-by-side" | "overlay" | "attribute";
|
|
3
|
+
export interface ComparisonLayer {
|
|
4
|
+
layerId: string;
|
|
5
|
+
layer: GeoserverLayer;
|
|
6
|
+
attributeKey?: string;
|
|
7
|
+
attributeLabel?: string;
|
|
8
|
+
styleIndex?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ComparisonConfig {
|
|
11
|
+
mode: ComparisonMode;
|
|
12
|
+
layers: ComparisonLayer[];
|
|
13
|
+
syncView: boolean;
|
|
14
|
+
showStats: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface ComparisonStats {
|
|
17
|
+
layerId: string;
|
|
18
|
+
attributeKey?: string;
|
|
19
|
+
totalFeatures?: number;
|
|
20
|
+
minValue?: number;
|
|
21
|
+
maxValue?: number;
|
|
22
|
+
avgValue?: number;
|
|
23
|
+
uniqueValues?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface AttributeOption {
|
|
26
|
+
key: string;
|
|
27
|
+
label: string;
|
|
28
|
+
type: "numeric" | "categorical" | "date";
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/map-comparison/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,SAAS,GAAG,WAAW,CAAC;AAEtE,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,cAAc,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,GAAG,aAAa,GAAG,MAAM,CAAC;CAC1C"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { GeoserverLayer } from "../../interfaces";
|
|
2
|
+
import { ComparisonConfig, ComparisonMode, AttributeOption } from "./types";
|
|
3
|
+
export declare function useMapComparison(): {
|
|
4
|
+
isOpen: boolean;
|
|
5
|
+
setIsOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
6
|
+
config: ComparisonConfig;
|
|
7
|
+
availableLayers: GeoserverLayer[];
|
|
8
|
+
getLayerAttributes: (layerId: string) => AttributeOption[];
|
|
9
|
+
addLayer: (layerId: string, attributeKey?: string, styleIndex?: number) => void;
|
|
10
|
+
removeLayer: (layerId: string) => void;
|
|
11
|
+
updateLayerAttribute: (layerId: string, attributeKey?: string, styleIndex?: number) => void;
|
|
12
|
+
setMode: (mode: ComparisonMode) => void;
|
|
13
|
+
toggleSyncView: () => void;
|
|
14
|
+
toggleStats: () => void;
|
|
15
|
+
clearComparison: () => void;
|
|
16
|
+
isLayerInComparison: (layerId: string) => boolean;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=use-map-comparison.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-map-comparison.d.ts","sourceRoot":"","sources":["../../../src/components/map-comparison/use-map-comparison.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EACL,gBAAgB,EAEhB,cAAc,EACd,eAAe,EAChB,MAAM,SAAS,CAAC;AAGjB,wBAAgB,gBAAgB;;;;;kCAiBlB,MAAM,KAAG,eAAe,EAAE;wBAqCzB,MAAM,iBACA,MAAM,eACR,MAAM;2BA2BmB,MAAM;oCASpC,MAAM,iBAAiB,MAAM,eAAe,MAAM;oBA0B3B,cAAc;;;;mCA0BrC,MAAM;EAqBnB"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useMapComparison = useMapComparison;
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
const use_layers_1 = __importDefault(require("../../hooks/use-layers"));
|
|
9
|
+
function useMapComparison() {
|
|
10
|
+
const { layer } = (0, use_layers_1.default)();
|
|
11
|
+
const [isOpen, setIsOpen] = (0, react_1.useState)(false);
|
|
12
|
+
const [config, setConfig] = (0, react_1.useState)({
|
|
13
|
+
mode: "side-by-side",
|
|
14
|
+
layers: [],
|
|
15
|
+
syncView: true,
|
|
16
|
+
showStats: false,
|
|
17
|
+
});
|
|
18
|
+
// Get available layers
|
|
19
|
+
const availableLayers = (0, react_1.useMemo)(() => {
|
|
20
|
+
return layer.all || [];
|
|
21
|
+
}, [layer.all]);
|
|
22
|
+
// Get available attributes for a layer
|
|
23
|
+
const getLayerAttributes = (0, react_1.useCallback)((layerId) => {
|
|
24
|
+
const layerData = availableLayers.find((l) => l.id === layerId);
|
|
25
|
+
if (!layerData?.data?.propertyMap)
|
|
26
|
+
return [];
|
|
27
|
+
const attributes = [];
|
|
28
|
+
const propertyMap = layerData.data.propertyMap;
|
|
29
|
+
// Add all properties from propertyMap
|
|
30
|
+
Object.entries(propertyMap).forEach(([key, label]) => {
|
|
31
|
+
attributes.push({
|
|
32
|
+
key,
|
|
33
|
+
label: String(label),
|
|
34
|
+
type: "categorical", // Default, can be enhanced with actual type detection
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
// Add style-based attributes if available
|
|
38
|
+
if (layerData.data.styles && layerData.data.styles.length > 0) {
|
|
39
|
+
layerData.data.styles.forEach((style, index) => {
|
|
40
|
+
if (style.styleName) {
|
|
41
|
+
attributes.push({
|
|
42
|
+
key: `style_${index}`,
|
|
43
|
+
label: style.styleTitle || style.styleName,
|
|
44
|
+
type: "categorical",
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return attributes;
|
|
50
|
+
}, [availableLayers]);
|
|
51
|
+
// Add layer to comparison
|
|
52
|
+
const addLayer = (0, react_1.useCallback)((layerId, attributeKey, styleIndex) => {
|
|
53
|
+
const layerData = availableLayers.find((l) => l.id === layerId);
|
|
54
|
+
if (!layerData)
|
|
55
|
+
return;
|
|
56
|
+
const attributeLabel = attributeKey
|
|
57
|
+
? getLayerAttributes(layerId).find((attr) => attr.key === attributeKey)
|
|
58
|
+
?.label || attributeKey
|
|
59
|
+
: undefined;
|
|
60
|
+
const newLayer = {
|
|
61
|
+
layerId,
|
|
62
|
+
layer: layerData,
|
|
63
|
+
attributeKey,
|
|
64
|
+
attributeLabel,
|
|
65
|
+
styleIndex,
|
|
66
|
+
};
|
|
67
|
+
setConfig((prev) => ({
|
|
68
|
+
...prev,
|
|
69
|
+
layers: [...prev.layers, newLayer],
|
|
70
|
+
}));
|
|
71
|
+
}, [availableLayers, getLayerAttributes]);
|
|
72
|
+
// Remove layer from comparison
|
|
73
|
+
const removeLayer = (0, react_1.useCallback)((layerId) => {
|
|
74
|
+
setConfig((prev) => ({
|
|
75
|
+
...prev,
|
|
76
|
+
layers: prev.layers.filter((l) => l.layerId !== layerId),
|
|
77
|
+
}));
|
|
78
|
+
}, []);
|
|
79
|
+
// Update layer attribute
|
|
80
|
+
const updateLayerAttribute = (0, react_1.useCallback)((layerId, attributeKey, styleIndex) => {
|
|
81
|
+
setConfig((prev) => ({
|
|
82
|
+
...prev,
|
|
83
|
+
layers: prev.layers.map((l) => {
|
|
84
|
+
if (l.layerId === layerId) {
|
|
85
|
+
const attributeLabel = attributeKey
|
|
86
|
+
? getLayerAttributes(layerId).find((attr) => attr.key === attributeKey)?.label || attributeKey
|
|
87
|
+
: undefined;
|
|
88
|
+
return {
|
|
89
|
+
...l,
|
|
90
|
+
attributeKey,
|
|
91
|
+
attributeLabel,
|
|
92
|
+
styleIndex,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return l;
|
|
96
|
+
}),
|
|
97
|
+
}));
|
|
98
|
+
}, [getLayerAttributes]);
|
|
99
|
+
// Set comparison mode
|
|
100
|
+
const setMode = (0, react_1.useCallback)((mode) => {
|
|
101
|
+
setConfig((prev) => ({ ...prev, mode }));
|
|
102
|
+
}, []);
|
|
103
|
+
// Toggle sync view
|
|
104
|
+
const toggleSyncView = (0, react_1.useCallback)(() => {
|
|
105
|
+
setConfig((prev) => ({ ...prev, syncView: !prev.syncView }));
|
|
106
|
+
}, []);
|
|
107
|
+
// Toggle stats
|
|
108
|
+
const toggleStats = (0, react_1.useCallback)(() => {
|
|
109
|
+
setConfig((prev) => ({ ...prev, showStats: !prev.showStats }));
|
|
110
|
+
}, []);
|
|
111
|
+
// Clear all comparisons
|
|
112
|
+
const clearComparison = (0, react_1.useCallback)(() => {
|
|
113
|
+
setConfig({
|
|
114
|
+
mode: "side-by-side",
|
|
115
|
+
layers: [],
|
|
116
|
+
syncView: true,
|
|
117
|
+
showStats: false,
|
|
118
|
+
});
|
|
119
|
+
}, []);
|
|
120
|
+
// Check if layer is in comparison
|
|
121
|
+
const isLayerInComparison = (0, react_1.useCallback)((layerId) => {
|
|
122
|
+
return config.layers.some((l) => l.layerId === layerId);
|
|
123
|
+
}, [config.layers]);
|
|
124
|
+
return {
|
|
125
|
+
isOpen,
|
|
126
|
+
setIsOpen,
|
|
127
|
+
config,
|
|
128
|
+
availableLayers,
|
|
129
|
+
getLayerAttributes,
|
|
130
|
+
addLayer,
|
|
131
|
+
removeLayer,
|
|
132
|
+
updateLayerAttribute,
|
|
133
|
+
setMode,
|
|
134
|
+
toggleSyncView,
|
|
135
|
+
toggleStats,
|
|
136
|
+
clearComparison,
|
|
137
|
+
isLayerInComparison,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { GeoserverLayer } from "../../../interfaces";
|
|
2
|
+
interface AttributeCompareAddonProps {
|
|
3
|
+
layer: GeoserverLayer;
|
|
4
|
+
}
|
|
5
|
+
export default function AttributeCompareAddon({ layer }: AttributeCompareAddonProps): import("react/jsx-runtime").JSX.Element | null;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=attribute-compare-addon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribute-compare-addon.d.ts","sourceRoot":"","sources":["../../../../src/components/sidebar/common/attribute-compare-addon.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,UAAU,0BAA0B;IAClC,KAAK,EAAE,cAAc,CAAC;CACvB;AAED,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,0BAA0B,kDAyElF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = AttributeCompareAddon;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
// AttributeCompareAddon.tsx - Component to compare different attributes of the same layer
|
|
9
|
+
const react_1 = require("react");
|
|
10
|
+
const use_layers_1 = __importDefault(require("../../../hooks/use-layers"));
|
|
11
|
+
function AttributeCompareAddon({ layer }) {
|
|
12
|
+
const { layer: layerContext } = (0, use_layers_1.default)();
|
|
13
|
+
// Get available attributes (styles) for this layer
|
|
14
|
+
const availableAttributes = (0, react_1.useMemo)(() => {
|
|
15
|
+
if (!layer.data?.styles || !Array.isArray(layer.data.styles)) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
return layer.data.styles.map((style, index) => ({
|
|
19
|
+
styleIndex: index,
|
|
20
|
+
attributeKey: style.styleName || `attribute_${index}`,
|
|
21
|
+
attributeTitle: style.styleTitle || `Attribute ${index + 1}`,
|
|
22
|
+
}));
|
|
23
|
+
}, [layer.data?.styles]);
|
|
24
|
+
// Don't show if layer has less than 2 attributes
|
|
25
|
+
if (availableAttributes.length < 2) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const comparedAttributes = layerContext.getComparedAttributes(layer.id);
|
|
29
|
+
const handleToggleAttribute = async (attributeKey, styleIndex, checked) => {
|
|
30
|
+
await layerContext.setCompareAttribute(layer.id, attributeKey, styleIndex, checked);
|
|
31
|
+
};
|
|
32
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-2 pt-2 border-t border-gray-200", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-sm font-medium text-gray-700", children: "Compare Attributes" }), (0, jsx_runtime_1.jsx)("div", { className: "flex flex-col gap-2", children: availableAttributes.map((attr) => {
|
|
33
|
+
const isChecked = layerContext.isAttributeCompared(layer.id, attr.attributeKey, attr.styleIndex);
|
|
34
|
+
return ((0, jsx_runtime_1.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer select-none text-sm", children: [(0, jsx_runtime_1.jsx)("input", { type: "checkbox", className: "h-4 w-4 accent-blue-600", checked: isChecked, onChange: (e) => handleToggleAttribute(attr.attributeKey, attr.styleIndex, e.target.checked) }), (0, jsx_runtime_1.jsx)("span", { className: "text-gray-700", children: attr.attributeTitle })] }, `${attr.styleIndex}-${attr.attributeKey}`));
|
|
35
|
+
}) }), comparedAttributes.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-gray-500 mt-1", children: [comparedAttributes.length, " attribute", comparedAttributes.length > 1 ? "s" : "", " selected"] }))] }));
|
|
36
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layer-item-style.d.ts","sourceRoot":"","sources":["../../../../src/components/sidebar/common/layer-item-style.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"layer-item-style.d.ts","sourceRoot":"","sources":["../../../../src/components/sidebar/common/layer-item-style.tsx"],"names":[],"mappings":"AAQA,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,GAAG,CAAA;CAAE,kDA4H7D"}
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.default = LayerItemStyle;
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
8
|
// @ts-nocheck
|
|
9
|
+
const react_1 = require("react");
|
|
9
10
|
const use_layers_1 = __importDefault(require("../../../hooks/use-layers"));
|
|
10
11
|
const core_1 = require("../../core");
|
|
11
12
|
const moreless_1 = __importDefault(require("./moreless"));
|
|
@@ -14,8 +15,52 @@ function LayerItemStyle({ item }) {
|
|
|
14
15
|
if (!item.data?.styles)
|
|
15
16
|
return null;
|
|
16
17
|
const { layer } = (0, use_layers_1.default)();
|
|
18
|
+
const [isOpen, setIsOpen] = (0, react_1.useState)(false);
|
|
19
|
+
const [selectedIndex, setSelectedIndex] = (0, react_1.useState)(0);
|
|
20
|
+
const dropdownRef = (0, react_1.useRef)(null);
|
|
21
|
+
// Close dropdown when clicking outside
|
|
22
|
+
(0, react_1.useEffect)(() => {
|
|
23
|
+
const handleClickOutside = (event) => {
|
|
24
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
25
|
+
setIsOpen(false);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
if (isOpen) {
|
|
29
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
30
|
+
}
|
|
31
|
+
return () => {
|
|
32
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
33
|
+
};
|
|
34
|
+
}, [isOpen]);
|
|
17
35
|
const onStyleChange = (e) => {
|
|
18
36
|
layer.updateStyle(item.id, Number(e.target.value));
|
|
37
|
+
setSelectedIndex(Number(e.target.value));
|
|
19
38
|
};
|
|
20
|
-
|
|
39
|
+
// Toggle checkbox for comparison (independent from dropdown selection)
|
|
40
|
+
const onCheckboxToggle = (styleIndex, event) => {
|
|
41
|
+
event.stopPropagation(); // Prevent dropdown item click
|
|
42
|
+
const attributeKey = `${item.id}-${styleIndex}`;
|
|
43
|
+
layer.toggleAttributeCompare(attributeKey);
|
|
44
|
+
};
|
|
45
|
+
const selectedStyle = item.data?.styles[selectedIndex];
|
|
46
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-4 pt-2", children: [item.layerType !== "RASTER" && ((0, jsx_runtime_1.jsxs)("div", { className: "relative", ref: dropdownRef, children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", onClick: () => setIsOpen(!isOpen), className: "block w-full px-4 py-2 mt-2 text-gray-700 border bg-white border-gray-200 rounded-md focus:outline-none focus:ring text-left flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("span", { children: selectedStyle?.styleTitle || "Select attribute" }), (0, jsx_runtime_1.jsx)("svg", { className: `w-4 h-4 transition-transform ${isOpen ? "rotate-180" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })] }), isOpen && ((0, jsx_runtime_1.jsx)("div", { className: "absolute z-50 w-full mt-1 bg-white border border-gray-200 rounded-md shadow-lg max-h-60 overflow-auto", children: item.data?.styles.map((opt, idx) => {
|
|
47
|
+
const attributeKey = `${item.id}-${idx}`;
|
|
48
|
+
const isChecked = layer.checkedAttributes.has(attributeKey);
|
|
49
|
+
const checkedCount = layer.getCheckedAttributesCount();
|
|
50
|
+
const isLimitReached = checkedCount >= 8 && !isChecked;
|
|
51
|
+
const isSelected = idx === selectedIndex;
|
|
52
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: `flex items-center justify-between px-4 py-2 border-b border-gray-100 last:border-b-0 ${isSelected
|
|
53
|
+
? "bg-blue-50 hover:bg-blue-100"
|
|
54
|
+
: "hover:bg-gray-50"}`, children: [(0, jsx_runtime_1.jsx)("span", { className: "flex-1 text-gray-700 cursor-pointer", onClick: () => {
|
|
55
|
+
onStyleChange({ target: { value: idx } });
|
|
56
|
+
setIsOpen(false);
|
|
57
|
+
}, children: opt.styleTitle }), (0, jsx_runtime_1.jsx)("div", { onClick: (e) => {
|
|
58
|
+
if (isLimitReached) {
|
|
59
|
+
e.stopPropagation();
|
|
60
|
+
alert("Maximum 8 attributes can be compared at a time");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
onCheckboxToggle(idx, e);
|
|
64
|
+
}, className: isLimitReached ? "opacity-50 cursor-not-allowed" : "cursor-pointer", title: isLimitReached ? "Maximum 8 attributes can be compared at a time" : "", children: (0, jsx_runtime_1.jsx)(core_1.CheckboxInput, { name: `compare-${item.id}-${idx}`, checked: isChecked, disabled: isLimitReached, onChange: () => { } }) })] }, idx));
|
|
65
|
+
}) }))] })), (0, jsx_runtime_1.jsx)(moreless_1.default, { children: (0, jsx_runtime_1.jsx)(style_legend_1.StyleLegend, { item: item }) })] }));
|
|
21
66
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layer-item.d.ts","sourceRoot":"","sources":["../../../../src/components/sidebar/common/layer-item.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"layer-item.d.ts","sourceRoot":"","sources":["../../../../src/components/sidebar/common/layer-item.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAwBrD,UAAU,cAAc;IACtB,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,oDAAoD;IACpD,eAAe,CAAC,EAAE,GAAG,CAAC;IACtB,aAAa,CAAC,EAAE,GAAG,CAAC;CACrB;AAED,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAChC,IAAI,EACJ,QAAQ,EACR,eAAe,EACf,aAAa,GACd,EAAE,cAAc,2CAmIhB"}
|
|
@@ -15,7 +15,6 @@ const grid_legend_1 = __importDefault(require("./grid-legend"));
|
|
|
15
15
|
const info_popover_1 = require("./info-popover");
|
|
16
16
|
const layer_item_style_1 = __importDefault(require("./layer-item-style"));
|
|
17
17
|
const opacity_handler_addon_1 = __importDefault(require("./opacity-handler-addon"));
|
|
18
|
-
const layer_compare_addon_1 = __importDefault(require("./layer-compare-addon"));
|
|
19
18
|
function LayerItem({ item, extended, dragHandleProps, dragHandleRef, }) {
|
|
20
19
|
const { layer, query, mp, query: { setClickedLngLat }, setIsInfoBarOpen, } = (0, use_layers_1.default)();
|
|
21
20
|
const [isAdded, setIsAdded] = (0, react_1.useState)(layer.selectedIds.includes(item.id));
|
|
@@ -56,5 +55,5 @@ function LayerItem({ item, extended, dragHandleProps, dragHandleRef, }) {
|
|
|
56
55
|
mp?.onLayerDownload(item.id);
|
|
57
56
|
};
|
|
58
57
|
const handleOnZoom = () => layer?.zoomToExtent(item?.id);
|
|
59
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "z-20 p-3 bg-white border-t border-gray-200", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center shrink-0", children: [(0, jsx_runtime_1.jsx)(core_1.CheckboxInput, { name: item.id, checked: isAdded, onChange: onToggleLayer, isLoading: isLoading }), extended && ((0, jsx_runtime_1.jsx)("div", { ref: dragHandleRef, ...dragHandleProps, className: "mt-1 w-6 text-center cursor-move", children: (0, jsx_runtime_1.jsx)(core_1.GrabberIcon, {}) }))] }), (0, jsx_runtime_1.jsx)("img", { className: "flex shrink-0 overflow-hidden h-16 w-16 p-1 mb-2 object-cover border border-gray-200 rounded", src: item.thumbnail || constants_1.FALLBACK_THUMB }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { title: item.title, className: "mb-1 leading-tight", style: constants_1.overflowStyle, children: (0, jsx_runtime_1.jsx)(highlighter_1.Highlighted, { text: item.title, highlight: query.term }) }), (0, jsx_runtime_1.jsx)("p", { title: item.description, className: "text-gray-600 text-sm", style: constants_1.overflowStyle2, children: item.description })] })] }), (0, jsx_runtime_1.jsx)("div", { className: "pb-3", children: extended && (0, jsx_runtime_1.jsx)(opacity_handler_addon_1.default, {}) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between", children: [
|
|
58
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "z-20 p-3 bg-white border-t border-gray-200", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center shrink-0", children: [(0, jsx_runtime_1.jsx)(core_1.CheckboxInput, { name: item.id, checked: isAdded, onChange: onToggleLayer, isLoading: isLoading }), extended && ((0, jsx_runtime_1.jsx)("div", { ref: dragHandleRef, ...dragHandleProps, className: "mt-1 w-6 text-center cursor-move", children: (0, jsx_runtime_1.jsx)(core_1.GrabberIcon, {}) }))] }), (0, jsx_runtime_1.jsx)("img", { className: "flex shrink-0 overflow-hidden h-16 w-16 p-1 mb-2 object-cover border border-gray-200 rounded", src: item.thumbnail || constants_1.FALLBACK_THUMB }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { title: item.title, className: "mb-1 leading-tight", style: constants_1.overflowStyle, children: (0, jsx_runtime_1.jsx)(highlighter_1.Highlighted, { text: item.title, highlight: query.term }) }), (0, jsx_runtime_1.jsx)("p", { title: item.description, className: "text-gray-600 text-sm", style: constants_1.overflowStyle2, children: item.description })] })] }), (0, jsx_runtime_1.jsx)("div", { className: "pb-3", children: extended && (0, jsx_runtime_1.jsx)(opacity_handler_addon_1.default, { layerId: item.id }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between", children: [!extended && ((0, jsx_runtime_1.jsxs)(core_1.Button, { onClick: onDownloadLayer, disabled: !item.isDownloadable, children: [(0, jsx_runtime_1.jsx)(core_1.DownloadIcon, {}), " Download"] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-3", children: [(0, jsx_runtime_1.jsx)(core_1.Button, { onClick: shareLayer, title: "Share", children: (0, jsx_runtime_1.jsx)(core_1.ShareIcon, {}) }), extended && ((0, jsx_runtime_1.jsx)(core_1.Button, { onClick: handleOnZoom, title: "Zoom To Extent", children: (0, jsx_runtime_1.jsx)(core_1.ZoomExtentIcon, {}) })), (0, jsx_runtime_1.jsx)(info_popover_1.PopoverWrapper, { item: item })] })] }), extended && (0, jsx_runtime_1.jsx)(layer_item_style_1.default, { item: item }), extended && item?.source?.type === "grid" && (0, jsx_runtime_1.jsx)(grid_legend_1.default, { item: item })] }));
|
|
60
59
|
}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
interface OpacityHandlerProps {
|
|
2
|
+
layerId: string;
|
|
3
|
+
}
|
|
4
|
+
declare const OpacityHandler: ({ layerId }: OpacityHandlerProps) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export default OpacityHandler;
|
|
3
6
|
//# sourceMappingURL=opacity-handler-addon.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opacity-handler-addon.d.ts","sourceRoot":"","sources":["../../../../src/components/sidebar/common/opacity-handler-addon.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"opacity-handler-addon.d.ts","sourceRoot":"","sources":["../../../../src/components/sidebar/common/opacity-handler-addon.tsx"],"names":[],"mappings":"AAGA,UAAU,mBAAmB;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,QAAA,MAAM,cAAc,GAAI,aAAa,mBAAmB,4CAgIvD,CAAC;AAEF,eAAe,cAAc,CAAC"}
|