@smartnet360/svelte-components 0.0.135 → 0.0.137

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.
@@ -1,336 +0,0 @@
1
- <script lang="ts">
2
- import CellTablePanel from './CellTablePanel.svelte';
3
- import type { CellTableGroupField, ColumnPreset, RowSelectionEvent, CellData } from './types';
4
- import { generateCellsFromPreset, getGeneratorInfo, type GeneratorPreset } from '../../shared/demo';
5
-
6
- let datasetSize: GeneratorPreset = $state('small');
7
- let demoCells = $state(generateCellsFromPreset('small'));
8
- let dataInfo = $derived(getGeneratorInfo(demoCells));
9
-
10
- let groupBy: CellTableGroupField = $state('none');
11
- let columnPreset: ColumnPreset = $state('default');
12
- let searchTerm = $state('');
13
-
14
- // Loading states
15
- let isCreating = $state(false);
16
- let isReloading = $state(false);
17
- let isLoading = $derived(isCreating || isReloading);
18
-
19
- // Check if 5G-3500 already exists for the searched site
20
- let has5G3500 = $derived.by(() => {
21
- const siteId = searchTerm.trim();
22
- if (!siteId) return false;
23
- return demoCells.some(cell =>
24
- cell.siteId.toLowerCase() === siteId.toLowerCase() &&
25
- cell.fband === '5G-3500'
26
- );
27
- });
28
-
29
- // Create button disabled state
30
- let createDisabled = $derived(!searchTerm.trim() || isLoading || has5G3500);
31
-
32
- // Tooltip for create button
33
- let createTooltip = $derived.by(() => {
34
- if (!searchTerm.trim()) return 'Enter a site ID first';
35
- if (has5G3500) return '5G-3500 already exists for this site';
36
- if (isCreating) return 'Creating...';
37
- if (isReloading) return 'Reloading...';
38
- return 'Create 5G-3500 cell for this site';
39
- });
40
-
41
- function handleSelectionChange(event: RowSelectionEvent) {
42
- console.log('Selection changed:', event.ids);
43
- }
44
-
45
- // Context menu action handlers
46
- function handleViewCell(cell: CellData) {
47
- console.log('View cell:', cell.id, cell.cellName);
48
- alert(`Viewing cell: ${cell.cellName}`);
49
- }
50
-
51
- function handleEditCell(cell: CellData) {
52
- console.log('Edit cell:', cell.id, cell.cellName);
53
- alert(`Edit cell: ${cell.cellName}`);
54
- }
55
-
56
- function handleDeleteCell(cell: CellData) {
57
- console.log('Delete cell:', cell.id, cell.cellName);
58
- if (confirm(`Delete cell ${cell.cellName}?`)) {
59
- demoCells = demoCells.filter(c => c.id !== cell.id);
60
- }
61
- }
62
-
63
- function handleShowOnMap(cell: CellData) {
64
- console.log('Show on map:', cell.latitude, cell.longitude);
65
- alert(`Show on map: ${cell.cellName}\nLat: ${cell.latitude}\nLon: ${cell.longitude}`);
66
- }
67
-
68
- /**
69
- * Compare two selected cells' antenna configurations
70
- */
71
- function handleCompareTwoCells(cell1: CellData, cell2: CellData) {
72
- const params = new URLSearchParams();
73
-
74
- // Use antenna from both cells
75
- if (cell1.antenna) params.set('ant1', cell1.antenna);
76
- if (cell2.antenna) params.set('ant2', cell2.antenna);
77
-
78
- // Use electrical tilt values (parse first value if comma-separated)
79
- const etilt1 = cell1.electricalTilt ? parseInt(cell1.electricalTilt.split(',')[0], 10) : 0;
80
- const etilt2 = cell2.electricalTilt ? parseInt(cell2.electricalTilt.split(',')[0], 10) : 0;
81
- params.set('etilt1', String(etilt1 || 0));
82
- params.set('etilt2', String(etilt2 || 0));
83
-
84
- // Add cell name + status as labels
85
- params.set('label1', `${cell1.cellName} (${cell1.status})`);
86
- params.set('label2', `${cell2.cellName} (${cell2.status})`);
87
-
88
- const url = `/apps/antenna-compare?${params.toString()}`;
89
- window.open(url, '_blank');
90
- }
91
-
92
- function regenerateData() {
93
- demoCells = generateCellsFromPreset(datasetSize);
94
- }
95
-
96
- function handleSearch() {
97
- const term = searchTerm.trim().toLowerCase();
98
- if (!term) {
99
- // Reset to full dataset
100
- demoCells = generateCellsFromPreset(datasetSize);
101
- return;
102
- }
103
- // Filter by siteId (case-insensitive, partial match)
104
- const allCells = generateCellsFromPreset(datasetSize);
105
- demoCells = allCells.filter(cell =>
106
- cell.siteId.toLowerCase().includes(term) ||
107
- cell.cellName.toLowerCase().includes(term)
108
- );
109
- console.log(`Search "${term}": found ${demoCells.length} cells`);
110
- }
111
-
112
- function handleSearchKeydown(event: KeyboardEvent) {
113
- if (event.key === 'Enter') {
114
- handleSearch();
115
- }
116
- }
117
-
118
- // ============================================
119
- // PLACEHOLDER FUNCTIONS - Replace with your API calls
120
- // ============================================
121
-
122
- /**
123
- * Create a new 5G-3500 cell for the given site
124
- * TODO: Replace with your actual API call
125
- */
126
- async function createCellForSite(siteId: string): Promise<void> {
127
- // Simulate API call - replace with your implementation
128
- console.log(`Creating 5G-3500 cell for site: ${siteId}`);
129
- await new Promise(resolve => setTimeout(resolve, 1000));
130
- console.log(`Cell created for site: ${siteId}`);
131
- }
132
-
133
- /**
134
- * Reload site data after creation
135
- * TODO: Replace with your actual API call
136
- */
137
- async function reloadSiteData(siteId: string): Promise<typeof demoCells> {
138
- // Simulate API call - replace with your implementation
139
- console.log(`Reloading data for site: ${siteId}`);
140
- await new Promise(resolve => setTimeout(resolve, 500));
141
- // For demo, just return filtered data
142
- const allCells = generateCellsFromPreset(datasetSize);
143
- return allCells.filter(cell =>
144
- cell.siteId.toLowerCase().includes(siteId.toLowerCase())
145
- );
146
- }
147
-
148
- // ============================================
149
-
150
- /**
151
- * Handle create cell button click
152
- */
153
- async function handleCreateCell() {
154
- const siteId = searchTerm.trim();
155
- if (!siteId || isLoading || has5G3500) return;
156
-
157
- try {
158
- // Step 1: Create the cell
159
- isCreating = true;
160
- await createCellForSite(siteId);
161
- isCreating = false;
162
-
163
- // Step 2: Reload the data
164
- isReloading = true;
165
- demoCells = await reloadSiteData(siteId);
166
- isReloading = false;
167
-
168
- console.log('Cell created and data reloaded successfully');
169
- } catch (error) {
170
- console.error('Error creating cell:', error);
171
- isCreating = false;
172
- isReloading = false;
173
- }
174
- }
175
- </script>
176
-
177
- <div class="cell-table-page vh-100 d-flex flex-column">
178
- <!-- Simple header for demo controls only -->
179
- <div class="demo-controls bg-light border-bottom px-3 py-2 d-flex align-items-center gap-3 flex-wrap">
180
- <div class="input-group input-group-sm" style="width: auto;">
181
- <span class="input-group-text">Dataset</span>
182
- <select class="form-select" bind:value={datasetSize} onchange={regenerateData}>
183
- <option value="small">Small (~300)</option>
184
- <option value="medium">Medium (~3K)</option>
185
- <option value="large">Large (~15K)</option>
186
- <option value="xlarge">XLarge (~60K)</option>
187
- </select>
188
- </div>
189
- <span class="badge bg-info">
190
- {dataInfo.totalCells.toLocaleString()} cells | {dataInfo.totalSites} sites
191
- </span>
192
- <span class="badge bg-secondary d-none d-md-inline">
193
- {Object.entries(dataInfo.techBreakdown).map(([k, v]) => `${k}: ${v}`).join(' | ')}
194
- </span>
195
- </div>
196
-
197
- <!-- CellTablePanel with integrated sidebar -->
198
- <div class="flex-grow-1 overflow-hidden">
199
- <CellTablePanel
200
- cells={demoCells}
201
- bind:groupBy
202
- bind:columnPreset
203
- selectable={true}
204
- multiSelect={true}
205
- showToolbar={true}
206
- showExport={true}
207
- headerFilters={true}
208
- showDetailsSidebar={true}
209
- sidebarWidth={320}
210
- showScrollSpy={true}
211
- title="Cell Data"
212
- onselectionchange={handleSelectionChange}
213
- >
214
- {#snippet headerSearch()}
215
- <div class="d-flex align-items-center gap-2">
216
- <div class="input-group input-group-sm" style="width: 180px;">
217
- <input
218
- type="text"
219
- class="form-control"
220
- placeholder="Search site or cell..."
221
- bind:value={searchTerm}
222
- onkeydown={handleSearchKeydown}
223
- disabled={isLoading}
224
- />
225
- <button
226
- class="btn btn-outline-primary"
227
- type="button"
228
- onclick={handleSearch}
229
- title="Search"
230
- aria-label="Search"
231
- disabled={isLoading}
232
- >
233
- {#if isReloading}
234
- <span class="spinner-border spinner-border-sm" role="status"></span>
235
- {:else}
236
- <i class="bi bi-search"></i>
237
- {/if}
238
- </button>
239
- </div>
240
- <button
241
- class="btn btn-sm"
242
- class:btn-outline-success={!has5G3500}
243
- class:btn-success={has5G3500}
244
- type="button"
245
- onclick={handleCreateCell}
246
- title={createTooltip}
247
- aria-label="Create 5G-3500 cell"
248
- disabled={createDisabled}
249
- >
250
- {#if isCreating}
251
- <span class="spinner-border spinner-border-sm" role="status"></span>
252
- {:else if has5G3500}
253
- <i class="bi bi-check-lg"></i>
254
- {:else}
255
- <i class="bi bi-plus-lg"></i>
256
- {/if}
257
- </button>
258
- </div>
259
- {/snippet}
260
-
261
- {#snippet footer({ selectedRows, selectedCount })}
262
- <div class="d-flex align-items-center justify-content-between">
263
- <span class="text-muted small">
264
- {#if selectedCount > 0}
265
- {selectedCount} cell(s) selected
266
- {:else}
267
- Click a row to view details
268
- {/if}
269
- </span>
270
- <div class="btn-group">
271
- <button
272
- type="button"
273
- class="btn btn-sm btn-outline-success"
274
- disabled={selectedCount !== 2}
275
- title={selectedCount === 2 ? 'Compare Atoll antennas of selected cells' : 'Select exactly 2 cells to compare'}
276
- onclick={() => handleCompareTwoCells(selectedRows[0], selectedRows[1])}
277
- >
278
- <i class="bi bi-broadcast-pin"></i>
279
- <span class="d-none d-sm-inline ms-1">Compare Antennas</span>
280
- </button>
281
- <button
282
- type="button"
283
- class="btn btn-sm btn-outline-primary"
284
- disabled={selectedCount === 0}
285
- onclick={() => console.log('Process:', selectedRows.map(r => r.id))}
286
- >
287
- <i class="bi bi-gear"></i>
288
- <span class="d-none d-sm-inline ms-1">Process</span>
289
- </button>
290
- <button
291
- type="button"
292
- class="btn btn-sm btn-outline-secondary"
293
- disabled={selectedCount === 0}
294
- onclick={() => console.log('Export:', selectedRows.map(r => r.id))}
295
- >
296
- <i class="bi bi-download"></i>
297
- <span class="d-none d-sm-inline ms-1">Export</span>
298
- </button>
299
- </div>
300
- </div>
301
- {/snippet}
302
-
303
- {#snippet contextMenu({ row, closeMenu })}
304
- <div class="dropdown-menu show shadow-lg" style="min-width: 180px;">
305
- <h6 class="dropdown-header text-truncate" style="max-width: 200px;">
306
- <i class="bi bi-broadcast me-1"></i>{row.cellName}
307
- </h6>
308
- <div class="dropdown-divider"></div>
309
- <button class="dropdown-item" onclick={() => { handleViewCell(row); closeMenu(); }}>
310
- <i class="bi bi-eye me-2 text-primary"></i>View Details
311
- </button>
312
- <button class="dropdown-item" onclick={() => { handleEditCell(row); closeMenu(); }}>
313
- <i class="bi bi-pencil me-2 text-warning"></i>Edit Cell
314
- </button>
315
- <button class="dropdown-item" onclick={() => { handleShowOnMap(row); closeMenu(); }}>
316
- <i class="bi bi-geo-alt me-2 text-info"></i>Show on Map
317
- </button>
318
- <div class="dropdown-divider"></div>
319
- <button class="dropdown-item text-danger" onclick={() => { handleDeleteCell(row); closeMenu(); }}>
320
- <i class="bi bi-trash me-2"></i>Delete Cell
321
- </button>
322
- </div>
323
- {/snippet}
324
- </CellTablePanel>
325
- </div>
326
- </div>
327
-
328
- <style>
329
- .cell-table-page {
330
- background: var(--bs-body-bg, #f8f9fa);
331
- }
332
-
333
- .demo-controls {
334
- flex-shrink: 0;
335
- }
336
- </style>
@@ -1,3 +0,0 @@
1
- declare const CellTableDemo: import("svelte").Component<Record<string, never>, {}, "">;
2
- type CellTableDemo = ReturnType<typeof CellTableDemo>;
3
- export default CellTableDemo;