@smartnet360/svelte-components 0.0.142 → 0.0.144
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-tools/components/AntennaControls.svelte +14 -6
- package/dist/apps/antenna-tools/components/AntennaTools.svelte +6 -5
- package/dist/core/Auth/auth.svelte.js +72 -39
- package/dist/core/Auth/config.d.ts +1 -0
- package/dist/core/Auth/config.js +3 -4
- package/dist/map-v3/demo/DemoMap.svelte +3 -1
- package/dist/map-v3/features/custom/components/CustomCellSetManager.svelte +205 -14
- package/dist/map-v3/features/custom/components/CustomCellSetManager.svelte.d.ts +3 -0
- package/dist/map-v3/features/custom/components/ServerSetBrowser.svelte +398 -0
- package/dist/map-v3/features/custom/components/ServerSetBrowser.svelte.d.ts +22 -0
- package/dist/map-v3/features/custom/components/index.d.ts +1 -0
- package/dist/map-v3/features/custom/components/index.js +1 -0
- package/dist/map-v3/features/custom/db/custom-sets-api.d.ts +65 -0
- package/dist/map-v3/features/custom/db/custom-sets-api.js +220 -0
- package/dist/map-v3/features/custom/db/custom-sets-repository.d.ts +77 -0
- package/dist/map-v3/features/custom/db/custom-sets-repository.js +195 -0
- package/dist/map-v3/features/custom/db/index.d.ts +10 -0
- package/dist/map-v3/features/custom/db/index.js +9 -0
- package/dist/map-v3/features/custom/db/schema.sql +102 -0
- package/dist/map-v3/features/custom/db/types.d.ts +95 -0
- package/dist/map-v3/features/custom/db/types.js +95 -0
- package/dist/map-v3/features/custom/index.d.ts +2 -0
- package/dist/map-v3/features/custom/index.js +2 -0
- package/dist/map-v3/features/custom/logic/csv-parser.d.ts +12 -1
- package/dist/map-v3/features/custom/logic/csv-parser.js +54 -16
- package/dist/map-v3/features/custom/logic/tree-adapter.js +5 -3
- package/dist/map-v3/features/custom/stores/custom-cell-sets.svelte.d.ts +5 -1
- package/dist/map-v3/features/custom/stores/custom-cell-sets.svelte.js +6 -3
- package/dist/shared/csv-import/ColumnMapper.svelte +194 -0
- package/dist/shared/csv-import/ColumnMapper.svelte.d.ts +22 -0
- package/dist/shared/csv-import/column-detector.d.ts +58 -0
- package/dist/shared/csv-import/column-detector.js +228 -0
- package/dist/shared/csv-import/index.d.ts +10 -0
- package/dist/shared/csv-import/index.js +12 -0
- package/dist/shared/csv-import/types.d.ts +67 -0
- package/dist/shared/csv-import/types.js +70 -0
- package/package.json +1 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CSV Import - Column Detector
|
|
3
|
+
*
|
|
4
|
+
* Auto-detects column mappings based on header names.
|
|
5
|
+
* Uses expandable alias maps for flexible matching.
|
|
6
|
+
*/
|
|
7
|
+
import type { ColumnMapping, StandardFieldType, ImportFieldsConfig, ImportMode } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* Alias map for auto-detecting column types
|
|
10
|
+
* Add new aliases here to expand recognition
|
|
11
|
+
*/
|
|
12
|
+
export declare const COLUMN_ALIASES: Record<StandardFieldType, string[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Find the best matching field type for a column header
|
|
15
|
+
*/
|
|
16
|
+
export declare function detectFieldType(header: string): StandardFieldType | null;
|
|
17
|
+
/**
|
|
18
|
+
* Auto-detect column mapping from headers
|
|
19
|
+
* Returns suggested mapping based on alias matching
|
|
20
|
+
*/
|
|
21
|
+
export declare function detectColumnMapping(headers: string[], fieldsConfig: ImportFieldsConfig): ColumnMapping;
|
|
22
|
+
/**
|
|
23
|
+
* Validate that all required fields are mapped
|
|
24
|
+
*/
|
|
25
|
+
export declare function validateMapping(mapping: ColumnMapping, fieldsConfig: ImportFieldsConfig): {
|
|
26
|
+
valid: boolean;
|
|
27
|
+
missing: string[];
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Detect the most likely import mode based on headers
|
|
31
|
+
* Returns 'point' if lat/lon found, 'site' if site-related, otherwise 'cell'
|
|
32
|
+
*/
|
|
33
|
+
export declare function detectImportMode(headers: string[]): ImportMode;
|
|
34
|
+
/**
|
|
35
|
+
* Auto-detect import mode and get initial mapping
|
|
36
|
+
*/
|
|
37
|
+
export declare function autoDetectImport(headers: string[]): {
|
|
38
|
+
mode: ImportMode;
|
|
39
|
+
mapping: ColumnMapping;
|
|
40
|
+
fieldsConfig: ImportFieldsConfig;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Detect delimiter from CSV content
|
|
44
|
+
*/
|
|
45
|
+
export declare function detectDelimiter(headerLine: string): ',' | ';';
|
|
46
|
+
/**
|
|
47
|
+
* Parse CSV header line and return headers array
|
|
48
|
+
*/
|
|
49
|
+
export declare function parseHeaderLine(line: string, delimiter: ',' | ';'): string[];
|
|
50
|
+
/**
|
|
51
|
+
* Get CSV headers and suggested mapping
|
|
52
|
+
*/
|
|
53
|
+
export declare function analyzeCSVHeaders(csvContent: string, fieldsConfig: ImportFieldsConfig): {
|
|
54
|
+
headers: string[];
|
|
55
|
+
delimiter: ',' | ';';
|
|
56
|
+
suggestedMapping: ColumnMapping;
|
|
57
|
+
rowCount: number;
|
|
58
|
+
};
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CSV Import - Column Detector
|
|
3
|
+
*
|
|
4
|
+
* Auto-detects column mappings based on header names.
|
|
5
|
+
* Uses expandable alias maps for flexible matching.
|
|
6
|
+
*/
|
|
7
|
+
import { getFieldsForMode } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* Alias map for auto-detecting column types
|
|
10
|
+
* Add new aliases here to expand recognition
|
|
11
|
+
*/
|
|
12
|
+
export const COLUMN_ALIASES = {
|
|
13
|
+
// Universal identifiers
|
|
14
|
+
id: [
|
|
15
|
+
'id', 'cellname', 'cell_name', 'txid', 'tx_id',
|
|
16
|
+
'site_id', 'siteid', 'site_code', 'sitecode',
|
|
17
|
+
'name', 'code', 'identifier', 'key', 'cell_id', 'cellid'
|
|
18
|
+
],
|
|
19
|
+
// Coordinates
|
|
20
|
+
lat: [
|
|
21
|
+
'lat', 'latitude', 'y', 'y_coord', 'ycoord',
|
|
22
|
+
'northing', 'north', 'lat_deg', 'latitude_deg'
|
|
23
|
+
],
|
|
24
|
+
lon: [
|
|
25
|
+
'lon', 'lng', 'long', 'longitude', 'x', 'x_coord', 'xcoord',
|
|
26
|
+
'easting', 'east', 'lon_deg', 'longitude_deg'
|
|
27
|
+
],
|
|
28
|
+
// Grouping
|
|
29
|
+
group: [
|
|
30
|
+
'customgroup', 'custom_group', 'group', 'category',
|
|
31
|
+
'type', 'region', 'area', 'zone', 'cluster', 'segment'
|
|
32
|
+
],
|
|
33
|
+
// Sizing
|
|
34
|
+
sizeFactor: [
|
|
35
|
+
'sizefactor', 'size_factor', 'size', 'scale', 'weight', 'factor'
|
|
36
|
+
],
|
|
37
|
+
// Cell-specific
|
|
38
|
+
tech: [
|
|
39
|
+
'tech', 'technology', 'rat', 'radio', 'system',
|
|
40
|
+
'network_type', 'networktype', 'access_technology'
|
|
41
|
+
],
|
|
42
|
+
band: [
|
|
43
|
+
'band', 'fband', 'frequency_band', 'frequencyband',
|
|
44
|
+
'freq', 'frequency', 'carrier', 'earfcn', 'arfcn'
|
|
45
|
+
],
|
|
46
|
+
azimuth: [
|
|
47
|
+
'azimuth', 'az', 'bearing', 'direction', 'heading',
|
|
48
|
+
'antenna_azimuth', 'ant_azimuth', 'ant_az'
|
|
49
|
+
],
|
|
50
|
+
tilt: [
|
|
51
|
+
'tilt', 'downtilt', 'etilt', 'mtilt', 'electrical_tilt',
|
|
52
|
+
'mechanical_tilt', 'antenna_tilt', 'ant_tilt'
|
|
53
|
+
],
|
|
54
|
+
siteId: [
|
|
55
|
+
'siteid', 'site_id', 'site', 'location_id', 'locationid',
|
|
56
|
+
'enodeb_id', 'enodebid', 'gnodeb_id', 'gnodebid', 'bts_id'
|
|
57
|
+
],
|
|
58
|
+
siteName: [
|
|
59
|
+
'sitename', 'site_name', 'location_name', 'locationname',
|
|
60
|
+
'site_label', 'sitelabel', 'station_name'
|
|
61
|
+
],
|
|
62
|
+
status: [
|
|
63
|
+
'status', 'state', 'cell_status', 'cellstatus',
|
|
64
|
+
'operational_status', 'op_status', 'active'
|
|
65
|
+
],
|
|
66
|
+
height: [
|
|
67
|
+
'height', 'antenna_height', 'ant_height', 'agl',
|
|
68
|
+
'elevation', 'tower_height', 'mast_height'
|
|
69
|
+
],
|
|
70
|
+
power: [
|
|
71
|
+
'power', 'tx_power', 'txpower', 'eirp',
|
|
72
|
+
'transmit_power', 'output_power', 'pwr'
|
|
73
|
+
]
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Normalize a column header for comparison
|
|
77
|
+
*/
|
|
78
|
+
function normalizeHeader(header) {
|
|
79
|
+
return header
|
|
80
|
+
.trim()
|
|
81
|
+
.toLowerCase()
|
|
82
|
+
.replace(/[\s\-\.]/g, '_'); // Normalize separators to underscore
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Find the best matching field type for a column header
|
|
86
|
+
*/
|
|
87
|
+
export function detectFieldType(header) {
|
|
88
|
+
const normalized = normalizeHeader(header);
|
|
89
|
+
for (const [fieldType, aliases] of Object.entries(COLUMN_ALIASES)) {
|
|
90
|
+
if (aliases.some(alias => normalized === alias || normalized.includes(alias))) {
|
|
91
|
+
return fieldType;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Auto-detect column mapping from headers
|
|
98
|
+
* Returns suggested mapping based on alias matching
|
|
99
|
+
*/
|
|
100
|
+
export function detectColumnMapping(headers, fieldsConfig) {
|
|
101
|
+
const mapping = {};
|
|
102
|
+
const usedIndices = new Set();
|
|
103
|
+
// Get all field types we're looking for
|
|
104
|
+
const allFields = [...fieldsConfig.required, ...fieldsConfig.optional];
|
|
105
|
+
// First pass: exact matches and strong matches
|
|
106
|
+
for (const field of allFields) {
|
|
107
|
+
const aliases = COLUMN_ALIASES[field.type] || [];
|
|
108
|
+
for (let i = 0; i < headers.length; i++) {
|
|
109
|
+
if (usedIndices.has(i))
|
|
110
|
+
continue;
|
|
111
|
+
const normalized = normalizeHeader(headers[i]);
|
|
112
|
+
// Check for exact match first
|
|
113
|
+
if (aliases.includes(normalized)) {
|
|
114
|
+
mapping[field.type] = i;
|
|
115
|
+
usedIndices.add(i);
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Second pass: partial matches for unmapped fields
|
|
121
|
+
for (const field of allFields) {
|
|
122
|
+
if (mapping[field.type] !== undefined)
|
|
123
|
+
continue;
|
|
124
|
+
const aliases = COLUMN_ALIASES[field.type] || [];
|
|
125
|
+
for (let i = 0; i < headers.length; i++) {
|
|
126
|
+
if (usedIndices.has(i))
|
|
127
|
+
continue;
|
|
128
|
+
const normalized = normalizeHeader(headers[i]);
|
|
129
|
+
// Check for partial match
|
|
130
|
+
if (aliases.some(alias => normalized.includes(alias) || alias.includes(normalized))) {
|
|
131
|
+
mapping[field.type] = i;
|
|
132
|
+
usedIndices.add(i);
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Set null for any fields not found
|
|
138
|
+
for (const field of allFields) {
|
|
139
|
+
if (mapping[field.type] === undefined) {
|
|
140
|
+
mapping[field.type] = null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return mapping;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Validate that all required fields are mapped
|
|
147
|
+
*/
|
|
148
|
+
export function validateMapping(mapping, fieldsConfig) {
|
|
149
|
+
const missing = [];
|
|
150
|
+
for (const field of fieldsConfig.required) {
|
|
151
|
+
if (mapping[field.type] === null || mapping[field.type] === undefined) {
|
|
152
|
+
missing.push(field.label);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
valid: missing.length === 0,
|
|
157
|
+
missing
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Detect the most likely import mode based on headers
|
|
162
|
+
* Returns 'point' if lat/lon found, 'site' if site-related, otherwise 'cell'
|
|
163
|
+
*/
|
|
164
|
+
export function detectImportMode(headers) {
|
|
165
|
+
const normalizedHeaders = headers.map(h => normalizeHeader(h));
|
|
166
|
+
// Check for lat/lon presence
|
|
167
|
+
const hasLat = normalizedHeaders.some(h => COLUMN_ALIASES.lat.some(alias => h === alias || h.includes(alias)));
|
|
168
|
+
const hasLon = normalizedHeaders.some(h => COLUMN_ALIASES.lon.some(alias => h === alias || h.includes(alias)));
|
|
169
|
+
const hasLatLon = hasLat && hasLon;
|
|
170
|
+
// Check for site-specific headers
|
|
171
|
+
const hasSiteId = normalizedHeaders.some(h => COLUMN_ALIASES.siteId.some(alias => h === alias || h.includes(alias)));
|
|
172
|
+
const hasSiteName = normalizedHeaders.some(h => COLUMN_ALIASES.siteName.some(alias => h === alias || h.includes(alias)));
|
|
173
|
+
// Check for cell-specific headers
|
|
174
|
+
const hasCellId = normalizedHeaders.some(h => ['cellname', 'cell_name', 'cellid', 'cell_id', 'txid', 'tx_id'].some(alias => h === alias || h.includes(alias)));
|
|
175
|
+
// Decision logic:
|
|
176
|
+
// 1. If has lat/lon AND site-specific headers → site mode
|
|
177
|
+
// 2. If has lat/lon AND no cell-specific headers → point mode
|
|
178
|
+
// 3. Otherwise → cell mode (ID resolves against existing cells)
|
|
179
|
+
if (hasLatLon && (hasSiteId || hasSiteName) && !hasCellId) {
|
|
180
|
+
return 'site';
|
|
181
|
+
}
|
|
182
|
+
if (hasLatLon && !hasCellId) {
|
|
183
|
+
return 'point';
|
|
184
|
+
}
|
|
185
|
+
return 'cell';
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Auto-detect import mode and get initial mapping
|
|
189
|
+
*/
|
|
190
|
+
export function autoDetectImport(headers) {
|
|
191
|
+
const mode = detectImportMode(headers);
|
|
192
|
+
const fieldsConfig = getFieldsForMode(mode);
|
|
193
|
+
const mapping = detectColumnMapping(headers, fieldsConfig);
|
|
194
|
+
return { mode, mapping, fieldsConfig };
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Detect delimiter from CSV content
|
|
198
|
+
*/
|
|
199
|
+
export function detectDelimiter(headerLine) {
|
|
200
|
+
const commaCount = (headerLine.match(/,/g) || []).length;
|
|
201
|
+
const semicolonCount = (headerLine.match(/;/g) || []).length;
|
|
202
|
+
return semicolonCount > commaCount ? ';' : ',';
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Parse CSV header line and return headers array
|
|
206
|
+
*/
|
|
207
|
+
export function parseHeaderLine(line, delimiter) {
|
|
208
|
+
// Simple parse (doesn't handle quoted fields with delimiters inside)
|
|
209
|
+
return line.split(delimiter).map(h => h.trim().replace(/^["']|["']$/g, ''));
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Get CSV headers and suggested mapping
|
|
213
|
+
*/
|
|
214
|
+
export function analyzeCSVHeaders(csvContent, fieldsConfig) {
|
|
215
|
+
const lines = csvContent.trim().split('\n');
|
|
216
|
+
if (lines.length === 0) {
|
|
217
|
+
return { headers: [], delimiter: ',', suggestedMapping: {}, rowCount: 0 };
|
|
218
|
+
}
|
|
219
|
+
const delimiter = detectDelimiter(lines[0]);
|
|
220
|
+
const headers = parseHeaderLine(lines[0], delimiter);
|
|
221
|
+
const suggestedMapping = detectColumnMapping(headers, fieldsConfig);
|
|
222
|
+
return {
|
|
223
|
+
headers,
|
|
224
|
+
delimiter,
|
|
225
|
+
suggestedMapping,
|
|
226
|
+
rowCount: lines.length - 1
|
|
227
|
+
};
|
|
228
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSV Import Module
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities for flexible CSV column mapping.
|
|
5
|
+
* Supports auto-detection of columns via aliases and manual mapping UI.
|
|
6
|
+
*/
|
|
7
|
+
export type { StandardFieldType, FieldDefinition, ColumnMapping, ImportFieldsConfig, ImportMode } from './types';
|
|
8
|
+
export { CUSTOM_POINTS_FIELDS, CELL_IMPORT_FIELDS, CELL_MODE_FIELDS, POINT_MODE_FIELDS, SITE_MODE_FIELDS, getFieldsForMode } from './types';
|
|
9
|
+
export { COLUMN_ALIASES, detectColumnMapping, detectImportMode, autoDetectImport, validateMapping, analyzeCSVHeaders } from './column-detector';
|
|
10
|
+
export { default as ColumnMapper } from './ColumnMapper.svelte';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSV Import Module
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities for flexible CSV column mapping.
|
|
5
|
+
* Supports auto-detection of columns via aliases and manual mapping UI.
|
|
6
|
+
*/
|
|
7
|
+
// Field configurations
|
|
8
|
+
export { CUSTOM_POINTS_FIELDS, CELL_IMPORT_FIELDS, CELL_MODE_FIELDS, POINT_MODE_FIELDS, SITE_MODE_FIELDS, getFieldsForMode } from './types';
|
|
9
|
+
// Column detection utilities
|
|
10
|
+
export { COLUMN_ALIASES, detectColumnMapping, detectImportMode, autoDetectImport, validateMapping, analyzeCSVHeaders } from './column-detector';
|
|
11
|
+
// UI Component
|
|
12
|
+
export { default as ColumnMapper } from './ColumnMapper.svelte';
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CSV Import - Types
|
|
3
|
+
*
|
|
4
|
+
* Reusable types for CSV column mapping across different import features.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Import mode - determines which fields are shown and required
|
|
8
|
+
*/
|
|
9
|
+
export type ImportMode = 'cell' | 'point' | 'site';
|
|
10
|
+
/**
|
|
11
|
+
* Standard field types that can be mapped
|
|
12
|
+
*/
|
|
13
|
+
export type StandardFieldType = 'id' | 'lat' | 'lon' | 'group' | 'sizeFactor' | 'tech' | 'band' | 'azimuth' | 'tilt' | 'siteId' | 'siteName' | 'status' | 'height' | 'power';
|
|
14
|
+
/**
|
|
15
|
+
* Definition of a field for mapping
|
|
16
|
+
*/
|
|
17
|
+
export interface FieldDefinition {
|
|
18
|
+
/** Field type identifier */
|
|
19
|
+
type: StandardFieldType;
|
|
20
|
+
/** Display label for UI */
|
|
21
|
+
label: string;
|
|
22
|
+
/** Whether this field is required */
|
|
23
|
+
required: boolean;
|
|
24
|
+
/** Description/help text */
|
|
25
|
+
description?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Mapping of field types to CSV column indices
|
|
29
|
+
*/
|
|
30
|
+
export interface ColumnMapping {
|
|
31
|
+
[fieldType: string]: number | null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Result of parsing CSV headers
|
|
35
|
+
*/
|
|
36
|
+
export interface CsvHeadersResult {
|
|
37
|
+
/** All column headers from CSV */
|
|
38
|
+
headers: string[];
|
|
39
|
+
/** Detected delimiter */
|
|
40
|
+
delimiter: ',' | ';';
|
|
41
|
+
/** Auto-detected column mapping (best guesses) */
|
|
42
|
+
suggestedMapping: ColumnMapping;
|
|
43
|
+
/** Total row count (excluding header) */
|
|
44
|
+
rowCount: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Configuration for a specific import context
|
|
48
|
+
*/
|
|
49
|
+
export interface ImportFieldsConfig {
|
|
50
|
+
/** Fields that must be mapped */
|
|
51
|
+
required: FieldDefinition[];
|
|
52
|
+
/** Fields that can optionally be mapped */
|
|
53
|
+
optional: FieldDefinition[];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Predefined field configurations for import modes
|
|
57
|
+
*/
|
|
58
|
+
/** Cell mode - ID resolves against existing cell data */
|
|
59
|
+
export declare const CELL_MODE_FIELDS: ImportFieldsConfig;
|
|
60
|
+
/** Point mode - creates markers at lat/lon coordinates */
|
|
61
|
+
export declare const POINT_MODE_FIELDS: ImportFieldsConfig;
|
|
62
|
+
/** Site mode - creates site markers at lat/lon */
|
|
63
|
+
export declare const SITE_MODE_FIELDS: ImportFieldsConfig;
|
|
64
|
+
/** Get field config for a given import mode */
|
|
65
|
+
export declare function getFieldsForMode(mode: ImportMode): ImportFieldsConfig;
|
|
66
|
+
export declare const CUSTOM_POINTS_FIELDS: ImportFieldsConfig;
|
|
67
|
+
export declare const CELL_IMPORT_FIELDS: ImportFieldsConfig;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CSV Import - Types
|
|
3
|
+
*
|
|
4
|
+
* Reusable types for CSV column mapping across different import features.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Predefined field configurations for import modes
|
|
8
|
+
*/
|
|
9
|
+
/** Cell mode - ID resolves against existing cell data */
|
|
10
|
+
export const CELL_MODE_FIELDS = {
|
|
11
|
+
required: [
|
|
12
|
+
{ type: 'id', label: 'Cell ID', required: true, description: 'e.g. cellName, txId' }
|
|
13
|
+
],
|
|
14
|
+
optional: [
|
|
15
|
+
{ type: 'group', label: 'Group', required: false, description: 'e.g. customGroup, category' },
|
|
16
|
+
{ type: 'sizeFactor', label: 'Size', required: false, description: 'e.g. sizeFactor, weight' }
|
|
17
|
+
]
|
|
18
|
+
};
|
|
19
|
+
/** Point mode - creates markers at lat/lon coordinates */
|
|
20
|
+
export const POINT_MODE_FIELDS = {
|
|
21
|
+
required: [
|
|
22
|
+
{ type: 'id', label: 'ID / Name', required: true, description: 'e.g. name, label, id' },
|
|
23
|
+
{ type: 'lat', label: 'Latitude', required: true, description: 'e.g. lat, latitude, y' },
|
|
24
|
+
{ type: 'lon', label: 'Longitude', required: true, description: 'e.g. lon, lng, longitude, x' }
|
|
25
|
+
],
|
|
26
|
+
optional: [
|
|
27
|
+
{ type: 'group', label: 'Group', required: false, description: 'e.g. category, type' },
|
|
28
|
+
{ type: 'sizeFactor', label: 'Size', required: false, description: 'e.g. size, weight' }
|
|
29
|
+
]
|
|
30
|
+
};
|
|
31
|
+
/** Site mode - creates site markers at lat/lon */
|
|
32
|
+
export const SITE_MODE_FIELDS = {
|
|
33
|
+
required: [
|
|
34
|
+
{ type: 'id', label: 'Site ID', required: true, description: 'e.g. siteId, site_id, enodeb_id' },
|
|
35
|
+
{ type: 'lat', label: 'Latitude', required: true, description: 'e.g. lat, latitude' },
|
|
36
|
+
{ type: 'lon', label: 'Longitude', required: true, description: 'e.g. lon, longitude' }
|
|
37
|
+
],
|
|
38
|
+
optional: [
|
|
39
|
+
{ type: 'siteName', label: 'Site Name', required: false, description: 'e.g. site_name, location' },
|
|
40
|
+
{ type: 'group', label: 'Group', required: false, description: 'e.g. region, area' }
|
|
41
|
+
]
|
|
42
|
+
};
|
|
43
|
+
/** Get field config for a given import mode */
|
|
44
|
+
export function getFieldsForMode(mode) {
|
|
45
|
+
switch (mode) {
|
|
46
|
+
case 'cell': return CELL_MODE_FIELDS;
|
|
47
|
+
case 'point': return POINT_MODE_FIELDS;
|
|
48
|
+
case 'site': return SITE_MODE_FIELDS;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Legacy exports for backward compatibility
|
|
52
|
+
export const CUSTOM_POINTS_FIELDS = CELL_MODE_FIELDS;
|
|
53
|
+
export const CELL_IMPORT_FIELDS = {
|
|
54
|
+
required: [
|
|
55
|
+
{ type: 'id', label: 'Cell ID', required: true, description: 'Unique cell identifier' },
|
|
56
|
+
{ type: 'lat', label: 'Latitude', required: true },
|
|
57
|
+
{ type: 'lon', label: 'Longitude', required: true },
|
|
58
|
+
{ type: 'azimuth', label: 'Azimuth', required: true, description: 'Antenna direction (0-360°)' }
|
|
59
|
+
],
|
|
60
|
+
optional: [
|
|
61
|
+
{ type: 'siteId', label: 'Site ID', required: false },
|
|
62
|
+
{ type: 'siteName', label: 'Site Name', required: false },
|
|
63
|
+
{ type: 'tech', label: 'Technology', required: false, description: 'e.g., LTE, NR, GSM' },
|
|
64
|
+
{ type: 'band', label: 'Band', required: false, description: 'Frequency band' },
|
|
65
|
+
{ type: 'tilt', label: 'Tilt', required: false },
|
|
66
|
+
{ type: 'height', label: 'Height', required: false },
|
|
67
|
+
{ type: 'power', label: 'Power', required: false },
|
|
68
|
+
{ type: 'status', label: 'Status', required: false }
|
|
69
|
+
]
|
|
70
|
+
};
|