@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/authoring.mjs
CHANGED
|
@@ -77229,15 +77229,27 @@ function QuestionTypeManager({ initialData, isLoading: isLoadingProp, onAdd, onU
|
|
|
77229
77229
|
|
|
77230
77230
|
// src/react-ui/components/metadata/LearningObjectiveManager.tsx
|
|
77231
77231
|
init_react_shim();
|
|
77232
|
-
function LearningObjectiveManager({
|
|
77232
|
+
function LearningObjectiveManager({
|
|
77233
|
+
initialData,
|
|
77234
|
+
subjects: subjectsProp,
|
|
77235
|
+
isLoading: isLoadingProp,
|
|
77236
|
+
onAdd,
|
|
77237
|
+
onUpdate,
|
|
77238
|
+
onDelete,
|
|
77239
|
+
onBulkAdd
|
|
77240
|
+
}) {
|
|
77233
77241
|
const [items, setItems] = useState([]);
|
|
77234
77242
|
const [subjects, setSubjects] = useState([]);
|
|
77235
77243
|
const [isLoading, setIsLoading] = useState(true);
|
|
77236
77244
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
77237
77245
|
const [isAlertOpen, setIsAlertOpen] = useState(false);
|
|
77238
|
-
const [currentItem, setCurrentItem] = useState(
|
|
77246
|
+
const [currentItem, setCurrentItem] = useState(
|
|
77247
|
+
null
|
|
77248
|
+
);
|
|
77239
77249
|
const [formState, setFormState] = useState({});
|
|
77240
|
-
const [itemToDelete, setItemToDelete] = useState(
|
|
77250
|
+
const [itemToDelete, setItemToDelete] = useState(
|
|
77251
|
+
null
|
|
77252
|
+
);
|
|
77241
77253
|
const [isPending, startTransition] = useTransition();
|
|
77242
77254
|
const { toast: toast2 } = useToast();
|
|
77243
77255
|
const isControlled = initialData !== void 0;
|
|
@@ -77248,7 +77260,11 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
77248
77260
|
setItems(MetadataService.getLearningObjectives());
|
|
77249
77261
|
setSubjects(MetadataService.getSubjects());
|
|
77250
77262
|
} catch (error) {
|
|
77251
|
-
toast2({
|
|
77263
|
+
toast2({
|
|
77264
|
+
title: "Error",
|
|
77265
|
+
description: "Failed to refresh data.",
|
|
77266
|
+
variant: "destructive"
|
|
77267
|
+
});
|
|
77252
77268
|
} finally {
|
|
77253
77269
|
setIsLoading(false);
|
|
77254
77270
|
}
|
|
@@ -77268,7 +77284,9 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
77268
77284
|
};
|
|
77269
77285
|
const handleAddItem = () => {
|
|
77270
77286
|
setCurrentItem(null);
|
|
77271
|
-
setFormState({
|
|
77287
|
+
setFormState({
|
|
77288
|
+
subjectCode: subjects.length > 0 ? subjects[0].code : ""
|
|
77289
|
+
});
|
|
77272
77290
|
setIsDialogOpen(true);
|
|
77273
77291
|
};
|
|
77274
77292
|
const handleEditItem = (item) => {
|
|
@@ -77290,9 +77308,16 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
77290
77308
|
MetadataService.deleteLearningObjective(itemToDelete.code);
|
|
77291
77309
|
refreshData();
|
|
77292
77310
|
}
|
|
77293
|
-
toast2({
|
|
77311
|
+
toast2({
|
|
77312
|
+
title: "Success",
|
|
77313
|
+
description: `Learning Objective "${itemToDelete.name}" deleted.`
|
|
77314
|
+
});
|
|
77294
77315
|
} catch (error) {
|
|
77295
|
-
toast2({
|
|
77316
|
+
toast2({
|
|
77317
|
+
title: "Error",
|
|
77318
|
+
description: error.message,
|
|
77319
|
+
variant: "destructive"
|
|
77320
|
+
});
|
|
77296
77321
|
} finally {
|
|
77297
77322
|
setIsAlertOpen(false);
|
|
77298
77323
|
setItemToDelete(null);
|
|
@@ -77301,7 +77326,11 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
77301
77326
|
};
|
|
77302
77327
|
const handleSubmit = () => {
|
|
77303
77328
|
if (!formState.name?.trim() || !formState.code?.trim()) {
|
|
77304
|
-
toast2({
|
|
77329
|
+
toast2({
|
|
77330
|
+
title: "Validation Error",
|
|
77331
|
+
description: "Code and Name are required.",
|
|
77332
|
+
variant: "destructive"
|
|
77333
|
+
});
|
|
77305
77334
|
return;
|
|
77306
77335
|
}
|
|
77307
77336
|
startTransition(async () => {
|
|
@@ -77310,75 +77339,291 @@ function LearningObjectiveManager({ initialData, subjects: subjectsProp, isLoadi
|
|
|
77310
77339
|
if (isControlled && onUpdate) {
|
|
77311
77340
|
await onUpdate({ ...currentItem, ...formState });
|
|
77312
77341
|
} else {
|
|
77313
|
-
MetadataService.updateLearningObjective(
|
|
77342
|
+
MetadataService.updateLearningObjective(
|
|
77343
|
+
currentItem.id,
|
|
77344
|
+
formState
|
|
77345
|
+
);
|
|
77314
77346
|
refreshData();
|
|
77315
77347
|
}
|
|
77316
|
-
toast2({
|
|
77348
|
+
toast2({
|
|
77349
|
+
title: "Success",
|
|
77350
|
+
description: "Learning Objective updated."
|
|
77351
|
+
});
|
|
77317
77352
|
} else {
|
|
77318
77353
|
if (isControlled && onAdd) {
|
|
77319
77354
|
await onAdd(formState);
|
|
77320
77355
|
} else {
|
|
77321
|
-
MetadataService.addLearningObjective(
|
|
77356
|
+
MetadataService.addLearningObjective(
|
|
77357
|
+
formState
|
|
77358
|
+
);
|
|
77322
77359
|
refreshData();
|
|
77323
77360
|
}
|
|
77324
|
-
toast2({
|
|
77361
|
+
toast2({
|
|
77362
|
+
title: "Success",
|
|
77363
|
+
description: "Learning Objective added."
|
|
77364
|
+
});
|
|
77325
77365
|
}
|
|
77326
77366
|
setIsDialogOpen(false);
|
|
77327
77367
|
} catch (error) {
|
|
77328
|
-
toast2({
|
|
77368
|
+
toast2({
|
|
77369
|
+
title: "Error",
|
|
77370
|
+
description: error.message,
|
|
77371
|
+
variant: "destructive"
|
|
77372
|
+
});
|
|
77329
77373
|
}
|
|
77330
77374
|
});
|
|
77331
77375
|
};
|
|
77332
77376
|
const handleImport = async (records) => {
|
|
77333
|
-
console.log(
|
|
77377
|
+
console.log(
|
|
77378
|
+
`[LO Manager] handleImport called with ${records.length} raw records.`
|
|
77379
|
+
);
|
|
77334
77380
|
if (!onBulkAdd) {
|
|
77335
77381
|
console.error("[LO Manager] onBulkAdd handler is not provided.");
|
|
77336
77382
|
return;
|
|
77337
77383
|
}
|
|
77338
77384
|
const parseStringToArray = (input) => {
|
|
77339
77385
|
if (Array.isArray(input)) return input;
|
|
77340
|
-
if (typeof input === "string")
|
|
77386
|
+
if (typeof input === "string")
|
|
77387
|
+
return input.split(",").map((s2) => s2.trim()).filter(Boolean);
|
|
77341
77388
|
return [];
|
|
77342
77389
|
};
|
|
77343
|
-
const validationResult = records.reduce(
|
|
77344
|
-
|
|
77345
|
-
|
|
77346
|
-
|
|
77347
|
-
|
|
77348
|
-
|
|
77349
|
-
|
|
77350
|
-
|
|
77351
|
-
|
|
77352
|
-
|
|
77353
|
-
|
|
77354
|
-
|
|
77355
|
-
|
|
77356
|
-
|
|
77357
|
-
|
|
77358
|
-
|
|
77359
|
-
|
|
77360
|
-
|
|
77361
|
-
|
|
77362
|
-
|
|
77363
|
-
|
|
77364
|
-
|
|
77365
|
-
|
|
77366
|
-
|
|
77390
|
+
const validationResult = records.reduce(
|
|
77391
|
+
(acc, rec) => {
|
|
77392
|
+
if (typeof rec["LO ID"] === "string" && rec["LO ID"].trim() && typeof rec["LO Description"] === "string" && rec["LO Description"].trim()) {
|
|
77393
|
+
acc.valid.push({
|
|
77394
|
+
code: rec["LO ID"],
|
|
77395
|
+
name: rec["LO ID"],
|
|
77396
|
+
description: rec["LO Description"],
|
|
77397
|
+
subject: rec["Subject"] || "",
|
|
77398
|
+
subjectCode: rec["Subject Code"] || rec["Subject"],
|
|
77399
|
+
category: rec["Category"] || "",
|
|
77400
|
+
categoryCode: rec["Category Code"] || rec["Category"],
|
|
77401
|
+
topic: rec["Topic"] || "",
|
|
77402
|
+
topicCode: rec["Topic Code"] || rec["Topic"],
|
|
77403
|
+
grade: rec["Grade"] || "",
|
|
77404
|
+
gradeCode: rec["Grade Code"] || rec["Grade"],
|
|
77405
|
+
keywords: parseStringToArray(rec["Keywords"]),
|
|
77406
|
+
stemElements: parseStringToArray(
|
|
77407
|
+
rec["STEM Element(s)"]
|
|
77408
|
+
),
|
|
77409
|
+
bloomLevelsGuideline: parseStringToArray(
|
|
77410
|
+
rec["Bloom\u2019s Level(s) Guideline"]
|
|
77411
|
+
)
|
|
77412
|
+
});
|
|
77413
|
+
} else {
|
|
77414
|
+
acc.invalidCount++;
|
|
77415
|
+
}
|
|
77416
|
+
return acc;
|
|
77417
|
+
},
|
|
77418
|
+
{ valid: [], invalidCount: 0 }
|
|
77419
|
+
);
|
|
77420
|
+
console.log(
|
|
77421
|
+
`[LO Manager] Validation complete. ${validationResult.valid.length} valid records found.`
|
|
77422
|
+
);
|
|
77367
77423
|
if (validationResult.invalidCount > 0) {
|
|
77368
77424
|
toast2({
|
|
77369
77425
|
title: "Import Warning",
|
|
77370
|
-
description: `${validationResult.invalidCount} records had invalid or missing '
|
|
77426
|
+
description: `${validationResult.invalidCount} records had invalid or missing 'LO ID' or 'LO Description' fields and were ignored.`,
|
|
77371
77427
|
variant: "destructive"
|
|
77372
77428
|
});
|
|
77373
77429
|
}
|
|
77374
77430
|
if (validationResult.valid.length > 0) {
|
|
77375
|
-
console.log(
|
|
77431
|
+
console.log(
|
|
77432
|
+
"[LO Manager] Calling onBulkAdd prop with validated data..."
|
|
77433
|
+
);
|
|
77376
77434
|
await onBulkAdd(validationResult.valid);
|
|
77377
77435
|
} else {
|
|
77378
77436
|
console.log("[LO Manager] No valid records to import.");
|
|
77379
77437
|
}
|
|
77380
77438
|
};
|
|
77381
|
-
return /* @__PURE__ */ React119__default.createElement(Card, null, /* @__PURE__ */ React119__default.createElement(CardHeader, null, /* @__PURE__ */ React119__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React119__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React119__default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " Manage Learning Objectives"), /* @__PURE__ */ React119__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React119__default.createElement(MetadataImportControls, { metadataName: "Learning Objectives", onImport: handleImport }), /* @__PURE__ */ React119__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React119__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective")))), /* @__PURE__ */ React119__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React119__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React119__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React119__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React119__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React119__default.createElement(Table2, null, /* @__PURE__ */ React119__default.createElement(TableHeader, null, /* @__PURE__ */ React119__default.createElement(TableRow, null, /* @__PURE__ */ React119__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React119__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React119__default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React119__default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React119__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React119__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React119__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React119__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React119__default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React119__default.createElement(TableCell, null, item.subject || item.subjectCode), /* @__PURE__ */ React119__default.createElement(TableCell, null, item.topic || item.topicCode), /* @__PURE__ */ React119__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React119__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleEditItem(item), className: "mr-2" }, /* @__PURE__ */ React119__default.createElement(PenLine, { className: "h-4 w-4" })), /* @__PURE__ */ React119__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteItem(item), className: "text-destructive hover:text-destructive" }, /* @__PURE__ */ React119__default.createElement(Trash2, { className: "h-4 w-4" })))))))), /* @__PURE__ */ React119__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React119__default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React119__default.createElement(DialogHeader, null, /* @__PURE__ */ React119__default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React119__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React119__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "code" }, "Code"), /* @__PURE__ */ React119__default.createElement(Input, { id: "code", value: formState.code || "", onChange: (e2) => handleFormChange("code", e2.target.value.toUpperCase()), disabled: !!currentItem })), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "name" }, "Name (Description)"), /* @__PURE__ */ React119__default.createElement(Input, { id: "name", value: formState.name || "", onChange: (e2) => handleFormChange("name", e2.target.value) }))), /* @__PURE__ */ React119__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "subject" }, "Subject Name"), /* @__PURE__ */ React119__default.createElement(Input, { id: "subject", value: formState.subject || "", onChange: (e2) => handleFormChange("subject", e2.target.value) })), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React119__default.createElement(EditableCombobox, { options: subjects.map((s2) => ({ value: s2.code, label: s2.name })), value: formState.subjectCode || "", onChange: (val) => handleFormChange("subjectCode", val), placeholder: "Select a subject..." }))), /* @__PURE__ */ React119__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "category" }, "Category Name"), /* @__PURE__ */ React119__default.createElement(Input, { id: "category", value: formState.category || "", onChange: (e2) => handleFormChange("category", e2.target.value) })), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "categoryCode" }, "Category Code"), /* @__PURE__ */ React119__default.createElement(Input, { id: "categoryCode", value: formState.categoryCode || "", onChange: (e2) => handleFormChange("categoryCode", e2.target.value) }))), /* @__PURE__ */ React119__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "topic" }, "Topic Name"), /* @__PURE__ */ React119__default.createElement(Input, { id: "topic", value: formState.topic || "", onChange: (e2) => handleFormChange("topic", e2.target.value) })), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "topicCode" }, "Topic Code"), /* @__PURE__ */ React119__default.createElement(Input, { id: "topicCode", value: formState.topicCode || "", onChange: (e2) => handleFormChange("topicCode", e2.target.value) }))), /* @__PURE__ */ React119__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "grade" }, "Grade Name"), /* @__PURE__ */ React119__default.createElement(Input, { id: "grade", value: formState.grade || "", onChange: (e2) => handleFormChange("grade", e2.target.value) })), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "gradeCode" }, "Grade Code"), /* @__PURE__ */ React119__default.createElement(Input, { id: "gradeCode", value: formState.gradeCode || "", onChange: (e2) => handleFormChange("gradeCode", e2.target.value) }))), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "keywords" }, "Keywords (comma-separated)"), /* @__PURE__ */ React119__default.createElement(Textarea, { id: "keywords", value: formState.keywords?.join(", ") || "", onChange: (e2) => handleFormChange("keywords", e2.target.value.split(",").map((s2) => s2.trim())) })), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "stemElements" }, "STEM Elements (comma-separated)"), /* @__PURE__ */ React119__default.createElement(Textarea, { id: "stemElements", value: formState.stemElements?.join(", ") || "", onChange: (e2) => handleFormChange("stemElements", e2.target.value.split(",").map((s2) => s2.trim())) })), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "bloomLevelsGuideline" }, "Bloom's Guideline (comma-separated)"), /* @__PURE__ */ React119__default.createElement(Textarea, { id: "bloomLevelsGuideline", value: formState.bloomLevelsGuideline?.join(", ") || "", onChange: (e2) => handleFormChange("bloomLevelsGuideline", e2.target.value.split(",").map((s2) => s2.trim())) }))), /* @__PURE__ */ React119__default.createElement(DialogFooter, null, /* @__PURE__ */ React119__default.createElement(Button, { type: "button", variant: "outline", onClick: () => setIsDialogOpen(false), disabled: isPending }, "Cancel"), /* @__PURE__ */ React119__default.createElement(Button, { type: "submit", onClick: handleSubmit, disabled: isPending || !formState.name?.trim() || !formState.code?.trim() }, isPending && /* @__PURE__ */ React119__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Save")))), /* @__PURE__ */ React119__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React119__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React119__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React119__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React119__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React119__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React119__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React119__default.createElement(AlertDialogAction2, { onClick: confirmDelete, disabled: isPending, className: "bg-destructive hover:bg-destructive/90" }, isPending && /* @__PURE__ */ React119__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), " Delete"))))));
|
|
77439
|
+
return /* @__PURE__ */ React119__default.createElement(Card, null, /* @__PURE__ */ React119__default.createElement(CardHeader, null, /* @__PURE__ */ React119__default.createElement(CardTitle, { className: "flex justify-between items-center" }, /* @__PURE__ */ React119__default.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React119__default.createElement(Lightbulb, { className: "mr-2 h-5 w-5 text-primary" }), " ", "Manage Learning Objectives"), /* @__PURE__ */ React119__default.createElement("div", { className: "flex items-center gap-2" }, onBulkAdd && /* @__PURE__ */ React119__default.createElement(
|
|
77440
|
+
MetadataImportControls,
|
|
77441
|
+
{
|
|
77442
|
+
metadataName: "Learning Objectives",
|
|
77443
|
+
onImport: handleImport
|
|
77444
|
+
}
|
|
77445
|
+
), /* @__PURE__ */ React119__default.createElement(Button, { onClick: handleAddItem, size: "sm" }, /* @__PURE__ */ React119__default.createElement(CirclePlus, { className: "mr-2 h-4 w-4" }), " Add Learning Objective")))), /* @__PURE__ */ React119__default.createElement(CardContent, null, isLoading ? /* @__PURE__ */ React119__default.createElement("div", { className: "flex justify-center items-center h-32" }, /* @__PURE__ */ React119__default.createElement(LoaderCircle, { className: "h-8 w-8 animate-spin text-primary" })) : items.length === 0 ? /* @__PURE__ */ React119__default.createElement("p", { className: "text-center text-muted-foreground py-4" }, "No Learning Objectives found.") : /* @__PURE__ */ React119__default.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React119__default.createElement(Table2, null, /* @__PURE__ */ React119__default.createElement(TableHeader, null, /* @__PURE__ */ React119__default.createElement(TableRow, null, /* @__PURE__ */ React119__default.createElement(TableHead, null, "Code"), /* @__PURE__ */ React119__default.createElement(TableHead, null, "Name"), /* @__PURE__ */ React119__default.createElement(TableHead, null, "Subject"), /* @__PURE__ */ React119__default.createElement(TableHead, null, "Topic"), /* @__PURE__ */ React119__default.createElement(TableHead, { className: "text-right w-[120px]" }, "Actions"))), /* @__PURE__ */ React119__default.createElement(TableBody, null, items.map((item) => /* @__PURE__ */ React119__default.createElement(TableRow, { key: item.id }, /* @__PURE__ */ React119__default.createElement(TableCell, { className: "font-mono text-xs" }, item.code), /* @__PURE__ */ React119__default.createElement(TableCell, { className: "font-medium" }, item.name), /* @__PURE__ */ React119__default.createElement(TableCell, null, item.subject || item.subjectCode), /* @__PURE__ */ React119__default.createElement(TableCell, null, item.topic || item.topicCode), /* @__PURE__ */ React119__default.createElement(TableCell, { className: "text-right" }, /* @__PURE__ */ React119__default.createElement(
|
|
77446
|
+
Button,
|
|
77447
|
+
{
|
|
77448
|
+
variant: "ghost",
|
|
77449
|
+
size: "icon",
|
|
77450
|
+
onClick: () => handleEditItem(item),
|
|
77451
|
+
className: "mr-2"
|
|
77452
|
+
},
|
|
77453
|
+
/* @__PURE__ */ React119__default.createElement(PenLine, { className: "h-4 w-4" })
|
|
77454
|
+
), /* @__PURE__ */ React119__default.createElement(
|
|
77455
|
+
Button,
|
|
77456
|
+
{
|
|
77457
|
+
variant: "ghost",
|
|
77458
|
+
size: "icon",
|
|
77459
|
+
onClick: () => handleDeleteItem(item),
|
|
77460
|
+
className: "text-destructive hover:text-destructive"
|
|
77461
|
+
},
|
|
77462
|
+
/* @__PURE__ */ React119__default.createElement(Trash2, { className: "h-4 w-4" })
|
|
77463
|
+
))))))), /* @__PURE__ */ React119__default.createElement(Dialog2, { open: isDialogOpen, onOpenChange: setIsDialogOpen }, /* @__PURE__ */ React119__default.createElement(DialogContent2, { className: "sm:max-w-2xl max-h-[90vh] overflow-y-auto" }, /* @__PURE__ */ React119__default.createElement(DialogHeader, null, /* @__PURE__ */ React119__default.createElement(DialogTitle2, null, currentItem ? "Edit Learning Objective" : "Add New Learning Objective")), /* @__PURE__ */ React119__default.createElement("div", { className: "grid gap-4 py-4" }, /* @__PURE__ */ React119__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "code" }, "Code"), /* @__PURE__ */ React119__default.createElement(
|
|
77464
|
+
Input,
|
|
77465
|
+
{
|
|
77466
|
+
id: "code",
|
|
77467
|
+
value: formState.code || "",
|
|
77468
|
+
onChange: (e2) => handleFormChange(
|
|
77469
|
+
"code",
|
|
77470
|
+
e2.target.value.toUpperCase()
|
|
77471
|
+
),
|
|
77472
|
+
disabled: !!currentItem
|
|
77473
|
+
}
|
|
77474
|
+
)), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "name" }, "Name (Description)"), /* @__PURE__ */ React119__default.createElement(
|
|
77475
|
+
Input,
|
|
77476
|
+
{
|
|
77477
|
+
id: "name",
|
|
77478
|
+
value: formState.name || "",
|
|
77479
|
+
onChange: (e2) => handleFormChange(
|
|
77480
|
+
"name",
|
|
77481
|
+
e2.target.value
|
|
77482
|
+
)
|
|
77483
|
+
}
|
|
77484
|
+
))), /* @__PURE__ */ React119__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "subject" }, "Subject Name"), /* @__PURE__ */ React119__default.createElement(
|
|
77485
|
+
Input,
|
|
77486
|
+
{
|
|
77487
|
+
id: "subject",
|
|
77488
|
+
value: formState.subject || "",
|
|
77489
|
+
onChange: (e2) => handleFormChange(
|
|
77490
|
+
"subject",
|
|
77491
|
+
e2.target.value
|
|
77492
|
+
)
|
|
77493
|
+
}
|
|
77494
|
+
)), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "subjectCode" }, "Subject Code"), /* @__PURE__ */ React119__default.createElement(
|
|
77495
|
+
EditableCombobox,
|
|
77496
|
+
{
|
|
77497
|
+
options: subjects.map((s2) => ({
|
|
77498
|
+
value: s2.code,
|
|
77499
|
+
label: s2.name
|
|
77500
|
+
})),
|
|
77501
|
+
value: formState.subjectCode || "",
|
|
77502
|
+
onChange: (val) => handleFormChange("subjectCode", val),
|
|
77503
|
+
placeholder: "Select a subject..."
|
|
77504
|
+
}
|
|
77505
|
+
))), /* @__PURE__ */ React119__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "category" }, "Category Name"), /* @__PURE__ */ React119__default.createElement(
|
|
77506
|
+
Input,
|
|
77507
|
+
{
|
|
77508
|
+
id: "category",
|
|
77509
|
+
value: formState.category || "",
|
|
77510
|
+
onChange: (e2) => handleFormChange(
|
|
77511
|
+
"category",
|
|
77512
|
+
e2.target.value
|
|
77513
|
+
)
|
|
77514
|
+
}
|
|
77515
|
+
)), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "categoryCode" }, "Category Code"), /* @__PURE__ */ React119__default.createElement(
|
|
77516
|
+
Input,
|
|
77517
|
+
{
|
|
77518
|
+
id: "categoryCode",
|
|
77519
|
+
value: formState.categoryCode || "",
|
|
77520
|
+
onChange: (e2) => handleFormChange(
|
|
77521
|
+
"categoryCode",
|
|
77522
|
+
e2.target.value
|
|
77523
|
+
)
|
|
77524
|
+
}
|
|
77525
|
+
))), /* @__PURE__ */ React119__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "topic" }, "Topic Name"), /* @__PURE__ */ React119__default.createElement(
|
|
77526
|
+
Input,
|
|
77527
|
+
{
|
|
77528
|
+
id: "topic",
|
|
77529
|
+
value: formState.topic || "",
|
|
77530
|
+
onChange: (e2) => handleFormChange(
|
|
77531
|
+
"topic",
|
|
77532
|
+
e2.target.value
|
|
77533
|
+
)
|
|
77534
|
+
}
|
|
77535
|
+
)), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "topicCode" }, "Topic Code"), /* @__PURE__ */ React119__default.createElement(
|
|
77536
|
+
Input,
|
|
77537
|
+
{
|
|
77538
|
+
id: "topicCode",
|
|
77539
|
+
value: formState.topicCode || "",
|
|
77540
|
+
onChange: (e2) => handleFormChange(
|
|
77541
|
+
"topicCode",
|
|
77542
|
+
e2.target.value
|
|
77543
|
+
)
|
|
77544
|
+
}
|
|
77545
|
+
))), /* @__PURE__ */ React119__default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "grade" }, "Grade Name"), /* @__PURE__ */ React119__default.createElement(
|
|
77546
|
+
Input,
|
|
77547
|
+
{
|
|
77548
|
+
id: "grade",
|
|
77549
|
+
value: formState.grade || "",
|
|
77550
|
+
onChange: (e2) => handleFormChange(
|
|
77551
|
+
"grade",
|
|
77552
|
+
e2.target.value
|
|
77553
|
+
)
|
|
77554
|
+
}
|
|
77555
|
+
)), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "gradeCode" }, "Grade Code"), /* @__PURE__ */ React119__default.createElement(
|
|
77556
|
+
Input,
|
|
77557
|
+
{
|
|
77558
|
+
id: "gradeCode",
|
|
77559
|
+
value: formState.gradeCode || "",
|
|
77560
|
+
onChange: (e2) => handleFormChange(
|
|
77561
|
+
"gradeCode",
|
|
77562
|
+
e2.target.value
|
|
77563
|
+
)
|
|
77564
|
+
}
|
|
77565
|
+
))), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "keywords" }, "Keywords (comma-separated)"), /* @__PURE__ */ React119__default.createElement(
|
|
77566
|
+
Textarea,
|
|
77567
|
+
{
|
|
77568
|
+
id: "keywords",
|
|
77569
|
+
value: formState.keywords?.join(", ") || "",
|
|
77570
|
+
onChange: (e2) => handleFormChange(
|
|
77571
|
+
"keywords",
|
|
77572
|
+
e2.target.value.split(",").map((s2) => s2.trim())
|
|
77573
|
+
)
|
|
77574
|
+
}
|
|
77575
|
+
)), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "stemElements" }, "STEM Elements (comma-separated)"), /* @__PURE__ */ React119__default.createElement(
|
|
77576
|
+
Textarea,
|
|
77577
|
+
{
|
|
77578
|
+
id: "stemElements",
|
|
77579
|
+
value: formState.stemElements?.join(", ") || "",
|
|
77580
|
+
onChange: (e2) => handleFormChange(
|
|
77581
|
+
"stemElements",
|
|
77582
|
+
e2.target.value.split(",").map((s2) => s2.trim())
|
|
77583
|
+
)
|
|
77584
|
+
}
|
|
77585
|
+
)), /* @__PURE__ */ React119__default.createElement("div", null, /* @__PURE__ */ React119__default.createElement(Label2, { htmlFor: "bloomLevelsGuideline" }, "Bloom's Guideline (comma-separated)"), /* @__PURE__ */ React119__default.createElement(
|
|
77586
|
+
Textarea,
|
|
77587
|
+
{
|
|
77588
|
+
id: "bloomLevelsGuideline",
|
|
77589
|
+
value: formState.bloomLevelsGuideline?.join(
|
|
77590
|
+
", "
|
|
77591
|
+
) || "",
|
|
77592
|
+
onChange: (e2) => handleFormChange(
|
|
77593
|
+
"bloomLevelsGuideline",
|
|
77594
|
+
e2.target.value.split(",").map((s2) => s2.trim())
|
|
77595
|
+
)
|
|
77596
|
+
}
|
|
77597
|
+
))), /* @__PURE__ */ React119__default.createElement(DialogFooter, null, /* @__PURE__ */ React119__default.createElement(
|
|
77598
|
+
Button,
|
|
77599
|
+
{
|
|
77600
|
+
type: "button",
|
|
77601
|
+
variant: "outline",
|
|
77602
|
+
onClick: () => setIsDialogOpen(false),
|
|
77603
|
+
disabled: isPending
|
|
77604
|
+
},
|
|
77605
|
+
"Cancel"
|
|
77606
|
+
), /* @__PURE__ */ React119__default.createElement(
|
|
77607
|
+
Button,
|
|
77608
|
+
{
|
|
77609
|
+
type: "submit",
|
|
77610
|
+
onClick: handleSubmit,
|
|
77611
|
+
disabled: isPending || !formState.name?.trim() || !formState.code?.trim()
|
|
77612
|
+
},
|
|
77613
|
+
isPending && /* @__PURE__ */ React119__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
77614
|
+
" ",
|
|
77615
|
+
"Save"
|
|
77616
|
+
)))), /* @__PURE__ */ React119__default.createElement(AlertDialog2, { open: isAlertOpen, onOpenChange: setIsAlertOpen }, /* @__PURE__ */ React119__default.createElement(AlertDialogContent2, null, /* @__PURE__ */ React119__default.createElement(AlertDialogHeader, null, /* @__PURE__ */ React119__default.createElement(AlertDialogTitle2, null, "Are you sure?"), /* @__PURE__ */ React119__default.createElement(AlertDialogDescription2, null, 'This will permanently delete "', itemToDelete?.name, '".')), /* @__PURE__ */ React119__default.createElement(AlertDialogFooter, null, /* @__PURE__ */ React119__default.createElement(AlertDialogCancel2, { disabled: isPending }, "Cancel"), /* @__PURE__ */ React119__default.createElement(
|
|
77617
|
+
AlertDialogAction2,
|
|
77618
|
+
{
|
|
77619
|
+
onClick: confirmDelete,
|
|
77620
|
+
disabled: isPending,
|
|
77621
|
+
className: "bg-destructive hover:bg-destructive/90"
|
|
77622
|
+
},
|
|
77623
|
+
isPending && /* @__PURE__ */ React119__default.createElement(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
77624
|
+
" ",
|
|
77625
|
+
"Delete"
|
|
77626
|
+
))))));
|
|
77382
77627
|
}
|
|
77383
77628
|
|
|
77384
77629
|
// src/react-ui/components/metadata/ContextManager.tsx
|