feat(migration): add skip rows option to CSV import
Allow users to skip the first N data rows when importing CSV files. This is useful when the CSV contains metadata rows before the actual task data begins. Adds skip_rows to ImportConfig (backend) and a number input in the parsing options UI (frontend).
This commit is contained in:
parent
f555762def
commit
3437f98dc3
|
|
@ -676,6 +676,7 @@
|
|||
"parsingOptions": "Parsing Options",
|
||||
"delimiter": "Delimiter",
|
||||
"dateFormat": "Date Format",
|
||||
"skipRows": "Skip Rows",
|
||||
"mapColumns": "Map Columns",
|
||||
"example": "e.g.",
|
||||
"preview": "Preview",
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ export interface ImportConfig {
|
|||
delimiter: string
|
||||
quote_char: string
|
||||
date_format: string
|
||||
skip_rows: number
|
||||
mapping: ColumnMapping[]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,17 @@
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="option-group">
|
||||
<label for="skipRows">{{ $t('migrate.csv.skipRows') }}</label>
|
||||
<input
|
||||
id="skipRows"
|
||||
v-model.number="config.skip_rows"
|
||||
type="number"
|
||||
class="input"
|
||||
min="0"
|
||||
@change="updatePreview"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -219,6 +230,7 @@ const config = ref<ImportConfig>({
|
|||
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: [],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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{}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue