@thanh01.pmt/interactive-quiz-kit 1.0.71 → 1.0.72
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 +287 -42
- package/dist/authoring.d.cts +1 -1
- package/dist/authoring.d.ts +1 -1
- package/dist/authoring.mjs +287 -42
- package/dist/react-ui.cjs +287 -42
- package/dist/react-ui.d.cts +1 -1
- package/dist/react-ui.d.ts +1 -1
- package/dist/react-ui.mjs +287 -42
- package/dist/{toaster-BWaJj0l-.d.cts → toaster-6AR8w2TO.d.cts} +3 -3
- package/dist/{toaster-BVaUJA6E.d.ts → toaster-DAXYZdrz.d.ts} +3 -3
- package/package.json +1 -1
package/dist/react-ui.cjs
CHANGED
|
@@ -139590,15 +139590,27 @@ function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onU
|
|
|
139590
139590
|
|
|
139591
139591
|
// src/react-ui/components/metadata/LearningObjectiveManager.tsx
|
|
139592
139592
|
init_react_shim();
|
|
139593
|
-
function LearningObjectiveManager({
|
|
139593
|
+
function LearningObjectiveManager({
|
|
139594
|
+
initialData,
|
|
139595
|
+
subjects: subjectsProp,
|
|
139596
|
+
isLoading: isLoadingProp,
|
|
139597
|
+
onAdd,
|
|
139598
|
+
onUpdate,
|
|
139599
|
+
onDelete,
|
|
139600
|
+
onBulkAdd
|
|
139601
|
+
}) {
|
|
139594
139602
|
const [items, setItems] = React169.useState([]);
|
|
139595
139603
|
const [subjects, setSubjects] = React169.useState([]);
|
|
139596
139604
|
const [isLoading, setIsLoading] = React169.useState(true);
|
|
139597
139605
|
const [isDialogOpen, setIsDialogOpen] = React169.useState(false);
|
|
139598
139606
|
const [isAlertOpen, setIsAlertOpen] = React169.useState(false);
|
|
139599
|
-
const [currentItem, setCurrentItem] = React169.useState(
|
|
139607
|
+
const [currentItem, setCurrentItem] = React169.useState(
|
|
139608
|
+
null
|
|
139609
|
+
);
|
|
139600
139610
|
const [formState, setFormState] = React169.useState({});
|
|
139601
|
-
const [itemToDelete, setItemToDelete] = React169.useState(
|
|
139611
|
+
const [itemToDelete, setItemToDelete] = React169.useState(
|
|
139612
|
+
null
|
|
139613
|
+
);
|
|
139602
139614
|
const [isPending, startTransition] = React169.useTransition();
|
|
139603
139615
|
const { toast: toast2 } = useToast();
|
|
139604
139616
|
const isControlled = initialData !== void 0;
|
|
@@ -139609,7 +139621,11 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
139609
139621
|
setItems(MetadataService.getLearningObjectives());
|
|
139610
139622
|
setSubjects(MetadataService.getSubjects());
|
|
139611
139623
|
} catch (error) {
|
|
139612
|
-
toast2({
|
|
139624
|
+
toast2({
|
|
139625
|
+
title: "Error",
|
|
139626
|
+
description: "Failed to refresh data.",
|
|
139627
|
+
variant: "destructive"
|
|
139628
|
+
});
|
|
139613
139629
|
} finally {
|
|
139614
139630
|
setIsLoading(false);
|
|
139615
139631
|
}
|
|
@@ -139629,7 +139645,9 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
139629
139645
|
};
|
|
139630
139646
|
const handleAddItem = () => {
|
|
139631
139647
|
setCurrentItem(null);
|
|
139632
|
-
setFormState({
|
|
139648
|
+
setFormState({
|
|
139649
|
+
subjectCode: subjects.length > 0 ? subjects[0].code : ""
|
|
139650
|
+
});
|
|
139633
139651
|
setIsDialogOpen(true);
|
|
139634
139652
|
};
|
|
139635
139653
|
const handleEditItem = (item) => {
|
|
@@ -139651,9 +139669,16 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
139651
139669
|
MetadataService.deleteLearningObjective(itemToDelete.code);
|
|
139652
139670
|
refreshData();
|
|
139653
139671
|
}
|
|
139654
|
-
toast2({
|
|
139672
|
+
toast2({
|
|
139673
|
+
title: "Success",
|
|
139674
|
+
description: `Learning Objective "${itemToDelete.name}" deleted.`
|
|
139675
|
+
});
|
|
139655
139676
|
} catch (error) {
|
|
139656
|
-
toast2({
|
|
139677
|
+
toast2({
|
|
139678
|
+
title: "Error",
|
|
139679
|
+
description: error.message,
|
|
139680
|
+
variant: "destructive"
|
|
139681
|
+
});
|
|
139657
139682
|
} finally {
|
|
139658
139683
|
setIsAlertOpen(false);
|
|
139659
139684
|
setItemToDelete(null);
|
|
@@ -139662,7 +139687,11 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
139662
139687
|
};
|
|
139663
139688
|
const handleSubmit = () => {
|
|
139664
139689
|
if (!formState.name?.trim() || !formState.code?.trim()) {
|
|
139665
|
-
toast2({
|
|
139690
|
+
toast2({
|
|
139691
|
+
title: "Validation Error",
|
|
139692
|
+
description: "Code and Name are required.",
|
|
139693
|
+
variant: "destructive"
|
|
139694
|
+
});
|
|
139666
139695
|
return;
|
|
139667
139696
|
}
|
|
139668
139697
|
startTransition(async () => {
|
|
@@ -139671,75 +139700,291 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
139671
139700
|
if (isControlled && onUpdate) {
|
|
139672
139701
|
await onUpdate({ ...currentItem, ...formState });
|
|
139673
139702
|
} else {
|
|
139674
|
-
MetadataService.updateLearningObjective(
|
|
139703
|
+
MetadataService.updateLearningObjective(
|
|
139704
|
+
currentItem.id,
|
|
139705
|
+
formState
|
|
139706
|
+
);
|
|
139675
139707
|
refreshData();
|
|
139676
139708
|
}
|
|
139677
|
-
toast2({
|
|
139709
|
+
toast2({
|
|
139710
|
+
title: "Success",
|
|
139711
|
+
description: "Learning Objective updated."
|
|
139712
|
+
});
|
|
139678
139713
|
} else {
|
|
139679
139714
|
if (isControlled && onAdd) {
|
|
139680
139715
|
await onAdd(formState);
|
|
139681
139716
|
} else {
|
|
139682
|
-
MetadataService.addLearningObjective(
|
|
139717
|
+
MetadataService.addLearningObjective(
|
|
139718
|
+
formState
|
|
139719
|
+
);
|
|
139683
139720
|
refreshData();
|
|
139684
139721
|
}
|
|
139685
|
-
toast2({
|
|
139722
|
+
toast2({
|
|
139723
|
+
title: "Success",
|
|
139724
|
+
description: "Learning Objective added."
|
|
139725
|
+
});
|
|
139686
139726
|
}
|
|
139687
139727
|
setIsDialogOpen(false);
|
|
139688
139728
|
} catch (error) {
|
|
139689
|
-
toast2({
|
|
139729
|
+
toast2({
|
|
139730
|
+
title: "Error",
|
|
139731
|
+
description: error.message,
|
|
139732
|
+
variant: "destructive"
|
|
139733
|
+
});
|
|
139690
139734
|
}
|
|
139691
139735
|
});
|
|
139692
139736
|
};
|
|
139693
139737
|
const handleImport = async (records) => {
|
|
139694
|
-
console.log(
|
|
139738
|
+
console.log(
|
|
139739
|
+
`[LO Manager] handleImport called with ${records.length} raw records.`
|
|
139740
|
+
);
|
|
139695
139741
|
if (!onBulkAdd) {
|
|
139696
139742
|
console.error("[LO Manager] onBulkAdd handler is not provided.");
|
|
139697
139743
|
return;
|
|
139698
139744
|
}
|
|
139699
139745
|
const parseStringToArray = (input) => {
|
|
139700
139746
|
if (Array.isArray(input)) return input;
|
|
139701
|
-
if (typeof input === "string")
|
|
139747
|
+
if (typeof input === "string")
|
|
139748
|
+
return input.split(",").map((s4) => s4.trim()).filter(Boolean);
|
|
139702
139749
|
return [];
|
|
139703
139750
|
};
|
|
139704
|
-
const validationResult = records.reduce(
|
|
139705
|
-
|
|
139706
|
-
|
|
139707
|
-
|
|
139708
|
-
|
|
139709
|
-
|
|
139710
|
-
|
|
139711
|
-
|
|
139712
|
-
|
|
139713
|
-
|
|
139714
|
-
|
|
139715
|
-
|
|
139716
|
-
|
|
139717
|
-
|
|
139718
|
-
|
|
139719
|
-
|
|
139720
|
-
|
|
139721
|
-
|
|
139722
|
-
|
|
139723
|
-
|
|
139724
|
-
|
|
139725
|
-
|
|
139726
|
-
|
|
139727
|
-
|
|
139751
|
+
const validationResult = records.reduce(
|
|
139752
|
+
(acc, rec) => {
|
|
139753
|
+
if (typeof rec["LO ID"] === "string" && rec["LO ID"].trim() && typeof rec["LO Description"] === "string" && rec["LO Description"].trim()) {
|
|
139754
|
+
acc.valid.push({
|
|
139755
|
+
code: rec["LO ID"],
|
|
139756
|
+
name: rec["LO ID"],
|
|
139757
|
+
description: rec["LO Description"],
|
|
139758
|
+
subject: rec["Subject"] || "",
|
|
139759
|
+
subjectCode: rec["Subject Code"] || rec["Subject"],
|
|
139760
|
+
category: rec["Category"] || "",
|
|
139761
|
+
categoryCode: rec["Category Code"] || rec["Category"],
|
|
139762
|
+
topic: rec["Topic"] || "",
|
|
139763
|
+
topicCode: rec["Topic Code"] || rec["Topic"],
|
|
139764
|
+
grade: rec["Grade"] || "",
|
|
139765
|
+
gradeCode: rec["Grade Code"] || rec["Grade"],
|
|
139766
|
+
keywords: parseStringToArray(rec["Keywords"]),
|
|
139767
|
+
stemElements: parseStringToArray(
|
|
139768
|
+
rec["STEM Element(s)"]
|
|
139769
|
+
),
|
|
139770
|
+
bloomLevelsGuideline: parseStringToArray(
|
|
139771
|
+
rec["Bloom\u2019s Level(s) Guideline"]
|
|
139772
|
+
)
|
|
139773
|
+
});
|
|
139774
|
+
} else {
|
|
139775
|
+
acc.invalidCount++;
|
|
139776
|
+
}
|
|
139777
|
+
return acc;
|
|
139778
|
+
},
|
|
139779
|
+
{ valid: [], invalidCount: 0 }
|
|
139780
|
+
);
|
|
139781
|
+
console.log(
|
|
139782
|
+
`[LO Manager] Validation complete. ${validationResult.valid.length} valid records found.`
|
|
139783
|
+
);
|
|
139728
139784
|
if (validationResult.invalidCount > 0) {
|
|
139729
139785
|
toast2({
|
|
139730
139786
|
title: "Import Warning",
|
|
139731
|
-
description: `${validationResult.invalidCount} records had invalid or missing '
|
|
139787
|
+
description: `${validationResult.invalidCount} records had invalid or missing 'LO ID' or 'LO Description' fields and were ignored.`,
|
|
139732
139788
|
variant: "destructive"
|
|
139733
139789
|
});
|
|
139734
139790
|
}
|
|
139735
139791
|
if (validationResult.valid.length > 0) {
|
|
139736
|
-
console.log(
|
|
139792
|
+
console.log(
|
|
139793
|
+
"[LO Manager] Calling onBulkAdd prop with validated data..."
|
|
139794
|
+
);
|
|
139737
139795
|
await onBulkAdd(validationResult.valid);
|
|
139738
139796
|
} else {
|
|
139739
139797
|
console.log("[LO Manager] No valid records to import.");
|
|
139740
139798
|
}
|
|
139741
139799
|
};
|
|
139742
|
-
return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Learning Objectives"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__namespace.default.createElement(MetadataImportControls, { metadataName: "Learning Objectives", onImport: handleImport }), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective")))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.subject || item.subjectCode), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.topic || item.topicCode), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__namespace.default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "code" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "code", value: formState.code || "", onChange: (e3) => handleFormChange("code", e3.target.value.toUpperCase()), disabled: !!currentItem })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "name" }, "Name (Description)"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "name", value: formState.name || "", onChange: (e3) => handleFormChange("name", e3.target.value) }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subject" }, "Subject Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "subject", value: formState.subject || "", onChange: (e3) => handleFormChange("subject", e3.target.value) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React169__namespace.default.createElement(EditableCombobox, { options: subjects.map((s4) => ({ value: s4.code, label: s4.name })), value: formState.subjectCode || "", onChange: (val) => handleFormChange("subjectCode", val), placeholder: "Select a subject..." }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "category" }, "Category Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "category", value: formState.category || "", onChange: (e3) => handleFormChange("category", e3.target.value) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "categoryCode" }, "Category Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "categoryCode", value: formState.categoryCode || "", onChange: (e3) => handleFormChange("categoryCode", e3.target.value) }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "topic" }, "Topic Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "topic", value: formState.topic || "", onChange: (e3) => handleFormChange("topic", e3.target.value) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "topicCode" }, "Topic Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "topicCode", value: formState.topicCode || "", onChange: (e3) => handleFormChange("topicCode", e3.target.value) }))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "grade" }, "Grade Name"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "grade", value: formState.grade || "", onChange: (e3) => handleFormChange("grade", e3.target.value) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "gradeCode" }, "Grade Code"), /* @__PURE__ */ React169__namespace.default.createElement(Input, { id: "gradeCode", value: formState.gradeCode || "", onChange: (e3) => handleFormChange("gradeCode", e3.target.value) }))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "keywords" }, "Keywords (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "keywords", value: formState.keywords?.join(", ") || "", onChange: (e3) => handleFormChange("keywords", e3.target.value.split(",").map((s4) => s4.trim())) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "stemElements" }, "STEM Elements (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "stemElements", value: formState.stemElements?.join(", ") || "", onChange: (e3) => handleFormChange("stemElements", e3.target.value.split(",").map((s4) => s4.trim())) })), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "bloomLevelsGuideline" }, "Bloom's Guideline (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(Textarea, { id: "bloomLevelsGuideline", value: formState.bloomLevelsGuideline?.join(", ") || "", onChange: (e3) => handleFormChange("bloomLevelsGuideline", e3.target.value.split(",").map((s4) => s4.trim())) }))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !formState.name?.trim() || !formState.code?.trim() }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
139800
|
+
return /* @__PURE__ */ React169__namespace.default.createElement(Card, null, /* @__PURE__ */ React169__namespace.default.createElement(CardHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__namespace.default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__namespace.default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " ", "Manage Learning Objectives"), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139801
|
+
MetadataImportControls,
|
|
139802
|
+
{
|
|
139803
|
+
metadataName: "Learning Objectives",
|
|
139804
|
+
onImport: handleImport
|
|
139805
|
+
}
|
|
139806
|
+
), /* @__PURE__ */ React169__namespace.default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__namespace.default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective")))), /* @__PURE__ */ React169__namespace.default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__namespace.default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(Table3, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(TableRow, null, /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React169__namespace.default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__namespace.default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__namespace.default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.subject || item.subjectCode), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, null, item.topic || item.topicCode), /* @__PURE__ */ React169__namespace.default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139807
|
+
Button,
|
|
139808
|
+
{
|
|
139809
|
+
variant: "ghost",
|
|
139810
|
+
size: "icon",
|
|
139811
|
+
onClick: () => handleEditItem(item),
|
|
139812
|
+
className: "mr-2"
|
|
139813
|
+
},
|
|
139814
|
+
/* @__PURE__ */ React169__namespace.default.createElement(PenLine, { className: "h-4 w-4" })
|
|
139815
|
+
), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139816
|
+
Button,
|
|
139817
|
+
{
|
|
139818
|
+
variant: "ghost",
|
|
139819
|
+
size: "icon",
|
|
139820
|
+
onClick: () => handleDeleteItem(item),
|
|
139821
|
+
className: "text-destructive hover:text-destructive"
|
|
139822
|
+
},
|
|
139823
|
+
/* @__PURE__ */ React169__namespace.default.createElement(Trash2, { className: "h-4 w-4" })
|
|
139824
|
+
))))))), /* @__PURE__ */ React169__namespace.default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__namespace.default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__namespace.default.createElement(DialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "code" }, "Code"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139825
|
+
Input,
|
|
139826
|
+
{
|
|
139827
|
+
id: "code",
|
|
139828
|
+
value: formState.code || "",
|
|
139829
|
+
onChange: (e3) => handleFormChange(
|
|
139830
|
+
"code",
|
|
139831
|
+
e3.target.value.toUpperCase()
|
|
139832
|
+
),
|
|
139833
|
+
disabled: !!currentItem
|
|
139834
|
+
}
|
|
139835
|
+
)), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "name" }, "Name (Description)"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139836
|
+
Input,
|
|
139837
|
+
{
|
|
139838
|
+
id: "name",
|
|
139839
|
+
value: formState.name || "",
|
|
139840
|
+
onChange: (e3) => handleFormChange(
|
|
139841
|
+
"name",
|
|
139842
|
+
e3.target.value
|
|
139843
|
+
)
|
|
139844
|
+
}
|
|
139845
|
+
))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subject" }, "Subject Name"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139846
|
+
Input,
|
|
139847
|
+
{
|
|
139848
|
+
id: "subject",
|
|
139849
|
+
value: formState.subject || "",
|
|
139850
|
+
onChange: (e3) => handleFormChange(
|
|
139851
|
+
"subject",
|
|
139852
|
+
e3.target.value
|
|
139853
|
+
)
|
|
139854
|
+
}
|
|
139855
|
+
)), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139856
|
+
EditableCombobox,
|
|
139857
|
+
{
|
|
139858
|
+
options: subjects.map((s4) => ({
|
|
139859
|
+
value: s4.code,
|
|
139860
|
+
label: s4.name
|
|
139861
|
+
})),
|
|
139862
|
+
value: formState.subjectCode || "",
|
|
139863
|
+
onChange: (val) => handleFormChange("subjectCode", val),
|
|
139864
|
+
placeholder: "Select a subject..."
|
|
139865
|
+
}
|
|
139866
|
+
))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "category" }, "Category Name"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139867
|
+
Input,
|
|
139868
|
+
{
|
|
139869
|
+
id: "category",
|
|
139870
|
+
value: formState.category || "",
|
|
139871
|
+
onChange: (e3) => handleFormChange(
|
|
139872
|
+
"category",
|
|
139873
|
+
e3.target.value
|
|
139874
|
+
)
|
|
139875
|
+
}
|
|
139876
|
+
)), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "categoryCode" }, "Category Code"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139877
|
+
Input,
|
|
139878
|
+
{
|
|
139879
|
+
id: "categoryCode",
|
|
139880
|
+
value: formState.categoryCode || "",
|
|
139881
|
+
onChange: (e3) => handleFormChange(
|
|
139882
|
+
"categoryCode",
|
|
139883
|
+
e3.target.value
|
|
139884
|
+
)
|
|
139885
|
+
}
|
|
139886
|
+
))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "topic" }, "Topic Name"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139887
|
+
Input,
|
|
139888
|
+
{
|
|
139889
|
+
id: "topic",
|
|
139890
|
+
value: formState.topic || "",
|
|
139891
|
+
onChange: (e3) => handleFormChange(
|
|
139892
|
+
"topic",
|
|
139893
|
+
e3.target.value
|
|
139894
|
+
)
|
|
139895
|
+
}
|
|
139896
|
+
)), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "topicCode" }, "Topic Code"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139897
|
+
Input,
|
|
139898
|
+
{
|
|
139899
|
+
id: "topicCode",
|
|
139900
|
+
value: formState.topicCode || "",
|
|
139901
|
+
onChange: (e3) => handleFormChange(
|
|
139902
|
+
"topicCode",
|
|
139903
|
+
e3.target.value
|
|
139904
|
+
)
|
|
139905
|
+
}
|
|
139906
|
+
))), /* @__PURE__ */ React169__namespace.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "grade" }, "Grade Name"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139907
|
+
Input,
|
|
139908
|
+
{
|
|
139909
|
+
id: "grade",
|
|
139910
|
+
value: formState.grade || "",
|
|
139911
|
+
onChange: (e3) => handleFormChange(
|
|
139912
|
+
"grade",
|
|
139913
|
+
e3.target.value
|
|
139914
|
+
)
|
|
139915
|
+
}
|
|
139916
|
+
)), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "gradeCode" }, "Grade Code"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139917
|
+
Input,
|
|
139918
|
+
{
|
|
139919
|
+
id: "gradeCode",
|
|
139920
|
+
value: formState.gradeCode || "",
|
|
139921
|
+
onChange: (e3) => handleFormChange(
|
|
139922
|
+
"gradeCode",
|
|
139923
|
+
e3.target.value
|
|
139924
|
+
)
|
|
139925
|
+
}
|
|
139926
|
+
))), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "keywords" }, "Keywords (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139927
|
+
Textarea,
|
|
139928
|
+
{
|
|
139929
|
+
id: "keywords",
|
|
139930
|
+
value: formState.keywords?.join(", ") || "",
|
|
139931
|
+
onChange: (e3) => handleFormChange(
|
|
139932
|
+
"keywords",
|
|
139933
|
+
e3.target.value.split(",").map((s4) => s4.trim())
|
|
139934
|
+
)
|
|
139935
|
+
}
|
|
139936
|
+
)), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "stemElements" }, "STEM Elements (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139937
|
+
Textarea,
|
|
139938
|
+
{
|
|
139939
|
+
id: "stemElements",
|
|
139940
|
+
value: formState.stemElements?.join(", ") || "",
|
|
139941
|
+
onChange: (e3) => handleFormChange(
|
|
139942
|
+
"stemElements",
|
|
139943
|
+
e3.target.value.split(",").map((s4) => s4.trim())
|
|
139944
|
+
)
|
|
139945
|
+
}
|
|
139946
|
+
)), /* @__PURE__ */ React169__namespace.default.createElement("div", null, /* @__PURE__ */ React169__namespace.default.createElement(Label2, { htmlFor: "bloomLevelsGuideline" }, "Bloom's Guideline (comma-separated)"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139947
|
+
Textarea,
|
|
139948
|
+
{
|
|
139949
|
+
id: "bloomLevelsGuideline",
|
|
139950
|
+
value: formState.bloomLevelsGuideline?.join(
|
|
139951
|
+
", "
|
|
139952
|
+
) || "",
|
|
139953
|
+
onChange: (e3) => handleFormChange(
|
|
139954
|
+
"bloomLevelsGuideline",
|
|
139955
|
+
e3.target.value.split(",").map((s4) => s4.trim())
|
|
139956
|
+
)
|
|
139957
|
+
}
|
|
139958
|
+
))), /* @__PURE__ */ React169__namespace.default.createElement(DialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139959
|
+
Button,
|
|
139960
|
+
{
|
|
139961
|
+
type: "button",
|
|
139962
|
+
variant: "outline",
|
|
139963
|
+
onClick: () => setIsDialogOpen(false),
|
|
139964
|
+
disabled: isPending
|
|
139965
|
+
},
|
|
139966
|
+
"Cancel"
|
|
139967
|
+
), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139968
|
+
Button,
|
|
139969
|
+
{
|
|
139970
|
+
type: "submit",
|
|
139971
|
+
onClick: handleSubmit,
|
|
139972
|
+
disabled: isPending || !formState.name?.trim() || !formState.code?.trim()
|
|
139973
|
+
},
|
|
139974
|
+
isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
139975
|
+
" ",
|
|
139976
|
+
"Save"
|
|
139977
|
+
)))), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__namespace.default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__namespace.default.createElement(
|
|
139978
|
+
AlertDialogAction2,
|
|
139979
|
+
{
|
|
139980
|
+
onClick: confirmDelete,
|
|
139981
|
+
disabled: isPending,
|
|
139982
|
+
className: "bg-destructive hover:bg-destructive/90"
|
|
139983
|
+
},
|
|
139984
|
+
isPending && /* @__PURE__ */ React169__namespace.default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
139985
|
+
" ",
|
|
139986
|
+
"Delete"
|
|
139987
|
+
))))));
|
|
139743
139988
|
}
|
|
139744
139989
|
|
|
139745
139990
|
// src/react-ui/components/metadata/ContextManager.tsx
|
package/dist/react-ui.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ import { Q as QuizResultType, U as UserAnswerType, n as PracticeSession, o as Pr
|
|
|
5
5
|
export { j as AchievementDefinition, r as ActivityCalendarData, u as AnalysisReport, A as AnswerDetail, x as ChatContext, C as ChatMessage, v as DashboardCardConfig, D as DashboardCardId, w as DashboardLayout, y as Goal, G as GoalType, t as ImageContextItem, I as ImportError, K as KnowledgeCard, L as LearningAnalysis, e as PerformanceByBloomLevel, b as PerformanceByCategory, d as PerformanceByDifficulty, P as PerformanceByLearningObjective, c as PerformanceByTopic, f as PerformanceMetric, s as PerformanceSummary, k as PracticeDifficulty, q as PracticeTopicSummary, g as QuestionReview, R as RoadmapItem, T as TestCaseResult, a as UserAnswers, W as WeeklyRoadmap } from './ai-ecosystem-DyQYZbyX.cjs';
|
|
6
6
|
import * as React$1 from 'react';
|
|
7
7
|
import React__default, { ReactNode } from 'react';
|
|
8
|
-
export { c as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, e as APIKeyManagerModal, f as ApiKeySettings, m as ApproachManager, B as BloomLevelManager, C as CategoryManager, l as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, n as MetadataImportControls, M as MetadataTabs, h as QuestionFilters, i as QuestionFormDialog, g as QuestionList, a as QuestionPreviewModal, k as QuestionTypeManager, Q as QuizAuthoringTool, b as QuizSettingsForm, d as SCORMExportModal, S as SelectedQuestionsPanel, j as SubjectManager, o as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-
|
|
8
|
+
export { c as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, e as APIKeyManagerModal, f as ApiKeySettings, m as ApproachManager, B as BloomLevelManager, C as CategoryManager, l as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, n as MetadataImportControls, M as MetadataTabs, h as QuestionFilters, i as QuestionFormDialog, g as QuestionList, a as QuestionPreviewModal, k as QuestionTypeManager, Q as QuizAuthoringTool, b as QuizSettingsForm, d as SCORMExportModal, S as SelectedQuestionsPanel, j as SubjectManager, o as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-6AR8w2TO.cjs';
|
|
9
9
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
10
10
|
import { VariantProps } from 'class-variance-authority';
|
|
11
11
|
import * as LabelPrimitive from '@radix-ui/react-label';
|
package/dist/react-ui.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Q as QuizResultType, U as UserAnswerType, n as PracticeSession, o as Pr
|
|
|
5
5
|
export { j as AchievementDefinition, r as ActivityCalendarData, u as AnalysisReport, A as AnswerDetail, x as ChatContext, C as ChatMessage, v as DashboardCardConfig, D as DashboardCardId, w as DashboardLayout, y as Goal, G as GoalType, t as ImageContextItem, I as ImportError, K as KnowledgeCard, L as LearningAnalysis, e as PerformanceByBloomLevel, b as PerformanceByCategory, d as PerformanceByDifficulty, P as PerformanceByLearningObjective, c as PerformanceByTopic, f as PerformanceMetric, s as PerformanceSummary, k as PracticeDifficulty, q as PracticeTopicSummary, g as QuestionReview, R as RoadmapItem, T as TestCaseResult, a as UserAnswers, W as WeeklyRoadmap } from './ai-ecosystem-Qa_SdE2T.js';
|
|
6
6
|
import * as React$1 from 'react';
|
|
7
7
|
import React__default, { ReactNode } from 'react';
|
|
8
|
-
export { c as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, e as APIKeyManagerModal, f as ApiKeySettings, m as ApproachManager, B as BloomLevelManager, C as CategoryManager, l as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, n as MetadataImportControls, M as MetadataTabs, h as QuestionFilters, i as QuestionFormDialog, g as QuestionList, a as QuestionPreviewModal, k as QuestionTypeManager, Q as QuizAuthoringTool, b as QuizSettingsForm, d as SCORMExportModal, S as SelectedQuestionsPanel, j as SubjectManager, o as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-
|
|
8
|
+
export { c as AIFullQuizGeneratorModal, A as AIQuestionGeneratorModal, e as APIKeyManagerModal, f as ApiKeySettings, m as ApproachManager, B as BloomLevelManager, C as CategoryManager, l as ContextManager, E as EditQuestionModal, G as GradeLevelManager, I as ImportQuestionsModal, L as LearningObjectiveManager, n as MetadataImportControls, M as MetadataTabs, h as QuestionFilters, i as QuestionFormDialog, g as QuestionList, a as QuestionPreviewModal, k as QuestionTypeManager, Q as QuizAuthoringTool, b as QuizSettingsForm, d as SCORMExportModal, S as SelectedQuestionsPanel, j as SubjectManager, o as Toaster, T as TopicManager, t as toast, u as useToast } from './toaster-DAXYZdrz.js';
|
|
9
9
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
10
10
|
import { VariantProps } from 'class-variance-authority';
|
|
11
11
|
import * as LabelPrimitive from '@radix-ui/react-label';
|