mirror of
https://github.com/faiztyanirh/clqms-shadcn-v1.git
synced 2026-04-22 17:19:52 +07:00
138 lines
2.8 KiB
JavaScript
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,
|
|
};
|
|
} |