@smartnet360/svelte-components 0.0.85 → 0.0.87
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/apps/antenna-pattern/components/AntennaControls.svelte +1 -106
- package/dist/apps/antenna-pattern/components/AntennaDiagrams.svelte +0 -36
- package/dist/apps/antenna-pattern/components/AntennaSettingsModal.svelte +0 -2
- package/dist/apps/antenna-pattern/components/PlotlyRadarChart.svelte +0 -22
- package/dist/apps/antenna-pattern/components/chart-engines/PolarAreaChart.svelte +0 -2
- package/dist/apps/antenna-pattern/components/chart-engines/PolarBarChart.svelte +0 -2
- package/dist/apps/antenna-pattern/components/chart-engines/PolarLineChart.svelte +0 -2
- package/dist/apps/site-check/data-loader.js +0 -8
- package/dist/core/Charts/GlobalControls.svelte +0 -4
- package/dist/core/Desktop/Grid/ResizeHandle.svelte +0 -7
- package/dist/core/Desktop/Grid/resizeStore.js +0 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/map-v2/demo/DemoMap.svelte +0 -2
- package/dist/map-v2/demo/demo-cells.js +0 -1
- package/dist/map-v2/features/cells/layers/CellsLayer.svelte +7 -26
- package/dist/map-v2/features/cells/utils/cellTree.js +0 -29
- package/dist/map-v2/features/repeaters/layers/RepeaterLabelsLayer.svelte +3 -27
- package/dist/map-v2/features/repeaters/layers/RepeatersLayer.svelte +8 -25
- package/dist/map-v2/features/repeaters/utils/repeaterTree.js +0 -6
- package/dist/map-v2/features/sites/controls/SiteFilterControl.svelte +0 -8
- package/dist/map-v2/features/sites/utils/siteTreeUtils.js +0 -6
- package/dist/map-v3/core/components/Map.svelte +89 -0
- package/dist/map-v3/core/components/Map.svelte.d.ts +13 -0
- package/dist/map-v3/core/controls/FeatureSettingsControl.svelte +103 -0
- package/dist/map-v3/core/controls/FeatureSettingsControl.svelte.d.ts +15 -0
- package/dist/map-v3/core/controls/MapStyleControl.svelte +271 -0
- package/dist/map-v3/core/controls/MapStyleControl.svelte.d.ts +28 -0
- package/dist/map-v3/core/index.d.ts +6 -0
- package/dist/map-v3/core/index.js +5 -0
- package/dist/map-v3/core/stores/map.store.svelte.d.ts +8 -0
- package/dist/map-v3/core/stores/map.store.svelte.js +29 -0
- package/dist/map-v3/core/stores/viewport.store.svelte.d.ts +38 -0
- package/dist/map-v3/core/stores/viewport.store.svelte.js +107 -0
- package/dist/map-v3/demo/DemoMap.svelte +104 -0
- package/dist/map-v3/demo/DemoMap.svelte.d.ts +6 -0
- package/dist/map-v3/demo/demo-cells.d.ts +13 -0
- package/dist/map-v3/demo/demo-cells.js +130 -0
- package/dist/map-v3/demo/demo-data.d.ts +8 -0
- package/dist/map-v3/demo/demo-data.js +104 -0
- package/dist/map-v3/demo/demo-repeaters.d.ts +13 -0
- package/dist/map-v3/demo/demo-repeaters.js +73 -0
- package/dist/map-v3/features/cells/components/CellFilterControl.svelte +208 -0
- package/dist/map-v3/features/cells/components/CellFilterControl.svelte.d.ts +12 -0
- package/dist/map-v3/features/cells/components/CellSettingsPanel.svelte +229 -0
- package/dist/map-v3/features/cells/components/CellSettingsPanel.svelte.d.ts +7 -0
- package/dist/map-v3/features/cells/constants.d.ts +18 -0
- package/dist/map-v3/features/cells/constants.js +37 -0
- package/dist/map-v3/features/cells/layers/CellLabelsLayer.svelte +230 -0
- package/dist/map-v3/features/cells/layers/CellLabelsLayer.svelte.d.ts +11 -0
- package/dist/map-v3/features/cells/layers/CellsLayer.svelte +194 -0
- package/dist/map-v3/features/cells/layers/CellsLayer.svelte.d.ts +11 -0
- package/dist/map-v3/features/cells/layers/index.d.ts +2 -0
- package/dist/map-v3/features/cells/layers/index.js +2 -0
- package/dist/map-v3/features/cells/logic/geometry.d.ts +12 -0
- package/dist/map-v3/features/cells/logic/geometry.js +35 -0
- package/dist/map-v3/features/cells/logic/grouping.d.ts +18 -0
- package/dist/map-v3/features/cells/logic/grouping.js +30 -0
- package/dist/map-v3/features/cells/logic/tree-adapter.d.ts +11 -0
- package/dist/map-v3/features/cells/logic/tree-adapter.js +53 -0
- package/dist/map-v3/features/cells/stores/cell.data.svelte.d.ts +9 -0
- package/dist/map-v3/features/cells/stores/cell.data.svelte.js +16 -0
- package/dist/map-v3/features/cells/stores/cell.display.svelte.d.ts +25 -0
- package/dist/map-v3/features/cells/stores/cell.display.svelte.js +67 -0
- package/dist/map-v3/features/cells/stores/cell.registry.svelte.d.ts +23 -0
- package/dist/map-v3/features/cells/stores/cell.registry.svelte.js +68 -0
- package/dist/map-v3/features/cells/types.d.ts +62 -0
- package/dist/map-v3/features/cells/types.js +6 -0
- package/dist/map-v3/features/repeaters/components/RepeaterFilterControl.svelte +148 -0
- package/dist/map-v3/features/repeaters/components/RepeaterFilterControl.svelte.d.ts +12 -0
- package/dist/map-v3/features/repeaters/components/RepeaterSettingsPanel.svelte +209 -0
- package/dist/map-v3/features/repeaters/components/RepeaterSettingsPanel.svelte.d.ts +7 -0
- package/dist/map-v3/features/repeaters/layers/RepeaterLabelsLayer.svelte +177 -0
- package/dist/map-v3/features/repeaters/layers/RepeaterLabelsLayer.svelte.d.ts +11 -0
- package/dist/map-v3/features/repeaters/layers/RepeatersLayer.svelte +163 -0
- package/dist/map-v3/features/repeaters/layers/RepeatersLayer.svelte.d.ts +11 -0
- package/dist/map-v3/features/repeaters/logic/geometry.d.ts +3 -0
- package/dist/map-v3/features/repeaters/logic/geometry.js +23 -0
- package/dist/map-v3/features/repeaters/logic/grouping.d.ts +8 -0
- package/dist/map-v3/features/repeaters/logic/grouping.js +20 -0
- package/dist/map-v3/features/repeaters/logic/tree-adapter.d.ts +8 -0
- package/dist/map-v3/features/repeaters/logic/tree-adapter.js +43 -0
- package/dist/map-v3/features/repeaters/stores/repeater.data.svelte.d.ts +8 -0
- package/dist/map-v3/features/repeaters/stores/repeater.data.svelte.js +13 -0
- package/dist/map-v3/features/repeaters/stores/repeater.display.svelte.d.ts +21 -0
- package/dist/map-v3/features/repeaters/stores/repeater.display.svelte.js +64 -0
- package/dist/map-v3/features/repeaters/stores/repeater.registry.svelte.d.ts +23 -0
- package/dist/map-v3/features/repeaters/stores/repeater.registry.svelte.js +68 -0
- package/dist/map-v3/features/repeaters/types.d.ts +18 -0
- package/dist/map-v3/features/repeaters/types.js +1 -0
- package/dist/map-v3/features/sites/components/SiteFilterControl.svelte +119 -0
- package/dist/map-v3/features/sites/components/SiteFilterControl.svelte.d.ts +12 -0
- package/dist/map-v3/features/sites/components/SiteSettingsPanel.svelte +241 -0
- package/dist/map-v3/features/sites/components/SiteSettingsPanel.svelte.d.ts +7 -0
- package/dist/map-v3/features/sites/layers/SiteLabelsLayer.svelte +152 -0
- package/dist/map-v3/features/sites/layers/SiteLabelsLayer.svelte.d.ts +11 -0
- package/dist/map-v3/features/sites/layers/SitesLayer.svelte +132 -0
- package/dist/map-v3/features/sites/layers/SitesLayer.svelte.d.ts +11 -0
- package/dist/map-v3/features/sites/logic/tree-adapter.d.ts +9 -0
- package/dist/map-v3/features/sites/logic/tree-adapter.js +75 -0
- package/dist/map-v3/features/sites/stores/site.data.svelte.d.ts +8 -0
- package/dist/map-v3/features/sites/stores/site.data.svelte.js +40 -0
- package/dist/map-v3/features/sites/stores/site.display.svelte.d.ts +20 -0
- package/dist/map-v3/features/sites/stores/site.display.svelte.js +63 -0
- package/dist/map-v3/features/sites/stores/site.registry.svelte.d.ts +13 -0
- package/dist/map-v3/features/sites/stores/site.registry.svelte.js +83 -0
- package/dist/map-v3/features/sites/types.d.ts +12 -0
- package/dist/map-v3/features/sites/types.js +1 -0
- package/dist/map-v3/index.d.ts +30 -0
- package/dist/map-v3/index.js +36 -0
- package/dist/map-v3/shared/controls/MapControl.svelte +242 -0
- package/dist/map-v3/shared/controls/MapControl.svelte.d.ts +27 -0
- package/dist/map-v3/shared/index.d.ts +1 -0
- package/dist/map-v3/shared/index.js +1 -0
- package/package.json +1 -1
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import type { RepeaterStoreContext } from '../stores/repeaterStoreContext.svelte';
|
|
17
17
|
import type { Repeater } from '../types';
|
|
18
18
|
import * as turf from '@turf/turf';
|
|
19
|
+
import { log } from '../../../../core/logger';
|
|
19
20
|
|
|
20
21
|
interface Props {
|
|
21
22
|
/** Repeater store context */
|
|
@@ -66,18 +67,7 @@
|
|
|
66
67
|
function buildLabelFeatures(): GeoJSON.FeatureCollection {
|
|
67
68
|
const features: GeoJSON.Feature[] = [];
|
|
68
69
|
|
|
69
|
-
console.log('RepeaterLabelsLayer: Building label features', {
|
|
70
|
-
showLabels: store.showLabels,
|
|
71
|
-
filteredRepeatersCount: store.filteredRepeaters.length,
|
|
72
|
-
hasMap: !!map
|
|
73
|
-
});
|
|
74
|
-
|
|
75
70
|
if (!store.showLabels || store.filteredRepeaters.length === 0 || !map) {
|
|
76
|
-
console.log('RepeaterLabelsLayer: Skipping labels -', {
|
|
77
|
-
showLabels: store.showLabels,
|
|
78
|
-
hasRepeaters: store.filteredRepeaters.length > 0,
|
|
79
|
-
hasMap: !!map
|
|
80
|
-
});
|
|
81
71
|
return { type: 'FeatureCollection', features: [] };
|
|
82
72
|
}
|
|
83
73
|
|
|
@@ -134,11 +124,7 @@
|
|
|
134
124
|
});
|
|
135
125
|
});
|
|
136
126
|
|
|
137
|
-
|
|
138
|
-
totalRepeaters: store.filteredRepeaters.length,
|
|
139
|
-
visibleInViewport: visibleRepeaters.length,
|
|
140
|
-
featuresGenerated: features.length
|
|
141
|
-
});
|
|
127
|
+
log('RepeaterLabelsLayer features:', features.length, 'of', visibleRepeaters.length, 'visible repeaters');
|
|
142
128
|
|
|
143
129
|
return { type: 'FeatureCollection', features };
|
|
144
130
|
}
|
|
@@ -151,15 +137,7 @@
|
|
|
151
137
|
|
|
152
138
|
const geojson = buildLabelFeatures();
|
|
153
139
|
|
|
154
|
-
|
|
155
|
-
sourceExists: !!map.getSource(sourceId),
|
|
156
|
-
layerExists: !!map.getLayer(layerId),
|
|
157
|
-
featureCount: geojson.features.length,
|
|
158
|
-
currentZoom: map.getZoom(),
|
|
159
|
-
minLabelZoom: store.minLabelZoom,
|
|
160
|
-
labelSize: store.labelSize,
|
|
161
|
-
labelColor: store.labelColor
|
|
162
|
-
});
|
|
140
|
+
log('RepeaterLabelsLayer: Updating', geojson.features.length, 'labels');
|
|
163
141
|
|
|
164
142
|
const source = map.getSource(sourceId) as mapboxgl.GeoJSONSource;
|
|
165
143
|
source.setData(geojson);
|
|
@@ -171,8 +149,6 @@
|
|
|
171
149
|
map.setPaintProperty(layerId, 'text-halo-color', store.labelHaloColor);
|
|
172
150
|
map.setPaintProperty(layerId, 'text-halo-width', store.labelHaloWidth);
|
|
173
151
|
map.setLayerZoomRange(layerId, store.minLabelZoom, 24);
|
|
174
|
-
|
|
175
|
-
console.log('RepeaterLabelsLayer: Updated layer properties');
|
|
176
152
|
}
|
|
177
153
|
}
|
|
178
154
|
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
import { repeatersToGeoJSON } from '../utils/repeaterGeoJSON';
|
|
19
19
|
import { REPEATER_FILL_Z_INDEX, REPEATER_LINE_Z_INDEX } from '../constants/zIndex';
|
|
20
20
|
import { Z_INDEX_BY_BAND } from '../constants/techBandZOrder';
|
|
21
|
+
import { log } from '../../../../core/logger';
|
|
21
22
|
|
|
22
23
|
interface Props {
|
|
23
24
|
/** Repeater store context */
|
|
@@ -59,7 +60,7 @@
|
|
|
59
60
|
viewportUpdateTimer = setTimeout(() => {
|
|
60
61
|
if (!map) return;
|
|
61
62
|
const newZoom = map.getZoom();
|
|
62
|
-
|
|
63
|
+
log('RepeatersLayer: Viewport changed, updating to zoom:', newZoom);
|
|
63
64
|
// Update zoom
|
|
64
65
|
store.setCurrentZoom(newZoom);
|
|
65
66
|
// Force $effect to re-run
|
|
@@ -74,8 +75,6 @@
|
|
|
74
75
|
function initializeLayer() {
|
|
75
76
|
if (!map) return;
|
|
76
77
|
|
|
77
|
-
console.log('RepeatersLayer: initializeLayer called');
|
|
78
|
-
|
|
79
78
|
// Set initial zoom
|
|
80
79
|
store.setCurrentZoom(map.getZoom());
|
|
81
80
|
|
|
@@ -91,12 +90,9 @@
|
|
|
91
90
|
}
|
|
92
91
|
|
|
93
92
|
onMount(() => {
|
|
94
|
-
console.log('RepeatersLayer: onMount, waiting for map...');
|
|
95
|
-
|
|
96
93
|
// Subscribe to map store
|
|
97
94
|
const unsubscribe = mapStore.subscribe((mapInstance) => {
|
|
98
95
|
if (mapInstance && !map) {
|
|
99
|
-
console.log('RepeatersLayer: Map available, initializing...');
|
|
100
96
|
map = mapInstance;
|
|
101
97
|
|
|
102
98
|
// Initial layer setup
|
|
@@ -137,19 +133,16 @@
|
|
|
137
133
|
}
|
|
138
134
|
});
|
|
139
135
|
|
|
140
|
-
// Reactive: Update GeoJSON when repeaters/zoom/settings change
|
|
136
|
+
// Reactive: Update GeoJSON when repeaters/zoom/filters/settings change
|
|
141
137
|
$effect(() => {
|
|
142
|
-
// Track viewportVersion to force re-run on
|
|
138
|
+
// Track viewportVersion to force re-run on viewport changes
|
|
143
139
|
viewportVersion;
|
|
144
140
|
|
|
145
|
-
|
|
141
|
+
log('RepeatersLayer update:', {
|
|
146
142
|
mounted,
|
|
147
143
|
hasMap: !!map,
|
|
148
144
|
showRepeaters: store.showRepeaters,
|
|
149
|
-
|
|
150
|
-
currentZoom: store.currentZoom,
|
|
151
|
-
baseRadius: store.baseRadius,
|
|
152
|
-
viewportVersion
|
|
145
|
+
filteredCount: store.filteredRepeaters.length
|
|
153
146
|
});
|
|
154
147
|
|
|
155
148
|
if (!mounted || !map) {
|
|
@@ -180,10 +173,7 @@
|
|
|
180
173
|
bounds.contains([repeater.longitude, repeater.latitude])
|
|
181
174
|
);
|
|
182
175
|
|
|
183
|
-
|
|
184
|
-
totalFiltered: store.filteredRepeaters.length,
|
|
185
|
-
visibleInViewport: visibleRepeaters.length
|
|
186
|
-
});
|
|
176
|
+
log('RepeatersLayer viewport filter:', visibleRepeaters.length, 'of', store.filteredRepeaters.length);
|
|
187
177
|
|
|
188
178
|
// Generate GeoJSON from visible repeaters only
|
|
189
179
|
const geoJSON = repeatersToGeoJSON(
|
|
@@ -193,18 +183,13 @@
|
|
|
193
183
|
store.techBandColorMap
|
|
194
184
|
);
|
|
195
185
|
|
|
196
|
-
|
|
197
|
-
featureCount: geoJSON.features.length,
|
|
198
|
-
firstFeature: geoJSON.features[0]
|
|
199
|
-
});
|
|
186
|
+
log('RepeatersLayer GeoJSON:', geoJSON.features.length, 'features');
|
|
200
187
|
|
|
201
188
|
// Update or create source
|
|
202
189
|
const source = map.getSource(SOURCE_ID);
|
|
203
190
|
if (source && source.type === 'geojson') {
|
|
204
|
-
console.log('RepeatersLayer: Updating existing source');
|
|
205
191
|
source.setData(geoJSON);
|
|
206
192
|
} else {
|
|
207
|
-
console.log('RepeatersLayer: Creating new source');
|
|
208
193
|
map.addSource(SOURCE_ID, {
|
|
209
194
|
type: 'geojson',
|
|
210
195
|
data: geoJSON
|
|
@@ -228,7 +213,6 @@
|
|
|
228
213
|
|
|
229
214
|
// Add fill layer if not exists
|
|
230
215
|
if (!map.getLayer(fillLayerId)) {
|
|
231
|
-
console.log(`RepeatersLayer: Creating fill layer for z-index ${zIndex}`);
|
|
232
216
|
map.addLayer({
|
|
233
217
|
id: fillLayerId,
|
|
234
218
|
type: 'fill',
|
|
@@ -249,7 +233,6 @@
|
|
|
249
233
|
|
|
250
234
|
// Add line layer if not exists
|
|
251
235
|
if (!map.getLayer(lineLayerId)) {
|
|
252
|
-
console.log(`RepeatersLayer: Creating line layer for z-index ${zIndex}`);
|
|
253
236
|
map.addLayer({
|
|
254
237
|
id: lineLayerId,
|
|
255
238
|
type: 'line',
|
|
@@ -75,10 +75,8 @@ export function buildRepeaterTree(repeaters, colorMap) {
|
|
|
75
75
|
*/
|
|
76
76
|
export function getFilteredRepeaters(checkedPaths) {
|
|
77
77
|
const selected = new Set();
|
|
78
|
-
console.log('getFilteredRepeaters - checkedPaths:', Array.from(checkedPaths));
|
|
79
78
|
// If only root is checked, all tech:fbands are visible
|
|
80
79
|
if (checkedPaths.has('root') && checkedPaths.size === 1) {
|
|
81
|
-
console.log('Only root checked - returning empty set for "all visible"');
|
|
82
80
|
return selected;
|
|
83
81
|
}
|
|
84
82
|
// Check each path - leaf nodes have tech:fband in their ID
|
|
@@ -86,14 +84,12 @@ export function getFilteredRepeaters(checkedPaths) {
|
|
|
86
84
|
// Paths are like "root:2G:2G:GSM900" where the node ID is the last segment
|
|
87
85
|
// The node ID for leaf nodes is "tech:fband" format
|
|
88
86
|
const parts = path.split(':');
|
|
89
|
-
console.log('Processing path:', path, 'parts:', parts);
|
|
90
87
|
// Check if this is a leaf node (contains tech:fband format)
|
|
91
88
|
// Leaf node IDs are like "2G:GSM900", "4G:LTE1800"
|
|
92
89
|
// The path would be "root:2G:2G:GSM900" (root -> tech -> tech:fband)
|
|
93
90
|
if (parts.length === 4 && parts[0] === 'root') {
|
|
94
91
|
// This is a leaf node: root:tech:tech:fband
|
|
95
92
|
const techBandKey = `${parts[2]}:${parts[3]}`;
|
|
96
|
-
console.log('Adding tech:fband key:', techBandKey);
|
|
97
93
|
selected.add(techBandKey);
|
|
98
94
|
}
|
|
99
95
|
else if (parts.length === 3 && parts[0] === 'root') {
|
|
@@ -101,11 +97,9 @@ export function getFilteredRepeaters(checkedPaths) {
|
|
|
101
97
|
const nodeId = parts[2];
|
|
102
98
|
if (nodeId && nodeId.includes(':')) {
|
|
103
99
|
// This is already in tech:fband format
|
|
104
|
-
console.log('Adding tech:fband key (alternative format):', nodeId);
|
|
105
100
|
selected.add(nodeId);
|
|
106
101
|
}
|
|
107
102
|
}
|
|
108
103
|
}
|
|
109
|
-
console.log('getFilteredRepeaters - selected tech:bands:', Array.from(selected));
|
|
110
104
|
return selected;
|
|
111
105
|
}
|
|
@@ -45,10 +45,7 @@
|
|
|
45
45
|
let treeStore = $state<Writable<TreeStoreValue> | null>(null);
|
|
46
46
|
|
|
47
47
|
onMount(() => {
|
|
48
|
-
console.log('SiteFilterControl: Mounted with', store.allSites.length, 'sites');
|
|
49
|
-
|
|
50
48
|
if (store.allSites.length > 0) {
|
|
51
|
-
console.log('SiteFilterControl: Building tree...');
|
|
52
49
|
const treeNodes = buildSiteTree(store.allSites, store.groupColorMap);
|
|
53
50
|
|
|
54
51
|
treeStore = createTreeStore({
|
|
@@ -57,17 +54,12 @@
|
|
|
57
54
|
persistState: true,
|
|
58
55
|
defaultExpandAll: false
|
|
59
56
|
});
|
|
60
|
-
|
|
61
|
-
console.log('SiteFilterControl: Tree store created');
|
|
62
57
|
|
|
63
58
|
// Subscribe to tree changes and update siteStore
|
|
64
59
|
if (treeStore) {
|
|
65
60
|
const unsub = treeStore.subscribe((treeValue: TreeStoreValue) => {
|
|
66
61
|
const checkedPaths = treeValue.getCheckedPaths();
|
|
67
|
-
console.log('TreeStore updated, checked paths:', checkedPaths);
|
|
68
|
-
|
|
69
62
|
const newFilteredSites = getFilteredSites(checkedPaths, store.allSites);
|
|
70
|
-
console.log('Filtered sites count:', newFilteredSites.length, 'of', store.allSites.length);
|
|
71
63
|
|
|
72
64
|
// Update the site store directly
|
|
73
65
|
store.filteredSites = newFilteredSites;
|
|
@@ -74,7 +74,6 @@ export function buildSiteTree(sites, colorMap) {
|
|
|
74
74
|
* Filters sites based on checked tree paths
|
|
75
75
|
*/
|
|
76
76
|
export function getFilteredSites(checkedPaths, allSites) {
|
|
77
|
-
console.log('getFilteredSites called with paths:', checkedPaths);
|
|
78
77
|
const checkedGroups = new Set();
|
|
79
78
|
const checkedProviders = new Set();
|
|
80
79
|
checkedPaths.forEach((path) => {
|
|
@@ -97,16 +96,12 @@ export function getFilteredSites(checkedPaths, allSites) {
|
|
|
97
96
|
checkedProviders.add(filteredParts[0]);
|
|
98
97
|
}
|
|
99
98
|
});
|
|
100
|
-
console.log('Checked groups:', Array.from(checkedGroups));
|
|
101
|
-
console.log('Checked providers:', Array.from(checkedProviders));
|
|
102
99
|
// If "all-sites" is checked and it's the only thing, return all
|
|
103
100
|
if (checkedPaths.includes('all-sites') && checkedGroups.size === 0 && checkedProviders.size === 0) {
|
|
104
|
-
console.log('All sites root checked, returning all');
|
|
105
101
|
return allSites;
|
|
106
102
|
}
|
|
107
103
|
// If nothing is checked, return empty
|
|
108
104
|
if (checkedGroups.size === 0 && checkedProviders.size === 0) {
|
|
109
|
-
console.log('Nothing checked, returning empty');
|
|
110
105
|
return [];
|
|
111
106
|
}
|
|
112
107
|
// Filter sites based on checked groups or providers
|
|
@@ -116,6 +111,5 @@ export function getFilteredSites(checkedPaths, allSites) {
|
|
|
116
111
|
const included = checkedGroups.has(key) || checkedProviders.has(site.provider);
|
|
117
112
|
return included;
|
|
118
113
|
});
|
|
119
|
-
console.log('Filtered:', filtered.length, 'of', allSites.length, 'sites');
|
|
120
114
|
return filtered;
|
|
121
115
|
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { setContext, onMount, onDestroy } from 'svelte';
|
|
3
|
+
import mapboxgl from 'mapbox-gl';
|
|
4
|
+
import 'mapbox-gl/dist/mapbox-gl.css';
|
|
5
|
+
import { createMapStore } from '../stores/map.store.svelte';
|
|
6
|
+
import { createViewportStore } from '../stores/viewport.store.svelte';
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
accessToken: string;
|
|
10
|
+
style?: string;
|
|
11
|
+
center?: [number, number];
|
|
12
|
+
zoom?: number;
|
|
13
|
+
class?: string;
|
|
14
|
+
children?: import('svelte').Snippet;
|
|
15
|
+
namespace?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
accessToken,
|
|
20
|
+
style = 'mapbox://styles/mapbox/streets-v12',
|
|
21
|
+
center = [0, 0],
|
|
22
|
+
zoom = 2,
|
|
23
|
+
class: className = '',
|
|
24
|
+
children,
|
|
25
|
+
namespace = 'map'
|
|
26
|
+
}: Props = $props();
|
|
27
|
+
|
|
28
|
+
let mapContainer: HTMLDivElement;
|
|
29
|
+
const mapStore = createMapStore();
|
|
30
|
+
|
|
31
|
+
// Initialize viewport store with defaults from props
|
|
32
|
+
const viewportStore = createViewportStore(namespace, { center, zoom });
|
|
33
|
+
|
|
34
|
+
setContext('MAP_CONTEXT', mapStore);
|
|
35
|
+
|
|
36
|
+
onMount(() => {
|
|
37
|
+
mapboxgl.accessToken = accessToken;
|
|
38
|
+
|
|
39
|
+
// Use viewport store values for initialization
|
|
40
|
+
mapStore.init(mapContainer, {
|
|
41
|
+
style,
|
|
42
|
+
center: viewportStore.center,
|
|
43
|
+
zoom: viewportStore.zoom,
|
|
44
|
+
bearing: viewportStore.bearing,
|
|
45
|
+
pitch: viewportStore.pitch
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Sync Map -> Store
|
|
49
|
+
const map = mapStore.map;
|
|
50
|
+
if (map) {
|
|
51
|
+
const updateStore = () => {
|
|
52
|
+
viewportStore.updateViewport({
|
|
53
|
+
center: map.getCenter().toArray() as [number, number],
|
|
54
|
+
zoom: map.getZoom(),
|
|
55
|
+
bearing: map.getBearing(),
|
|
56
|
+
pitch: map.getPitch()
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
map.on('moveend', updateStore);
|
|
61
|
+
map.on('zoomend', updateStore);
|
|
62
|
+
map.on('rotateend', updateStore);
|
|
63
|
+
map.on('pitchend', updateStore);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
onDestroy(() => {
|
|
68
|
+
mapStore.destroy();
|
|
69
|
+
});
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<div class="map-wrapper {className}">
|
|
73
|
+
<div bind:this={mapContainer} class="map-instance"></div>
|
|
74
|
+
{#if mapStore.loaded}
|
|
75
|
+
{@render children?.()}
|
|
76
|
+
{/if}
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<style>
|
|
80
|
+
.map-wrapper {
|
|
81
|
+
width: 100%;
|
|
82
|
+
height: 100%;
|
|
83
|
+
position: relative;
|
|
84
|
+
}
|
|
85
|
+
.map-instance {
|
|
86
|
+
width: 100%;
|
|
87
|
+
height: 100%;
|
|
88
|
+
}
|
|
89
|
+
</style>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import 'mapbox-gl/dist/mapbox-gl.css';
|
|
2
|
+
interface Props {
|
|
3
|
+
accessToken: string;
|
|
4
|
+
style?: string;
|
|
5
|
+
center?: [number, number];
|
|
6
|
+
zoom?: number;
|
|
7
|
+
class?: string;
|
|
8
|
+
children?: import('svelte').Snippet;
|
|
9
|
+
namespace?: string;
|
|
10
|
+
}
|
|
11
|
+
declare const Map: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type Map = ReturnType<typeof Map>;
|
|
13
|
+
export default Map;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { MapControl } from '../../shared';
|
|
3
|
+
import CellSettingsPanel from '../../features/cells/components/CellSettingsPanel.svelte';
|
|
4
|
+
import RepeaterSettingsPanel from '../../features/repeaters/components/RepeaterSettingsPanel.svelte';
|
|
5
|
+
import SiteSettingsPanel from '../../features/sites/components/SiteSettingsPanel.svelte';
|
|
6
|
+
import type { CellDisplayStore } from '../../features/cells/stores/cell.display.svelte';
|
|
7
|
+
import type { RepeaterDisplayStore } from '../../features/repeaters/stores/repeater.display.svelte';
|
|
8
|
+
import type { SiteDisplayStore } from '../../features/sites/stores/site.display.svelte';
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
cellDisplayStore: CellDisplayStore;
|
|
12
|
+
repeaterDisplayStore?: RepeaterDisplayStore;
|
|
13
|
+
siteDisplayStore?: SiteDisplayStore;
|
|
14
|
+
position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
15
|
+
title?: string;
|
|
16
|
+
icon?: string;
|
|
17
|
+
initiallyCollapsed?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let {
|
|
21
|
+
cellDisplayStore,
|
|
22
|
+
repeaterDisplayStore,
|
|
23
|
+
siteDisplayStore,
|
|
24
|
+
position = 'top-right',
|
|
25
|
+
title = 'Feature Settings',
|
|
26
|
+
icon = 'sliders',
|
|
27
|
+
initiallyCollapsed = true
|
|
28
|
+
}: Props = $props();
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<MapControl {position} {title} {icon} {initiallyCollapsed} controlWidth="380px" edgeOffset="12px">
|
|
32
|
+
<div class="d-flex flex-column p-0">
|
|
33
|
+
<ul class="nav nav-tabs" id="settings-tabs" role="tablist">
|
|
34
|
+
<!-- Cell Tab -->
|
|
35
|
+
<li class="nav-item" role="presentation">
|
|
36
|
+
<button class="nav-link active" id="cell-tab" data-bs-toggle="tab" data-bs-target="#cell" type="button" role="tab">Cells</button>
|
|
37
|
+
</li>
|
|
38
|
+
<!-- Site Tab -->
|
|
39
|
+
{#if siteDisplayStore}
|
|
40
|
+
<li class="nav-item" role="presentation">
|
|
41
|
+
<button class="nav-link" id="site-tab" data-bs-toggle="tab" data-bs-target="#site" type="button" role="tab">Sites</button>
|
|
42
|
+
</li>
|
|
43
|
+
{/if}
|
|
44
|
+
<!-- Repeater Tab -->
|
|
45
|
+
{#if repeaterDisplayStore}
|
|
46
|
+
<li class="nav-item" role="presentation">
|
|
47
|
+
<button class="nav-link" id="repeater-tab" data-bs-toggle="tab" data-bs-target="#repeater" type="button" role="tab">Repeaters</button>
|
|
48
|
+
</li>
|
|
49
|
+
{/if}
|
|
50
|
+
</ul>
|
|
51
|
+
|
|
52
|
+
<div class="tab-content rounded-2 shadow-sm bg-white border p-2" id="settings-tab-content">
|
|
53
|
+
<!-- Cell Panel -->
|
|
54
|
+
<div class="tab-pane show active" id="cell" role="tabpanel">
|
|
55
|
+
<CellSettingsPanel displayStore={cellDisplayStore} />
|
|
56
|
+
</div>
|
|
57
|
+
<!-- Site Panel -->
|
|
58
|
+
{#if siteDisplayStore}
|
|
59
|
+
<div class="tab-pane" id="site" role="tabpanel">
|
|
60
|
+
<SiteSettingsPanel displayStore={siteDisplayStore} />
|
|
61
|
+
</div>
|
|
62
|
+
{/if}
|
|
63
|
+
<!-- Repeater Panel -->
|
|
64
|
+
{#if repeaterDisplayStore}
|
|
65
|
+
<div class="tab-pane" id="repeater" role="tabpanel">
|
|
66
|
+
<RepeaterSettingsPanel displayStore={repeaterDisplayStore} />
|
|
67
|
+
</div>
|
|
68
|
+
{/if}
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</MapControl>
|
|
72
|
+
|
|
73
|
+
<style>
|
|
74
|
+
:global(.map-control-content) {
|
|
75
|
+
padding: 0.25rem;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.nav-tabs {
|
|
79
|
+
border-bottom: 1px solid #dee2e6;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.nav-link {
|
|
83
|
+
border: 1px solid transparent;
|
|
84
|
+
border-top-left-radius: 0.375rem;
|
|
85
|
+
border-top-right-radius: 0.375rem;
|
|
86
|
+
font-size: 0.95rem;
|
|
87
|
+
font-weight: 500;
|
|
88
|
+
padding: 0.5rem 1rem;
|
|
89
|
+
color: #6c757d;
|
|
90
|
+
white-space: nowrap;
|
|
91
|
+
min-width: fit-content;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.nav-link.active {
|
|
95
|
+
color: #495057;
|
|
96
|
+
background-color: #fff;
|
|
97
|
+
border-color: #dee2e6 #dee2e6 #fff;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.tab-content {
|
|
101
|
+
padding: 0;
|
|
102
|
+
}
|
|
103
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CellDisplayStore } from '../../features/cells/stores/cell.display.svelte';
|
|
2
|
+
import type { RepeaterDisplayStore } from '../../features/repeaters/stores/repeater.display.svelte';
|
|
3
|
+
import type { SiteDisplayStore } from '../../features/sites/stores/site.display.svelte';
|
|
4
|
+
interface Props {
|
|
5
|
+
cellDisplayStore: CellDisplayStore;
|
|
6
|
+
repeaterDisplayStore?: RepeaterDisplayStore;
|
|
7
|
+
siteDisplayStore?: SiteDisplayStore;
|
|
8
|
+
position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
9
|
+
title?: string;
|
|
10
|
+
icon?: string;
|
|
11
|
+
initiallyCollapsed?: boolean;
|
|
12
|
+
}
|
|
13
|
+
declare const FeatureSettingsControl: import("svelte").Component<Props, {}, "">;
|
|
14
|
+
type FeatureSettingsControl = ReturnType<typeof FeatureSettingsControl>;
|
|
15
|
+
export default FeatureSettingsControl;
|