260330:1011 Addied correspondence_revieion_attcahments table table #01
CI / CD Pipeline / build (push) Failing after 21m19s
CI / CD Pipeline / deploy (push) Has been skipped

This commit is contained in:
admin
2026-03-30 10:11:40 +07:00
parent 1c6fec6c65
commit c83588ab43
287 changed files with 15117 additions and 69 deletions
+10 -3
View File
@@ -53,7 +53,9 @@ export function CorrespondenceDetail({ data, selectedRevisionId }: Correspondenc
const subject = currentRevision?.subject || '-';
const description = currentRevision?.description || '-';
const status = currentRevision?.status?.statusCode || 'UNKNOWN';
const attachments = currentRevision?.attachments || [];
// [FIX v1.8.1] flatten attachmentLinks จาก junction table แทน attachments โดยตรง
const attachments =
currentRevision?.attachmentLinks?.map((link) => link.attachment) ?? [];
const importance = (currentRevision?.details?.importance as string) || 'NORMAL';
const canEditMetadata = hasPermission('correspondence.edit');
const privilegedEditableStatuses = ['SUBCSC', 'SUBOWN', 'IN_REVIEW_CSC'];
@@ -294,10 +296,15 @@ export function CorrespondenceDetail({ data, selectedRevisionId }: Correspondenc
>
<div className="flex items-center gap-3">
<FileText className="h-5 w-5 text-primary" />
<span className="text-sm font-medium">{file.name}</span>
<span className="text-sm font-medium">{file.originalFilename}</span>
</div>
<Button variant="ghost" size="sm" asChild>
<a href={file.url} target="_blank" rel="noopener noreferrer">
<a
href={file.filePath}
target="_blank"
rel="noopener noreferrer"
aria-label={`Download ${file.originalFilename}`}
>
<Download className="h-4 w-4" />
</a>
</Button>
+26 -2
View File
@@ -24,7 +24,9 @@ import { toast } from 'sonner';
// Updated Zod Schema with all required fields
const correspondenceSchema = z.object({
projectId: z.string().min(1, 'Please select a Project'),
contractId: z.string().min(1, 'Please select a Contract'),
// [FIX v1.8.1] contractId optional เพราะ correspondences ไม่มี contract_id โดยตรง
// จะ auto-populate จาก discipline เฉพาะ UI เท่านั้น
contractId: z.string().optional(),
documentTypeId: z.number().min(1, 'Please select a Document Type'),
disciplineId: z.number().optional(),
subject: z.string().min(5, 'Subject must be at least 5 characters'),
@@ -66,6 +68,12 @@ interface DisciplineOption {
id: number;
disciplineCode: string;
codeNameEn?: string;
// [FIX v1.8.1] บาง API ส่ง contract relation มาด้วย → ใช้ resolve contractId
contract?: {
publicId?: string;
contractName?: string;
contractCode?: string;
};
}
interface InitialCorrespondenceData {
@@ -168,7 +176,8 @@ export function CorrespondenceForm({
projectId:
normalizePublicId(initialData?.project?.publicId) ??
normalizePublicId(initialData?.projectId),
contractId: normalizePublicId(initialData?.contract?.publicId),
// [FIX v1.8.1] correspondences ไม่มี contract_id โดยตรง → จะ auto-populate จาก discipline useEffect
contractId: undefined,
documentTypeId: initialData?.correspondenceTypeId || undefined,
disciplineId: initialData?.disciplineId || undefined,
subject: currentRev?.subject || currentRev?.title || '',
@@ -241,6 +250,21 @@ export function CorrespondenceForm({
}
}, [contractId, setValue]);
// [FIX v1.8.1] Auto-populate contractId จาก discipline เมื่อ edit mode
// disciplines API ส่ง contract relation มาด้วย ถ้ามี discipline
useEffect(() => {
if (!initialData?.disciplineId) return;
if (disciplines.length === 0) return;
// ถ้ามี contractId ใน form แล้ว ไม่ต้อง override
const currentContractId = watch('contractId');
if (currentContractId) return;
const matched = disciplines.find((d) => d.id === initialData.disciplineId);
if (matched?.contract?.publicId) {
setValue('contractId', matched.contract.publicId);
}
}, [initialData?.disciplineId, disciplines, setValue, watch]);
const [isUploading, setIsUploading] = useState(false);
const onSubmit = async (data: FormData) => {