New-Thanasoft/thanasoft-front/src/stores/documentAttachmentStore.ts
2025-12-01 17:02:01 +03:00

506 lines
13 KiB
TypeScript

import { defineStore } from "pinia";
import { ref, computed } from "vue";
import DocumentAttachmentService from "@/services/documentAttachment";
import type {
DocumentAttachment,
CreateAttachmentPayload,
UpdateAttachmentPayload,
BulkDeletePayload,
ReorderAttachmentPayload,
} from "@/services/documentAttachment";
export const useDocumentAttachmentStore = defineStore(
"documentAttachment",
() => {
// State
const attachments = ref<DocumentAttachment[]>([]);
const loading = ref(false);
const error = ref<string | null>(null);
const success = ref(false);
// Getters
const allAttachments = computed(() => attachments.value);
const isLoading = computed(() => loading.value);
const hasError = computed(() => error.value !== null);
const getError = computed(() => error.value);
const isSuccess = computed(() => success.value);
const getAttachmentsByType = computed(() => (type: string) =>
attachments.value?.filter(
(attachment) => attachment.attachable_type === type
) || []
);
const getAttachmentsById = computed(() => (id: number) =>
attachments.value?.filter(
(attachment) => attachment.attachable_id === id
) || []
);
const getInterventionAttachments = computed(
() => (interventionId: number) =>
attachments.value?.filter(
(attachment) =>
attachment.attachable_type === "App\\Models\\Intervention" &&
attachment.attachable_id === interventionId
) || []
);
const getClientAttachments = computed(() => (clientId: number) =>
attachments.value?.filter(
(attachment) =>
attachment.attachable_type === "App\\Models\\Client" &&
attachment.attachable_id === clientId
) || []
);
const getDeceasedAttachments = computed(() => (deceasedId: number) =>
attachments.value?.filter(
(attachment) =>
attachment.attachable_type === "App\\Models\\Deceased" &&
attachment.attachable_id === deceasedId
) || []
);
// Actions
const setLoading = (isLoading: boolean) => {
loading.value = isLoading;
};
const setError = (err: string | null) => {
error.value = err;
};
const clearError = () => {
error.value = null;
};
const setSuccess = (isSuccess: boolean) => {
success.value = isSuccess;
};
const clearSuccess = () => {
success.value = false;
};
const setAttachments = (newAttachments: DocumentAttachment[]) => {
attachments.value = newAttachments || [];
};
const addAttachment = (attachment: DocumentAttachment) => {
if (!attachments.value) {
attachments.value = [];
}
attachments.value.push(attachment);
};
const updateAttachment = (updatedAttachment: DocumentAttachment) => {
if (!attachments.value) return;
const index = attachments.value.findIndex(
(attachment) => attachment.id === updatedAttachment.id
);
if (index !== -1) {
attachments.value[index] = updatedAttachment;
}
};
const removeAttachment = (attachmentId: number) => {
if (!attachments.value) return;
attachments.value = attachments.value.filter(
(attachment) => attachment.id !== attachmentId
);
};
const removeAttachments = (attachmentIds: number[]) => {
if (!attachments.value) return;
attachments.value = attachments.value.filter(
(attachment) => !attachmentIds.includes(attachment.id)
);
};
/**
* Attach a file to a model
*/
const attachFile = async (payload: CreateAttachmentPayload) => {
setLoading(true);
setError(null);
setSuccess(false);
try {
const response = await DocumentAttachmentService.attachFile(payload);
addAttachment(response.data);
setSuccess(true);
return response.data;
} catch (err: any) {
const errorMessage =
err.response?.data?.message ||
err.message ||
"Échec de l'attachement du fichier";
setError(errorMessage);
throw err;
} finally {
setLoading(false);
}
};
/**
* Detach a file from a model
*/
const detachFile = async (attachmentId: number) => {
setLoading(true);
setError(null);
setSuccess(false);
try {
await DocumentAttachmentService.detachFile(attachmentId);
removeAttachment(attachmentId);
setSuccess(true);
return { message: "Fichier détaché avec succès" };
} catch (err: any) {
const errorMessage =
err.response?.data?.message ||
err.message ||
"Échec du détachement du fichier";
setError(errorMessage);
throw err;
} finally {
setLoading(false);
}
};
/**
* Update file attachment metadata
*/
const updateAttachmentMetadata = async (
attachmentId: number,
payload: UpdateAttachmentPayload
) => {
setLoading(true);
setError(null);
setSuccess(false);
try {
const response = await DocumentAttachmentService.updateAttachment(
attachmentId,
payload
);
updateAttachment(response.data);
setSuccess(true);
return response.data;
} catch (err: any) {
const errorMessage =
err.response?.data?.message ||
err.message ||
"Échec de la mise à jour du document";
setError(errorMessage);
throw err;
} finally {
setLoading(false);
}
};
/**
* Get files attached to a specific model
*/
const fetchAttachedFiles = async (
attachableType: string,
attachableId: number
) => {
setLoading(true);
setError(null);
setSuccess(false);
try {
const response = await DocumentAttachmentService.getAttachedFiles(
attachableType,
attachableId
);
setAttachments(response.data);
return response.data;
} catch (err: any) {
const errorMessage =
err.response?.data?.message ||
err.message ||
"Échec du chargement des fichiers attachés";
setError(errorMessage);
throw err;
} finally {
setLoading(false);
}
};
/**
* Get files attached to an intervention
*/
const fetchInterventionFiles = async (interventionId: number) => {
setLoading(true);
setError(null);
setSuccess(false);
try {
const response = await DocumentAttachmentService.getInterventionFiles(
interventionId
);
setAttachments(response.data);
return response.data;
} catch (err: any) {
const errorMessage =
err.response?.data?.message ||
err.message ||
"Échec du chargement des fichiers de l'intervention";
setError(errorMessage);
throw err;
} finally {
setLoading(false);
}
};
/**
* Get files attached to a client
*/
const fetchClientFiles = async (clientId: number) => {
setLoading(true);
setError(null);
setSuccess(false);
try {
const response = await DocumentAttachmentService.getClientFiles(
clientId
);
setAttachments(response.data);
return response.data;
} catch (err: any) {
const errorMessage =
err.response?.data?.message ||
err.message ||
"Échec du chargement des fichiers du client";
setError(errorMessage);
throw err;
} finally {
setLoading(false);
}
};
/**
* Get files attached to a deceased
*/
const fetchDeceasedFiles = async (deceasedId: number) => {
setLoading(true);
setError(null);
setSuccess(false);
try {
const response = await DocumentAttachmentService.getDeceasedFiles(
deceasedId
);
setAttachments(response.data);
return response.data;
} catch (err: any) {
const errorMessage =
err.response?.data?.message ||
err.message ||
"Échec du chargement des fichiers du défunt";
setError(errorMessage);
throw err;
} finally {
setLoading(false);
}
};
/**
* Detach multiple files at once
*/
const detachMultipleFiles = async (payload: BulkDeletePayload) => {
setLoading(true);
setError(null);
setSuccess(false);
try {
const response = await DocumentAttachmentService.detachMultiple(
payload
);
removeAttachments(payload.attachment_ids);
setSuccess(true);
return response;
} catch (err: any) {
const errorMessage =
err.response?.data?.message ||
err.message ||
"Échec de la suppression des fichiers";
setError(errorMessage);
throw err;
} finally {
setLoading(false);
}
};
/**
* Reorder file attachments
*/
const reorderAttachments = async (payload: ReorderAttachmentPayload) => {
setLoading(true);
setError(null);
setSuccess(false);
try {
const response = await DocumentAttachmentService.reorderAttachments(
payload
);
// Update sort order in local state
if (attachments.value) {
payload.attachments.forEach((item) => {
const attachment = attachments.value.find((a) => a.id === item.id);
if (attachment) {
attachment.sort_order = item.sort_order;
}
});
// Sort attachments by sort_order
attachments.value.sort((a, b) => a.sort_order - b.sort_order);
}
setSuccess(true);
return response;
} catch (err: any) {
const errorMessage =
err.response?.data?.message ||
err.message ||
"Échec de la réorganisation des fichiers";
setError(errorMessage);
throw err;
} finally {
setLoading(false);
}
};
/**
* Upload and attach files to a model
*/
const uploadAndAttachFiles = async (
files: File[],
attachableType: string,
attachableId: number,
options?: {
labels?: string[];
onProgress?: (progress: number) => void;
}
) => {
setLoading(true);
setError(null);
setSuccess(false);
try {
const uploadedAttachments = await DocumentAttachmentService.uploadAndAttachFiles(
files,
attachableType,
attachableId,
options
);
// Add all uploaded attachments to the store
uploadedAttachments.forEach((attachment) => {
addAttachment(attachment);
});
setSuccess(true);
return uploadedAttachments;
} catch (err: any) {
const errorMessage =
err.response?.data?.message ||
err.message ||
"Échec du téléchargement des fichiers";
setError(errorMessage);
throw err;
} finally {
setLoading(false);
}
};
/**
* Validate file before upload
*/
const validateFile = (
file: File,
maxSize: number = 10 * 1024 * 1024
): { valid: boolean; error?: string } => {
return DocumentAttachmentService.validateFile(file, maxSize);
};
/**
* Format file size for display
*/
const formatFileSize = (bytes: number | null): string => {
return DocumentAttachmentService.formatFileSize(bytes);
};
/**
* Get file icon based on MIME type
*/
const getFileIcon = (mimeType: string | null): string => {
return DocumentAttachmentService.getFileIcon(mimeType);
};
/**
* Reset the state
*/
const resetState = () => {
attachments.value = [];
loading.value = false;
error.value = null;
success.value = false;
};
return {
// State
attachments,
loading,
error,
success,
// Getters
allAttachments,
isLoading,
hasError,
getError,
isSuccess,
getAttachmentsByType,
getAttachmentsById,
getInterventionAttachments,
getClientAttachments,
getDeceasedAttachments,
// Actions
setLoading,
setError,
clearError,
setSuccess,
clearSuccess,
setAttachments,
addAttachment,
updateAttachment,
removeAttachment,
removeAttachments,
attachFile,
detachFile,
updateAttachmentMetadata,
fetchAttachedFiles,
fetchInterventionFiles,
fetchClientFiles,
fetchDeceasedFiles,
detachMultipleFiles,
reorderAttachments,
uploadAndAttachFiles,
validateFile,
formatFileSize,
getFileIcon,
resetState,
};
}
);
export default useDocumentAttachmentStore;