clqms-shadcn-v1/src/lib/components/composable/use-master-detail.svelte.js
2026-02-10 19:58:56 +07:00

138 lines
2.8 KiB
JavaScript

import { useResponsive } from "./use-responsive.svelte.js";
import { useForm } from "./use-form.svelte.js";
export function useMasterDetail(options = {}) {
const { onSelect = null, formConfig = null, } = options;
let selectedItem = $state(null);
let mode = $state("view");
let isLoadingDetail = $state(false);
const formState = useForm(formConfig);
const { isMobile } = useResponsive();
const isFormMode = $derived(mode === "create" || mode === "edit");
const showMaster = $derived(!isMobile || (mode === "view" && !selectedItem));
const showDetail = $derived(!isMobile || selectedItem || isFormMode);
const layout = $derived({
masterWidth: isMobile ? "w-full" : isFormMode ? "w-[3%]" : "w-[35%]",
detailWidth: isMobile ? "w-full" : isFormMode ? "w-[97%]" : "w-[65%]",
});
async function select(item) {
mode = "view";
if (onSelect) {
isLoadingDetail = true;
try {
const detailData = await onSelect(item);
selectedItem = detailData;
} catch (error) {
console.error("Failed to fetch detail:", error);
selectedItem = null;
} finally {
isLoadingDetail = false;
}
} else {
selectedItem = item;
}
}
function enterCreate(initialData = null) {
mode = "create";
selectedItem = null;
formState.reset();
if (initialData) {
formState.setForm({
...formState.form,
...initialData
});
}
}
function enterEdit(mapToForm = null) {
if (!selectedItem) return;
mode = "edit";
const data = mapToForm
? mapToForm(selectedItem)
: selectedItem;
formState.reset();
Object.assign(formState.form, data);
Object.keys(formState.errors).forEach(key => {
formState.errors[key] = null;
});
}
function exitForm() {
// const confirmed = confirm('You have unsaved changes. Are you sure you want to exit?');
// if (!confirmed) return;
mode = "view";
selectedItem = null;
}
function backToList() {
selectedItem = null;
mode = "view";
}
function saveForm() {
// Commit changes (mark as saved)
formSnapshot = { ...form };
}
return {
// State
get selectedItem() {
return selectedItem;
},
get mode() {
return mode;
},
get isFormMode() {
return isFormMode;
},
get isMobile() {
return isMobile;
},
get showMaster() {
return showMaster;
},
get showDetail() {
return showDetail;
},
get layout() {
return layout;
},
// get form() {
// return form;
// },
// get isDirty() {
// return isDirty;
// },
get isLoadingDetail() {
return isLoadingDetail;
},
get formState() {
return formState;
},
// Actions
select,
enterCreate,
enterEdit,
exitForm,
backToList,
saveForm,
};
}