fix: added column separator select (comma, semicolon and both) in CSV viewer (#5604)

Co-authored-by: Henrique Dias <mail@hacdias.com>
This commit is contained in:
Ariel Leyva 2025-12-06 05:08:50 -05:00 committed by GitHub
parent f029c3005e
commit 204a3f0eea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 64 additions and 7 deletions

View file

@ -25,9 +25,29 @@
</tr>
</tbody>
</table>
<div v-if="data.rows.length > 100" class="csv-info">
<i class="material-icons">info</i>
<span>Showing {{ data.rows.length }} rows</span>
<div class="csv-footer">
<div class="csv-info" v-if="data.rows.length > 100">
<i class="material-icons">info</i>
<span>Showing {{ data.rows.length }} rows</span>
</div>
<div class="column-separator">
<label for="columnSeparator">Column Separator</label>
<select
id="columnSeparator"
class="input input--block"
v-model="columnSeparator"
>
<option :value="[',']">
{{ $t("available_csv_separators.comma") }}
</option>
<option :value="[';']">
{{ $t("available_csv_separators.semicolon") }}
</option>
<option :value="[',', ';']">
{{ $t("available_csv_separators.both") }}
</option>
</select>
</div>
</div>
</div>
</div>
@ -35,7 +55,7 @@
<script setup lang="ts">
import { parseCSV, type CsvData } from "@/utils/csv";
import { computed } from "vue";
import { computed, ref } from "vue";
interface Props {
content: string;
@ -46,9 +66,11 @@ const props = withDefaults(defineProps<Props>(), {
error: "",
});
const columnSeparator = ref([","]);
const data = computed<CsvData>(() => {
try {
return parseCSV(props.content);
return parseCSV(props.content, columnSeparator.value);
} catch (e) {
console.error("Failed to parse CSV:", e);
return { headers: [], rows: [] };
@ -181,6 +203,18 @@ const displayError = computed(() => {
transition: background-color 0.15s ease;
}
.csv-footer {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
padding: 0.5rem;
}
.csv-footer > :only-child {
margin-left: auto;
}
.csv-info {
display: flex;
align-items: center;
@ -194,6 +228,21 @@ const displayError = computed(() => {
font-size: 0.875rem;
}
.column-separator {
display: flex;
align-items: center;
gap: 0.5rem;
}
.column-separator > label {
font-size: small;
text-align: end;
}
.column-separator > select {
margin-bottom: 0;
}
.csv-info i {
font-size: 1.2rem;
color: var(--blue);

View file

@ -272,5 +272,10 @@
"minutes": "Minutes",
"seconds": "Seconds",
"unit": "Time Unit"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}

View file

@ -7,7 +7,10 @@ export interface CsvData {
* Parse CSV content into headers and rows
* Supports quoted fields and handles commas within quotes
*/
export function parseCSV(content: string): CsvData {
export function parseCSV(
content: string,
columnSeparator: Array<string>
): CsvData {
if (!content || content.trim().length === 0) {
return { headers: [], rows: [] };
}
@ -35,7 +38,7 @@ export function parseCSV(content: string): CsvData {
// Toggle quote state
inQuotes = !inQuotes;
}
} else if (char === "," && !inQuotes) {
} else if (columnSeparator.includes(char) && !inQuotes) {
// Field separator
row.push(currentField);
currentField = "";