[released bug] UI: Fix exporting data as CSV for json results (#19955)

This commit is contained in:
RachelElysia
2024-06-26 09:22:16 -04:00
committed by GitHub
parent 837e15308b
commit 8fa0d0890b
3 changed files with 55 additions and 6 deletions
+1
View File
@@ -0,0 +1 @@
- Fix exporting CSVs with fields that contain commas to render properly
@@ -11,10 +11,36 @@ const objArray = [
},
];
const objArray2 = [
{
host_display_name: "Rachel@Fleet",
last_fetched: "2024-06-25T13:11:18Z",
uid: "145",
json_result: {
"AC Power:": {
acwake: "0",
hibernatefile: "/var/vm/sleepimage",
},
},
},
];
const tableHeaders = [
{ id: "host_display_name", sortType: "caseInsensitive" },
{ id: "last_fetched", sortType: "caseInsensitive" },
{ id: "uid", sortType: "alphanumeric" },
{ id: "json_result", sortType: "caseInsensitive" },
];
describe("convertToCSV - utility", () => {
it("converts an array of objects to CSV format", () => {
expect(convertToCSV({ objArray })).toEqual(
'"first_name","last_name"\n"Mike","Stone"\n"Paul","Simon"'
);
});
it("correctly creates table headers and fields with quotes and commas to CSV format", () => {
expect(convertToCSV({ objArray: objArray2, tableHeaders })).toEqual(
'"host_display_name","last_fetched","uid","json_result"\n"Rachel@Fleet","2024-06-25T13:11:18Z","145","{""AC Power:"":{""acwake"":""0"",""hibernatefile"":""/var/vm/sleepimage""}}"'
);
});
});
+28 -6
View File
@@ -1,7 +1,7 @@
const defaultFieldSortFunc = (fields: string[]) => fields;
interface ConvertToCSV {
objArray: any; // TODO: typing
objArray: any[]; // TODO: typing
fieldSortFunc?: (fields: string[]) => string[];
tableHeaders?: any[]; // TODO: typing
}
@@ -12,21 +12,43 @@ const convertToCSV = ({
tableHeaders,
}: ConvertToCSV) => {
const tableHeadersStrings: string[] = tableHeaders
? tableHeaders.map((header: { id: string }) => header.id) // TODO: typing
? tableHeaders.map((header: { id: string }) => header.id)
: Object.keys(objArray[0]);
const fields = fieldSortFunc(tableHeadersStrings);
// TODO: Remove after v5 when host_hostname is removed rom API response.
const hostNameIndex = fields.indexOf("host_hostname");
// TODO: Revisit after v5 if column names are modified/removed from API response.
const hostNameIndex = fields.indexOf("Host");
if (hostNameIndex >= 0) {
fields.splice(hostNameIndex, 1);
}
// Remove end
// Revisit end
const jsonFields = fields.map((field) => JSON.stringify(field));
const rows = objArray.map((row: any) => {
// TODO: typing
return fields.map((field) => JSON.stringify(row[field])).join(",");
return fields
.map((field) => {
// Check if the value of the field is a string and needs to be quoted
let value = row[field];
// If the value is an object, stringify it first
if (typeof value === "object") {
value = JSON.stringify(value);
}
// Escape double quotes in the value by doubling them
if (typeof value === "string") {
value = value.replace(/"/g, '""');
}
// Wrap the value in double quotes to enclose any value tha
// might have a, or a " in it to distinguish them from a comma separated delimiter
value = `"${value}"`;
return value;
})
.join(",");
});
rows.unshift(jsonFields.join(","));