@thanh01.pmt/interactive-quiz-kit 1.0.68 → 1.0.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authoring.cjs +10 -10
- package/dist/authoring.mjs +10 -10
- package/dist/react-ui.cjs +10 -10
- package/dist/react-ui.mjs +10 -10
- package/package.json +1 -1
package/dist/authoring.cjs
CHANGED
|
@@ -76443,8 +76443,8 @@ function MetadataImportControls({ metadataName, onImport }) {
|
|
|
76443
76443
|
const handleFileSelected = (event) => {
|
|
76444
76444
|
const file = event.target.files?.[0];
|
|
76445
76445
|
if (!file) return;
|
|
76446
|
-
if (file.type
|
|
76447
|
-
toast2({ title: "Invalid File Type", description: "Please select a JSON or
|
|
76446
|
+
if (!file.type.includes("json") && !file.type.includes("tab-separated-values") && !file.name.endsWith(".tsv") && !file.name.endsWith(".txt")) {
|
|
76447
|
+
toast2({ title: "Invalid File Type", description: "Please select a JSON or TSV/TXT file.", variant: "destructive" });
|
|
76448
76448
|
if (event.target) event.target.value = "";
|
|
76449
76449
|
return;
|
|
76450
76450
|
}
|
|
@@ -76452,18 +76452,18 @@ function MetadataImportControls({ metadataName, onImport }) {
|
|
|
76452
76452
|
try {
|
|
76453
76453
|
const fileContent = await file.text();
|
|
76454
76454
|
let records = [];
|
|
76455
|
-
if (file.type
|
|
76455
|
+
if (file.type.includes("json")) {
|
|
76456
76456
|
records = JSON.parse(fileContent);
|
|
76457
76457
|
if (!Array.isArray(records)) throw new Error("JSON file must contain an array of objects.");
|
|
76458
|
-
} else
|
|
76459
|
-
const lines = fileContent.split(/\r
|
|
76460
|
-
if (lines.length < 2) throw new Error("
|
|
76461
|
-
const headers = lines[0].split("
|
|
76458
|
+
} else {
|
|
76459
|
+
const lines = fileContent.split(/\r?\n/).filter((line) => line.trim() !== "");
|
|
76460
|
+
if (lines.length < 2) throw new Error("TSV file must have a header and at least one data row.");
|
|
76461
|
+
const headers = lines[0].split(" ").map((h2) => h2.trim());
|
|
76462
76462
|
records = lines.slice(1).map((line) => {
|
|
76463
|
-
const values = line.split("
|
|
76463
|
+
const values = line.split(" ");
|
|
76464
76464
|
const record = {};
|
|
76465
76465
|
headers.forEach((header, index3) => {
|
|
76466
|
-
record[header] = values[index3];
|
|
76466
|
+
record[header] = values[index3]?.trim() || "";
|
|
76467
76467
|
});
|
|
76468
76468
|
return record;
|
|
76469
76469
|
});
|
|
@@ -76490,7 +76490,7 @@ function MetadataImportControls({ metadataName, onImport }) {
|
|
|
76490
76490
|
}
|
|
76491
76491
|
});
|
|
76492
76492
|
};
|
|
76493
|
-
return /* @__PURE__ */ React119__namespace.default.createElement(Dialog2, { open: isOpen, onOpenChange: setIsOpen }, /* @__PURE__ */ React119__namespace.default.createElement(DialogTrigger2, { asChild: true }, /* @__PURE__ */ React119__namespace.default.createElement(Button, { size: "sm", variant: "outline" }, /* @__PURE__ */ React119__namespace.default.createElement(Upload, { className: "mr-2 h-4 w-4" }), " Import ", metadataName)), /* @__PURE__ */ React119__namespace.default.createElement(DialogContent2, null, /* @__PURE__ */ React119__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React119__namespace.default.createElement(DialogTitle2, null, "Bulk Import ", metadataName), /* @__PURE__ */ React119__namespace.default.createElement(DialogDescription2, null, "Import multiple records from a file or by pasting JSON data.")), /* @__PURE__ */ React119__namespace.default.createElement(Tabs2, { defaultValue: "file" }, /* @__PURE__ */ React119__namespace.default.createElement(TabsList2, { className: "grid w-full grid-cols-2" }, /* @__PURE__ */ React119__namespace.default.createElement(TabsTrigger2, { value: "file" }, /* @__PURE__ */ React119__namespace.default.createElement(FileJson, { className: "mr-2 h-4 w-4" }), " From File"), /* @__PURE__ */ React119__namespace.default.createElement(TabsTrigger2, { value: "text" }, /* @__PURE__ */ React119__namespace.default.createElement(ClipboardPaste, { className: "mr-2 h-4 w-4" }), " From Text")), /* @__PURE__ */ React119__namespace.default.createElement(TabsContent2, { value: "file", className: "pt-4" }, /* @__PURE__ */ React119__namespace.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React119__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, "Select a JSON or
|
|
76493
|
+
return /* @__PURE__ */ React119__namespace.default.createElement(Dialog2, { open: isOpen, onOpenChange: setIsOpen }, /* @__PURE__ */ React119__namespace.default.createElement(DialogTrigger2, { asChild: true }, /* @__PURE__ */ React119__namespace.default.createElement(Button, { size: "sm", variant: "outline" }, /* @__PURE__ */ React119__namespace.default.createElement(Upload, { className: "mr-2 h-4 w-4" }), " Import ", metadataName)), /* @__PURE__ */ React119__namespace.default.createElement(DialogContent2, null, /* @__PURE__ */ React119__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React119__namespace.default.createElement(DialogTitle2, null, "Bulk Import ", metadataName), /* @__PURE__ */ React119__namespace.default.createElement(DialogDescription2, null, "Import multiple records from a file or by pasting JSON data.")), /* @__PURE__ */ React119__namespace.default.createElement(Tabs2, { defaultValue: "file" }, /* @__PURE__ */ React119__namespace.default.createElement(TabsList2, { className: "grid w-full grid-cols-2" }, /* @__PURE__ */ React119__namespace.default.createElement(TabsTrigger2, { value: "file" }, /* @__PURE__ */ React119__namespace.default.createElement(FileJson, { className: "mr-2 h-4 w-4" }), " From File"), /* @__PURE__ */ React119__namespace.default.createElement(TabsTrigger2, { value: "text" }, /* @__PURE__ */ React119__namespace.default.createElement(ClipboardPaste, { className: "mr-2 h-4 w-4" }), " From Text")), /* @__PURE__ */ React119__namespace.default.createElement(TabsContent2, { value: "file", className: "pt-4" }, /* @__PURE__ */ React119__namespace.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React119__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, "Select a JSON or TSV/TXT file. Ensure column names in the file match the table schema (e.g., 'code', 'name', 'subjectCode')."), /* @__PURE__ */ React119__namespace.default.createElement(Button, { variant: "outline", onClick: () => fileInputRef.current?.click(), disabled: isImporting }, isImporting ? /* @__PURE__ */ React119__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ React119__namespace.default.createElement(Upload, { className: "mr-2 h-4 w-4" }), isImporting ? "Importing..." : "Select File"), /* @__PURE__ */ React119__namespace.default.createElement("input", { type: "file", ref: fileInputRef, onChange: handleFileSelected, accept: ".json,.tsv,.txt,text/tab-separated-values", className: "hidden" }))), /* @__PURE__ */ React119__namespace.default.createElement(TabsContent2, { value: "text", className: "pt-4" }, /* @__PURE__ */ React119__namespace.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React119__namespace.default.createElement(Label2, { htmlFor: "jsonInput" }, "JSON Data (Array of Objects)"), /* @__PURE__ */ React119__namespace.default.createElement(
|
|
76494
76494
|
Textarea,
|
|
76495
76495
|
{
|
|
76496
76496
|
id: "jsonInput",
|
package/dist/authoring.mjs
CHANGED
|
@@ -76378,8 +76378,8 @@ function MetadataImportControls({ metadataName, onImport }) {
|
|
|
76378
76378
|
const handleFileSelected = (event) => {
|
|
76379
76379
|
const file = event.target.files?.[0];
|
|
76380
76380
|
if (!file) return;
|
|
76381
|
-
if (file.type
|
|
76382
|
-
toast2({ title: "Invalid File Type", description: "Please select a JSON or
|
|
76381
|
+
if (!file.type.includes("json") && !file.type.includes("tab-separated-values") && !file.name.endsWith(".tsv") && !file.name.endsWith(".txt")) {
|
|
76382
|
+
toast2({ title: "Invalid File Type", description: "Please select a JSON or TSV/TXT file.", variant: "destructive" });
|
|
76383
76383
|
if (event.target) event.target.value = "";
|
|
76384
76384
|
return;
|
|
76385
76385
|
}
|
|
@@ -76387,18 +76387,18 @@ function MetadataImportControls({ metadataName, onImport }) {
|
|
|
76387
76387
|
try {
|
|
76388
76388
|
const fileContent = await file.text();
|
|
76389
76389
|
let records = [];
|
|
76390
|
-
if (file.type
|
|
76390
|
+
if (file.type.includes("json")) {
|
|
76391
76391
|
records = JSON.parse(fileContent);
|
|
76392
76392
|
if (!Array.isArray(records)) throw new Error("JSON file must contain an array of objects.");
|
|
76393
|
-
} else
|
|
76394
|
-
const lines = fileContent.split(/\r
|
|
76395
|
-
if (lines.length < 2) throw new Error("
|
|
76396
|
-
const headers = lines[0].split("
|
|
76393
|
+
} else {
|
|
76394
|
+
const lines = fileContent.split(/\r?\n/).filter((line) => line.trim() !== "");
|
|
76395
|
+
if (lines.length < 2) throw new Error("TSV file must have a header and at least one data row.");
|
|
76396
|
+
const headers = lines[0].split(" ").map((h2) => h2.trim());
|
|
76397
76397
|
records = lines.slice(1).map((line) => {
|
|
76398
|
-
const values = line.split("
|
|
76398
|
+
const values = line.split(" ");
|
|
76399
76399
|
const record = {};
|
|
76400
76400
|
headers.forEach((header, index3) => {
|
|
76401
|
-
record[header] = values[index3];
|
|
76401
|
+
record[header] = values[index3]?.trim() || "";
|
|
76402
76402
|
});
|
|
76403
76403
|
return record;
|
|
76404
76404
|
});
|
|
@@ -76425,7 +76425,7 @@ function MetadataImportControls({ metadataName, onImport }) {
|
|
|
76425
76425
|
}
|
|
76426
76426
|
});
|
|
76427
76427
|
};
|
|
76428
|
-
return /* @__PURE__ */ React119__default.createElement(Dialog2, { open: isOpen, onOpenChange: setIsOpen }, /* @__PURE__ */ React119__default.createElement(DialogTrigger2, { asChild: true }, /* @__PURE__ */ React119__default.createElement(Button, { size: "sm", variant: "outline" }, /* @__PURE__ */ React119__default.createElement(Upload, { className: "mr-2 h-4 w-4" }), " Import ", metadataName)), /* @__PURE__ */ React119__default.createElement(DialogContent2, null, /* @__PURE__ */ React119__default.createElement(DialogHeader, null, /* @__PURE__ */ React119__default.createElement(DialogTitle2, null, "Bulk Import ", metadataName), /* @__PURE__ */ React119__default.createElement(DialogDescription2, null, "Import multiple records from a file or by pasting JSON data.")), /* @__PURE__ */ React119__default.createElement(Tabs2, { defaultValue: "file" }, /* @__PURE__ */ React119__default.createElement(TabsList2, { className: "grid w-full grid-cols-2" }, /* @__PURE__ */ React119__default.createElement(TabsTrigger2, { value: "file" }, /* @__PURE__ */ React119__default.createElement(FileJson, { className: "mr-2 h-4 w-4" }), " From File"), /* @__PURE__ */ React119__default.createElement(TabsTrigger2, { value: "text" }, /* @__PURE__ */ React119__default.createElement(ClipboardPaste, { className: "mr-2 h-4 w-4" }), " From Text")), /* @__PURE__ */ React119__default.createElement(TabsContent2, { value: "file", className: "pt-4" }, /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React119__default.createElement("p", { className: "text-sm text-muted-foreground" }, "Select a JSON or
|
|
76428
|
+
return /* @__PURE__ */ React119__default.createElement(Dialog2, { open: isOpen, onOpenChange: setIsOpen }, /* @__PURE__ */ React119__default.createElement(DialogTrigger2, { asChild: true }, /* @__PURE__ */ React119__default.createElement(Button, { size: "sm", variant: "outline" }, /* @__PURE__ */ React119__default.createElement(Upload, { className: "mr-2 h-4 w-4" }), " Import ", metadataName)), /* @__PURE__ */ React119__default.createElement(DialogContent2, null, /* @__PURE__ */ React119__default.createElement(DialogHeader, null, /* @__PURE__ */ React119__default.createElement(DialogTitle2, null, "Bulk Import ", metadataName), /* @__PURE__ */ React119__default.createElement(DialogDescription2, null, "Import multiple records from a file or by pasting JSON data.")), /* @__PURE__ */ React119__default.createElement(Tabs2, { defaultValue: "file" }, /* @__PURE__ */ React119__default.createElement(TabsList2, { className: "grid w-full grid-cols-2" }, /* @__PURE__ */ React119__default.createElement(TabsTrigger2, { value: "file" }, /* @__PURE__ */ React119__default.createElement(FileJson, { className: "mr-2 h-4 w-4" }), " From File"), /* @__PURE__ */ React119__default.createElement(TabsTrigger2, { value: "text" }, /* @__PURE__ */ React119__default.createElement(ClipboardPaste, { className: "mr-2 h-4 w-4" }), " From Text")), /* @__PURE__ */ React119__default.createElement(TabsContent2, { value: "file", className: "pt-4" }, /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React119__default.createElement("p", { className: "text-sm text-muted-foreground" }, "Select a JSON or TSV/TXT file. Ensure column names in the file match the table schema (e.g., 'code', 'name', 'subjectCode')."), /* @__PURE__ */ React119__default.createElement(Button, { variant: "outline", onClick: () => fileInputRef.current?.click(), disabled: isImporting }, isImporting ? /* @__PURE__ */ React119__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ React119__default.createElement(Upload, { className: "mr-2 h-4 w-4" }), isImporting ? "Importing..." : "Select File"), /* @__PURE__ */ React119__default.createElement("input", { type: "file", ref: fileInputRef, onChange: handleFileSelected, accept: ".json,.tsv,.txt,text/tab-separated-values", className: "hidden" }))), /* @__PURE__ */ React119__default.createElement(TabsContent2, { value: "text", className: "pt-4" }, /* @__PURE__ */ React119__default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "jsonInput" }, "JSON Data (Array of Objects)"), /* @__PURE__ */ React119__default.createElement(
|
|
76429
76429
|
Textarea,
|
|
76430
76430
|
{
|
|
76431
76431
|
id: "jsonInput",
|
package/dist/react-ui.cjs
CHANGED
|
@@ -138739,8 +138739,8 @@ function MetadataImportControls({ metadataName, onImport }) {
|
|
|
138739
138739
|
const handleFileSelected = (event) => {
|
|
138740
138740
|
const file = event.target.files?.[0];
|
|
138741
138741
|
if (!file) return;
|
|
138742
|
-
if (file.type
|
|
138743
|
-
toast2({ title: "Invalid File Type", description: "Please select a JSON or
|
|
138742
|
+
if (!file.type.includes("json") && !file.type.includes("tab-separated-values") && !file.name.endsWith(".tsv") && !file.name.endsWith(".txt")) {
|
|
138743
|
+
toast2({ title: "Invalid File Type", description: "Please select a JSON or TSV/TXT file.", variant: "destructive" });
|
|
138744
138744
|
if (event.target) event.target.value = "";
|
|
138745
138745
|
return;
|
|
138746
138746
|
}
|
|
@@ -138748,18 +138748,18 @@ function MetadataImportControls({ metadataName, onImport }) {
|
|
|
138748
138748
|
try {
|
|
138749
138749
|
const fileContent = await file.text();
|
|
138750
138750
|
let records = [];
|
|
138751
|
-
if (file.type
|
|
138751
|
+
if (file.type.includes("json")) {
|
|
138752
138752
|
records = JSON.parse(fileContent);
|
|
138753
138753
|
if (!Array.isArray(records)) throw new Error("JSON file must contain an array of objects.");
|
|
138754
|
-
} else
|
|
138755
|
-
const lines = fileContent.split(/\r
|
|
138756
|
-
if (lines.length < 2) throw new Error("
|
|
138757
|
-
const headers = lines[0].split("
|
|
138754
|
+
} else {
|
|
138755
|
+
const lines = fileContent.split(/\r?\n/).filter((line) => line.trim() !== "");
|
|
138756
|
+
if (lines.length < 2) throw new Error("TSV file must have a header and at least one data row.");
|
|
138757
|
+
const headers = lines[0].split(" ").map((h3) => h3.trim());
|
|
138758
138758
|
records = lines.slice(1).map((line) => {
|
|
138759
|
-
const values = line.split("
|
|
138759
|
+
const values = line.split(" ");
|
|
138760
138760
|
const record = {};
|
|
138761
138761
|
headers.forEach((header, index3) => {
|
|
138762
|
-
record[header] = values[index3];
|
|
138762
|
+
record[header] = values[index3]?.trim() || "";
|
|
138763
138763
|
});
|
|
138764
138764
|
return record;
|
|
138765
138765
|
});
|
|
@@ -138786,7 +138786,7 @@ function MetadataImportControls({ metadataName, onImport }) {
|
|
|
138786
138786
|
}
|
|
138787
138787
|
});
|
|
138788
138788
|
};
|
|
138789
|
-
return /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isOpen, onOpenChange: setIsOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogTrigger2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { size: "sm", variant: "outline" }, /* @__PURE__ */ React169__namespace.default.createElement(Upload, { className: "mr-2 h-4 w-4" }), " Import ", metadataName)), /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, "Bulk Import ", metadataName), /* @__PURE__ */ React169__namespace.default.createElement(DialogDescription2, null, "Import multiple records from a file or by pasting JSON data.")), /* @__PURE__ */ React169__namespace.default.createElement(Tabs2, { defaultValue: "file" }, /* @__PURE__ */ React169__namespace.default.createElement(TabsList2, { className: "grid w-full grid-cols-2" }, /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "file" }, /* @__PURE__ */ React169__namespace.default.createElement(FileJson, { className: "mr-2 h-4 w-4" }), " From File"), /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "text" }, /* @__PURE__ */ React169__namespace.default.createElement(ClipboardPaste, { className: "mr-2 h-4 w-4" }), " From Text")), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "file", className: "pt-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, "Select a JSON or
|
|
138789
|
+
return /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isOpen, onOpenChange: setIsOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogTrigger2, { asChild: true }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { size: "sm", variant: "outline" }, /* @__PURE__ */ React169__namespace.default.createElement(Upload, { className: "mr-2 h-4 w-4" }), " Import ", metadataName)), /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, "Bulk Import ", metadataName), /* @__PURE__ */ React169__namespace.default.createElement(DialogDescription2, null, "Import multiple records from a file or by pasting JSON data.")), /* @__PURE__ */ React169__namespace.default.createElement(Tabs2, { defaultValue: "file" }, /* @__PURE__ */ React169__namespace.default.createElement(TabsList2, { className: "grid w-full grid-cols-2" }, /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "file" }, /* @__PURE__ */ React169__namespace.default.createElement(FileJson, { className: "mr-2 h-4 w-4" }), " From File"), /* @__PURE__ */ React169__namespace.default.createElement(TabsTrigger2, { value: "text" }, /* @__PURE__ */ React169__namespace.default.createElement(ClipboardPaste, { className: "mr-2 h-4 w-4" }), " From Text")), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "file", className: "pt-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-sm text-muted-foreground" }, "Select a JSON or TSV/TXT file. Ensure column names in the file match the table schema (e.g., 'code', 'name', 'subjectCode')."), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "outline", onClick: () => fileInputRef.current?.click(), disabled: isImporting }, isImporting ? /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ React169__namespace.default.createElement(Upload, { className: "mr-2 h-4 w-4" }), isImporting ? "Importing..." : "Select File"), /* @__PURE__ */ React169__namespace.default.createElement("input", { type: "file", ref: fileInputRef, onChange: handleFileSelected, accept: ".json,.tsv,.txt,text/tab-separated-values", className: "hidden" }))), /* @__PURE__ */ React169__namespace.default.createElement(TabsContent2, { value: "text", className: "pt-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "jsonInput" }, "JSON Data (Array of Objects)"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
138790
138790
|
Textarea,
|
|
138791
138791
|
{
|
|
138792
138792
|
id: "jsonInput",
|
package/dist/react-ui.mjs
CHANGED
|
@@ -138673,8 +138673,8 @@ function MetadataImportControls({ metadataName, onImport }) {
|
|
|
138673
138673
|
const handleFileSelected = (event) => {
|
|
138674
138674
|
const file = event.target.files?.[0];
|
|
138675
138675
|
if (!file) return;
|
|
138676
|
-
if (file.type
|
|
138677
|
-
toast2({ title: "Invalid File Type", description: "Please select a JSON or
|
|
138676
|
+
if (!file.type.includes("json") && !file.type.includes("tab-separated-values") && !file.name.endsWith(".tsv") && !file.name.endsWith(".txt")) {
|
|
138677
|
+
toast2({ title: "Invalid File Type", description: "Please select a JSON or TSV/TXT file.", variant: "destructive" });
|
|
138678
138678
|
if (event.target) event.target.value = "";
|
|
138679
138679
|
return;
|
|
138680
138680
|
}
|
|
@@ -138682,18 +138682,18 @@ function MetadataImportControls({ metadataName, onImport }) {
|
|
|
138682
138682
|
try {
|
|
138683
138683
|
const fileContent = await file.text();
|
|
138684
138684
|
let records = [];
|
|
138685
|
-
if (file.type
|
|
138685
|
+
if (file.type.includes("json")) {
|
|
138686
138686
|
records = JSON.parse(fileContent);
|
|
138687
138687
|
if (!Array.isArray(records)) throw new Error("JSON file must contain an array of objects.");
|
|
138688
|
-
} else
|
|
138689
|
-
const lines = fileContent.split(/\r
|
|
138690
|
-
if (lines.length < 2) throw new Error("
|
|
138691
|
-
const headers = lines[0].split("
|
|
138688
|
+
} else {
|
|
138689
|
+
const lines = fileContent.split(/\r?\n/).filter((line) => line.trim() !== "");
|
|
138690
|
+
if (lines.length < 2) throw new Error("TSV file must have a header and at least one data row.");
|
|
138691
|
+
const headers = lines[0].split(" ").map((h3) => h3.trim());
|
|
138692
138692
|
records = lines.slice(1).map((line) => {
|
|
138693
|
-
const values = line.split("
|
|
138693
|
+
const values = line.split(" ");
|
|
138694
138694
|
const record = {};
|
|
138695
138695
|
headers.forEach((header, index3) => {
|
|
138696
|
-
record[header] = values[index3];
|
|
138696
|
+
record[header] = values[index3]?.trim() || "";
|
|
138697
138697
|
});
|
|
138698
138698
|
return record;
|
|
138699
138699
|
});
|
|
@@ -138720,7 +138720,7 @@ function MetadataImportControls({ metadataName, onImport }) {
|
|
|
138720
138720
|
}
|
|
138721
138721
|
});
|
|
138722
138722
|
};
|
|
138723
|
-
return /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isOpen, onOpenChange: setIsOpen }, /* @__PURE__ */ React169__default.createElement(DialogTrigger2, { asChild: true }, /* @__PURE__ */ React169__default.createElement(Button, { size: "sm", variant: "outline" }, /* @__PURE__ */ React169__default.createElement(Upload, { className: "mr-2 h-4 w-4" }), " Import ", metadataName)), /* @__PURE__ */ React169__default.createElement(DialogContent2, null, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, "Bulk Import ", metadataName), /* @__PURE__ */ React169__default.createElement(DialogDescription2, null, "Import multiple records from a file or by pasting JSON data.")), /* @__PURE__ */ React169__default.createElement(Tabs2, { defaultValue: "file" }, /* @__PURE__ */ React169__default.createElement(TabsList2, { className: "grid w-full grid-cols-2" }, /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "file" }, /* @__PURE__ */ React169__default.createElement(FileJson, { className: "mr-2 h-4 w-4" }), " From File"), /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "text" }, /* @__PURE__ */ React169__default.createElement(ClipboardPaste, { className: "mr-2 h-4 w-4" }), " From Text")), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "file", className: "pt-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground" }, "Select a JSON or
|
|
138723
|
+
return /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isOpen, onOpenChange: setIsOpen }, /* @__PURE__ */ React169__default.createElement(DialogTrigger2, { asChild: true }, /* @__PURE__ */ React169__default.createElement(Button, { size: "sm", variant: "outline" }, /* @__PURE__ */ React169__default.createElement(Upload, { className: "mr-2 h-4 w-4" }), " Import ", metadataName)), /* @__PURE__ */ React169__default.createElement(DialogContent2, null, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, "Bulk Import ", metadataName), /* @__PURE__ */ React169__default.createElement(DialogDescription2, null, "Import multiple records from a file or by pasting JSON data.")), /* @__PURE__ */ React169__default.createElement(Tabs2, { defaultValue: "file" }, /* @__PURE__ */ React169__default.createElement(TabsList2, { className: "grid w-full grid-cols-2" }, /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "file" }, /* @__PURE__ */ React169__default.createElement(FileJson, { className: "mr-2 h-4 w-4" }), " From File"), /* @__PURE__ */ React169__default.createElement(TabsTrigger2, { value: "text" }, /* @__PURE__ */ React169__default.createElement(ClipboardPaste, { className: "mr-2 h-4 w-4" }), " From Text")), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "file", className: "pt-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React169__default.createElement("p", { className: "text-sm text-muted-foreground" }, "Select a JSON or TSV/TXT file. Ensure column names in the file match the table schema (e.g., 'code', 'name', 'subjectCode')."), /* @__PURE__ */ React169__default.createElement(Button, { variant: "outline", onClick: () => fileInputRef.current?.click(), disabled: isImporting }, isImporting ? /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ React169__default.createElement(Upload, { className: "mr-2 h-4 w-4" }), isImporting ? "Importing..." : "Select File"), /* @__PURE__ */ React169__default.createElement("input", { type: "file", ref: fileInputRef, onChange: handleFileSelected, accept: ".json,.tsv,.txt,text/tab-separated-values", className: "hidden" }))), /* @__PURE__ */ React169__default.createElement(TabsContent2, { value: "text", className: "pt-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "jsonInput" }, "JSON Data (Array of Objects)"), /* @__PURE__ */ React169__default.createElement(
|
|
138724
138724
|
Textarea,
|
|
138725
138725
|
{
|
|
138726
138726
|
id: "jsonInput",
|
package/package.json
CHANGED