@smartnet360/svelte-components 0.0.135 → 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/index.d.ts +1 -2
- package/dist/core/index.js +2 -5
- 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/CellTable.svelte +0 -597
- package/dist/core/CellTable/CellTable.svelte.d.ts +0 -40
- package/dist/core/CellTable/CellTableDemo.svelte +0 -336
- package/dist/core/CellTable/CellTableDemo.svelte.d.ts +0 -3
- package/dist/core/CellTable/CellTablePanel.svelte +0 -833
- package/dist/core/CellTable/CellTablePanel.svelte.d.ts +0 -84
- package/dist/core/CellTable/CellTableToolbar.svelte +0 -323
- package/dist/core/CellTable/CellTableToolbar.svelte.d.ts +0 -59
- package/dist/core/CellTable/ColumnPicker.svelte +0 -214
- package/dist/core/CellTable/ColumnPicker.svelte.d.ts +0 -26
- package/dist/core/CellTable/column-config.d.ts +0 -139
- package/dist/core/CellTable/column-config.js +0 -872
- 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/types.d.ts +0 -172
- package/dist/core/CellTable/types.js +0 -6
|
@@ -1,872 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CellTable - Column Configuration
|
|
3
|
-
*
|
|
4
|
-
* Defines column definitions, presets, and formatters for the cell table
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Default technology colors (Bootstrap-aligned)
|
|
8
|
-
* 2G: Yellow, 4G: Purple, 5G: Green
|
|
9
|
-
*/
|
|
10
|
-
export const DEFAULT_TECH_COLORS = {
|
|
11
|
-
'2G': '#ffc107', // Yellow
|
|
12
|
-
'3G': '#0d6efd', // primary blue
|
|
13
|
-
'4G': '#9333ea', // Purple
|
|
14
|
-
'5G': '#22c55e', // Green
|
|
15
|
-
'LTE': '#9333ea', // Purple (same as 4G)
|
|
16
|
-
'NR': '#22c55e', // Green (same as 5G)
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Default status colors (Bootstrap-aligned)
|
|
20
|
-
*/
|
|
21
|
-
export const DEFAULT_STATUS_COLORS = {
|
|
22
|
-
'On_Air': '#198754', // success green
|
|
23
|
-
'On_Air_UNDER_CONSTRUCTION': '#4ce207ff', // warning yellow
|
|
24
|
-
'On_Air_Locked': '#e04001ff', // info cyan
|
|
25
|
-
'RF_Plan_Ready': '#e69603ff', // primary blue
|
|
26
|
-
'Re-Planned_RF_Plan_Ready': '#c1a342ff', // purple
|
|
27
|
-
'Tavlati_RF_Plan_Ready': '#25ddfdff', // orange
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* Frequency band colors
|
|
31
|
-
* GSM: Yellow shades (darker = higher freq)
|
|
32
|
-
* LTE: Purple shades (darker = higher freq)
|
|
33
|
-
* 5G: Green shades (stronger = higher freq)
|
|
34
|
-
*/
|
|
35
|
-
export const FBAND_COLORS = {
|
|
36
|
-
// GSM - Yellow shades (900 lighter, 1800 darker)
|
|
37
|
-
'GSM900': '#ffc107', // Light yellow
|
|
38
|
-
'GSM1800': '#cc9a06', // Darker yellow/gold
|
|
39
|
-
// LTE - Purple shades (700 lightest → 2600 darkest)
|
|
40
|
-
'LTE700': '#d8b4fe', // Light purple
|
|
41
|
-
'LTE800': '#c084fc', //
|
|
42
|
-
'LTE900': '#a855f7', //
|
|
43
|
-
'LTE1800': '#9333ea', //
|
|
44
|
-
'LTE2100': '#7e22ce', //
|
|
45
|
-
'LTE2600': '#6b21a8', // Dark purple
|
|
46
|
-
// 5G - Green shades (700 lighter → 3500 stronger)
|
|
47
|
-
'5G-700': '#86efac', // Light green
|
|
48
|
-
'5G-2100': '#22c55e', // Medium green
|
|
49
|
-
'5G-3500': '#15803d', // Strong/dark green
|
|
50
|
-
'NR3500': '#15803d', // Same as 5G-3500
|
|
51
|
-
};
|
|
52
|
-
/**
|
|
53
|
-
* Column groups for different presets
|
|
54
|
-
*/
|
|
55
|
-
export const COLUMN_GROUPS = {
|
|
56
|
-
core: ['siteId', 'txId', 'cellName', 'tech', 'fband', 'status'],
|
|
57
|
-
physical: ['antenna', 'azimuth', 'height', 'beamwidth'],
|
|
58
|
-
network: ['nwET', 'nwPW', 'nwRS', 'nwBW', 'dlEarfn', 'bcch', 'pci', 'rru', 'cellID', 'cellId2G', 'ctrlid'],
|
|
59
|
-
planning: ['planner', 'comment', 'onAirDate'],
|
|
60
|
-
atoll: ['atollET', 'atollMT', 'atollPW', 'atollRS', 'atollBW'],
|
|
61
|
-
position: ['latitude', 'longitude', 'siteLatitude', 'siteLongitude', 'dx', 'dy'],
|
|
62
|
-
compare: ['compareET', 'comparePW', 'compareRS', 'compareBW'],
|
|
63
|
-
kpi: ['kpiTraffic', 'kpiThroughput', 'kpiAvailability', 'kpiSuccessRate'],
|
|
64
|
-
history: ['configDate', 'frequency', 'antennaChange', 'etiltChange', 'mtiltChange', 'powerChange'],
|
|
65
|
-
};
|
|
66
|
-
/**
|
|
67
|
-
* Create a technology badge formatter
|
|
68
|
-
*/
|
|
69
|
-
export function createTechFormatter(colors = DEFAULT_TECH_COLORS) {
|
|
70
|
-
return (cell) => {
|
|
71
|
-
const value = cell.getValue();
|
|
72
|
-
const color = colors[value] || '#6c757d';
|
|
73
|
-
return `<span class="badge" style="background-color: ${color}; color: white;">${value}</span>`;
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Create a status badge formatter
|
|
78
|
-
*/
|
|
79
|
-
export function createStatusFormatter(colors = DEFAULT_STATUS_COLORS) {
|
|
80
|
-
return (cell) => {
|
|
81
|
-
const value = cell.getValue();
|
|
82
|
-
const color = colors[value] || '#6c757d';
|
|
83
|
-
const displayValue = value.replace(/_/g, ' ');
|
|
84
|
-
return `<span class="badge" style="background-color: ${color}; color: white; font-size: 0.7rem;">${displayValue}</span>`;
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Create an fband badge formatter
|
|
89
|
-
*/
|
|
90
|
-
export function createFbandFormatter() {
|
|
91
|
-
return (cell) => {
|
|
92
|
-
const value = cell.getValue();
|
|
93
|
-
const color = FBAND_COLORS[value] || '#6c757d';
|
|
94
|
-
return `<span class="badge" style="background-color: ${color}; color: white;">${value}</span>`;
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Number formatter with fixed decimals
|
|
99
|
-
*/
|
|
100
|
-
export function numberFormatter(decimals = 2) {
|
|
101
|
-
return (cell) => {
|
|
102
|
-
const value = cell.getValue();
|
|
103
|
-
if (value === null || value === undefined || value === '')
|
|
104
|
-
return '';
|
|
105
|
-
const num = Number(value);
|
|
106
|
-
return isNaN(num) ? String(value) : num.toFixed(decimals);
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Coordinate formatter (lat/lng)
|
|
111
|
-
*/
|
|
112
|
-
export function coordinateFormatter(cell) {
|
|
113
|
-
const value = cell.getValue();
|
|
114
|
-
if (value === null || value === undefined || value === '')
|
|
115
|
-
return '';
|
|
116
|
-
const num = Number(value);
|
|
117
|
-
return isNaN(num) ? String(value) : num.toFixed(6);
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Azimuth formatter with degree symbol
|
|
121
|
-
*/
|
|
122
|
-
export function azimuthFormatter(cell) {
|
|
123
|
-
const value = cell.getValue();
|
|
124
|
-
if (value === null || value === undefined || value === '')
|
|
125
|
-
return '';
|
|
126
|
-
return `${value}°`;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Height formatter with meter unit
|
|
130
|
-
*/
|
|
131
|
-
export function heightFormatter(cell) {
|
|
132
|
-
const value = cell.getValue();
|
|
133
|
-
if (value === null || value === undefined || value === '')
|
|
134
|
-
return '';
|
|
135
|
-
return `${value}m`;
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Comparison formatter for Atoll vs Network values
|
|
139
|
-
* Shows both values side by side with color coding:
|
|
140
|
-
* - Green: values match exactly
|
|
141
|
-
* - Red: values don't match
|
|
142
|
-
* - Gray: one or both values missing
|
|
143
|
-
*/
|
|
144
|
-
export function createCompareFormatter(atollField, nwtField) {
|
|
145
|
-
return (cell) => {
|
|
146
|
-
const row = cell.getRow().getData();
|
|
147
|
-
const atollVal = row[atollField];
|
|
148
|
-
const nwtVal = row[nwtField];
|
|
149
|
-
const atollStr = atollVal !== null && atollVal !== undefined ? String(atollVal) : '-';
|
|
150
|
-
const nwtStr = nwtVal !== null && nwtVal !== undefined ? String(nwtVal) : '-';
|
|
151
|
-
// Determine match status
|
|
152
|
-
const atollMissing = atollVal === null || atollVal === undefined;
|
|
153
|
-
const nwtMissing = nwtVal === null || nwtVal === undefined;
|
|
154
|
-
let bgColor;
|
|
155
|
-
let textColor = 'white';
|
|
156
|
-
if (atollMissing || nwtMissing) {
|
|
157
|
-
// One or both missing - gray
|
|
158
|
-
bgColor = '#6c757d';
|
|
159
|
-
}
|
|
160
|
-
else if (atollVal === nwtVal) {
|
|
161
|
-
// Exact match - green
|
|
162
|
-
bgColor = '#198754';
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
// Mismatch - red
|
|
166
|
-
bgColor = '#dc3545';
|
|
167
|
-
}
|
|
168
|
-
return `<span class="badge" style="background-color: ${bgColor}; color: ${textColor}; font-size: 0.75rem; font-weight: normal;">${atollStr} | ${nwtStr}</span>`;
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Create a history change formatter for showing current vs previous values
|
|
173
|
-
* Highlights changes in yellow/amber, unchanged values in muted style
|
|
174
|
-
*
|
|
175
|
-
* @param currentField - Field name for current value
|
|
176
|
-
* @param prevField - Field name for previous value
|
|
177
|
-
*/
|
|
178
|
-
export function createHistoryChangeFormatter(currentField, prevField) {
|
|
179
|
-
return (cell) => {
|
|
180
|
-
const row = cell.getRow().getData();
|
|
181
|
-
const currentVal = row[currentField];
|
|
182
|
-
const prevVal = row[prevField];
|
|
183
|
-
const currentStr = currentVal !== null && currentVal !== undefined ? String(currentVal) : '-';
|
|
184
|
-
const prevStr = prevVal !== null && prevVal !== undefined ? String(prevVal) : '-';
|
|
185
|
-
const hasChanged = currentVal !== prevVal;
|
|
186
|
-
if (hasChanged) {
|
|
187
|
-
// Value changed - highlight with amber/warning color
|
|
188
|
-
return `<span class="badge bg-warning text-dark" style="font-size: 0.75rem; font-weight: 500;" title="Changed from: ${prevStr}">${currentStr}</span>`;
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
// No change - muted style
|
|
192
|
-
return `<span class="text-muted">${currentStr}</span>`;
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Format ISO date string to YYYY.MM.DD format for history display
|
|
198
|
-
*/
|
|
199
|
-
export function historyDateFormatter(cell) {
|
|
200
|
-
const value = cell.getValue();
|
|
201
|
-
if (!value)
|
|
202
|
-
return '-';
|
|
203
|
-
try {
|
|
204
|
-
const date = new Date(value);
|
|
205
|
-
const year = date.getFullYear();
|
|
206
|
-
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
207
|
-
const day = String(date.getDate()).padStart(2, '0');
|
|
208
|
-
return `${year}-${month}-${day}`;
|
|
209
|
-
}
|
|
210
|
-
catch {
|
|
211
|
-
return value;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
export function createSparklineFormatter(options = {}) {
|
|
215
|
-
const { width = 80, height = 24, lineColor = '#0d6efd', fillColor = 'rgba(13,110,253,0.2)', showDots = false, showLastValue = true, unit = '', decimals = 1 } = options;
|
|
216
|
-
return (cell) => {
|
|
217
|
-
const data = cell.getValue();
|
|
218
|
-
if (!data || !Array.isArray(data) || data.length === 0) {
|
|
219
|
-
return '<span class="text-muted">—</span>';
|
|
220
|
-
}
|
|
221
|
-
const values = data.filter(v => typeof v === 'number' && !isNaN(v));
|
|
222
|
-
if (values.length === 0) {
|
|
223
|
-
return '<span class="text-muted">—</span>';
|
|
224
|
-
}
|
|
225
|
-
const min = Math.min(...values);
|
|
226
|
-
const max = Math.max(...values);
|
|
227
|
-
const range = max - min || 1;
|
|
228
|
-
const padding = 2;
|
|
229
|
-
const chartWidth = showLastValue ? width - 35 : width - 4;
|
|
230
|
-
const chartHeight = height - 4;
|
|
231
|
-
// Generate SVG path
|
|
232
|
-
const points = values.map((v, i) => {
|
|
233
|
-
const x = padding + (i / (values.length - 1 || 1)) * (chartWidth - padding * 2);
|
|
234
|
-
const y = padding + (1 - (v - min) / range) * (chartHeight - padding * 2);
|
|
235
|
-
return { x, y, v };
|
|
236
|
-
});
|
|
237
|
-
// Line path
|
|
238
|
-
const linePath = points.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x.toFixed(1)} ${p.y.toFixed(1)}`).join(' ');
|
|
239
|
-
// Fill path (closed polygon)
|
|
240
|
-
const fillPath = `${linePath} L ${points[points.length - 1].x.toFixed(1)} ${chartHeight - padding} L ${padding} ${chartHeight - padding} Z`;
|
|
241
|
-
// Dots
|
|
242
|
-
const dots = showDots
|
|
243
|
-
? points.map(p => `<circle cx="${p.x.toFixed(1)}" cy="${p.y.toFixed(1)}" r="1.5" fill="${lineColor}"/>`).join('')
|
|
244
|
-
: '';
|
|
245
|
-
// Last value text
|
|
246
|
-
const lastValue = values[values.length - 1];
|
|
247
|
-
const valueText = showLastValue
|
|
248
|
-
? `<text x="${width - 2}" y="${height / 2 + 4}" text-anchor="end" font-size="10" fill="#333">${lastValue.toFixed(decimals)}${unit}</text>`
|
|
249
|
-
: '';
|
|
250
|
-
// Trend indicator (comparing last vs first)
|
|
251
|
-
const trend = values.length > 1 ? values[values.length - 1] - values[0] : 0;
|
|
252
|
-
const trendColor = trend >= 0 ? '#198754' : '#dc3545';
|
|
253
|
-
return `
|
|
254
|
-
<svg width="${width}" height="${height}" style="vertical-align: middle;">
|
|
255
|
-
<path d="${fillPath}" fill="${fillColor}" />
|
|
256
|
-
<path d="${linePath}" fill="none" stroke="${lineColor}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
257
|
-
${dots}
|
|
258
|
-
${valueText}
|
|
259
|
-
</svg>
|
|
260
|
-
`.trim().replace(/\s+/g, ' ');
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* Custom sorter for fband - extracts numeric portion and sorts numerically
|
|
265
|
-
* Examples: LTE700 → 700, GSM900 → 900, LTE1800 → 1800, 5G-3500 → 3500
|
|
266
|
-
*/
|
|
267
|
-
export function fbandSorter(a, b) {
|
|
268
|
-
const numA = parseInt(a.replace(/\D/g, ''), 10) || 0;
|
|
269
|
-
const numB = parseInt(b.replace(/\D/g, ''), 10) || 0;
|
|
270
|
-
return numA - numB;
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Custom sorter for cellName - sorts by the 5th character (sector digit)
|
|
274
|
-
* Example: 10001 → '1', 10002 → '2', 10003 → '3'
|
|
275
|
-
*/
|
|
276
|
-
export function cellNameSectorSorter(a, b) {
|
|
277
|
-
const charA = a.charAt(4) || '0';
|
|
278
|
-
const charB = b.charAt(4) || '0';
|
|
279
|
-
return charA.localeCompare(charB);
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Combined multi-level sorter for cell data
|
|
283
|
-
* Sort order: tech (asc) → fband by numeric value (asc) → cellName by 5th digit (asc)
|
|
284
|
-
*/
|
|
285
|
-
export function cellDataSorter(a, b) {
|
|
286
|
-
// 1. Sort by tech (string comparison)
|
|
287
|
-
const techA = String(a.tech || '');
|
|
288
|
-
const techB = String(b.tech || '');
|
|
289
|
-
const techCompare = techA.localeCompare(techB);
|
|
290
|
-
if (techCompare !== 0)
|
|
291
|
-
return techCompare;
|
|
292
|
-
// 2. Sort by fband (numeric extraction)
|
|
293
|
-
const fbandA = String(a.fband || '');
|
|
294
|
-
const fbandB = String(b.fband || '');
|
|
295
|
-
const fbandCompare = fbandSorter(fbandA, fbandB);
|
|
296
|
-
if (fbandCompare !== 0)
|
|
297
|
-
return fbandCompare;
|
|
298
|
-
// 3. Sort by cellName 5th character (sector)
|
|
299
|
-
const cellNameA = String(a.cellName || '');
|
|
300
|
-
const cellNameB = String(b.cellName || '');
|
|
301
|
-
return cellNameSectorSorter(cellNameA, cellNameB);
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Get all column definitions
|
|
305
|
-
*/
|
|
306
|
-
export function getAllColumns(techColors = DEFAULT_TECH_COLORS, statusColors = DEFAULT_STATUS_COLORS, headerFilters = true) {
|
|
307
|
-
const headerFilterParams = headerFilters ? { headerFilter: 'input' } : {};
|
|
308
|
-
const selectHeaderFilter = headerFilters ? { headerFilter: 'list', headerFilterParams: { valuesLookup: true } } : {};
|
|
309
|
-
return [
|
|
310
|
-
// Core columns - siteId, txId, cellName first (frozen)
|
|
311
|
-
{
|
|
312
|
-
title: 'Site ID',
|
|
313
|
-
field: 'siteId',
|
|
314
|
-
width: 120,
|
|
315
|
-
frozen: true,
|
|
316
|
-
...headerFilterParams,
|
|
317
|
-
},
|
|
318
|
-
{
|
|
319
|
-
title: 'TX ID',
|
|
320
|
-
field: 'txId',
|
|
321
|
-
width: 100,
|
|
322
|
-
frozen: true,
|
|
323
|
-
...headerFilterParams,
|
|
324
|
-
},
|
|
325
|
-
{
|
|
326
|
-
title: 'Cell Name',
|
|
327
|
-
field: 'cellName',
|
|
328
|
-
width: 150,
|
|
329
|
-
frozen: true,
|
|
330
|
-
...headerFilterParams,
|
|
331
|
-
},
|
|
332
|
-
{
|
|
333
|
-
title: 'Tech',
|
|
334
|
-
field: 'tech',
|
|
335
|
-
width: 80,
|
|
336
|
-
hozAlign: 'center',
|
|
337
|
-
formatter: createTechFormatter(techColors),
|
|
338
|
-
...selectHeaderFilter,
|
|
339
|
-
},
|
|
340
|
-
{
|
|
341
|
-
title: 'Band',
|
|
342
|
-
field: 'fband',
|
|
343
|
-
width: 100,
|
|
344
|
-
hozAlign: 'center',
|
|
345
|
-
formatter: createFbandFormatter(),
|
|
346
|
-
...selectHeaderFilter,
|
|
347
|
-
},
|
|
348
|
-
{
|
|
349
|
-
title: 'Freq',
|
|
350
|
-
field: 'frq',
|
|
351
|
-
width: 80,
|
|
352
|
-
hozAlign: 'center',
|
|
353
|
-
...selectHeaderFilter,
|
|
354
|
-
},
|
|
355
|
-
{
|
|
356
|
-
title: 'Status',
|
|
357
|
-
field: 'status',
|
|
358
|
-
width: 180,
|
|
359
|
-
formatter: createStatusFormatter(statusColors),
|
|
360
|
-
...selectHeaderFilter,
|
|
361
|
-
},
|
|
362
|
-
{
|
|
363
|
-
title: 'On Air Date',
|
|
364
|
-
field: 'onAirDate',
|
|
365
|
-
width: 120,
|
|
366
|
-
...headerFilterParams,
|
|
367
|
-
},
|
|
368
|
-
{
|
|
369
|
-
title: 'Config Date',
|
|
370
|
-
field: 'configDate',
|
|
371
|
-
width: 120,
|
|
372
|
-
formatter: historyDateFormatter,
|
|
373
|
-
...headerFilterParams,
|
|
374
|
-
},
|
|
375
|
-
{
|
|
376
|
-
title: 'Freq (MHz)',
|
|
377
|
-
field: 'frequency',
|
|
378
|
-
width: 100,
|
|
379
|
-
hozAlign: 'right',
|
|
380
|
-
...headerFilterParams,
|
|
381
|
-
},
|
|
382
|
-
// History change columns (current vs previous, highlights changes)
|
|
383
|
-
{
|
|
384
|
-
title: 'Antenna',
|
|
385
|
-
field: 'antennaChange',
|
|
386
|
-
width: 160,
|
|
387
|
-
formatter: createHistoryChangeFormatter('antenna', 'prevAntenna'),
|
|
388
|
-
...headerFilterParams,
|
|
389
|
-
},
|
|
390
|
-
{
|
|
391
|
-
title: 'E-Tilt',
|
|
392
|
-
field: 'etiltChange',
|
|
393
|
-
width: 80,
|
|
394
|
-
hozAlign: 'center',
|
|
395
|
-
formatter: createHistoryChangeFormatter('electricalTilt', 'prevElectricalTilt'),
|
|
396
|
-
},
|
|
397
|
-
{
|
|
398
|
-
title: 'M-Tilt',
|
|
399
|
-
field: 'mtiltChange',
|
|
400
|
-
width: 80,
|
|
401
|
-
hozAlign: 'center',
|
|
402
|
-
formatter: createHistoryChangeFormatter('mechanicalTilt', 'prevMechanicalTilt'),
|
|
403
|
-
},
|
|
404
|
-
{
|
|
405
|
-
title: 'Power',
|
|
406
|
-
field: 'powerChange',
|
|
407
|
-
width: 80,
|
|
408
|
-
hozAlign: 'center',
|
|
409
|
-
formatter: createHistoryChangeFormatter('power', 'prevPower'),
|
|
410
|
-
},
|
|
411
|
-
// Physical columns
|
|
412
|
-
{
|
|
413
|
-
title: 'Antenna',
|
|
414
|
-
field: 'antenna',
|
|
415
|
-
width: 150,
|
|
416
|
-
...headerFilterParams,
|
|
417
|
-
},
|
|
418
|
-
{
|
|
419
|
-
title: 'Azimuth',
|
|
420
|
-
field: 'azimuth',
|
|
421
|
-
width: 90,
|
|
422
|
-
hozAlign: 'right',
|
|
423
|
-
formatter: azimuthFormatter,
|
|
424
|
-
...headerFilterParams,
|
|
425
|
-
},
|
|
426
|
-
{
|
|
427
|
-
title: 'Height',
|
|
428
|
-
field: 'height',
|
|
429
|
-
width: 80,
|
|
430
|
-
hozAlign: 'right',
|
|
431
|
-
formatter: heightFormatter,
|
|
432
|
-
...headerFilterParams,
|
|
433
|
-
},
|
|
434
|
-
{
|
|
435
|
-
title: 'Beamwidth',
|
|
436
|
-
field: 'beamwidth',
|
|
437
|
-
width: 100,
|
|
438
|
-
hozAlign: 'right',
|
|
439
|
-
formatter: azimuthFormatter,
|
|
440
|
-
...headerFilterParams,
|
|
441
|
-
},
|
|
442
|
-
// Network columns
|
|
443
|
-
{
|
|
444
|
-
title: 'DL EARFCN',
|
|
445
|
-
field: 'dlEarfn',
|
|
446
|
-
width: 100,
|
|
447
|
-
hozAlign: 'right',
|
|
448
|
-
...headerFilterParams,
|
|
449
|
-
},
|
|
450
|
-
{
|
|
451
|
-
title: 'BCCH',
|
|
452
|
-
field: 'bcch',
|
|
453
|
-
width: 80,
|
|
454
|
-
hozAlign: 'right',
|
|
455
|
-
...headerFilterParams,
|
|
456
|
-
},
|
|
457
|
-
{
|
|
458
|
-
title: 'PCI',
|
|
459
|
-
field: 'pci',
|
|
460
|
-
width: 80,
|
|
461
|
-
hozAlign: 'right',
|
|
462
|
-
...headerFilterParams,
|
|
463
|
-
},
|
|
464
|
-
{
|
|
465
|
-
title: 'Cell ID',
|
|
466
|
-
field: 'cellID',
|
|
467
|
-
width: 100,
|
|
468
|
-
...headerFilterParams,
|
|
469
|
-
},
|
|
470
|
-
{
|
|
471
|
-
title: 'Cell ID 2G',
|
|
472
|
-
field: 'cellID2G',
|
|
473
|
-
width: 100,
|
|
474
|
-
...headerFilterParams,
|
|
475
|
-
},
|
|
476
|
-
{
|
|
477
|
-
title: 'Ctrl ID',
|
|
478
|
-
field: 'ctrlid',
|
|
479
|
-
width: 100,
|
|
480
|
-
...headerFilterParams,
|
|
481
|
-
},
|
|
482
|
-
{
|
|
483
|
-
title: 'RRU',
|
|
484
|
-
field: 'rru',
|
|
485
|
-
width: 100,
|
|
486
|
-
...headerFilterParams,
|
|
487
|
-
},
|
|
488
|
-
{
|
|
489
|
-
title: 'NW ET',
|
|
490
|
-
field: 'nwET',
|
|
491
|
-
width: 80,
|
|
492
|
-
hozAlign: 'right',
|
|
493
|
-
formatter: numberFormatter(1),
|
|
494
|
-
...headerFilterParams,
|
|
495
|
-
},
|
|
496
|
-
{
|
|
497
|
-
title: 'NW PW',
|
|
498
|
-
field: 'nwPW',
|
|
499
|
-
width: 80,
|
|
500
|
-
hozAlign: 'right',
|
|
501
|
-
formatter: numberFormatter(1),
|
|
502
|
-
...headerFilterParams,
|
|
503
|
-
},
|
|
504
|
-
{
|
|
505
|
-
title: 'NW RS',
|
|
506
|
-
field: 'nwRS',
|
|
507
|
-
width: 80,
|
|
508
|
-
hozAlign: 'right',
|
|
509
|
-
...headerFilterParams,
|
|
510
|
-
},
|
|
511
|
-
{
|
|
512
|
-
title: 'NW BW',
|
|
513
|
-
field: 'nwBW',
|
|
514
|
-
width: 80,
|
|
515
|
-
hozAlign: 'right',
|
|
516
|
-
...headerFilterParams,
|
|
517
|
-
},
|
|
518
|
-
// Atoll columns
|
|
519
|
-
{
|
|
520
|
-
title: 'Atoll ET',
|
|
521
|
-
field: 'atollET',
|
|
522
|
-
width: 90,
|
|
523
|
-
hozAlign: 'right',
|
|
524
|
-
formatter: numberFormatter(1),
|
|
525
|
-
...headerFilterParams,
|
|
526
|
-
},
|
|
527
|
-
{
|
|
528
|
-
title: 'Atoll MT',
|
|
529
|
-
field: 'atollMT',
|
|
530
|
-
width: 90,
|
|
531
|
-
hozAlign: 'right',
|
|
532
|
-
formatter: numberFormatter(1),
|
|
533
|
-
...headerFilterParams,
|
|
534
|
-
},
|
|
535
|
-
{
|
|
536
|
-
title: 'Atoll PW',
|
|
537
|
-
field: 'atollPW',
|
|
538
|
-
width: 90,
|
|
539
|
-
hozAlign: 'right',
|
|
540
|
-
formatter: numberFormatter(1),
|
|
541
|
-
...headerFilterParams,
|
|
542
|
-
},
|
|
543
|
-
{
|
|
544
|
-
title: 'Atoll RS',
|
|
545
|
-
field: 'atollRS',
|
|
546
|
-
width: 90,
|
|
547
|
-
hozAlign: 'right',
|
|
548
|
-
formatter: numberFormatter(1),
|
|
549
|
-
...headerFilterParams,
|
|
550
|
-
},
|
|
551
|
-
{
|
|
552
|
-
title: 'Atoll BW',
|
|
553
|
-
field: 'atollBW',
|
|
554
|
-
width: 90,
|
|
555
|
-
hozAlign: 'right',
|
|
556
|
-
formatter: numberFormatter(1),
|
|
557
|
-
...headerFilterParams,
|
|
558
|
-
},
|
|
559
|
-
// Compare columns (Atoll vs Network)
|
|
560
|
-
{
|
|
561
|
-
title: 'Δ ET',
|
|
562
|
-
field: 'compareET',
|
|
563
|
-
width: 110,
|
|
564
|
-
hozAlign: 'center',
|
|
565
|
-
formatter: createCompareFormatter('atollET', 'nwET'),
|
|
566
|
-
headerTooltip: 'Atoll ET | Network ET',
|
|
567
|
-
},
|
|
568
|
-
{
|
|
569
|
-
title: 'Δ PW',
|
|
570
|
-
field: 'comparePW',
|
|
571
|
-
width: 110,
|
|
572
|
-
hozAlign: 'center',
|
|
573
|
-
formatter: createCompareFormatter('atollPW', 'nwPW'),
|
|
574
|
-
headerTooltip: 'Atoll PW | Network PW',
|
|
575
|
-
},
|
|
576
|
-
{
|
|
577
|
-
title: 'Δ RS',
|
|
578
|
-
field: 'compareRS',
|
|
579
|
-
width: 110,
|
|
580
|
-
hozAlign: 'center',
|
|
581
|
-
formatter: createCompareFormatter('atollRS', 'nwRS'),
|
|
582
|
-
headerTooltip: 'Atoll RS | Network RS',
|
|
583
|
-
},
|
|
584
|
-
{
|
|
585
|
-
title: 'Δ BW',
|
|
586
|
-
field: 'compareBW',
|
|
587
|
-
width: 110,
|
|
588
|
-
hozAlign: 'center',
|
|
589
|
-
formatter: createCompareFormatter('atollBW', 'nwBW'),
|
|
590
|
-
headerTooltip: 'Atoll BW | Network BW',
|
|
591
|
-
},
|
|
592
|
-
// KPI Sparkline columns
|
|
593
|
-
{
|
|
594
|
-
title: 'Traffic',
|
|
595
|
-
field: 'kpiTraffic',
|
|
596
|
-
width: 120,
|
|
597
|
-
hozAlign: 'center',
|
|
598
|
-
formatter: createSparklineFormatter({
|
|
599
|
-
unit: '',
|
|
600
|
-
lineColor: '#0d6efd',
|
|
601
|
-
fillColor: 'rgba(13,110,253,0.15)',
|
|
602
|
-
decimals: 0
|
|
603
|
-
}),
|
|
604
|
-
headerTooltip: 'Traffic volume trend (GB)',
|
|
605
|
-
headerSort: false,
|
|
606
|
-
},
|
|
607
|
-
{
|
|
608
|
-
title: 'Throughput',
|
|
609
|
-
field: 'kpiThroughput',
|
|
610
|
-
width: 120,
|
|
611
|
-
hozAlign: 'center',
|
|
612
|
-
formatter: createSparklineFormatter({
|
|
613
|
-
unit: '',
|
|
614
|
-
lineColor: '#6f42c1',
|
|
615
|
-
fillColor: 'rgba(111,66,193,0.15)',
|
|
616
|
-
decimals: 1
|
|
617
|
-
}),
|
|
618
|
-
headerTooltip: 'Throughput trend (Mbps)',
|
|
619
|
-
headerSort: false,
|
|
620
|
-
},
|
|
621
|
-
{
|
|
622
|
-
title: 'Avail %',
|
|
623
|
-
field: 'kpiAvailability',
|
|
624
|
-
width: 120,
|
|
625
|
-
hozAlign: 'center',
|
|
626
|
-
formatter: createSparklineFormatter({
|
|
627
|
-
unit: '%',
|
|
628
|
-
lineColor: '#198754',
|
|
629
|
-
fillColor: 'rgba(25,135,84,0.15)',
|
|
630
|
-
decimals: 1
|
|
631
|
-
}),
|
|
632
|
-
headerTooltip: 'Availability trend (%)',
|
|
633
|
-
headerSort: false,
|
|
634
|
-
},
|
|
635
|
-
{
|
|
636
|
-
title: 'Success %',
|
|
637
|
-
field: 'kpiSuccessRate',
|
|
638
|
-
width: 120,
|
|
639
|
-
hozAlign: 'center',
|
|
640
|
-
formatter: createSparklineFormatter({
|
|
641
|
-
unit: '%',
|
|
642
|
-
lineColor: '#fd7e14',
|
|
643
|
-
fillColor: 'rgba(253,126,20,0.15)',
|
|
644
|
-
decimals: 1
|
|
645
|
-
}),
|
|
646
|
-
headerTooltip: 'Success rate trend (%)',
|
|
647
|
-
headerSort: false,
|
|
648
|
-
},
|
|
649
|
-
// Position columns
|
|
650
|
-
{
|
|
651
|
-
title: 'Latitude',
|
|
652
|
-
field: 'latitude',
|
|
653
|
-
width: 120,
|
|
654
|
-
hozAlign: 'right',
|
|
655
|
-
formatter: coordinateFormatter,
|
|
656
|
-
...headerFilterParams,
|
|
657
|
-
},
|
|
658
|
-
{
|
|
659
|
-
title: 'Longitude',
|
|
660
|
-
field: 'longitude',
|
|
661
|
-
width: 120,
|
|
662
|
-
hozAlign: 'right',
|
|
663
|
-
formatter: coordinateFormatter,
|
|
664
|
-
...headerFilterParams,
|
|
665
|
-
},
|
|
666
|
-
{
|
|
667
|
-
title: 'Site Lat',
|
|
668
|
-
field: 'siteLatitude',
|
|
669
|
-
width: 120,
|
|
670
|
-
hozAlign: 'right',
|
|
671
|
-
formatter: coordinateFormatter,
|
|
672
|
-
...headerFilterParams,
|
|
673
|
-
},
|
|
674
|
-
{
|
|
675
|
-
title: 'Site Lng',
|
|
676
|
-
field: 'siteLongitude',
|
|
677
|
-
width: 120,
|
|
678
|
-
hozAlign: 'right',
|
|
679
|
-
formatter: coordinateFormatter,
|
|
680
|
-
...headerFilterParams,
|
|
681
|
-
},
|
|
682
|
-
{
|
|
683
|
-
title: 'DX',
|
|
684
|
-
field: 'dx',
|
|
685
|
-
width: 80,
|
|
686
|
-
hozAlign: 'right',
|
|
687
|
-
formatter: numberFormatter(2),
|
|
688
|
-
...headerFilterParams,
|
|
689
|
-
},
|
|
690
|
-
{
|
|
691
|
-
title: 'DY',
|
|
692
|
-
field: 'dy',
|
|
693
|
-
width: 80,
|
|
694
|
-
hozAlign: 'right',
|
|
695
|
-
formatter: numberFormatter(2),
|
|
696
|
-
...headerFilterParams,
|
|
697
|
-
},
|
|
698
|
-
// Planning columns
|
|
699
|
-
{
|
|
700
|
-
title: 'Planner',
|
|
701
|
-
field: 'planner',
|
|
702
|
-
width: 120,
|
|
703
|
-
...headerFilterParams,
|
|
704
|
-
},
|
|
705
|
-
{
|
|
706
|
-
title: 'Comment',
|
|
707
|
-
field: 'comment',
|
|
708
|
-
width: 200,
|
|
709
|
-
...headerFilterParams,
|
|
710
|
-
},
|
|
711
|
-
{
|
|
712
|
-
title: 'Subgroup',
|
|
713
|
-
field: 'customSubgroup',
|
|
714
|
-
width: 120,
|
|
715
|
-
...headerFilterParams,
|
|
716
|
-
},
|
|
717
|
-
];
|
|
718
|
-
}
|
|
719
|
-
/**
|
|
720
|
-
* Get columns for a specific preset
|
|
721
|
-
*/
|
|
722
|
-
export function getColumnsForPreset(preset, techColors = DEFAULT_TECH_COLORS, statusColors = DEFAULT_STATUS_COLORS, headerFilters = true) {
|
|
723
|
-
const allColumns = getAllColumns(techColors, statusColors, headerFilters);
|
|
724
|
-
let visibleFields;
|
|
725
|
-
switch (preset) {
|
|
726
|
-
case 'compact':
|
|
727
|
-
visibleFields = ['siteId', 'txId', 'cellName', 'tech', 'fband', 'status'];
|
|
728
|
-
break;
|
|
729
|
-
case 'full':
|
|
730
|
-
return allColumns;
|
|
731
|
-
case 'physical':
|
|
732
|
-
visibleFields = [...COLUMN_GROUPS.core, ...COLUMN_GROUPS.physical];
|
|
733
|
-
break;
|
|
734
|
-
case 'network':
|
|
735
|
-
visibleFields = [...COLUMN_GROUPS.core, ...COLUMN_GROUPS.network];
|
|
736
|
-
break;
|
|
737
|
-
case 'planning':
|
|
738
|
-
visibleFields = [...COLUMN_GROUPS.core, ...COLUMN_GROUPS.planning];
|
|
739
|
-
break;
|
|
740
|
-
case 'compare':
|
|
741
|
-
visibleFields = [...COLUMN_GROUPS.core, ...COLUMN_GROUPS.compare];
|
|
742
|
-
break;
|
|
743
|
-
case 'kpi':
|
|
744
|
-
visibleFields = [...COLUMN_GROUPS.core, ...COLUMN_GROUPS.kpi];
|
|
745
|
-
break;
|
|
746
|
-
case 'history':
|
|
747
|
-
// Simplified view for config history - just cellName, date, and config fields
|
|
748
|
-
visibleFields = ['cellName', ...COLUMN_GROUPS.history];
|
|
749
|
-
break;
|
|
750
|
-
case 'default':
|
|
751
|
-
default:
|
|
752
|
-
visibleFields = [
|
|
753
|
-
'siteId', 'txId', 'cellName', 'tech', 'fband', 'frq', 'status',
|
|
754
|
-
'azimuth', 'height', 'antenna'
|
|
755
|
-
];
|
|
756
|
-
}
|
|
757
|
-
return allColumns.filter(col => visibleFields.includes(col.field));
|
|
758
|
-
}
|
|
759
|
-
/**
|
|
760
|
-
* Get group header formatter for a specific field
|
|
761
|
-
*/
|
|
762
|
-
export function getGroupHeaderFormatter(groupField) {
|
|
763
|
-
return (value, count) => {
|
|
764
|
-
const displayValue = String(value).replace(/_/g, ' ');
|
|
765
|
-
let color = '#6c757d';
|
|
766
|
-
if (groupField === 'tech') {
|
|
767
|
-
color = DEFAULT_TECH_COLORS[String(value)] || color;
|
|
768
|
-
}
|
|
769
|
-
else if (groupField === 'fband') {
|
|
770
|
-
color = FBAND_COLORS[String(value)] || color;
|
|
771
|
-
}
|
|
772
|
-
else if (groupField === 'status') {
|
|
773
|
-
color = DEFAULT_STATUS_COLORS[String(value)] || color;
|
|
774
|
-
}
|
|
775
|
-
return `<span class="badge me-2" style="background-color: ${color}; color: white;">${displayValue}</span>
|
|
776
|
-
<span class="text-muted">(${count} cell${count !== 1 ? 's' : ''})</span>`;
|
|
777
|
-
};
|
|
778
|
-
}
|
|
779
|
-
/**
|
|
780
|
-
* Get column metadata for the column picker UI
|
|
781
|
-
*/
|
|
782
|
-
export function getColumnMetadata() {
|
|
783
|
-
return [
|
|
784
|
-
// Core
|
|
785
|
-
{ field: 'siteId', title: 'Site ID', group: 'Core' },
|
|
786
|
-
{ field: 'txId', title: 'TX ID', group: 'Core' },
|
|
787
|
-
{ field: 'cellName', title: 'Cell Name', group: 'Core' },
|
|
788
|
-
{ field: 'tech', title: 'Technology', group: 'Core' },
|
|
789
|
-
{ field: 'fband', title: 'Band', group: 'Core' },
|
|
790
|
-
{ field: 'frq', title: 'Frequency', group: 'Core' },
|
|
791
|
-
{ field: 'status', title: 'Status', group: 'Core' },
|
|
792
|
-
{ field: 'onAirDate', title: 'On Air Date', group: 'Core' },
|
|
793
|
-
// Antenna Physical
|
|
794
|
-
{ field: 'antenna', title: 'Antenna', group: 'Antenna Physical' },
|
|
795
|
-
{ field: 'azimuth', title: 'Azimuth', group: 'Antenna Physical' },
|
|
796
|
-
{ field: 'height', title: 'Height', group: 'Antenna Physical' },
|
|
797
|
-
{ field: 'beamwidth', title: 'Beamwidth', group: 'Antenna Physical' },
|
|
798
|
-
{ field: 'atollMT', title: 'Atoll MT', group: 'Atoll' },
|
|
799
|
-
// Atoll antenna settings
|
|
800
|
-
{ field: 'atollET', title: 'Atoll ET', group: 'Atoll' },
|
|
801
|
-
{ field: 'atollPW', title: 'Atoll PW', group: 'Atoll' },
|
|
802
|
-
{ field: 'atollRS', title: 'Atoll RS', group: 'Atoll' },
|
|
803
|
-
{ field: 'atollBW', title: 'Atoll BW', group: 'Atoll' },
|
|
804
|
-
// Network antena settings
|
|
805
|
-
{ field: 'nwET', title: 'NW ET', group: 'Network' },
|
|
806
|
-
{ field: 'nwPW', title: 'NW PW', group: 'Network' },
|
|
807
|
-
{ field: 'nwRS', title: 'NW RS', group: 'Network' },
|
|
808
|
-
{ field: 'nwBW', title: 'NW BW', group: 'Network' },
|
|
809
|
-
// Compare (Atoll vs Network)
|
|
810
|
-
{ field: 'compareET', title: 'Δ ET', group: 'Compare' },
|
|
811
|
-
{ field: 'comparePW', title: 'Δ PW', group: 'Compare' },
|
|
812
|
-
{ field: 'compareRS', title: 'Δ RS', group: 'Compare' },
|
|
813
|
-
{ field: 'compareBW', title: 'Δ BW', group: 'Compare' },
|
|
814
|
-
// Network settings
|
|
815
|
-
{ field: 'dlEarfn', title: 'DL EARFCN', group: 'Network' },
|
|
816
|
-
{ field: 'bcch', title: 'BCCH', group: 'Network' },
|
|
817
|
-
{ field: 'pci', title: 'PCI', group: 'Network' },
|
|
818
|
-
{ field: 'rru', title: 'RRU', group: 'Network' },
|
|
819
|
-
{ field: 'cellID', title: 'Cell ID', group: 'Network' },
|
|
820
|
-
{ field: 'cellId2G', title: 'Cell ID 2G', group: 'Network' },
|
|
821
|
-
{ field: 'ctrlid', title: 'Ctrl ID', group: 'Network' },
|
|
822
|
-
// History
|
|
823
|
-
{ field: 'configDate', title: 'Config Date', group: 'History' },
|
|
824
|
-
{ field: 'frequency', title: 'Freq (MHz)', group: 'History' },
|
|
825
|
-
{ field: 'antennaChange', title: 'Antenna (Δ)', group: 'History' },
|
|
826
|
-
{ field: 'etiltChange', title: 'E-Tilt (Δ)', group: 'History' },
|
|
827
|
-
{ field: 'mtiltChange', title: 'M-Tilt (Δ)', group: 'History' },
|
|
828
|
-
{ field: 'powerChange', title: 'Power (Δ)', group: 'History' },
|
|
829
|
-
// KPI Trends
|
|
830
|
-
{ field: 'kpiTraffic', title: 'Traffic', group: 'KPI' },
|
|
831
|
-
{ field: 'kpiThroughput', title: 'Throughput', group: 'KPI' },
|
|
832
|
-
{ field: 'kpiAvailability', title: 'Availability', group: 'KPI' },
|
|
833
|
-
{ field: 'kpiSuccessRate', title: 'Success Rate', group: 'KPI' },
|
|
834
|
-
// Position
|
|
835
|
-
// { field: 'latitude', title: 'Latitude', group: 'Position' },
|
|
836
|
-
// { field: 'longitude', title: 'Longitude', group: 'Position' },
|
|
837
|
-
// { field: 'siteLatitude', title: 'Site Latitude', group: 'Position' },
|
|
838
|
-
// { field: 'siteLongitude', title: 'Site Longitude', group: 'Position' },
|
|
839
|
-
// { field: 'dx', title: 'DX', group: 'Position' },
|
|
840
|
-
// { field: 'dy', title: 'DY', group: 'Position' },
|
|
841
|
-
// Planning
|
|
842
|
-
{ field: 'planner', title: 'Planner', group: 'Planning' },
|
|
843
|
-
{ field: 'comment', title: 'Comment', group: 'Planning' },
|
|
844
|
-
// { field: 'customSubgroup', title: 'Subgroup', group: 'Planning' },
|
|
845
|
-
];
|
|
846
|
-
}
|
|
847
|
-
/**
|
|
848
|
-
* Get default visible columns for a preset
|
|
849
|
-
*/
|
|
850
|
-
export function getPresetVisibleFields(preset) {
|
|
851
|
-
switch (preset) {
|
|
852
|
-
case 'compact':
|
|
853
|
-
return ['siteId', 'txId', 'cellName', 'tech', 'fband', 'status'];
|
|
854
|
-
case 'full':
|
|
855
|
-
return getColumnMetadata().map(c => c.field);
|
|
856
|
-
case 'physical':
|
|
857
|
-
return [...COLUMN_GROUPS.core, ...COLUMN_GROUPS.physical];
|
|
858
|
-
case 'network':
|
|
859
|
-
return [...COLUMN_GROUPS.core, ...COLUMN_GROUPS.network];
|
|
860
|
-
case 'planning':
|
|
861
|
-
return [...COLUMN_GROUPS.core, ...COLUMN_GROUPS.planning];
|
|
862
|
-
case 'compare':
|
|
863
|
-
return [...COLUMN_GROUPS.core, ...COLUMN_GROUPS.compare];
|
|
864
|
-
case 'kpi':
|
|
865
|
-
return [...COLUMN_GROUPS.core, ...COLUMN_GROUPS.kpi];
|
|
866
|
-
case 'history':
|
|
867
|
-
return ['cellName', ...COLUMN_GROUPS.history];
|
|
868
|
-
case 'default':
|
|
869
|
-
default:
|
|
870
|
-
return ['siteId', 'txId', 'cellName', 'tech', 'fband', 'frq', 'status', 'azimuth', 'height', 'antenna'];
|
|
871
|
-
}
|
|
872
|
-
}
|