shoc-frontend-new/src/domain/work-orders/utils/work-order-media-limits.ts
2026-09-09 17:46:10 -03:00

76 lines
2.6 KiB
TypeScript

import { isWorkOrderCompletionSurfaceReadOnly } from "@/domain/work-orders/utils/work-order-lock";
/** Backend RequestSizeLimit for media and completion-doc uploads. */
export const MAX_WORK_ORDER_MEDIA_BYTES = 50_000_000;
const MEDIA_MIME_TYPES = new Set([
"image/jpeg",
"image/jpg",
"image/png",
"video/mp4",
"video/quicktime",
]);
const MEDIA_EXTENSIONS = new Set([".jpg", ".jpeg", ".png", ".mp4", ".mov"]);
const EXTRA_DOC_MIME_TYPES = new Set([
...MEDIA_MIME_TYPES,
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
]);
const EXTRA_DOC_EXTENSIONS = new Set([...MEDIA_EXTENSIONS, ".pdf", ".doc", ".docx"]);
function fileExtension(file: File): string {
const name = file.name.toLowerCase();
const dot = name.lastIndexOf(".");
return dot >= 0 ? name.slice(dot) : "";
}
function isTypeAllowed(file: File, mimes: Set<string>, extensions: Set<string>): boolean {
const mimeOk = Boolean(file.type) && mimes.has(file.type.toLowerCase());
const extOk = extensions.has(fileExtension(file));
return mimeOk || extOk;
}
export function isWorkOrderFileTooLarge(
file: File,
maxBytes = MAX_WORK_ORDER_MEDIA_BYTES,
): boolean {
return file.size > maxBytes;
}
export function isWorkOrderMediaTypeAllowed(file: File): boolean {
return isTypeAllowed(file, MEDIA_MIME_TYPES, MEDIA_EXTENSIONS);
}
export function isWorkOrderExtraDocTypeAllowed(file: File): boolean {
return isTypeAllowed(file, EXTRA_DOC_MIME_TYPES, EXTRA_DOC_EXTENSIONS);
}
export function workOrderMediaAcceptAttribute(): string {
return "image/jpeg,image/jpg,image/png,video/mp4,video/quicktime,.jpg,.jpeg,.png,.mp4,.mov";
}
export function workOrderExtraDocsAcceptAttribute(): string {
return `${workOrderMediaAcceptAttribute()},.pdf,.doc,.docx,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document`;
}
export function formatMediaSizeLimit(maxBytes = MAX_WORK_ORDER_MEDIA_BYTES): string {
return `${Math.round(maxBytes / 1_000_000)} MB`;
}
/** Completion-doc / completion-media lock: Canceled or Completed. Extra Docs use canMutateWorkOrderExtraDocs. */
export function isWorkOrderDocumentsReadOnly(status: string | null | undefined): boolean {
return isWorkOrderCompletionSurfaceReadOnly(status);
}
export function canDeleteWorkOrderMedia(media: {
id: string | number;
isLegacy?: boolean;
}): boolean {
if (media.isLegacy) return false;
const numericId = typeof media.id === "number" ? media.id : Number(media.id);
return Number.isFinite(numericId) && numericId > 0;
}