@smartnet360/svelte-components 0.0.13 â 0.0.15
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 +209 -57
- package/dist/apps/antenna-pattern/components/AntennaDiagrams.svelte +173 -96
- package/dist/apps/antenna-pattern/components/chart-engines/PolarAreaChart.svelte +125 -0
- package/dist/apps/antenna-pattern/components/chart-engines/PolarAreaChart.svelte.d.ts +16 -0
- package/dist/apps/antenna-pattern/components/chart-engines/PolarBarChart.svelte +121 -0
- package/dist/apps/antenna-pattern/components/chart-engines/PolarBarChart.svelte.d.ts +15 -0
- package/dist/apps/antenna-pattern/components/chart-engines/PolarLineChart.svelte +125 -0
- package/dist/apps/antenna-pattern/components/chart-engines/PolarLineChart.svelte.d.ts +16 -0
- package/dist/apps/antenna-pattern/components/chart-engines/index.d.ts +9 -0
- package/dist/apps/antenna-pattern/components/chart-engines/index.js +8 -0
- package/dist/apps/antenna-pattern/index.d.ts +1 -0
- package/dist/apps/antenna-pattern/index.js +2 -0
- package/dist/apps/antenna-pattern/utils/chart-engines/polar-area-utils.d.ts +89 -0
- package/dist/apps/antenna-pattern/utils/chart-engines/polar-area-utils.js +146 -0
- package/dist/apps/antenna-pattern/utils/chart-engines/polar-bar-utils.d.ts +88 -0
- package/dist/apps/antenna-pattern/utils/chart-engines/polar-bar-utils.js +131 -0
- package/dist/apps/antenna-pattern/utils/chart-engines/polar-line-utils.d.ts +88 -0
- package/dist/apps/antenna-pattern/utils/chart-engines/polar-line-utils.js +134 -0
- package/dist/apps/antenna-pattern/utils/recent-antennas.d.ts +20 -0
- package/dist/apps/antenna-pattern/utils/recent-antennas.js +60 -0
- package/package.json +4 -4
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
<script lang="ts">
|
4
4
|
import type { Antenna } from '../db';
|
5
|
+
import { sortAntennasWithRecent, addToRecentAntennas } from '../utils/recent-antennas';
|
5
6
|
|
6
7
|
interface Props {
|
7
8
|
antennas?: Antenna[];
|
@@ -47,23 +48,37 @@
|
|
47
48
|
$effect(() => {
|
48
49
|
// Only update internal state if the prop actually changed
|
49
50
|
// Avoid overwriting user selections
|
50
|
-
console.log(`[Antenna ${antennaNumber}] Effect triggered - selectedAntenna prop:`, selectedAntenna?.name || 'null', 'internal:', internalSelectedAntenna?.name || 'null');
|
51
51
|
if (selectedAntenna !== internalSelectedAntenna) {
|
52
|
-
console.log(`[Antenna ${antennaNumber}] Effect updating internal state from:`, internalSelectedAntenna?.name || 'null', 'to:', selectedAntenna?.name || 'null');
|
53
52
|
internalSelectedAntenna = selectedAntenna;
|
54
53
|
}
|
55
54
|
});
|
56
55
|
|
57
|
-
|
56
|
+
// Get available electrical tilts from antennas with the selected name and frequency
|
58
57
|
let availableElectricalTilts = $state<string[]>(['0']);
|
59
58
|
$effect(() => {
|
59
|
+
console.log('đ [TILTS] Effect triggered - updating available tilts:', {
|
60
|
+
antenna: internalSelectedAntenna?.name,
|
61
|
+
frequency: selectedFrequency,
|
62
|
+
currentTilts: availableElectricalTilts,
|
63
|
+
timestamp: new Date().toISOString()
|
64
|
+
});
|
65
|
+
|
66
|
+
let newTilts: string[] = ['0'];
|
67
|
+
|
60
68
|
if (internalSelectedAntenna) {
|
61
69
|
// Find ALL antennas with the same name and frequency to collect all electrical tilts
|
62
70
|
let sameName = antennas.filter(a => a.name === internalSelectedAntenna!.name);
|
71
|
+
console.log('đ [TILTS] Found antennas with same name:', sameName.length);
|
63
72
|
|
64
73
|
// If frequency is selected, filter by it
|
65
74
|
if (selectedFrequency) {
|
75
|
+
const beforeFilter = sameName.length;
|
66
76
|
sameName = sameName.filter(a => a.frequency === selectedFrequency);
|
77
|
+
console.log('đ [TILTS] After frequency filter:', {
|
78
|
+
before: beforeFilter,
|
79
|
+
after: sameName.length,
|
80
|
+
frequency: selectedFrequency
|
81
|
+
});
|
67
82
|
}
|
68
83
|
|
69
84
|
const allTilts = new Set<string>();
|
@@ -80,41 +95,36 @@
|
|
80
95
|
});
|
81
96
|
|
82
97
|
// Convert to sorted array
|
83
|
-
|
98
|
+
newTilts = Array.from(allTilts).sort((a, b) => parseFloat(a) - parseFloat(b));
|
99
|
+
|
100
|
+
console.log('â
[TILTS] Available tilts calculated:', {
|
101
|
+
from: availableElectricalTilts,
|
102
|
+
to: newTilts,
|
103
|
+
changed: JSON.stringify(availableElectricalTilts) !== JSON.stringify(newTilts)
|
104
|
+
});
|
84
105
|
} else {
|
85
|
-
|
106
|
+
console.log('âšī¸ [TILTS] No antenna selected, using default tilts');
|
107
|
+
}
|
108
|
+
|
109
|
+
// Only update if actually changed to prevent infinite loops
|
110
|
+
if (JSON.stringify(availableElectricalTilts) !== JSON.stringify(newTilts)) {
|
111
|
+
availableElectricalTilts = newTilts;
|
86
112
|
}
|
87
113
|
});
|
88
114
|
|
89
115
|
// Find the specific antenna that matches name, frequency, and electrical tilt
|
90
116
|
function findAntennaWithTilt(antennaName: string, tiltIndex: number): Antenna | null {
|
91
|
-
|
92
|
-
|
93
|
-
if (!antennaName) {
|
94
|
-
console.log(`[Antenna ${antennaNumber}] No antennaName provided, returning null`);
|
95
|
-
return null;
|
96
|
-
}
|
117
|
+
if (!antennaName) return null;
|
97
118
|
|
98
119
|
// Handle case where availableElectricalTilts might not be populated yet
|
99
120
|
const targetTilt = availableElectricalTilts[tiltIndex] || '0';
|
100
|
-
console.log(`[Antenna ${antennaNumber}] availableElectricalTilts:`, availableElectricalTilts);
|
101
|
-
console.log(`[Antenna ${antennaNumber}] targetTilt:`, targetTilt);
|
102
|
-
console.log(`[Antenna ${antennaNumber}] selectedFrequency:`, selectedFrequency);
|
103
121
|
|
104
122
|
// Find antenna with matching name, frequency, and electrical tilt
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
if (antenna.name !== antennaName) {
|
109
|
-
console.log(`[Antenna ${antennaNumber}] Name mismatch:`, antenna.name, '!==', antennaName);
|
110
|
-
return false;
|
111
|
-
}
|
123
|
+
return antennas.find(antenna => {
|
124
|
+
if (antenna.name !== antennaName) return false;
|
112
125
|
|
113
126
|
// If frequency is selected, must match
|
114
|
-
if (selectedFrequency && antenna.frequency !== selectedFrequency)
|
115
|
-
console.log(`[Antenna ${antennaNumber}] Frequency mismatch:`, antenna.frequency, '!==', selectedFrequency);
|
116
|
-
return false;
|
117
|
-
}
|
127
|
+
if (selectedFrequency && antenna.frequency !== selectedFrequency) return false;
|
118
128
|
|
119
129
|
if (antenna.tilt) {
|
120
130
|
const tiltString = antenna.tilt.toString();
|
@@ -122,37 +132,155 @@
|
|
122
132
|
? tiltString.split(',').map(t => t.trim())
|
123
133
|
: [tiltString];
|
124
134
|
|
125
|
-
|
126
|
-
const tiltMatch = antennasTilts.includes(targetTilt);
|
127
|
-
console.log(`[Antenna ${antennaNumber}] Tilt match:`, tiltMatch);
|
128
|
-
return tiltMatch;
|
135
|
+
return antennasTilts.includes(targetTilt);
|
129
136
|
}
|
130
137
|
|
131
|
-
|
132
|
-
console.log(`[Antenna ${antennaNumber}] Default tilt match:`, defaultMatch);
|
133
|
-
return defaultMatch; // Default tilt
|
138
|
+
return targetTilt === '0'; // Default tilt
|
134
139
|
}) || null;
|
135
|
-
|
136
|
-
console.log(`[Antenna ${antennaNumber}] findAntennaWithTilt result:`, result?.name || 'null');
|
137
|
-
return result;
|
138
140
|
}
|
139
141
|
|
140
142
|
// Handle frequency selection
|
141
143
|
function handleFrequencyChange(frequency: number) {
|
144
|
+
console.log('đ [FREQ] handleFrequencyChange called:', {
|
145
|
+
requestedFrequency: frequency,
|
146
|
+
currentSelectedFrequency: selectedFrequency,
|
147
|
+
currentAntenna: internalSelectedAntenna?.name,
|
148
|
+
currentTiltIndex: internalElectricalTiltIndex,
|
149
|
+
availableTilts: availableElectricalTilts,
|
150
|
+
timestamp: new Date().toISOString()
|
151
|
+
});
|
152
|
+
|
153
|
+
const previousFrequency = selectedFrequency;
|
142
154
|
selectedFrequency = frequency;
|
143
155
|
|
144
|
-
|
145
|
-
|
156
|
+
console.log('đ [FREQ] Frequency state updated:', {
|
157
|
+
from: previousFrequency,
|
158
|
+
to: selectedFrequency,
|
159
|
+
changed: previousFrequency !== selectedFrequency
|
160
|
+
});
|
146
161
|
|
147
|
-
// Find the antenna with the new frequency and default tilt
|
148
162
|
if (internalSelectedAntenna) {
|
149
|
-
|
163
|
+
// STEP 1: Calculate available tilts for the new frequency
|
164
|
+
let sameName = antennas.filter(a => a.name === internalSelectedAntenna!.name && a.frequency === frequency);
|
165
|
+
|
166
|
+
console.log('đ [FREQ] Found antennas with same name and new frequency:', {
|
167
|
+
antennaName: internalSelectedAntenna.name,
|
168
|
+
frequency: frequency,
|
169
|
+
count: sameName.length
|
170
|
+
});
|
171
|
+
|
172
|
+
const allTilts = new Set<string>();
|
173
|
+
sameName.forEach(antenna => {
|
174
|
+
if (antenna.tilt) {
|
175
|
+
const tiltString = antenna.tilt.toString();
|
176
|
+
if (tiltString.includes(',')) {
|
177
|
+
tiltString.split(',').forEach(t => allTilts.add(t.trim()));
|
178
|
+
} else {
|
179
|
+
allTilts.add(tiltString);
|
180
|
+
}
|
181
|
+
}
|
182
|
+
});
|
183
|
+
|
184
|
+
const newAvailableTilts = Array.from(allTilts).sort((a, b) => parseFloat(a) - parseFloat(b));
|
185
|
+
|
186
|
+
console.log('đ§ [FREQ] Calculated tilts for new frequency:', {
|
187
|
+
availableTilts: newAvailableTilts,
|
188
|
+
hasZeroTilt: newAvailableTilts.includes('0')
|
189
|
+
});
|
190
|
+
|
191
|
+
// STEP 2: Determine the best tilt index to use
|
192
|
+
let bestTiltIndex = 0;
|
193
|
+
let bestTiltValue = '0';
|
194
|
+
|
195
|
+
if (newAvailableTilts.length > 0) {
|
196
|
+
// Prefer '0' tilt if available, otherwise use first available
|
197
|
+
if (newAvailableTilts.includes('0')) {
|
198
|
+
bestTiltIndex = newAvailableTilts.indexOf('0');
|
199
|
+
bestTiltValue = '0';
|
200
|
+
} else {
|
201
|
+
bestTiltIndex = 0;
|
202
|
+
bestTiltValue = newAvailableTilts[0];
|
203
|
+
}
|
204
|
+
}
|
205
|
+
|
206
|
+
console.log('đ¯ [FREQ] Selected best tilt:', {
|
207
|
+
index: bestTiltIndex,
|
208
|
+
value: bestTiltValue,
|
209
|
+
reason: newAvailableTilts.includes('0') ? 'preferred 0 tilt' : 'first available tilt'
|
210
|
+
});
|
211
|
+
|
212
|
+
// STEP 3: Find antenna with the new frequency and best tilt
|
213
|
+
const antennaWithNewFreq = antennas.find(antenna => {
|
214
|
+
if (antenna.name !== internalSelectedAntenna!.name) return false;
|
215
|
+
if (antenna.frequency !== frequency) return false;
|
216
|
+
|
217
|
+
// Check if this antenna has the target tilt
|
218
|
+
if (antenna.tilt) {
|
219
|
+
const antennaTiltString = antenna.tilt.toString();
|
220
|
+
const antennaTilts = antennaTiltString.includes(',')
|
221
|
+
? antennaTiltString.split(',').map(t => t.trim())
|
222
|
+
: [antennaTiltString];
|
223
|
+
return antennaTilts.includes(bestTiltValue);
|
224
|
+
}
|
225
|
+
return bestTiltValue === '0';
|
226
|
+
});
|
227
|
+
|
228
|
+
console.log('đ¯ [FREQ] Antenna search result:', {
|
229
|
+
found: !!antennaWithNewFreq,
|
230
|
+
searchCriteria: {
|
231
|
+
name: internalSelectedAntenna.name,
|
232
|
+
frequency: frequency,
|
233
|
+
tiltValue: bestTiltValue
|
234
|
+
},
|
235
|
+
antenna: antennaWithNewFreq ? {
|
236
|
+
name: antennaWithNewFreq.name,
|
237
|
+
frequency: antennaWithNewFreq.frequency,
|
238
|
+
tilt: antennaWithNewFreq.tilt
|
239
|
+
} : null
|
240
|
+
});
|
241
|
+
|
150
242
|
if (antennaWithNewFreq) {
|
243
|
+
const previousAntenna = internalSelectedAntenna;
|
244
|
+
const previousTiltIndex = internalElectricalTiltIndex;
|
245
|
+
|
151
246
|
internalSelectedAntenna = antennaWithNewFreq;
|
247
|
+
internalElectricalTiltIndex = bestTiltIndex;
|
248
|
+
|
249
|
+
console.log('â
[FREQ] Antenna and tilt updated:', {
|
250
|
+
antenna: {
|
251
|
+
from: {
|
252
|
+
name: previousAntenna.name,
|
253
|
+
frequency: previousAntenna.frequency,
|
254
|
+
tilt: previousAntenna.tilt
|
255
|
+
},
|
256
|
+
to: {
|
257
|
+
name: antennaWithNewFreq.name,
|
258
|
+
frequency: antennaWithNewFreq.frequency,
|
259
|
+
tilt: antennaWithNewFreq.tilt
|
260
|
+
}
|
261
|
+
},
|
262
|
+
tiltIndex: {
|
263
|
+
from: previousTiltIndex,
|
264
|
+
to: bestTiltIndex
|
265
|
+
}
|
266
|
+
});
|
267
|
+
|
268
|
+
console.log('đ [FREQ] Calling onAntennaChange callback');
|
152
269
|
onAntennaChange?.(antennaWithNewFreq);
|
270
|
+
|
271
|
+
console.log('đ [FREQ] Calling onElectricalTiltChange callback with index', bestTiltIndex);
|
272
|
+
onElectricalTiltChange?.(bestTiltIndex);
|
273
|
+
} else {
|
274
|
+
console.warn('â ī¸ [FREQ] No antenna found for frequency, keeping current antenna');
|
275
|
+
// Reset tilt to 0 as fallback
|
276
|
+
internalElectricalTiltIndex = 0;
|
277
|
+
onElectricalTiltChange?.(0);
|
153
278
|
}
|
279
|
+
} else {
|
280
|
+
console.log('âšī¸ [FREQ] No current antenna selected');
|
281
|
+
internalElectricalTiltIndex = 0;
|
282
|
+
onElectricalTiltChange?.(0);
|
154
283
|
}
|
155
|
-
onElectricalTiltChange?.(0);
|
156
284
|
}
|
157
285
|
|
158
286
|
// Handle antenna selection
|
@@ -160,9 +288,6 @@
|
|
160
288
|
const target = event.target as HTMLSelectElement;
|
161
289
|
const antennaName = target.value;
|
162
290
|
|
163
|
-
console.log(`[Antenna ${antennaNumber}] handleAntennaChange called with:`, antennaName);
|
164
|
-
console.log(`[Antenna ${antennaNumber}] Before change - internalSelectedAntenna:`, internalSelectedAntenna?.name || 'null');
|
165
|
-
|
166
291
|
// Reset tilt and frequency values when antenna changes
|
167
292
|
internalElectricalTiltIndex = 0;
|
168
293
|
internalMechanicalTilt = 0;
|
@@ -170,12 +295,10 @@
|
|
170
295
|
|
171
296
|
// Handle "Select Antenna" case (empty string)
|
172
297
|
if (!antennaName) {
|
173
|
-
console.log(`[Antenna ${antennaNumber}] Setting to null (Select Antenna case)`);
|
174
298
|
internalSelectedAntenna = null;
|
175
299
|
onAntennaChange?.(null);
|
176
300
|
onElectricalTiltChange?.(0);
|
177
301
|
onMechanicalTiltChange?.(0);
|
178
|
-
console.log(`[Antenna ${antennaNumber}] After null set - internalSelectedAntenna:`, internalSelectedAntenna?.name || 'null');
|
179
302
|
return;
|
180
303
|
}
|
181
304
|
|
@@ -191,9 +314,6 @@
|
|
191
314
|
let tiltToUse = tilts.includes('0') ? '0' : tilts[0];
|
192
315
|
let tiltIndexToUse = tilts.includes('0') ? tilts.indexOf('0') : 0;
|
193
316
|
|
194
|
-
console.log(`[Antenna ${antennaNumber}] Available tilts for ${antennaName}:`, tilts);
|
195
|
-
console.log(`[Antenna ${antennaNumber}] Using tilt:`, tiltToUse, 'at index:', tiltIndexToUse);
|
196
|
-
|
197
317
|
// Find the specific antenna with the chosen tilt
|
198
318
|
const newAntenna = antennas.find(antenna => {
|
199
319
|
if (antenna.name !== antennaName) return false;
|
@@ -207,21 +327,23 @@
|
|
207
327
|
return tiltToUse === '0';
|
208
328
|
});
|
209
329
|
|
210
|
-
console.log(`[Antenna ${antennaNumber}] Found antenna with tilt ${tiltToUse}:`, newAntenna?.name || 'null');
|
211
330
|
internalSelectedAntenna = newAntenna || null;
|
212
331
|
internalElectricalTiltIndex = tiltIndexToUse;
|
213
332
|
|
214
333
|
} else {
|
215
334
|
// Fallback: use findAntennaWithTilt with index 0
|
216
335
|
const newAntenna = findAntennaWithTilt(antennaName, 0);
|
217
|
-
console.log(`[Antenna ${antennaNumber}] Fallback - Found antenna:`, newAntenna?.name || 'null');
|
218
336
|
internalSelectedAntenna = newAntenna;
|
219
337
|
}
|
220
338
|
|
221
339
|
onAntennaChange?.(internalSelectedAntenna);
|
222
340
|
onElectricalTiltChange?.(internalElectricalTiltIndex);
|
223
341
|
onMechanicalTiltChange?.(0);
|
224
|
-
|
342
|
+
|
343
|
+
// Track antenna selection in recent list
|
344
|
+
if (internalSelectedAntenna) {
|
345
|
+
addToRecentAntennas(internalSelectedAntenna);
|
346
|
+
}
|
225
347
|
}
|
226
348
|
|
227
349
|
// Handle electrical tilt changes
|
@@ -300,6 +422,9 @@
|
|
300
422
|
|
301
423
|
// Get unique antennas (by name, not by individual DB entries with different tilts)
|
302
424
|
let uniqueAntennas = $state<Antenna[]>([]);
|
425
|
+
let recentAntennas = $state<Antenna[]>([]);
|
426
|
+
let otherAntennas = $state<Antenna[]>([]);
|
427
|
+
|
303
428
|
$effect(() => {
|
304
429
|
if (antennas.length > 0) {
|
305
430
|
// Group antennas by name and take the first one from each group
|
@@ -309,7 +434,13 @@
|
|
309
434
|
antennaMap.set(antenna.name, antenna);
|
310
435
|
}
|
311
436
|
});
|
312
|
-
|
437
|
+
const allUniqueAntennas = Array.from(antennaMap.values()).sort((a, b) => a.name.localeCompare(b.name));
|
438
|
+
|
439
|
+
// Sort with recent antennas first
|
440
|
+
const { recent, others } = sortAntennasWithRecent(allUniqueAntennas);
|
441
|
+
recentAntennas = recent;
|
442
|
+
otherAntennas = others;
|
443
|
+
uniqueAntennas = [...recent, ...others];
|
313
444
|
}
|
314
445
|
});
|
315
446
|
</script>
|
@@ -330,12 +461,24 @@
|
|
330
461
|
class="form-select form-select-sm"
|
331
462
|
value={internalSelectedAntenna?.name || ''}
|
332
463
|
onchange={handleAntennaChange}
|
333
|
-
onfocus={() => console.log(`[Antenna ${antennaNumber}] Dropdown focused - current value:`, internalSelectedAntenna?.name || 'null')}
|
334
464
|
>
|
335
465
|
<option value="">-- Select Antenna --</option>
|
336
|
-
|
337
|
-
|
338
|
-
{
|
466
|
+
|
467
|
+
<!-- Recent Antennas -->
|
468
|
+
{#if recentAntennas.length > 0}
|
469
|
+
<optgroup label="Recent">
|
470
|
+
{#each recentAntennas as antenna}
|
471
|
+
<option value={antenna.name}>⸠{antenna.name}</option>
|
472
|
+
{/each}
|
473
|
+
</optgroup>
|
474
|
+
{/if}
|
475
|
+
|
476
|
+
<!-- All Other Antennas -->
|
477
|
+
<optgroup label="All Antennas">
|
478
|
+
{#each otherAntennas as antenna}
|
479
|
+
<option value={antenna.name}>{antenna.name}</option>
|
480
|
+
{/each}
|
481
|
+
</optgroup>
|
339
482
|
</select>
|
340
483
|
{#if internalSelectedAntenna}
|
341
484
|
<small class="text-muted mt-1 d-block">
|
@@ -355,7 +498,16 @@
|
|
355
498
|
<button
|
356
499
|
type="button"
|
357
500
|
class="btn btn-sm {selectedFrequency === freq ? 'btn-primary' : 'btn-outline-secondary'}"
|
358
|
-
onclick={() =>
|
501
|
+
onclick={(e) => {
|
502
|
+
console.log('đąī¸ [FREQ] Button clicked:', {
|
503
|
+
frequency: freq,
|
504
|
+
currentSelectedFrequency: selectedFrequency,
|
505
|
+
isAlreadySelected: selectedFrequency === freq,
|
506
|
+
clickEvent: e.type,
|
507
|
+
timestamp: new Date().toISOString()
|
508
|
+
});
|
509
|
+
handleFrequencyChange(freq);
|
510
|
+
}}
|
359
511
|
>
|
360
512
|
{freq} MHz
|
361
513
|
</button>
|