@smartnet360/svelte-components 0.0.84 → 0.0.86
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/SiteCheck.svelte +60 -80
- package/dist/apps/site-check/data-loader.d.ts +9 -6
- package/dist/apps/site-check/data-loader.js +2 -11
- package/dist/apps/site-check/helper.d.ts +3 -2
- package/dist/apps/site-check/helper.js +7 -5
- package/dist/apps/site-check/index.d.ts +1 -1
- package/dist/apps/site-check/transforms.d.ts +4 -2
- package/dist/apps/site-check/transforms.js +49 -10
- 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 +3 -0
- package/dist/map-v3/core/index.js +3 -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 +26 -0
- package/dist/map-v3/index.js +31 -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
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getContext } from 'svelte';
|
|
3
|
+
import type { MapStore } from '../../../core/stores/map.store.svelte';
|
|
4
|
+
import type { SiteDataStore } from '../stores/site.data.svelte';
|
|
5
|
+
import type { SiteDisplayStore } from '../stores/site.display.svelte';
|
|
6
|
+
import type { SiteRegistry } from '../stores/site.registry.svelte';
|
|
7
|
+
import type mapboxgl from 'mapbox-gl';
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
dataStore: SiteDataStore;
|
|
11
|
+
displayStore: SiteDisplayStore;
|
|
12
|
+
registry: SiteRegistry;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let { dataStore, displayStore, registry }: Props = $props();
|
|
16
|
+
|
|
17
|
+
const mapStore = getContext<MapStore>('MAP_CONTEXT');
|
|
18
|
+
let sourceId = 'sites-source';
|
|
19
|
+
let layerId = 'sites-layer';
|
|
20
|
+
let updateTimeout: any;
|
|
21
|
+
|
|
22
|
+
$effect(() => {
|
|
23
|
+
const map = mapStore.map;
|
|
24
|
+
if (!map) return;
|
|
25
|
+
|
|
26
|
+
const addLayers = () => {
|
|
27
|
+
if (!map.getSource(sourceId)) {
|
|
28
|
+
map.addSource(sourceId, {
|
|
29
|
+
type: 'geojson',
|
|
30
|
+
data: { type: 'FeatureCollection', features: [] }
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!map.getLayer(layerId)) {
|
|
35
|
+
map.addLayer({
|
|
36
|
+
id: layerId,
|
|
37
|
+
type: 'circle',
|
|
38
|
+
source: sourceId,
|
|
39
|
+
paint: {
|
|
40
|
+
'circle-radius': displayStore.radius,
|
|
41
|
+
'circle-color': ['get', 'color'],
|
|
42
|
+
'circle-opacity': displayStore.opacity,
|
|
43
|
+
'circle-stroke-color': displayStore.strokeColor,
|
|
44
|
+
'circle-stroke-width': displayStore.strokeWidth
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
updateLayer();
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
addLayers();
|
|
53
|
+
map.on('style.load', addLayers);
|
|
54
|
+
map.on('moveend', updateLayer);
|
|
55
|
+
map.on('zoomend', updateLayer);
|
|
56
|
+
|
|
57
|
+
return () => {
|
|
58
|
+
map.off('style.load', addLayers);
|
|
59
|
+
map.off('moveend', updateLayer);
|
|
60
|
+
map.off('zoomend', updateLayer);
|
|
61
|
+
|
|
62
|
+
if (map.getLayer(layerId)) map.removeLayer(layerId);
|
|
63
|
+
if (map.getSource(sourceId)) map.removeSource(sourceId);
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// React to display changes
|
|
68
|
+
$effect(() => {
|
|
69
|
+
const map = mapStore.map;
|
|
70
|
+
if (!map || !map.getLayer(layerId)) return;
|
|
71
|
+
|
|
72
|
+
map.setPaintProperty(layerId, 'circle-radius', displayStore.radius);
|
|
73
|
+
// Color is now data-driven
|
|
74
|
+
// map.setPaintProperty(layerId, 'circle-color', displayStore.color);
|
|
75
|
+
map.setPaintProperty(layerId, 'circle-opacity', displayStore.opacity);
|
|
76
|
+
map.setPaintProperty(layerId, 'circle-stroke-color', displayStore.strokeColor);
|
|
77
|
+
map.setPaintProperty(layerId, 'circle-stroke-width', displayStore.strokeWidth);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// React to data changes
|
|
81
|
+
$effect(() => {
|
|
82
|
+
const _sites = dataStore.sites;
|
|
83
|
+
const _version = registry.version;
|
|
84
|
+
updateLayer();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
function updateLayer() {
|
|
88
|
+
const map = mapStore.map;
|
|
89
|
+
if (!map) return;
|
|
90
|
+
|
|
91
|
+
clearTimeout(updateTimeout);
|
|
92
|
+
updateTimeout = setTimeout(() => {
|
|
93
|
+
renderSites(map);
|
|
94
|
+
}, 100);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function renderSites(map: mapboxgl.Map) {
|
|
98
|
+
const bounds = map.getBounds();
|
|
99
|
+
if (!bounds) return;
|
|
100
|
+
|
|
101
|
+
const sites = dataStore.sites;
|
|
102
|
+
const features: GeoJSON.Feature[] = [];
|
|
103
|
+
|
|
104
|
+
for (const site of sites) {
|
|
105
|
+
if (!registry.isVisible(site.siteId)) continue;
|
|
106
|
+
if (!bounds.contains([site.longitude, site.latitude])) continue;
|
|
107
|
+
|
|
108
|
+
const color = registry.getColor(site.level1, site.level2, displayStore.color);
|
|
109
|
+
|
|
110
|
+
features.push({
|
|
111
|
+
type: 'Feature',
|
|
112
|
+
geometry: {
|
|
113
|
+
type: 'Point',
|
|
114
|
+
coordinates: [site.longitude, site.latitude]
|
|
115
|
+
},
|
|
116
|
+
properties: {
|
|
117
|
+
siteId: site.siteId,
|
|
118
|
+
name: site.siteName,
|
|
119
|
+
color: color
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const source = map.getSource(sourceId) as mapboxgl.GeoJSONSource;
|
|
125
|
+
if (source) {
|
|
126
|
+
source.setData({
|
|
127
|
+
type: 'FeatureCollection',
|
|
128
|
+
features
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
</script>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SiteDataStore } from '../stores/site.data.svelte';
|
|
2
|
+
import type { SiteDisplayStore } from '../stores/site.display.svelte';
|
|
3
|
+
import type { SiteRegistry } from '../stores/site.registry.svelte';
|
|
4
|
+
interface Props {
|
|
5
|
+
dataStore: SiteDataStore;
|
|
6
|
+
displayStore: SiteDisplayStore;
|
|
7
|
+
registry: SiteRegistry;
|
|
8
|
+
}
|
|
9
|
+
declare const SitesLayer: import("svelte").Component<Props, {}, "">;
|
|
10
|
+
type SitesLayer = ReturnType<typeof SitesLayer>;
|
|
11
|
+
export default SitesLayer;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TreeNode } from '../../../../core/TreeView/tree.model';
|
|
2
|
+
import type { Site } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Converts a list of sites into a Tree structure for the TreeView component
|
|
5
|
+
* Structure: Root (Sites) -> Level 1 -> Level 2 -> Site
|
|
6
|
+
*/
|
|
7
|
+
export declare function buildSiteTree(sites: Site[]): TreeNode<{
|
|
8
|
+
count: number;
|
|
9
|
+
}>[];
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a list of sites into a Tree structure for the TreeView component
|
|
3
|
+
* Structure: Root (Sites) -> Level 1 -> Level 2 -> Site
|
|
4
|
+
*/
|
|
5
|
+
export function buildSiteTree(sites) {
|
|
6
|
+
// Root node
|
|
7
|
+
const rootNode = {
|
|
8
|
+
id: 'root-sites',
|
|
9
|
+
label: 'Sites',
|
|
10
|
+
children: [],
|
|
11
|
+
defaultExpanded: true
|
|
12
|
+
};
|
|
13
|
+
const level1Map = new Map();
|
|
14
|
+
for (const site of sites) {
|
|
15
|
+
const l1 = site.level1 || 'Unknown';
|
|
16
|
+
const l2 = site.level2 || 'Unknown';
|
|
17
|
+
// Level 1
|
|
18
|
+
if (!level1Map.has(l1)) {
|
|
19
|
+
const node = {
|
|
20
|
+
id: `l1-${l1}`,
|
|
21
|
+
label: l1,
|
|
22
|
+
children: [],
|
|
23
|
+
defaultExpanded: true
|
|
24
|
+
};
|
|
25
|
+
level1Map.set(l1, node);
|
|
26
|
+
rootNode.children.push(node);
|
|
27
|
+
}
|
|
28
|
+
const l1Node = level1Map.get(l1);
|
|
29
|
+
// Level 2
|
|
30
|
+
// We use a composite ID to ensure uniqueness if same L2 name exists in different L1s
|
|
31
|
+
// But we need to find the node object in the children array
|
|
32
|
+
let l2Node = l1Node.children.find(c => c.label === l2);
|
|
33
|
+
if (!l2Node) {
|
|
34
|
+
l2Node = {
|
|
35
|
+
id: `l2-${l1}-${l2}`,
|
|
36
|
+
label: l2,
|
|
37
|
+
children: [],
|
|
38
|
+
defaultExpanded: false,
|
|
39
|
+
metadata: {
|
|
40
|
+
level1: l1,
|
|
41
|
+
level2: l2,
|
|
42
|
+
siteIds: [],
|
|
43
|
+
count: 0,
|
|
44
|
+
color: '#3388ff' // Default color, will be overridden by registry in UI
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
l1Node.children.push(l2Node);
|
|
48
|
+
}
|
|
49
|
+
// Add site to L2 metadata
|
|
50
|
+
l2Node.metadata.siteIds.push(site.siteId);
|
|
51
|
+
l2Node.metadata.count++;
|
|
52
|
+
}
|
|
53
|
+
// Sort Level 1
|
|
54
|
+
rootNode.children.sort((a, b) => a.label.localeCompare(b.label));
|
|
55
|
+
// Sort Level 2 and Calculate Counts
|
|
56
|
+
let totalCount = 0;
|
|
57
|
+
for (const l1Node of rootNode.children) {
|
|
58
|
+
let l1Count = 0;
|
|
59
|
+
if (l1Node.children) {
|
|
60
|
+
l1Node.children.sort((a, b) => a.label.localeCompare(b.label));
|
|
61
|
+
for (const l2Node of l1Node.children) {
|
|
62
|
+
const count = l2Node.metadata?.count || 0;
|
|
63
|
+
l1Count += count;
|
|
64
|
+
// Update L2 label with count
|
|
65
|
+
l2Node.label = `${l2Node.label} (${count})`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
totalCount += l1Count;
|
|
69
|
+
// Update L1 label with count
|
|
70
|
+
l1Node.label = `${l1Node.label} (${l1Count})`;
|
|
71
|
+
}
|
|
72
|
+
// Update Root label with count
|
|
73
|
+
rootNode.label = `${rootNode.label} (${totalCount})`;
|
|
74
|
+
return [rootNode];
|
|
75
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CellDataStore } from '../../cells/stores/cell.data.svelte';
|
|
2
|
+
import type { Site } from '../types';
|
|
3
|
+
export declare class SiteDataStore {
|
|
4
|
+
cellDataStore: CellDataStore;
|
|
5
|
+
constructor(cellDataStore: CellDataStore);
|
|
6
|
+
get sites(): Site[];
|
|
7
|
+
}
|
|
8
|
+
export declare function createSiteDataStore(cellDataStore: CellDataStore): SiteDataStore;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export class SiteDataStore {
|
|
2
|
+
cellDataStore;
|
|
3
|
+
constructor(cellDataStore) {
|
|
4
|
+
this.cellDataStore = cellDataStore;
|
|
5
|
+
}
|
|
6
|
+
get sites() {
|
|
7
|
+
const cells = this.cellDataStore.filteredCells;
|
|
8
|
+
const siteMap = new Map();
|
|
9
|
+
for (const cell of cells) {
|
|
10
|
+
if (!cell.siteId)
|
|
11
|
+
continue;
|
|
12
|
+
if (!siteMap.has(cell.siteId)) {
|
|
13
|
+
siteMap.set(cell.siteId, {
|
|
14
|
+
siteId: cell.siteId,
|
|
15
|
+
siteName: cell.cellName, // Fallback to cell name if site name not available
|
|
16
|
+
latitude: cell.siteLatitude || cell.latitude,
|
|
17
|
+
longitude: cell.siteLongitude || cell.longitude,
|
|
18
|
+
techs: [cell.tech],
|
|
19
|
+
fbands: [cell.fband],
|
|
20
|
+
provider: 'Cetin',
|
|
21
|
+
level1: 'Cetin', // Need to check where provider comes from in V3,
|
|
22
|
+
level2: 'Unknown',
|
|
23
|
+
cellCount: 1
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const site = siteMap.get(cell.siteId);
|
|
28
|
+
if (!site.techs.includes(cell.tech))
|
|
29
|
+
site.techs.push(cell.tech);
|
|
30
|
+
if (!site.fbands.includes(cell.fband))
|
|
31
|
+
site.fbands.push(cell.fband);
|
|
32
|
+
site.cellCount++;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return Array.from(siteMap.values());
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function createSiteDataStore(cellDataStore) {
|
|
39
|
+
return new SiteDataStore(cellDataStore);
|
|
40
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare class SiteDisplayStore {
|
|
2
|
+
key: string;
|
|
3
|
+
radius: number;
|
|
4
|
+
color: string;
|
|
5
|
+
opacity: number;
|
|
6
|
+
strokeColor: string;
|
|
7
|
+
strokeWidth: number;
|
|
8
|
+
showLabels: boolean;
|
|
9
|
+
labelPixelDistance: number;
|
|
10
|
+
labelFontSize: number;
|
|
11
|
+
labelColor: string;
|
|
12
|
+
labelHaloColor: string;
|
|
13
|
+
labelHaloWidth: number;
|
|
14
|
+
labels: {
|
|
15
|
+
primary: string;
|
|
16
|
+
secondary: string;
|
|
17
|
+
};
|
|
18
|
+
constructor();
|
|
19
|
+
}
|
|
20
|
+
export declare function createSiteDisplayStore(): SiteDisplayStore;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { browser } from '$app/environment';
|
|
2
|
+
export class SiteDisplayStore {
|
|
3
|
+
key = 'map-v3-site-display';
|
|
4
|
+
// Circle Appearance
|
|
5
|
+
radius = $state(6);
|
|
6
|
+
color = $state('#808080'); // Default gray for sites
|
|
7
|
+
opacity = $state(0.8);
|
|
8
|
+
strokeColor = $state('#ffffff');
|
|
9
|
+
strokeWidth = $state(1);
|
|
10
|
+
// Label Settings
|
|
11
|
+
showLabels = $state(false);
|
|
12
|
+
labelPixelDistance = $state(15);
|
|
13
|
+
labelFontSize = $state(12);
|
|
14
|
+
labelColor = $state('#333333');
|
|
15
|
+
labelHaloColor = $state('#ffffff');
|
|
16
|
+
labelHaloWidth = $state(1);
|
|
17
|
+
// Label Fields
|
|
18
|
+
labels = $state({ primary: 'siteId', secondary: 'none' });
|
|
19
|
+
constructor() {
|
|
20
|
+
if (browser) {
|
|
21
|
+
const saved = localStorage.getItem(this.key);
|
|
22
|
+
if (saved) {
|
|
23
|
+
try {
|
|
24
|
+
const parsed = JSON.parse(saved);
|
|
25
|
+
this.radius = parsed.radius ?? 6;
|
|
26
|
+
this.color = parsed.color ?? '#808080';
|
|
27
|
+
this.opacity = parsed.opacity ?? 0.8;
|
|
28
|
+
this.strokeColor = parsed.strokeColor ?? '#ffffff';
|
|
29
|
+
this.strokeWidth = parsed.strokeWidth ?? 1;
|
|
30
|
+
this.showLabels = parsed.showLabels ?? false;
|
|
31
|
+
this.labelPixelDistance = parsed.labelPixelDistance ?? 15;
|
|
32
|
+
this.labelFontSize = parsed.labelFontSize ?? 12;
|
|
33
|
+
this.labelColor = parsed.labelColor ?? '#333333';
|
|
34
|
+
this.labelHaloColor = parsed.labelHaloColor ?? '#ffffff';
|
|
35
|
+
this.labelHaloWidth = parsed.labelHaloWidth ?? 1;
|
|
36
|
+
this.labels = parsed.labels ?? { primary: 'siteId', secondary: 'none' };
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
console.error('Failed to load site display settings', e);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
$effect(() => {
|
|
43
|
+
localStorage.setItem(this.key, JSON.stringify({
|
|
44
|
+
radius: this.radius,
|
|
45
|
+
color: this.color,
|
|
46
|
+
opacity: this.opacity,
|
|
47
|
+
strokeColor: this.strokeColor,
|
|
48
|
+
strokeWidth: this.strokeWidth,
|
|
49
|
+
showLabels: this.showLabels,
|
|
50
|
+
labelPixelDistance: this.labelPixelDistance,
|
|
51
|
+
labelFontSize: this.labelFontSize,
|
|
52
|
+
labelColor: this.labelColor,
|
|
53
|
+
labelHaloColor: this.labelHaloColor,
|
|
54
|
+
labelHaloWidth: this.labelHaloWidth,
|
|
55
|
+
labels: this.labels
|
|
56
|
+
}));
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export function createSiteDisplayStore() {
|
|
62
|
+
return new SiteDisplayStore();
|
|
63
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class SiteRegistry {
|
|
2
|
+
namespace: string;
|
|
3
|
+
hiddenSites: Set<string>;
|
|
4
|
+
groupColors: Map<string, string>;
|
|
5
|
+
version: number;
|
|
6
|
+
constructor(namespace: string);
|
|
7
|
+
isVisible(siteId: string): boolean;
|
|
8
|
+
getColor(level1: string, level2: string, defaultColor?: string): string;
|
|
9
|
+
setGroupColor(level1: string, level2: string, color: string): void;
|
|
10
|
+
toggleVisibility(siteId: string, visible?: boolean): void;
|
|
11
|
+
setVisible(siteIds: string[], visible: boolean): void;
|
|
12
|
+
}
|
|
13
|
+
export declare function createSiteRegistry(namespace: string): SiteRegistry;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { browser } from '$app/environment';
|
|
2
|
+
export class SiteRegistry {
|
|
3
|
+
namespace;
|
|
4
|
+
// Map of siteId -> visible (boolean)
|
|
5
|
+
// If a siteId is NOT in the map, it is assumed visible (default true)
|
|
6
|
+
hiddenSites = $state(new Set());
|
|
7
|
+
// Map of Group ID (e.g. "L1:L2") -> Color
|
|
8
|
+
groupColors = $state(new Map());
|
|
9
|
+
// Version counter to trigger reactivity in layers
|
|
10
|
+
version = $state(0);
|
|
11
|
+
constructor(namespace) {
|
|
12
|
+
this.namespace = namespace;
|
|
13
|
+
if (browser) {
|
|
14
|
+
// Load state
|
|
15
|
+
const savedColors = localStorage.getItem(`${this.namespace}:site-colors`);
|
|
16
|
+
if (savedColors) {
|
|
17
|
+
try {
|
|
18
|
+
const parsed = JSON.parse(savedColors);
|
|
19
|
+
this.groupColors = new Map(parsed);
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
console.warn('Failed to load site colors', e);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
$effect(() => {
|
|
27
|
+
if (browser) {
|
|
28
|
+
localStorage.setItem(`${this.namespace}:site-colors`, JSON.stringify(Array.from(this.groupColors.entries())));
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
isVisible(siteId) {
|
|
33
|
+
return !this.hiddenSites.has(siteId);
|
|
34
|
+
}
|
|
35
|
+
getColor(level1, level2, defaultColor = '#3388ff') {
|
|
36
|
+
const key = `${level1}:${level2}`;
|
|
37
|
+
return this.groupColors.get(key) || defaultColor;
|
|
38
|
+
}
|
|
39
|
+
setGroupColor(level1, level2, color) {
|
|
40
|
+
const key = `${level1}:${level2}`;
|
|
41
|
+
this.groupColors.set(key, color);
|
|
42
|
+
// Force reactivity
|
|
43
|
+
this.groupColors = new Map(this.groupColors);
|
|
44
|
+
this.version++;
|
|
45
|
+
}
|
|
46
|
+
toggleVisibility(siteId, visible) {
|
|
47
|
+
const isHidden = this.hiddenSites.has(siteId);
|
|
48
|
+
const shouldBeVisible = visible !== undefined ? visible : isHidden;
|
|
49
|
+
if (shouldBeVisible) {
|
|
50
|
+
this.hiddenSites.delete(siteId);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
this.hiddenSites.add(siteId);
|
|
54
|
+
}
|
|
55
|
+
// Force reactivity
|
|
56
|
+
this.hiddenSites = new Set(this.hiddenSites);
|
|
57
|
+
this.version++;
|
|
58
|
+
}
|
|
59
|
+
setVisible(siteIds, visible) {
|
|
60
|
+
let changed = false;
|
|
61
|
+
for (const id of siteIds) {
|
|
62
|
+
if (visible) {
|
|
63
|
+
if (this.hiddenSites.has(id)) {
|
|
64
|
+
this.hiddenSites.delete(id);
|
|
65
|
+
changed = true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
if (!this.hiddenSites.has(id)) {
|
|
70
|
+
this.hiddenSites.add(id);
|
|
71
|
+
changed = true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (changed) {
|
|
76
|
+
this.hiddenSites = new Set(this.hiddenSites);
|
|
77
|
+
this.version++;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export function createSiteRegistry(namespace) {
|
|
82
|
+
return new SiteRegistry(namespace);
|
|
83
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export * from './core';
|
|
2
|
+
export * from './shared';
|
|
3
|
+
export * from './features/cells/types';
|
|
4
|
+
export { default as CellsLayer } from './features/cells/layers/CellsLayer.svelte';
|
|
5
|
+
export { default as CellLabelsLayer } from './features/cells/layers/CellLabelsLayer.svelte';
|
|
6
|
+
export { default as CellFilterControl } from './features/cells/components/CellFilterControl.svelte';
|
|
7
|
+
export { default as CellSettingsPanel } from './features/cells/components/CellSettingsPanel.svelte';
|
|
8
|
+
export * from './features/cells/stores/cell.data.svelte';
|
|
9
|
+
export * from './features/cells/stores/cell.display.svelte';
|
|
10
|
+
export * from './features/cells/stores/cell.registry.svelte';
|
|
11
|
+
export * from './features/repeaters/types';
|
|
12
|
+
export { default as RepeatersLayer } from './features/repeaters/layers/RepeatersLayer.svelte';
|
|
13
|
+
export { default as RepeaterLabelsLayer } from './features/repeaters/layers/RepeaterLabelsLayer.svelte';
|
|
14
|
+
export { default as RepeaterFilterControl } from './features/repeaters/components/RepeaterFilterControl.svelte';
|
|
15
|
+
export { default as RepeaterSettingsPanel } from './features/repeaters/components/RepeaterSettingsPanel.svelte';
|
|
16
|
+
export * from './features/repeaters/stores/repeater.data.svelte';
|
|
17
|
+
export * from './features/repeaters/stores/repeater.display.svelte';
|
|
18
|
+
export * from './features/repeaters/stores/repeater.registry.svelte';
|
|
19
|
+
export * from './features/sites/types';
|
|
20
|
+
export { default as SitesLayer } from './features/sites/layers/SitesLayer.svelte';
|
|
21
|
+
export { default as SiteLabelsLayer } from './features/sites/layers/SiteLabelsLayer.svelte';
|
|
22
|
+
export { default as SiteFilterControl } from './features/sites/components/SiteFilterControl.svelte';
|
|
23
|
+
export { default as SiteSettingsPanel } from './features/sites/components/SiteSettingsPanel.svelte';
|
|
24
|
+
export * from './features/sites/stores/site.data.svelte';
|
|
25
|
+
export * from './features/sites/stores/site.display.svelte';
|
|
26
|
+
export * from './features/sites/stores/site.registry.svelte';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Core
|
|
2
|
+
export * from './core';
|
|
3
|
+
// Shared
|
|
4
|
+
export * from './shared';
|
|
5
|
+
// Features - Cells
|
|
6
|
+
export * from './features/cells/types';
|
|
7
|
+
export { default as CellsLayer } from './features/cells/layers/CellsLayer.svelte';
|
|
8
|
+
export { default as CellLabelsLayer } from './features/cells/layers/CellLabelsLayer.svelte';
|
|
9
|
+
export { default as CellFilterControl } from './features/cells/components/CellFilterControl.svelte';
|
|
10
|
+
export { default as CellSettingsPanel } from './features/cells/components/CellSettingsPanel.svelte';
|
|
11
|
+
export * from './features/cells/stores/cell.data.svelte';
|
|
12
|
+
export * from './features/cells/stores/cell.display.svelte';
|
|
13
|
+
export * from './features/cells/stores/cell.registry.svelte';
|
|
14
|
+
// Features - Repeaters
|
|
15
|
+
export * from './features/repeaters/types';
|
|
16
|
+
export { default as RepeatersLayer } from './features/repeaters/layers/RepeatersLayer.svelte';
|
|
17
|
+
export { default as RepeaterLabelsLayer } from './features/repeaters/layers/RepeaterLabelsLayer.svelte';
|
|
18
|
+
export { default as RepeaterFilterControl } from './features/repeaters/components/RepeaterFilterControl.svelte';
|
|
19
|
+
export { default as RepeaterSettingsPanel } from './features/repeaters/components/RepeaterSettingsPanel.svelte';
|
|
20
|
+
export * from './features/repeaters/stores/repeater.data.svelte';
|
|
21
|
+
export * from './features/repeaters/stores/repeater.display.svelte';
|
|
22
|
+
export * from './features/repeaters/stores/repeater.registry.svelte';
|
|
23
|
+
// Features - Sites
|
|
24
|
+
export * from './features/sites/types';
|
|
25
|
+
export { default as SitesLayer } from './features/sites/layers/SitesLayer.svelte';
|
|
26
|
+
export { default as SiteLabelsLayer } from './features/sites/layers/SiteLabelsLayer.svelte';
|
|
27
|
+
export { default as SiteFilterControl } from './features/sites/components/SiteFilterControl.svelte';
|
|
28
|
+
export { default as SiteSettingsPanel } from './features/sites/components/SiteSettingsPanel.svelte';
|
|
29
|
+
export * from './features/sites/stores/site.data.svelte';
|
|
30
|
+
export * from './features/sites/stores/site.display.svelte';
|
|
31
|
+
export * from './features/sites/stores/site.registry.svelte';
|