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{}
}