diff --git a/frontend/src/i18n/lang/en.json b/frontend/src/i18n/lang/en.json index 98e484a23..551349ef7 100644 --- a/frontend/src/i18n/lang/en.json +++ b/frontend/src/i18n/lang/en.json @@ -676,6 +676,7 @@ "parsingOptions": "Parsing Options", "delimiter": "Delimiter", "dateFormat": "Date Format", + "skipRows": "Skip Rows", "mapColumns": "Map Columns", "example": "e.g.", "preview": "Preview", diff --git a/frontend/src/services/migrator/csvMigration.ts b/frontend/src/services/migrator/csvMigration.ts index ecbc26561..7bcc25c03 100644 --- a/frontend/src/services/migrator/csvMigration.ts +++ b/frontend/src/services/migrator/csvMigration.ts @@ -46,6 +46,7 @@ export interface ImportConfig { delimiter: string quote_char: string date_format: string + skip_rows: number mapping: ColumnMapping[] } diff --git a/frontend/src/views/migrate/MigrationCSV.vue b/frontend/src/views/migrate/MigrationCSV.vue index 2aab57101..1318032ce 100644 --- a/frontend/src/views/migrate/MigrationCSV.vue +++ b/frontend/src/views/migrate/MigrationCSV.vue @@ -82,6 +82,17 @@ +
+ + +
@@ -219,6 +230,7 @@ const config = ref({ delimiter: ',', quote_char: '"', date_format: '2006-01-02', + skip_rows: 0, mapping: [], }) @@ -303,6 +315,7 @@ async function handleFileUpload() { delimiter: result.delimiter, quote_char: result.quote_char, date_format: result.date_format, + skip_rows: 0, mapping: result.suggested_mapping, } @@ -366,6 +379,7 @@ function resetToUpload() { delimiter: ',', quote_char: '"', date_format: '2006-01-02', + skip_rows: 0, mapping: [], } } diff --git a/pkg/modules/migration/csv/csv.go b/pkg/modules/migration/csv/csv.go index f20221a01..81e3dc00a 100644 --- a/pkg/modules/migration/csv/csv.go +++ b/pkg/modules/migration/csv/csv.go @@ -127,6 +127,7 @@ type ImportConfig struct { Delimiter string `json:"delimiter"` QuoteChar string `json:"quote_char"` DateFormat string `json:"date_format"` + SkipRows int `json:"skip_rows"` Mapping []ColumnMapping `json:"mapping"` } @@ -396,6 +397,17 @@ func PreviewImport(file io.ReaderAt, size int64, config *ImportConfig) (*Preview return nil, &migration.ErrNotACSVFile{} } + // Skip rows if configured + if config.SkipRows > 0 { + if config.SkipRows >= len(rows) { + return &PreviewResult{ + Tasks: []PreviewTask{}, + TotalRows: 0, + }, nil + } + rows = rows[config.SkipRows:] + } + result := &PreviewResult{ Tasks: make([]PreviewTask, 0, minInt(5, len(rows))), TotalRows: len(rows), @@ -566,6 +578,15 @@ func MigrateWithConfig(u *user.User, file io.ReaderAt, size int64, config *Impor return &migration.ErrNotACSVFile{} } + // Skip rows if configured + if config.SkipRows > 0 { + if config.SkipRows >= len(rows) { + rows = nil + } else { + rows = rows[config.SkipRows:] + } + } + if len(rows) == 0 { return &migration.ErrFileIsEmpty{} }