@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.mjs
CHANGED
|
@@ -139524,15 +139524,27 @@ function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onU
|
|
|
139524
139524
|
|
|
139525
139525
|
// src/react-ui/components/metadata/LearningObjectiveManager.tsx
|
|
139526
139526
|
init_react_shim();
|
|
139527
|
-
function LearningObjectiveManager({
|
|
139527
|
+
function LearningObjectiveManager({
|
|
139528
|
+
initialData,
|
|
139529
|
+
subjects: subjectsProp,
|
|
139530
|
+
isLoading: isLoadingProp,
|
|
139531
|
+
onAdd,
|
|
139532
|
+
onUpdate,
|
|
139533
|
+
onDelete,
|
|
139534
|
+
onBulkAdd
|
|
139535
|
+
}) {
|
|
139528
139536
|
const [items, setItems] = useState([]);
|
|
139529
139537
|
const [subjects, setSubjects] = useState([]);
|
|
139530
139538
|
const [isLoading, setIsLoading] = useState(true);
|
|
139531
139539
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
139532
139540
|
const [isAlertOpen, setIsAlertOpen] = useState(false);
|
|
139533
|
-
const [currentItem, setCurrentItem] = useState(
|
|
139541
|
+
const [currentItem, setCurrentItem] = useState(
|
|
139542
|
+
null
|
|
139543
|
+
);
|
|
139534
139544
|
const [formState, setFormState] = useState({});
|
|
139535
|
-
const [itemToDelete, setItemToDelete] = useState(
|
|
139545
|
+
const [itemToDelete, setItemToDelete] = useState(
|
|
139546
|
+
null
|
|
139547
|
+
);
|
|
139536
139548
|
const [isPending, startTransition] = useTransition();
|
|
139537
139549
|
const { toast: toast2 } = useToast();
|
|
139538
139550
|
const isControlled = initialData !== void 0;
|
|
@@ -139543,7 +139555,11 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
139543
139555
|
setItems(MetadataService.getLearningObjectives());
|
|
139544
139556
|
setSubjects(MetadataService.getSubjects());
|
|
139545
139557
|
} catch (error) {
|
|
139546
|
-
toast2({
|
|
139558
|
+
toast2({
|
|
139559
|
+
title: "Error",
|
|
139560
|
+
description: "Failed to refresh data.",
|
|
139561
|
+
variant: "destructive"
|
|
139562
|
+
});
|
|
139547
139563
|
} finally {
|
|
139548
139564
|
setIsLoading(false);
|
|
139549
139565
|
}
|
|
@@ -139563,7 +139579,9 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
139563
139579
|
};
|
|
139564
139580
|
const handleAddItem = () => {
|
|
139565
139581
|
setCurrentItem(null);
|
|
139566
|
-
setFormState({
|
|
139582
|
+
setFormState({
|
|
139583
|
+
subjectCode: subjects.length > 0 ? subjects[0].code : ""
|
|
139584
|
+
});
|
|
139567
139585
|
setIsDialogOpen(true);
|
|
139568
139586
|
};
|
|
139569
139587
|
const handleEditItem = (item) => {
|
|
@@ -139585,9 +139603,16 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
139585
139603
|
MetadataService.deleteLearningObjective(itemToDelete.code);
|
|
139586
139604
|
refreshData();
|
|
139587
139605
|
}
|
|
139588
|
-
toast2({
|
|
139606
|
+
toast2({
|
|
139607
|
+
title: "Success",
|
|
139608
|
+
description: `Learning Objective "${itemToDelete.name}" deleted.`
|
|
139609
|
+
});
|
|
139589
139610
|
} catch (error) {
|
|
139590
|
-
toast2({
|
|
139611
|
+
toast2({
|
|
139612
|
+
title: "Error",
|
|
139613
|
+
description: error.message,
|
|
139614
|
+
variant: "destructive"
|
|
139615
|
+
});
|
|
139591
139616
|
} finally {
|
|
139592
139617
|
setIsAlertOpen(false);
|
|
139593
139618
|
setItemToDelete(null);
|
|
@@ -139596,7 +139621,11 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
139596
139621
|
};
|
|
139597
139622
|
const handleSubmit = () => {
|
|
139598
139623
|
if (!formState.name?.trim() || !formState.code?.trim()) {
|
|
139599
|
-
toast2({
|
|
139624
|
+
toast2({
|
|
139625
|
+
title: "Validation Error",
|
|
139626
|
+
description: "Code and Name are required.",
|
|
139627
|
+
variant: "destructive"
|
|
139628
|
+
});
|
|
139600
139629
|
return;
|
|
139601
139630
|
}
|
|
139602
139631
|
startTransition(async () => {
|
|
@@ -139605,75 +139634,291 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
139605
139634
|
if (isControlled && onUpdate) {
|
|
139606
139635
|
await onUpdate({ ...currentItem, ...formState });
|
|
139607
139636
|
} else {
|
|
139608
|
-
MetadataService.updateLearningObjective(
|
|
139637
|
+
MetadataService.updateLearningObjective(
|
|
139638
|
+
currentItem.id,
|
|
139639
|
+
formState
|
|
139640
|
+
);
|
|
139609
139641
|
refreshData();
|
|
139610
139642
|
}
|
|
139611
|
-
toast2({
|
|
139643
|
+
toast2({
|
|
139644
|
+
title: "Success",
|
|
139645
|
+
description: "Learning Objective updated."
|
|
139646
|
+
});
|
|
139612
139647
|
} else {
|
|
139613
139648
|
if (isControlled && onAdd) {
|
|
139614
139649
|
await onAdd(formState);
|
|
139615
139650
|
} else {
|
|
139616
|
-
MetadataService.addLearningObjective(
|
|
139651
|
+
MetadataService.addLearningObjective(
|
|
139652
|
+
formState
|
|
139653
|
+
);
|
|
139617
139654
|
refreshData();
|
|
139618
139655
|
}
|
|
139619
|
-
toast2({
|
|
139656
|
+
toast2({
|
|
139657
|
+
title: "Success",
|
|
139658
|
+
description: "Learning Objective added."
|
|
139659
|
+
});
|
|
139620
139660
|
}
|
|
139621
139661
|
setIsDialogOpen(false);
|
|
139622
139662
|
} catch (error) {
|
|
139623
|
-
toast2({
|
|
139663
|
+
toast2({
|
|
139664
|
+
title: "Error",
|
|
139665
|
+
description: error.message,
|
|
139666
|
+
variant: "destructive"
|
|
139667
|
+
});
|
|
139624
139668
|
}
|
|
139625
139669
|
});
|
|
139626
139670
|
};
|
|
139627
139671
|
const handleImport = async (records) => {
|
|
139628
|
-
console.log(
|
|
139672
|
+
console.log(
|
|
139673
|
+
`[LO Manager] handleImport called with ${records.length} raw records.`
|
|
139674
|
+
);
|
|
139629
139675
|
if (!onBulkAdd) {
|
|
139630
139676
|
console.error("[LO Manager] onBulkAdd handler is not provided.");
|
|
139631
139677
|
return;
|
|
139632
139678
|
}
|
|
139633
139679
|
const parseStringToArray = (input) => {
|
|
139634
139680
|
if (Array.isArray(input)) return input;
|
|
139635
|
-
if (typeof input === "string")
|
|
139681
|
+
if (typeof input === "string")
|
|
139682
|
+
return input.split(",").map((s4) => s4.trim()).filter(Boolean);
|
|
139636
139683
|
return [];
|
|
139637
139684
|
};
|
|
139638
|
-
const validationResult = records.reduce(
|
|
139639
|
-
|
|
139640
|
-
|
|
139641
|
-
|
|
139642
|
-
|
|
139643
|
-
|
|
139644
|
-
|
|
139645
|
-
|
|
139646
|
-
|
|
139647
|
-
|
|
139648
|
-
|
|
139649
|
-
|
|
139650
|
-
|
|
139651
|
-
|
|
139652
|
-
|
|
139653
|
-
|
|
139654
|
-
|
|
139655
|
-
|
|
139656
|
-
|
|
139657
|
-
|
|
139658
|
-
|
|
139659
|
-
|
|
139660
|
-
|
|
139661
|
-
|
|
139685
|
+
const validationResult = records.reduce(
|
|
139686
|
+
(acc, rec) => {
|
|
139687
|
+
if (typeof rec["LO ID"] === "string" && rec["LO ID"].trim() && typeof rec["LO Description"] === "string" && rec["LO Description"].trim()) {
|
|
139688
|
+
acc.valid.push({
|
|
139689
|
+
code: rec["LO ID"],
|
|
139690
|
+
name: rec["LO ID"],
|
|
139691
|
+
description: rec["LO Description"],
|
|
139692
|
+
subject: rec["Subject"] || "",
|
|
139693
|
+
subjectCode: rec["Subject Code"] || rec["Subject"],
|
|
139694
|
+
category: rec["Category"] || "",
|
|
139695
|
+
categoryCode: rec["Category Code"] || rec["Category"],
|
|
139696
|
+
topic: rec["Topic"] || "",
|
|
139697
|
+
topicCode: rec["Topic Code"] || rec["Topic"],
|
|
139698
|
+
grade: rec["Grade"] || "",
|
|
139699
|
+
gradeCode: rec["Grade Code"] || rec["Grade"],
|
|
139700
|
+
keywords: parseStringToArray(rec["Keywords"]),
|
|
139701
|
+
stemElements: parseStringToArray(
|
|
139702
|
+
rec["STEM Element(s)"]
|
|
139703
|
+
),
|
|
139704
|
+
bloomLevelsGuideline: parseStringToArray(
|
|
139705
|
+
rec["Bloom\u2019s Level(s) Guideline"]
|
|
139706
|
+
)
|
|
139707
|
+
});
|
|
139708
|
+
} else {
|
|
139709
|
+
acc.invalidCount++;
|
|
139710
|
+
}
|
|
139711
|
+
return acc;
|
|
139712
|
+
},
|
|
139713
|
+
{ valid: [], invalidCount: 0 }
|
|
139714
|
+
);
|
|
139715
|
+
console.log(
|
|
139716
|
+
`[LO Manager] Validation complete. ${validationResult.valid.length} valid records found.`
|
|
139717
|
+
);
|
|
139662
139718
|
if (validationResult.invalidCount > 0) {
|
|
139663
139719
|
toast2({
|
|
139664
139720
|
title: "Import Warning",
|
|
139665
|
-
description: `${validationResult.invalidCount} records had invalid or missing '
|
|
139721
|
+
description: `${validationResult.invalidCount} records had invalid or missing 'LO ID' or 'LO Description' fields and were ignored.`,
|
|
139666
139722
|
variant: "destructive"
|
|
139667
139723
|
});
|
|
139668
139724
|
}
|
|
139669
139725
|
if (validationResult.valid.length > 0) {
|
|
139670
|
-
console.log(
|
|
139726
|
+
console.log(
|
|
139727
|
+
"[LO Manager] Calling onBulkAdd prop with validated data..."
|
|
139728
|
+
);
|
|
139671
139729
|
await onBulkAdd(validationResult.valid);
|
|
139672
139730
|
} else {
|
|
139673
139731
|
console.log("[LO Manager] No valid records to import.");
|
|
139674
139732
|
}
|
|
139675
139733
|
};
|
|
139676
|
-
return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Learning Objectives"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__default.createElement(MetadataImportControls, { metadataName: "Learning Objectives", onImport: handleImport }), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective")))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.subject || item.subjectCode), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.topic || item.topicCode), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React169__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "code" }, "Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "code", value: formState.code || "", onChange: (e3) => handleFormChange("code", e3.target.value.toUpperCase()), disabled: !!currentItem })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "name" }, "Name (Description)"), /* @__PURE__ */ React169__default.createElement(Input, { id: "name", value: formState.name || "", onChange: (e3) => handleFormChange("name", e3.target.value) }))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subject" }, "Subject Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "subject", value: formState.subject || "", onChange: (e3) => handleFormChange("subject", e3.target.value) })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React169__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__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "category" }, "Category Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "category", value: formState.category || "", onChange: (e3) => handleFormChange("category", e3.target.value) })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "categoryCode" }, "Category Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "categoryCode", value: formState.categoryCode || "", onChange: (e3) => handleFormChange("categoryCode", e3.target.value) }))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "topic" }, "Topic Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "topic", value: formState.topic || "", onChange: (e3) => handleFormChange("topic", e3.target.value) })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "topicCode" }, "Topic Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "topicCode", value: formState.topicCode || "", onChange: (e3) => handleFormChange("topicCode", e3.target.value) }))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "grade" }, "Grade Name"), /* @__PURE__ */ React169__default.createElement(Input, { id: "grade", value: formState.grade || "", onChange: (e3) => handleFormChange("grade", e3.target.value) })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "gradeCode" }, "Grade Code"), /* @__PURE__ */ React169__default.createElement(Input, { id: "gradeCode", value: formState.gradeCode || "", onChange: (e3) => handleFormChange("gradeCode", e3.target.value) }))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "keywords" }, "Keywords (comma-separated)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "keywords", value: formState.keywords?.join(", ") || "", onChange: (e3) => handleFormChange("keywords", e3.target.value.split(",").map((s4) => s4.trim())) })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "stemElements" }, "STEM Elements (comma-separated)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "stemElements", value: formState.stemElements?.join(", ") || "", onChange: (e3) => handleFormChange("stemElements", e3.target.value.split(",").map((s4) => s4.trim())) })), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "bloomLevelsGuideline" }, "Bloom's Guideline (comma-separated)"), /* @__PURE__ */ React169__default.createElement(Textarea, { id: "bloomLevelsGuideline", value: formState.bloomLevelsGuideline?.join(", ") || "", onChange: (e3) => handleFormChange("bloomLevelsGuideline", e3.target.value.split(",").map((s4) => s4.trim())) }))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !formState.name?.trim() || !formState.code?.trim() }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
139734
|
+
return /* @__PURE__ */ React169__default.createElement(Card, null, /* @__PURE__ */ React169__default.createElement(CardHeader, null, /* @__PURE__ */ React169__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React169__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React169__default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " ", "Manage Learning Objectives"), /* @__PURE__ */ React169__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React169__default.createElement(
|
|
139735
|
+
MetadataImportControls,
|
|
139736
|
+
{
|
|
139737
|
+
metadataName: "Learning Objectives",
|
|
139738
|
+
onImport: handleImport
|
|
139739
|
+
}
|
|
139740
|
+
), /* @__PURE__ */ React169__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React169__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective")))), /* @__PURE__ */ React169__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React169__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React169__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React169__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React169__default.createElement(Table3, null, /* @__PURE__ */ React169__default.createElement(TableHeader, null, /* @__PURE__ */ React169__default.createElement(TableRow, null, /* @__PURE__ */ React169__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React169__default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React169__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React169__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React169__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.subject || item.subjectCode), /* @__PURE__ */ React169__default.createElement(TableCell, null, item.topic || item.topicCode), /* @__PURE__ */ React169__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React169__default.createElement(
|
|
139741
|
+
Button,
|
|
139742
|
+
{
|
|
139743
|
+
variant: "ghost",
|
|
139744
|
+
size: "icon",
|
|
139745
|
+
onClick: () => handleEditItem(item),
|
|
139746
|
+
className: "mr-2"
|
|
139747
|
+
},
|
|
139748
|
+
/* @__PURE__ */ React169__default.createElement(PenLine, { className: "h-4 w-4" })
|
|
139749
|
+
), /* @__PURE__ */ React169__default.createElement(
|
|
139750
|
+
Button,
|
|
139751
|
+
{
|
|
139752
|
+
variant: "ghost",
|
|
139753
|
+
size: "icon",
|
|
139754
|
+
onClick: () => handleDeleteItem(item),
|
|
139755
|
+
className: "text-destructive hover:text-destructive"
|
|
139756
|
+
},
|
|
139757
|
+
/* @__PURE__ */ React169__default.createElement(Trash2, { className: "h-4 w-4" })
|
|
139758
|
+
))))))), /* @__PURE__ */ React169__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React169__default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React169__default.createElement(DialogHeader, null, /* @__PURE__ */ React169__default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React169__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "code" }, "Code"), /* @__PURE__ */ React169__default.createElement(
|
|
139759
|
+
Input,
|
|
139760
|
+
{
|
|
139761
|
+
id: "code",
|
|
139762
|
+
value: formState.code || "",
|
|
139763
|
+
onChange: (e3) => handleFormChange(
|
|
139764
|
+
"code",
|
|
139765
|
+
e3.target.value.toUpperCase()
|
|
139766
|
+
),
|
|
139767
|
+
disabled: !!currentItem
|
|
139768
|
+
}
|
|
139769
|
+
)), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "name" }, "Name (Description)"), /* @__PURE__ */ React169__default.createElement(
|
|
139770
|
+
Input,
|
|
139771
|
+
{
|
|
139772
|
+
id: "name",
|
|
139773
|
+
value: formState.name || "",
|
|
139774
|
+
onChange: (e3) => handleFormChange(
|
|
139775
|
+
"name",
|
|
139776
|
+
e3.target.value
|
|
139777
|
+
)
|
|
139778
|
+
}
|
|
139779
|
+
))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subject" }, "Subject Name"), /* @__PURE__ */ React169__default.createElement(
|
|
139780
|
+
Input,
|
|
139781
|
+
{
|
|
139782
|
+
id: "subject",
|
|
139783
|
+
value: formState.subject || "",
|
|
139784
|
+
onChange: (e3) => handleFormChange(
|
|
139785
|
+
"subject",
|
|
139786
|
+
e3.target.value
|
|
139787
|
+
)
|
|
139788
|
+
}
|
|
139789
|
+
)), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React169__default.createElement(
|
|
139790
|
+
EditableCombobox,
|
|
139791
|
+
{
|
|
139792
|
+
options: subjects.map((s4) => ({
|
|
139793
|
+
value: s4.code,
|
|
139794
|
+
label: s4.name
|
|
139795
|
+
})),
|
|
139796
|
+
value: formState.subjectCode || "",
|
|
139797
|
+
onChange: (val) => handleFormChange("subjectCode", val),
|
|
139798
|
+
placeholder: "Select a subject..."
|
|
139799
|
+
}
|
|
139800
|
+
))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "category" }, "Category Name"), /* @__PURE__ */ React169__default.createElement(
|
|
139801
|
+
Input,
|
|
139802
|
+
{
|
|
139803
|
+
id: "category",
|
|
139804
|
+
value: formState.category || "",
|
|
139805
|
+
onChange: (e3) => handleFormChange(
|
|
139806
|
+
"category",
|
|
139807
|
+
e3.target.value
|
|
139808
|
+
)
|
|
139809
|
+
}
|
|
139810
|
+
)), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "categoryCode" }, "Category Code"), /* @__PURE__ */ React169__default.createElement(
|
|
139811
|
+
Input,
|
|
139812
|
+
{
|
|
139813
|
+
id: "categoryCode",
|
|
139814
|
+
value: formState.categoryCode || "",
|
|
139815
|
+
onChange: (e3) => handleFormChange(
|
|
139816
|
+
"categoryCode",
|
|
139817
|
+
e3.target.value
|
|
139818
|
+
)
|
|
139819
|
+
}
|
|
139820
|
+
))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "topic" }, "Topic Name"), /* @__PURE__ */ React169__default.createElement(
|
|
139821
|
+
Input,
|
|
139822
|
+
{
|
|
139823
|
+
id: "topic",
|
|
139824
|
+
value: formState.topic || "",
|
|
139825
|
+
onChange: (e3) => handleFormChange(
|
|
139826
|
+
"topic",
|
|
139827
|
+
e3.target.value
|
|
139828
|
+
)
|
|
139829
|
+
}
|
|
139830
|
+
)), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "topicCode" }, "Topic Code"), /* @__PURE__ */ React169__default.createElement(
|
|
139831
|
+
Input,
|
|
139832
|
+
{
|
|
139833
|
+
id: "topicCode",
|
|
139834
|
+
value: formState.topicCode || "",
|
|
139835
|
+
onChange: (e3) => handleFormChange(
|
|
139836
|
+
"topicCode",
|
|
139837
|
+
e3.target.value
|
|
139838
|
+
)
|
|
139839
|
+
}
|
|
139840
|
+
))), /* @__PURE__ */ React169__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "grade" }, "Grade Name"), /* @__PURE__ */ React169__default.createElement(
|
|
139841
|
+
Input,
|
|
139842
|
+
{
|
|
139843
|
+
id: "grade",
|
|
139844
|
+
value: formState.grade || "",
|
|
139845
|
+
onChange: (e3) => handleFormChange(
|
|
139846
|
+
"grade",
|
|
139847
|
+
e3.target.value
|
|
139848
|
+
)
|
|
139849
|
+
}
|
|
139850
|
+
)), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "gradeCode" }, "Grade Code"), /* @__PURE__ */ React169__default.createElement(
|
|
139851
|
+
Input,
|
|
139852
|
+
{
|
|
139853
|
+
id: "gradeCode",
|
|
139854
|
+
value: formState.gradeCode || "",
|
|
139855
|
+
onChange: (e3) => handleFormChange(
|
|
139856
|
+
"gradeCode",
|
|
139857
|
+
e3.target.value
|
|
139858
|
+
)
|
|
139859
|
+
}
|
|
139860
|
+
))), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "keywords" }, "Keywords (comma-separated)"), /* @__PURE__ */ React169__default.createElement(
|
|
139861
|
+
Textarea,
|
|
139862
|
+
{
|
|
139863
|
+
id: "keywords",
|
|
139864
|
+
value: formState.keywords?.join(", ") || "",
|
|
139865
|
+
onChange: (e3) => handleFormChange(
|
|
139866
|
+
"keywords",
|
|
139867
|
+
e3.target.value.split(",").map((s4) => s4.trim())
|
|
139868
|
+
)
|
|
139869
|
+
}
|
|
139870
|
+
)), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "stemElements" }, "STEM Elements (comma-separated)"), /* @__PURE__ */ React169__default.createElement(
|
|
139871
|
+
Textarea,
|
|
139872
|
+
{
|
|
139873
|
+
id: "stemElements",
|
|
139874
|
+
value: formState.stemElements?.join(", ") || "",
|
|
139875
|
+
onChange: (e3) => handleFormChange(
|
|
139876
|
+
"stemElements",
|
|
139877
|
+
e3.target.value.split(",").map((s4) => s4.trim())
|
|
139878
|
+
)
|
|
139879
|
+
}
|
|
139880
|
+
)), /* @__PURE__ */ React169__default.createElement("div", null, /* @__PURE__ */ React169__default.createElement(Label2, { htmlFor: "bloomLevelsGuideline" }, "Bloom's Guideline (comma-separated)"), /* @__PURE__ */ React169__default.createElement(
|
|
139881
|
+
Textarea,
|
|
139882
|
+
{
|
|
139883
|
+
id: "bloomLevelsGuideline",
|
|
139884
|
+
value: formState.bloomLevelsGuideline?.join(
|
|
139885
|
+
", "
|
|
139886
|
+
) || "",
|
|
139887
|
+
onChange: (e3) => handleFormChange(
|
|
139888
|
+
"bloomLevelsGuideline",
|
|
139889
|
+
e3.target.value.split(",").map((s4) => s4.trim())
|
|
139890
|
+
)
|
|
139891
|
+
}
|
|
139892
|
+
))), /* @__PURE__ */ React169__default.createElement(DialogFooter, null, /* @__PURE__ */ React169__default.createElement(
|
|
139893
|
+
Button,
|
|
139894
|
+
{
|
|
139895
|
+
type: "button",
|
|
139896
|
+
variant: "outline",
|
|
139897
|
+
onClick: () => setIsDialogOpen(false),
|
|
139898
|
+
disabled: isPending
|
|
139899
|
+
},
|
|
139900
|
+
"Cancel"
|
|
139901
|
+
), /* @__PURE__ */ React169__default.createElement(
|
|
139902
|
+
Button,
|
|
139903
|
+
{
|
|
139904
|
+
type: "submit",
|
|
139905
|
+
onClick: handleSubmit,
|
|
139906
|
+
disabled: isPending || !formState.name?.trim() || !formState.code?.trim()
|
|
139907
|
+
},
|
|
139908
|
+
isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
139909
|
+
" ",
|
|
139910
|
+
"Save"
|
|
139911
|
+
)))), /* @__PURE__ */ React169__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React169__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React169__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React169__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React169__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React169__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React169__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React169__default.createElement(
|
|
139912
|
+
AlertDialogAction2,
|
|
139913
|
+
{
|
|
139914
|
+
onClick: confirmDelete,
|
|
139915
|
+
disabled: isPending,
|
|
139916
|
+
className: "bg-destructive hover:bg-destructive/90"
|
|
139917
|
+
},
|
|
139918
|
+
isPending && /* @__PURE__ */ React169__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
139919
|
+
" ",
|
|
139920
|
+
"Delete"
|
|
139921
|
+
))))));
|
|
139677
139922
|
}
|
|
139678
139923
|
|
|
139679
139924
|
// src/react-ui/components/metadata/ContextManager.tsx
|
|
@@ -265,12 +265,12 @@ interface LearningObjectiveManagerProps {
|
|
|
265
265
|
initialData?: LearningObjective[];
|
|
266
266
|
subjects?: Subject[];
|
|
267
267
|
isLoading?: boolean;
|
|
268
|
-
onAdd?: (item: Omit<LearningObjective,
|
|
268
|
+
onAdd?: (item: Omit<LearningObjective, "id">) => Promise<void>;
|
|
269
269
|
onUpdate?: (item: LearningObjective) => Promise<void>;
|
|
270
270
|
onDelete?: (item: LearningObjective) => Promise<void>;
|
|
271
|
-
onBulkAdd?: (items: Omit<LearningObjective,
|
|
271
|
+
onBulkAdd?: (items: Omit<LearningObjective, "id">[]) => Promise<void>;
|
|
272
272
|
}
|
|
273
|
-
declare function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }: LearningObjectiveManagerProps): React__default.JSX.Element;
|
|
273
|
+
declare function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd, }: LearningObjectiveManagerProps): React__default.JSX.Element;
|
|
274
274
|
|
|
275
275
|
interface ContextManagerProps {
|
|
276
276
|
initialData?: Context[];
|
|
@@ -265,12 +265,12 @@ interface LearningObjectiveManagerProps {
|
|
|
265
265
|
initialData?: LearningObjective[];
|
|
266
266
|
subjects?: Subject[];
|
|
267
267
|
isLoading?: boolean;
|
|
268
|
-
onAdd?: (item: Omit<LearningObjective,
|
|
268
|
+
onAdd?: (item: Omit<LearningObjective, "id">) => Promise<void>;
|
|
269
269
|
onUpdate?: (item: LearningObjective) => Promise<void>;
|
|
270
270
|
onDelete?: (item: LearningObjective) => Promise<void>;
|
|
271
|
-
onBulkAdd?: (items: Omit<LearningObjective,
|
|
271
|
+
onBulkAdd?: (items: Omit<LearningObjective, "id">[]) => Promise<void>;
|
|
272
272
|
}
|
|
273
|
-
declare function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd }: LearningObjectiveManagerProps): React__default.JSX.Element;
|
|
273
|
+
declare function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoading: isLoadingProp, onAdd, onUpdate, onDelete, onBulkAdd, }: LearningObjectiveManagerProps): React__default.JSX.Element;
|
|
274
274
|
|
|
275
275
|
interface ContextManagerProps {
|
|
276
276
|
initialData?: Context[];
|
package/package.json
CHANGED