@smartnet360/svelte-components 0.0.134 → 0.0.136
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/core/CellHistory/CellHistoryPanel.svelte +178 -0
- package/dist/core/CellHistory/CellHistoryPanel.svelte.d.ts +4 -0
- package/dist/core/CellHistory/column-config.d.ts +26 -0
- package/dist/core/CellHistory/column-config.js +120 -0
- package/dist/core/CellHistory/index.d.ts +9 -0
- package/dist/core/CellHistory/index.js +10 -0
- package/dist/core/CellHistory/transformers.d.ts +16 -0
- package/dist/core/CellHistory/transformers.js +76 -0
- package/dist/core/CellHistory/types.d.ts +54 -0
- package/dist/core/CellHistory/types.js +6 -0
- package/dist/core/{CellTable → CellTableV2}/CellTable.svelte +7 -3
- package/dist/core/{CellTable → CellTableV2}/CellTable.svelte.d.ts +3 -0
- package/dist/core/{CellTable → CellTableV2}/CellTablePanel.svelte +87 -235
- package/dist/core/{CellTable → CellTableV2}/CellTablePanel.svelte.d.ts +16 -2
- package/dist/core/{CellTable → CellTableV2}/CellTableToolbar.svelte +0 -1
- package/dist/core/{CellTable → CellTableV2}/column-config.d.ts +11 -30
- package/dist/core/{CellTable → CellTableV2}/column-config.js +21 -220
- package/dist/core/CellTableV2/composables/index.d.ts +12 -0
- package/dist/core/CellTableV2/composables/index.js +9 -0
- package/dist/core/CellTableV2/composables/useColumnVisibility.svelte.d.ts +45 -0
- package/dist/core/CellTableV2/composables/useColumnVisibility.svelte.js +98 -0
- package/dist/core/CellTableV2/composables/usePersistence.svelte.d.ts +28 -0
- package/dist/core/CellTableV2/composables/usePersistence.svelte.js +101 -0
- package/dist/core/CellTableV2/composables/useScrollSpy.svelte.d.ts +44 -0
- package/dist/core/CellTableV2/composables/useScrollSpy.svelte.js +91 -0
- package/dist/core/CellTableV2/index.d.ts +12 -0
- package/dist/core/CellTableV2/index.js +14 -0
- package/dist/core/{CellTable → CellTableV2}/types.d.ts +3 -3
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.js +3 -1
- package/package.json +1 -1
- package/dist/core/CellTable/CellHistoryDemo.svelte +0 -240
- package/dist/core/CellTable/CellHistoryDemo.svelte.d.ts +0 -3
- package/dist/core/CellTable/CellTableDemo.svelte +0 -336
- package/dist/core/CellTable/CellTableDemo.svelte.d.ts +0 -3
- package/dist/core/CellTable/history-api-helper.d.ts +0 -79
- package/dist/core/CellTable/history-api-helper.js +0 -83
- package/dist/core/CellTable/index.d.ts +0 -15
- package/dist/core/CellTable/index.js +0 -20
- /package/dist/core/{CellTable → CellTableV2}/CellTableToolbar.svelte.d.ts +0 -0
- /package/dist/core/{CellTable → CellTableV2}/ColumnPicker.svelte +0 -0
- /package/dist/core/{CellTable → CellTableV2}/ColumnPicker.svelte.d.ts +0 -0
- /package/dist/core/{CellTable → CellTableV2}/types.js +0 -0
|
@@ -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,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cell History API Helper
|
|
3
|
-
*
|
|
4
|
-
* Transform functions for converting database records to frontend-ready format.
|
|
5
|
-
* Use these in your API endpoint before sending the response.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Raw database record format (Oracle/SQL style - UPPER_CASE)
|
|
9
|
-
*/
|
|
10
|
-
export interface CellHistoryDbRecord {
|
|
11
|
-
CELLNAME: string;
|
|
12
|
-
CONFIG_DATE: string | Date;
|
|
13
|
-
ANTENNA_TYPE: string;
|
|
14
|
-
PREV_ANTENNA_TYPE: string;
|
|
15
|
-
ANTOUTPUTPWR: number;
|
|
16
|
-
PREV_ANTOUTPUTPWR: number;
|
|
17
|
-
MECHANIC_TILT: number;
|
|
18
|
-
PREV_MECHANIC_TILT: number;
|
|
19
|
-
ELECTRONIC_TILT: number;
|
|
20
|
-
PREV_ELECTRONIC_TILT: number;
|
|
21
|
-
[key: string]: unknown;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Frontend-ready API response format (camelCase)
|
|
25
|
-
*/
|
|
26
|
-
export interface CellHistoryApiResponse {
|
|
27
|
-
cellName: string;
|
|
28
|
-
configDate: string;
|
|
29
|
-
antenna: string;
|
|
30
|
-
prevAntenna: string;
|
|
31
|
-
power: number;
|
|
32
|
-
prevPower: number;
|
|
33
|
-
mechanicalTilt: number;
|
|
34
|
-
prevMechanicalTilt: number;
|
|
35
|
-
electricalTilt: number;
|
|
36
|
-
prevElectricalTilt: number;
|
|
37
|
-
hasChanges: boolean;
|
|
38
|
-
changedFields: string[];
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Format a date to YYYY.MM.DD string
|
|
42
|
-
*/
|
|
43
|
-
export declare function formatConfigDate(date: string | Date): string;
|
|
44
|
-
/**
|
|
45
|
-
* Transform a single database record to API response format
|
|
46
|
-
*/
|
|
47
|
-
export declare function transformDbRecord(record: CellHistoryDbRecord): CellHistoryApiResponse;
|
|
48
|
-
/**
|
|
49
|
-
* Transform an array of database records to API response format
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* // In your API endpoint:
|
|
53
|
-
* const dbRecords = await db.query('SELECT * FROM CELL_CONFIG_HISTORY WHERE CELLNAME = ?', [cellName]);
|
|
54
|
-
* const response = transformDbRecords(dbRecords);
|
|
55
|
-
* return json(response);
|
|
56
|
-
*/
|
|
57
|
-
export declare function transformDbRecords(records: CellHistoryDbRecord[]): CellHistoryApiResponse[];
|
|
58
|
-
/**
|
|
59
|
-
* Example usage in a SvelteKit API endpoint:
|
|
60
|
-
*
|
|
61
|
-
* ```typescript
|
|
62
|
-
* // src/routes/api/cell-history/[cellName]/+server.ts
|
|
63
|
-
* import { json } from '@sveltejs/kit';
|
|
64
|
-
* import { transformDbRecords } from './history-api-helper';
|
|
65
|
-
* import { db } from '../../server/database';
|
|
66
|
-
*
|
|
67
|
-
* export async function GET({ params }) {
|
|
68
|
-
* const { cellName } = params;
|
|
69
|
-
*
|
|
70
|
-
* const dbRecords = await db.query(`
|
|
71
|
-
* SELECT * FROM CELL_CONFIG_HISTORY
|
|
72
|
-
* WHERE CELLNAME = :cellName
|
|
73
|
-
* ORDER BY CONFIG_DATE DESC
|
|
74
|
-
* `, { cellName });
|
|
75
|
-
*
|
|
76
|
-
* return json(transformDbRecords(dbRecords));
|
|
77
|
-
* }
|
|
78
|
-
* ```
|
|
79
|
-
*/
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cell History API Helper
|
|
3
|
-
*
|
|
4
|
-
* Transform functions for converting database records to frontend-ready format.
|
|
5
|
-
* Use these in your API endpoint before sending the response.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Format a date to YYYY.MM.DD string
|
|
9
|
-
*/
|
|
10
|
-
export function formatConfigDate(date) {
|
|
11
|
-
const d = typeof date === 'string' ? new Date(date) : date;
|
|
12
|
-
const year = d.getFullYear();
|
|
13
|
-
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
14
|
-
const day = String(d.getDate()).padStart(2, '0');
|
|
15
|
-
return `${year}.${month}.${day}`;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Transform a single database record to API response format
|
|
19
|
-
*/
|
|
20
|
-
export function transformDbRecord(record) {
|
|
21
|
-
// Detect which fields changed
|
|
22
|
-
const changedFields = [];
|
|
23
|
-
if (record.ANTENNA_TYPE !== record.PREV_ANTENNA_TYPE) {
|
|
24
|
-
changedFields.push('antenna');
|
|
25
|
-
}
|
|
26
|
-
if (record.ANTOUTPUTPWR !== record.PREV_ANTOUTPUTPWR) {
|
|
27
|
-
changedFields.push('power');
|
|
28
|
-
}
|
|
29
|
-
if (record.MECHANIC_TILT !== record.PREV_MECHANIC_TILT) {
|
|
30
|
-
changedFields.push('mechanicalTilt');
|
|
31
|
-
}
|
|
32
|
-
if (record.ELECTRONIC_TILT !== record.PREV_ELECTRONIC_TILT) {
|
|
33
|
-
changedFields.push('electricalTilt');
|
|
34
|
-
}
|
|
35
|
-
return {
|
|
36
|
-
cellName: record.CELLNAME,
|
|
37
|
-
configDate: formatConfigDate(record.CONFIG_DATE),
|
|
38
|
-
antenna: record.ANTENNA_TYPE,
|
|
39
|
-
prevAntenna: record.PREV_ANTENNA_TYPE,
|
|
40
|
-
power: record.ANTOUTPUTPWR,
|
|
41
|
-
prevPower: record.PREV_ANTOUTPUTPWR,
|
|
42
|
-
mechanicalTilt: record.MECHANIC_TILT,
|
|
43
|
-
prevMechanicalTilt: record.PREV_MECHANIC_TILT,
|
|
44
|
-
electricalTilt: record.ELECTRONIC_TILT,
|
|
45
|
-
prevElectricalTilt: record.PREV_ELECTRONIC_TILT,
|
|
46
|
-
hasChanges: changedFields.length > 0,
|
|
47
|
-
changedFields
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Transform an array of database records to API response format
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* // In your API endpoint:
|
|
55
|
-
* const dbRecords = await db.query('SELECT * FROM CELL_CONFIG_HISTORY WHERE CELLNAME = ?', [cellName]);
|
|
56
|
-
* const response = transformDbRecords(dbRecords);
|
|
57
|
-
* return json(response);
|
|
58
|
-
*/
|
|
59
|
-
export function transformDbRecords(records) {
|
|
60
|
-
return records.map(transformDbRecord);
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Example usage in a SvelteKit API endpoint:
|
|
64
|
-
*
|
|
65
|
-
* ```typescript
|
|
66
|
-
* // src/routes/api/cell-history/[cellName]/+server.ts
|
|
67
|
-
* import { json } from '@sveltejs/kit';
|
|
68
|
-
* import { transformDbRecords } from './history-api-helper';
|
|
69
|
-
* import { db } from '../../server/database';
|
|
70
|
-
*
|
|
71
|
-
* export async function GET({ params }) {
|
|
72
|
-
* const { cellName } = params;
|
|
73
|
-
*
|
|
74
|
-
* const dbRecords = await db.query(`
|
|
75
|
-
* SELECT * FROM CELL_CONFIG_HISTORY
|
|
76
|
-
* WHERE CELLNAME = :cellName
|
|
77
|
-
* ORDER BY CONFIG_DATE DESC
|
|
78
|
-
* `, { cellName });
|
|
79
|
-
*
|
|
80
|
-
* return json(transformDbRecords(dbRecords));
|
|
81
|
-
* }
|
|
82
|
-
* ```
|
|
83
|
-
*/
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CellTable Component - Exports
|
|
3
|
-
*
|
|
4
|
-
* A Bootstrap-themed Tabulator wrapper for displaying cell data
|
|
5
|
-
*/
|
|
6
|
-
export { default as CellTable } from './CellTable.svelte';
|
|
7
|
-
export { default as CellTableToolbar } from './CellTableToolbar.svelte';
|
|
8
|
-
export { default as CellTablePanel } from './CellTablePanel.svelte';
|
|
9
|
-
export { default as CellTableDemo } from './CellTableDemo.svelte';
|
|
10
|
-
export { default as CellHistoryDemo } from './CellHistoryDemo.svelte';
|
|
11
|
-
export { default as ColumnPicker } from './ColumnPicker.svelte';
|
|
12
|
-
export { transformDbRecord, transformDbRecords, formatConfigDate, type CellHistoryDbRecord, type CellHistoryApiResponse } from './history-api-helper';
|
|
13
|
-
export { generateCells, generateCellsFromPreset, getGeneratorInfo, GENERATOR_PRESETS, type CellGeneratorConfig, type GeneratorPreset } from '../../shared/demo';
|
|
14
|
-
export type { CellData, CellTableGroupField, ColumnPreset, ColumnVisibility, TechColorMap, StatusColorMap, CellTableProps, RowSelectionEvent, RowClickEvent, RowDblClickEvent, RowContextMenuEvent, DataChangeEvent, CellTableColumn, ColumnGroups, CellHistoryData, GroupOption } from './types';
|
|
15
|
-
export { DEFAULT_TECH_COLORS, DEFAULT_STATUS_COLORS, FBAND_COLORS, COLUMN_GROUPS, getAllColumns, getColumnsForPreset, getGroupHeaderFormatter, getColumnMetadata, getPresetVisibleFields, fbandSorter, cellNameSectorSorter, cellDataSorter, createTechFormatter, createStatusFormatter, createFbandFormatter, createHistoryChangeFormatter, historyDateFormatter, numberFormatter, coordinateFormatter, azimuthFormatter, heightFormatter, type ColumnMeta } from './column-config';
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CellTable Component - Exports
|
|
3
|
-
*
|
|
4
|
-
* A Bootstrap-themed Tabulator wrapper for displaying cell data
|
|
5
|
-
*/
|
|
6
|
-
// Components
|
|
7
|
-
export { default as CellTable } from './CellTable.svelte';
|
|
8
|
-
export { default as CellTableToolbar } from './CellTableToolbar.svelte';
|
|
9
|
-
export { default as CellTablePanel } from './CellTablePanel.svelte';
|
|
10
|
-
export { default as CellTableDemo } from './CellTableDemo.svelte';
|
|
11
|
-
export { default as CellHistoryDemo } from './CellHistoryDemo.svelte';
|
|
12
|
-
export { default as ColumnPicker } from './ColumnPicker.svelte';
|
|
13
|
-
// History API helpers (for backend transformation)
|
|
14
|
-
export { transformDbRecord, transformDbRecords, formatConfigDate } from './history-api-helper';
|
|
15
|
-
// Re-export shared demo data utilities for convenience
|
|
16
|
-
// Note: Cell type is NOT re-exported here to avoid conflicts with map-v2
|
|
17
|
-
// Import Cell from '$lib/shared/demo' or '@smartnet360/svelte-components' directly
|
|
18
|
-
export { generateCells, generateCellsFromPreset, getGeneratorInfo, GENERATOR_PRESETS } from '../../shared/demo';
|
|
19
|
-
// Configuration utilities
|
|
20
|
-
export { DEFAULT_TECH_COLORS, DEFAULT_STATUS_COLORS, FBAND_COLORS, COLUMN_GROUPS, getAllColumns, getColumnsForPreset, getGroupHeaderFormatter, getColumnMetadata, getPresetVisibleFields, fbandSorter, cellNameSectorSorter, cellDataSorter, createTechFormatter, createStatusFormatter, createFbandFormatter, createHistoryChangeFormatter, historyDateFormatter, numberFormatter, coordinateFormatter, azimuthFormatter, heightFormatter } from './column-config';
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|