@smartnet360/svelte-components 0.0.126 → 0.0.128

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.
Files changed (22) hide show
  1. package/dist/map-v3/demo/DemoMap.svelte +18 -0
  2. package/dist/map-v3/features/cells/custom/stores/custom-cell-sets.svelte.d.ts +16 -5
  3. package/dist/map-v3/features/cells/custom/stores/custom-cell-sets.svelte.js +26 -13
  4. package/dist/map-v3/features/sites/custom/components/CustomSiteFilterControl.svelte +203 -0
  5. package/dist/map-v3/features/sites/custom/components/CustomSiteFilterControl.svelte.d.ts +15 -0
  6. package/dist/map-v3/features/sites/custom/components/CustomSiteSetManager.svelte +261 -0
  7. package/dist/map-v3/features/sites/custom/components/CustomSiteSetManager.svelte.d.ts +10 -0
  8. package/dist/map-v3/features/sites/custom/index.d.ts +13 -0
  9. package/dist/map-v3/features/sites/custom/index.js +16 -0
  10. package/dist/map-v3/features/sites/custom/layers/CustomSitesLayer.svelte +201 -0
  11. package/dist/map-v3/features/sites/custom/layers/CustomSitesLayer.svelte.d.ts +8 -0
  12. package/dist/map-v3/features/sites/custom/logic/csv-parser.d.ts +12 -0
  13. package/dist/map-v3/features/sites/custom/logic/csv-parser.js +182 -0
  14. package/dist/map-v3/features/sites/custom/logic/tree-adapter.d.ts +16 -0
  15. package/dist/map-v3/features/sites/custom/logic/tree-adapter.js +59 -0
  16. package/dist/map-v3/features/sites/custom/stores/custom-site-sets.svelte.d.ts +78 -0
  17. package/dist/map-v3/features/sites/custom/stores/custom-site-sets.svelte.js +248 -0
  18. package/dist/map-v3/features/sites/custom/types.d.ts +74 -0
  19. package/dist/map-v3/features/sites/custom/types.js +8 -0
  20. package/dist/map-v3/index.d.ts +2 -0
  21. package/dist/map-v3/index.js +4 -0
  22. 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
+ }
@@ -0,0 +1,8 @@
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
+ export {};
@@ -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';
@@ -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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartnet360/svelte-components",
3
- "version": "0.0.126",
3
+ "version": "0.0.128",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",