@smartnet360/svelte-components 0.0.126 → 0.0.127
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/map-v3/demo/DemoMap.svelte +18 -0
- package/dist/map-v3/features/sites/custom/components/CustomSiteFilterControl.svelte +203 -0
- package/dist/map-v3/features/sites/custom/components/CustomSiteFilterControl.svelte.d.ts +15 -0
- package/dist/map-v3/features/sites/custom/components/CustomSiteSetManager.svelte +261 -0
- package/dist/map-v3/features/sites/custom/components/CustomSiteSetManager.svelte.d.ts +10 -0
- package/dist/map-v3/features/sites/custom/index.d.ts +13 -0
- package/dist/map-v3/features/sites/custom/index.js +16 -0
- package/dist/map-v3/features/sites/custom/layers/CustomSitesLayer.svelte +201 -0
- package/dist/map-v3/features/sites/custom/layers/CustomSitesLayer.svelte.d.ts +8 -0
- package/dist/map-v3/features/sites/custom/logic/csv-parser.d.ts +12 -0
- package/dist/map-v3/features/sites/custom/logic/csv-parser.js +182 -0
- package/dist/map-v3/features/sites/custom/logic/tree-adapter.d.ts +16 -0
- package/dist/map-v3/features/sites/custom/logic/tree-adapter.js +59 -0
- package/dist/map-v3/features/sites/custom/stores/custom-site-sets.svelte.d.ts +78 -0
- package/dist/map-v3/features/sites/custom/stores/custom-site-sets.svelte.js +248 -0
- package/dist/map-v3/features/sites/custom/types.d.ts +74 -0
- package/dist/map-v3/features/sites/custom/types.js +8 -0
- package/dist/map-v3/index.d.ts +2 -0
- package/dist/map-v3/index.js +4 -0
- package/package.json +1 -1
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Site Sets Store
|
|
3
|
+
*
|
|
4
|
+
* Manages multiple custom site sets with CRUD operations,
|
|
5
|
+
* localStorage persistence, and group visibility/color controls.
|
|
6
|
+
*/
|
|
7
|
+
import { parseCustomSitesCsv } from '../logic/csv-parser';
|
|
8
|
+
/** Default colors for groups */
|
|
9
|
+
const DEFAULT_COLORS = [
|
|
10
|
+
'#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00',
|
|
11
|
+
'#ffff33', '#a65628', '#f781bf', '#999999', '#66c2a5',
|
|
12
|
+
'#fc8d62', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f'
|
|
13
|
+
];
|
|
14
|
+
const STORAGE_KEY = 'custom-site-sets';
|
|
15
|
+
/**
|
|
16
|
+
* Store for managing custom site sets
|
|
17
|
+
*/
|
|
18
|
+
export class CustomSiteSetsStore {
|
|
19
|
+
/** All custom site sets */
|
|
20
|
+
_sets = $state([]);
|
|
21
|
+
/** Version counter for reactivity triggers */
|
|
22
|
+
_version = $state(0);
|
|
23
|
+
constructor() {
|
|
24
|
+
this.loadFromStorage();
|
|
25
|
+
}
|
|
26
|
+
// ─────────────────────────────────────────────────────────────
|
|
27
|
+
// Public Getters
|
|
28
|
+
// ─────────────────────────────────────────────────────────────
|
|
29
|
+
get sets() {
|
|
30
|
+
return this._sets;
|
|
31
|
+
}
|
|
32
|
+
get version() {
|
|
33
|
+
return this._version;
|
|
34
|
+
}
|
|
35
|
+
// ─────────────────────────────────────────────────────────────
|
|
36
|
+
// Import / Create
|
|
37
|
+
// ─────────────────────────────────────────────────────────────
|
|
38
|
+
/**
|
|
39
|
+
* Import sites from CSV content
|
|
40
|
+
*/
|
|
41
|
+
importFromCsv(csvContent, fileName) {
|
|
42
|
+
const result = parseCustomSitesCsv(csvContent);
|
|
43
|
+
if (result.sites.length === 0) {
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
// Create a new set
|
|
47
|
+
const setId = this.createSet(fileName.replace(/\.csv$/i, ''), result.sites, result.groups);
|
|
48
|
+
return { ...result, setId };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Create a new custom site set
|
|
52
|
+
*/
|
|
53
|
+
createSet(name, sites, groups) {
|
|
54
|
+
const id = `custom-sites-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
55
|
+
// Assign colors to groups
|
|
56
|
+
const groupColors = new Map();
|
|
57
|
+
groups.forEach((group, idx) => {
|
|
58
|
+
groupColors.set(group, DEFAULT_COLORS[idx % DEFAULT_COLORS.length]);
|
|
59
|
+
});
|
|
60
|
+
const newSet = {
|
|
61
|
+
id,
|
|
62
|
+
name,
|
|
63
|
+
sites,
|
|
64
|
+
groups,
|
|
65
|
+
groupColors,
|
|
66
|
+
baseSize: 8,
|
|
67
|
+
opacity: 0.8,
|
|
68
|
+
visible: true,
|
|
69
|
+
visibleGroups: new Set(groups)
|
|
70
|
+
};
|
|
71
|
+
this._sets = [...this._sets, newSet];
|
|
72
|
+
this._version++;
|
|
73
|
+
this.saveToStorage();
|
|
74
|
+
return id;
|
|
75
|
+
}
|
|
76
|
+
// ─────────────────────────────────────────────────────────────
|
|
77
|
+
// Update Operations
|
|
78
|
+
// ─────────────────────────────────────────────────────────────
|
|
79
|
+
/**
|
|
80
|
+
* Toggle visibility of entire set
|
|
81
|
+
*/
|
|
82
|
+
toggleSetVisibility(setId) {
|
|
83
|
+
const set = this._sets.find(s => s.id === setId);
|
|
84
|
+
if (set) {
|
|
85
|
+
set.visible = !set.visible;
|
|
86
|
+
this._version++;
|
|
87
|
+
this.saveToStorage();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Toggle visibility of a specific group within a set
|
|
92
|
+
*/
|
|
93
|
+
toggleGroupVisibility(setId, groupId) {
|
|
94
|
+
const set = this._sets.find(s => s.id === setId);
|
|
95
|
+
if (set) {
|
|
96
|
+
if (set.visibleGroups.has(groupId)) {
|
|
97
|
+
set.visibleGroups.delete(groupId);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
set.visibleGroups.add(groupId);
|
|
101
|
+
}
|
|
102
|
+
this._version++;
|
|
103
|
+
this.saveToStorage();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Set color for a group
|
|
108
|
+
*/
|
|
109
|
+
setGroupColor(setId, groupId, color) {
|
|
110
|
+
const set = this._sets.find(s => s.id === setId);
|
|
111
|
+
if (set) {
|
|
112
|
+
set.groupColors.set(groupId, color);
|
|
113
|
+
this._version++;
|
|
114
|
+
this.saveToStorage();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Update base size for a set
|
|
119
|
+
*/
|
|
120
|
+
setBaseSize(setId, size) {
|
|
121
|
+
const set = this._sets.find(s => s.id === setId);
|
|
122
|
+
if (set) {
|
|
123
|
+
set.baseSize = Math.max(2, Math.min(50, size));
|
|
124
|
+
this._version++;
|
|
125
|
+
this.saveToStorage();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Update opacity for a set
|
|
130
|
+
*/
|
|
131
|
+
setOpacity(setId, opacity) {
|
|
132
|
+
const set = this._sets.find(s => s.id === setId);
|
|
133
|
+
if (set) {
|
|
134
|
+
set.opacity = Math.max(0.1, Math.min(1, opacity));
|
|
135
|
+
this._version++;
|
|
136
|
+
this.saveToStorage();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Rename a set
|
|
141
|
+
*/
|
|
142
|
+
renameSet(setId, newName) {
|
|
143
|
+
const set = this._sets.find(s => s.id === setId);
|
|
144
|
+
if (set && newName.trim()) {
|
|
145
|
+
set.name = newName.trim();
|
|
146
|
+
this._version++;
|
|
147
|
+
this.saveToStorage();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// ─────────────────────────────────────────────────────────────
|
|
151
|
+
// Delete
|
|
152
|
+
// ─────────────────────────────────────────────────────────────
|
|
153
|
+
/**
|
|
154
|
+
* Remove a set
|
|
155
|
+
*/
|
|
156
|
+
removeSet(setId) {
|
|
157
|
+
this._sets = this._sets.filter(s => s.id !== setId);
|
|
158
|
+
this._version++;
|
|
159
|
+
this.saveToStorage();
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Clear all sets
|
|
163
|
+
*/
|
|
164
|
+
clearAll() {
|
|
165
|
+
this._sets = [];
|
|
166
|
+
this._version++;
|
|
167
|
+
this.saveToStorage();
|
|
168
|
+
}
|
|
169
|
+
// ─────────────────────────────────────────────────────────────
|
|
170
|
+
// Persistence
|
|
171
|
+
// ─────────────────────────────────────────────────────────────
|
|
172
|
+
saveToStorage() {
|
|
173
|
+
try {
|
|
174
|
+
const serialized = this._sets.map(set => ({
|
|
175
|
+
id: set.id,
|
|
176
|
+
name: set.name,
|
|
177
|
+
sites: set.sites,
|
|
178
|
+
groups: set.groups,
|
|
179
|
+
groupColors: Array.from(set.groupColors.entries()),
|
|
180
|
+
baseSize: set.baseSize,
|
|
181
|
+
opacity: set.opacity,
|
|
182
|
+
visible: set.visible,
|
|
183
|
+
visibleGroups: Array.from(set.visibleGroups)
|
|
184
|
+
}));
|
|
185
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(serialized));
|
|
186
|
+
}
|
|
187
|
+
catch (e) {
|
|
188
|
+
console.error('[CustomSiteSetsStore] Failed to save to storage:', e);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
loadFromStorage() {
|
|
192
|
+
try {
|
|
193
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
194
|
+
if (!stored)
|
|
195
|
+
return;
|
|
196
|
+
const serialized = JSON.parse(stored);
|
|
197
|
+
this._sets = serialized.map(s => ({
|
|
198
|
+
id: s.id,
|
|
199
|
+
name: s.name,
|
|
200
|
+
sites: s.sites,
|
|
201
|
+
groups: s.groups,
|
|
202
|
+
groupColors: new Map(s.groupColors),
|
|
203
|
+
baseSize: s.baseSize,
|
|
204
|
+
opacity: s.opacity,
|
|
205
|
+
visible: s.visible,
|
|
206
|
+
visibleGroups: new Set(s.visibleGroups)
|
|
207
|
+
}));
|
|
208
|
+
this._version++;
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
console.error('[CustomSiteSetsStore] Failed to load from storage:', e);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// ─────────────────────────────────────────────────────────────
|
|
215
|
+
// Query Helpers
|
|
216
|
+
// ─────────────────────────────────────────────────────────────
|
|
217
|
+
/**
|
|
218
|
+
* Get a specific set by ID
|
|
219
|
+
*/
|
|
220
|
+
getSet(setId) {
|
|
221
|
+
return this._sets.find(s => s.id === setId);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Get visible sites for a set (filtered by visible groups)
|
|
225
|
+
*/
|
|
226
|
+
getVisibleSites(setId) {
|
|
227
|
+
const set = this._sets.find(s => s.id === setId);
|
|
228
|
+
if (!set || !set.visible)
|
|
229
|
+
return [];
|
|
230
|
+
return set.sites.filter(site => set.visibleGroups.has(site.customGroup));
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Get all visible sites across all sets
|
|
234
|
+
*/
|
|
235
|
+
getAllVisibleSites() {
|
|
236
|
+
const result = [];
|
|
237
|
+
for (const set of this._sets) {
|
|
238
|
+
if (!set.visible)
|
|
239
|
+
continue;
|
|
240
|
+
for (const site of set.sites) {
|
|
241
|
+
if (set.visibleGroups.has(site.customGroup)) {
|
|
242
|
+
result.push({ site, set });
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return result;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Sites Types
|
|
3
|
+
*
|
|
4
|
+
* Types for user-uploaded custom site points with grouping and styling.
|
|
5
|
+
* Unlike custom cells, these are standalone points (lat/lon) that don't
|
|
6
|
+
* need to be resolved against existing data.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* A custom site point from CSV import
|
|
10
|
+
*/
|
|
11
|
+
export interface CustomSite {
|
|
12
|
+
/** Unique identifier from CSV */
|
|
13
|
+
id: string;
|
|
14
|
+
/** Latitude coordinate */
|
|
15
|
+
lat: number;
|
|
16
|
+
/** Longitude coordinate */
|
|
17
|
+
lon: number;
|
|
18
|
+
/** Group for TreeView organization */
|
|
19
|
+
customGroup: string;
|
|
20
|
+
/** Size multiplier (default 1.0) */
|
|
21
|
+
sizeFactor: number;
|
|
22
|
+
/** Any additional columns from CSV */
|
|
23
|
+
extraFields: Record<string, string>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A set of custom sites imported from a single CSV
|
|
27
|
+
*/
|
|
28
|
+
export interface CustomSiteSet {
|
|
29
|
+
/** Unique ID for this set */
|
|
30
|
+
id: string;
|
|
31
|
+
/** Display name (typically filename) */
|
|
32
|
+
name: string;
|
|
33
|
+
/** All sites in this set */
|
|
34
|
+
sites: CustomSite[];
|
|
35
|
+
/** List of unique group names */
|
|
36
|
+
groups: string[];
|
|
37
|
+
/** Color per group */
|
|
38
|
+
groupColors: Map<string, string>;
|
|
39
|
+
/** Base circle radius in pixels */
|
|
40
|
+
baseSize: number;
|
|
41
|
+
/** Layer opacity 0-1 */
|
|
42
|
+
opacity: number;
|
|
43
|
+
/** Is this set visible on map? */
|
|
44
|
+
visible: boolean;
|
|
45
|
+
/** Which groups are currently visible */
|
|
46
|
+
visibleGroups: Set<string>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Result from parsing a custom sites CSV
|
|
50
|
+
*/
|
|
51
|
+
export interface CustomSiteImportResult {
|
|
52
|
+
/** Successfully parsed sites */
|
|
53
|
+
sites: CustomSite[];
|
|
54
|
+
/** Unique group names found */
|
|
55
|
+
groups: string[];
|
|
56
|
+
/** Number of rows that couldn't be parsed */
|
|
57
|
+
invalidRows: number;
|
|
58
|
+
/** Error messages for invalid rows */
|
|
59
|
+
errors: string[];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Serializable version of CustomSiteSet for localStorage
|
|
63
|
+
*/
|
|
64
|
+
export interface CustomSiteSetSerialized {
|
|
65
|
+
id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
sites: CustomSite[];
|
|
68
|
+
groups: string[];
|
|
69
|
+
groupColors: [string, string][];
|
|
70
|
+
baseSize: number;
|
|
71
|
+
opacity: number;
|
|
72
|
+
visible: boolean;
|
|
73
|
+
visibleGroups: string[];
|
|
74
|
+
}
|
package/dist/map-v3/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { default as CellSettingsPanel } from './features/cells/components/CellSe
|
|
|
8
8
|
export * from './features/cells/stores/cell.data.svelte';
|
|
9
9
|
export * from './features/cells/stores/cell.display.svelte';
|
|
10
10
|
export * from './features/cells/stores/cell.registry.svelte';
|
|
11
|
+
export * as CustomCells from './features/cells/custom';
|
|
11
12
|
export * from './features/repeaters/types';
|
|
12
13
|
export { default as RepeatersLayer } from './features/repeaters/layers/RepeatersLayer.svelte';
|
|
13
14
|
export { default as RepeaterLabelsLayer } from './features/repeaters/layers/RepeaterLabelsLayer.svelte';
|
|
@@ -24,6 +25,7 @@ export { default as SiteSettingsPanel } from './features/sites/components/SiteSe
|
|
|
24
25
|
export * from './features/sites/stores/site.data.svelte';
|
|
25
26
|
export * from './features/sites/stores/site.display.svelte';
|
|
26
27
|
export * from './features/sites/stores/site.registry.svelte';
|
|
28
|
+
export * as CustomSites from './features/sites/custom';
|
|
27
29
|
export * from './features/selection';
|
|
28
30
|
export * from './features/coverage/types';
|
|
29
31
|
export { default as CoverageLayer } from './features/coverage/layers/CoverageLayer.svelte';
|
package/dist/map-v3/index.js
CHANGED
|
@@ -11,6 +11,8 @@ export { default as CellSettingsPanel } from './features/cells/components/CellSe
|
|
|
11
11
|
export * from './features/cells/stores/cell.data.svelte';
|
|
12
12
|
export * from './features/cells/stores/cell.display.svelte';
|
|
13
13
|
export * from './features/cells/stores/cell.registry.svelte';
|
|
14
|
+
// Features - Cells Custom
|
|
15
|
+
export * as CustomCells from './features/cells/custom';
|
|
14
16
|
// Features - Repeaters
|
|
15
17
|
export * from './features/repeaters/types';
|
|
16
18
|
export { default as RepeatersLayer } from './features/repeaters/layers/RepeatersLayer.svelte';
|
|
@@ -29,6 +31,8 @@ export { default as SiteSettingsPanel } from './features/sites/components/SiteSe
|
|
|
29
31
|
export * from './features/sites/stores/site.data.svelte';
|
|
30
32
|
export * from './features/sites/stores/site.display.svelte';
|
|
31
33
|
export * from './features/sites/stores/site.registry.svelte';
|
|
34
|
+
// Features - Sites Custom
|
|
35
|
+
export * as CustomSites from './features/sites/custom';
|
|
32
36
|
// Features - Selection
|
|
33
37
|
export * from './features/selection';
|
|
34
38
|
// Features - Coverage
|