fix(app): normalize grid JSON smart quotes
This commit is contained in:
parent
51662c692f
commit
c4a268f670
|
|
@ -269,7 +269,26 @@ export function useDataGridEditor(options: UseDataGridEditorOptions) {
|
|||
if (typeof oldVal === "boolean") {
|
||||
return value === "true" || value === "1";
|
||||
}
|
||||
return value;
|
||||
return normalizeSmartQuotedJsonInput(value);
|
||||
}
|
||||
|
||||
function normalizeSmartQuotedJsonInput(value: string): string {
|
||||
if (!/[“”]/.test(value)) return value;
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return value;
|
||||
try {
|
||||
JSON.parse(value);
|
||||
return value;
|
||||
} catch {
|
||||
// macOS smart punctuation can turn JSON delimiters into Chinese-style quotes.
|
||||
}
|
||||
const normalized = value.replace(/[“”]/g, '"');
|
||||
try {
|
||||
JSON.parse(normalized);
|
||||
return normalized;
|
||||
} catch {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
function canEditColumn(columnIndex: number): boolean {
|
||||
|
|
|
|||
|
|
@ -379,3 +379,59 @@ test("saving edited rows without deletes does not reload table data", async () =
|
|||
|
||||
assert.deepEqual(emitted, []);
|
||||
});
|
||||
|
||||
test("saving manually typed JSON from a MySQL grid normalizes smart quotes", async () => {
|
||||
setActivePinia(createPinia());
|
||||
installBrowserTestGlobals();
|
||||
|
||||
const result = computed(() => ({
|
||||
columns: ["id", "payload"],
|
||||
rows: [[1, "{}"] as CellValue[]],
|
||||
}));
|
||||
const rowStatusFilter = ref<"all" | "changed" | "edited" | "new" | "deleted">("all");
|
||||
const executedSql: string[] = [];
|
||||
|
||||
const editor = useDataGridEditor({
|
||||
result,
|
||||
editable: computed(() => true),
|
||||
databaseType: computed(() => "mysql"),
|
||||
connectionId: computed(() => undefined),
|
||||
database: computed(() => undefined),
|
||||
tableMeta: computed(() => ({
|
||||
tableName: "settings",
|
||||
columns: [column("id", true), { ...column("payload"), data_type: "json" }],
|
||||
primaryKeys: ["id"],
|
||||
})),
|
||||
onExecuteSql: computed(() => async (sql: string) => {
|
||||
executedSql.push(sql);
|
||||
}),
|
||||
customSave: computed(() => undefined),
|
||||
sql: computed(() => "SELECT id, payload FROM settings"),
|
||||
searchText: ref(""),
|
||||
whereFilterInput: ref(""),
|
||||
orderByInput: ref(""),
|
||||
rowStatusFilter,
|
||||
pageSize: ref(50),
|
||||
currentPage: ref(1),
|
||||
getRowItem: (rowId) => {
|
||||
if (rowId !== 0) return undefined;
|
||||
return {
|
||||
id: 0,
|
||||
sourceIndex: 0,
|
||||
data: result.value.rows[0],
|
||||
isNew: false,
|
||||
isDeleted: false,
|
||||
isDirtyCol: [false, false],
|
||||
status: "clean",
|
||||
};
|
||||
},
|
||||
emit: () => {},
|
||||
});
|
||||
|
||||
editor.applyCellValue(0, 1, "{“2:3”:“3:4”,“3:2”:“4:3”,“21:9”:“16:9”}");
|
||||
await editor.saveChanges();
|
||||
|
||||
assert.deepEqual(executedSql, [
|
||||
`UPDATE "settings" SET "payload" = '{"2:3":"3:4","3:2":"4:3","21:9":"16:9"}' WHERE "id" = 1;`,
|
||||
]);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue