690328:1106 Fixing Refactor uuid by Kimi #01
This commit is contained in:
Vendored
+2
-1
@@ -1,3 +1,4 @@
|
||||
{
|
||||
"npm.packageManager": "pnpm"
|
||||
"npm.packageManager": "pnpm",
|
||||
"editor.fontSize": 16
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import { useProjects } from '@/hooks/use-projects';
|
||||
import { CreateRfaDto } from '@/types/dto/rfa/rfa.dto';
|
||||
import { useState, useEffect, type FormEvent } from 'react';
|
||||
import { correspondenceService } from '@/lib/services/correspondence.service';
|
||||
import { Contract, getContractPublicId } from '@/types/contract';
|
||||
import { Contract } from '@/types/contract';
|
||||
|
||||
const rfaSchema = z.object({
|
||||
projectId: z.string().min(1, 'Project is required'), // ADR-019: UUID
|
||||
@@ -41,16 +41,12 @@ type RFAFormData = z.infer<typeof rfaSchema>;
|
||||
|
||||
type ProjectOption = {
|
||||
publicId?: string;
|
||||
uuid?: string; // Legacy alias for publicId
|
||||
id?: number;
|
||||
projectName?: string;
|
||||
projectCode?: string;
|
||||
};
|
||||
|
||||
type ContractOption = {
|
||||
publicId?: string;
|
||||
uuid?: string;
|
||||
id?: string;
|
||||
contractName?: string;
|
||||
name?: string;
|
||||
contractCode?: string;
|
||||
@@ -78,20 +74,19 @@ type CorrespondenceTypeOption = {
|
||||
};
|
||||
|
||||
type OrganizationOption = {
|
||||
uuid?: string;
|
||||
id?: number;
|
||||
publicId?: string;
|
||||
organizationCode?: string;
|
||||
organizationName?: string;
|
||||
};
|
||||
|
||||
type SelectableDrawingOption = {
|
||||
uuid?: string;
|
||||
publicId?: string;
|
||||
drawingNumber?: string;
|
||||
title?: string;
|
||||
legacyDrawingNumber?: string;
|
||||
currentRevisionUuid?: string;
|
||||
currentRevisionPublicId?: string;
|
||||
currentRevision?: {
|
||||
uuid?: string;
|
||||
publicId?: string;
|
||||
revisionLabel?: string;
|
||||
revisionNumber?: number | string;
|
||||
title?: string;
|
||||
@@ -145,11 +140,11 @@ export function RFAForm() {
|
||||
const createMutation = useCreateRFA();
|
||||
|
||||
const { data: projectsData, isLoading: isLoadingProjects } = useProjects();
|
||||
const projects = dedupeByKey(extractArrayData<ProjectOption>(projectsData), (project) => project.publicId ?? project.uuid ?? project.id);
|
||||
const projects = dedupeByKey(extractArrayData<ProjectOption>(projectsData), (project) => project.publicId);
|
||||
const { data: organizationsData, isLoading: isLoadingOrganizations } = useOrganizations({ isActive: true });
|
||||
const organizations = dedupeByKey(
|
||||
extractArrayData<OrganizationOption>(organizationsData),
|
||||
(organization) => organization.uuid ?? organization.id
|
||||
(organization) => organization.publicId
|
||||
);
|
||||
const { data: correspondenceTypesData } = useCorrespondenceTypes();
|
||||
const correspondenceTypes = extractArrayData<CorrespondenceTypeOption>(correspondenceTypesData);
|
||||
@@ -185,7 +180,7 @@ export function RFAForm() {
|
||||
const { data: contractsData, isLoading: isLoadingContracts } = useContracts(selectedProjectId);
|
||||
const contracts = dedupeByKey(
|
||||
extractArrayData<ContractOption & Contract>(contractsData),
|
||||
(contract) => contract.publicId ?? contract.uuid ?? contract.id
|
||||
(contract) => contract.publicId
|
||||
);
|
||||
|
||||
const selectedContractId = watch('contractId');
|
||||
@@ -196,27 +191,27 @@ export function RFAForm() {
|
||||
const [shopDrawingSearch, setShopDrawingSearch] = useState('');
|
||||
const [shopDrawingPage, setShopDrawingPage] = useState(1);
|
||||
const { data: shopDrawingsData, isLoading: isLoadingShopDrawings } = useDrawings('SHOP', {
|
||||
projectUuid: selectedProjectId || '',
|
||||
projectPublicId: selectedProjectId || '',
|
||||
search: shopDrawingSearch,
|
||||
page: shopDrawingPage,
|
||||
limit: 10,
|
||||
});
|
||||
const shopDrawings = dedupeByKey(
|
||||
extractArrayData<SelectableDrawingOption>(shopDrawingsData),
|
||||
(drawing) => drawing.currentRevisionUuid ?? drawing.currentRevision?.uuid ?? drawing.uuid
|
||||
(drawing) => drawing.currentRevisionPublicId ?? drawing.currentRevision?.publicId ?? drawing.publicId
|
||||
);
|
||||
|
||||
const [asBuiltDrawingSearch, setAsBuiltDrawingSearch] = useState('');
|
||||
const [asBuiltDrawingPage, setAsBuiltDrawingPage] = useState(1);
|
||||
const { data: asBuiltDrawingsData, isLoading: isLoadingAsBuiltDrawings } = useDrawings('AS_BUILT', {
|
||||
projectUuid: selectedProjectId || '',
|
||||
projectPublicId: selectedProjectId || '',
|
||||
search: asBuiltDrawingSearch,
|
||||
page: asBuiltDrawingPage,
|
||||
limit: 10,
|
||||
});
|
||||
const asBuiltDrawings = dedupeByKey(
|
||||
extractArrayData<SelectableDrawingOption>(asBuiltDrawingsData),
|
||||
(drawing) => drawing.currentRevisionUuid ?? drawing.currentRevision?.uuid ?? drawing.uuid
|
||||
(drawing) => drawing.currentRevisionPublicId ?? drawing.currentRevision?.publicId ?? drawing.publicId
|
||||
);
|
||||
const selectedDisciplineId = watch('disciplineId');
|
||||
|
||||
@@ -381,7 +376,7 @@ export function RFAForm() {
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{projects.map((p) => {
|
||||
const projectValue = getOptionValue(p.publicId ?? p.uuid ?? p.id);
|
||||
const projectValue = getOptionValue(p.publicId);
|
||||
|
||||
if (!projectValue) {
|
||||
return null;
|
||||
@@ -417,7 +412,7 @@ export function RFAForm() {
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{contracts.map((c) => {
|
||||
const contractValue = getOptionValue(getContractPublicId(c) || c.uuid);
|
||||
const contractValue = getOptionValue(c.publicId);
|
||||
|
||||
if (!contractValue) {
|
||||
return null;
|
||||
@@ -499,7 +494,7 @@ export function RFAForm() {
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{organizations.map((organization) => {
|
||||
const organizationValue = getOptionValue(organization.uuid ?? organization.id);
|
||||
const organizationValue = getOptionValue(organization.publicId);
|
||||
|
||||
if (!organizationValue) {
|
||||
return null;
|
||||
@@ -551,24 +546,24 @@ export function RFAForm() {
|
||||
)}
|
||||
<div className="grid grid-cols-1 gap-3">
|
||||
{shopDrawings.map((drawing) => {
|
||||
const revisionUuid = drawing.currentRevisionUuid ?? drawing.currentRevision?.uuid;
|
||||
const revisionPublicId = drawing.currentRevisionPublicId ?? drawing.currentRevision?.publicId;
|
||||
|
||||
if (!revisionUuid) {
|
||||
if (!revisionPublicId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<label
|
||||
key={revisionUuid}
|
||||
key={revisionPublicId}
|
||||
className="flex items-start gap-3 rounded-lg border p-3 cursor-pointer hover:bg-muted/50 transition-colors"
|
||||
>
|
||||
<Checkbox
|
||||
checked={selectedShopDrawingRevisionIds.includes(revisionUuid)}
|
||||
checked={selectedShopDrawingRevisionIds.includes(revisionPublicId)}
|
||||
onCheckedChange={(checked) => {
|
||||
const nextValues =
|
||||
checked === true
|
||||
? [...selectedShopDrawingRevisionIds, revisionUuid]
|
||||
: selectedShopDrawingRevisionIds.filter((value) => value !== revisionUuid);
|
||||
? [...selectedShopDrawingRevisionIds, revisionPublicId]
|
||||
: selectedShopDrawingRevisionIds.filter((value) => value !== revisionPublicId);
|
||||
setValue('shopDrawingRevisionIds', nextValues, { shouldDirty: true, shouldValidate: true });
|
||||
clearErrors('shopDrawingRevisionIds');
|
||||
}}
|
||||
@@ -647,24 +642,24 @@ export function RFAForm() {
|
||||
)}
|
||||
<div className="grid grid-cols-1 gap-3">
|
||||
{asBuiltDrawings.map((drawing) => {
|
||||
const revisionUuid = drawing.currentRevisionUuid ?? drawing.currentRevision?.uuid;
|
||||
const revisionPublicId = drawing.currentRevisionPublicId ?? drawing.currentRevision?.publicId;
|
||||
|
||||
if (!revisionUuid) {
|
||||
if (!revisionPublicId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<label
|
||||
key={revisionUuid}
|
||||
key={revisionPublicId}
|
||||
className="flex items-start gap-3 rounded-lg border p-3 cursor-pointer hover:bg-muted/50 transition-colors"
|
||||
>
|
||||
<Checkbox
|
||||
checked={selectedAsBuiltDrawingRevisionIds.includes(revisionUuid)}
|
||||
checked={selectedAsBuiltDrawingRevisionIds.includes(revisionPublicId)}
|
||||
onCheckedChange={(checked) => {
|
||||
const nextValues =
|
||||
checked === true
|
||||
? [...selectedAsBuiltDrawingRevisionIds, revisionUuid]
|
||||
: selectedAsBuiltDrawingRevisionIds.filter((value) => value !== revisionUuid);
|
||||
? [...selectedAsBuiltDrawingRevisionIds, revisionPublicId]
|
||||
: selectedAsBuiltDrawingRevisionIds.filter((value) => value !== revisionPublicId);
|
||||
setValue('asBuiltDrawingRevisionIds', nextValues, {
|
||||
shouldDirty: true,
|
||||
shouldValidate: true,
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
export interface ContractProjectReference {
|
||||
publicId?: string;
|
||||
id?: string;
|
||||
projectCode: string;
|
||||
projectName: string;
|
||||
}
|
||||
|
||||
export interface Contract {
|
||||
publicId?: string;
|
||||
id?: string;
|
||||
contractCode: string;
|
||||
contractName: string;
|
||||
projectId?: number | string;
|
||||
@@ -16,10 +14,3 @@ export interface Contract {
|
||||
endDate?: string;
|
||||
project?: ContractProjectReference;
|
||||
}
|
||||
|
||||
export const getContractPublicId = (contract?: Pick<Contract, 'publicId' | 'id'>): string =>
|
||||
String(contract?.publicId ?? contract?.id ?? '');
|
||||
|
||||
export const getProjectPublicId = (
|
||||
project?: Pick<ContractProjectReference, 'publicId' | 'id'>
|
||||
): string => String(project?.publicId ?? project?.id ?? '');
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
export interface Organization {
|
||||
publicId: string; // ADR-019: exposed as 'id' in API responses
|
||||
id?: number; // Excluded from API responses (ADR-019)
|
||||
publicId: string; // ADR-019: public identifier
|
||||
organizationName: string;
|
||||
organizationCode: string;
|
||||
}
|
||||
|
||||
export interface Attachment {
|
||||
publicId: string; // ADR-019: exposed as 'id' in API responses
|
||||
id?: number; // Excluded from API responses (ADR-019)
|
||||
publicId: string; // ADR-019: public identifier
|
||||
name: string;
|
||||
url: string;
|
||||
size?: number;
|
||||
@@ -17,8 +15,7 @@ export interface Attachment {
|
||||
|
||||
// Used in List View mainly
|
||||
export interface CorrespondenceRevision {
|
||||
publicId: string; // ADR-019: exposed as 'id' in API responses
|
||||
id?: number; // Excluded from API responses (ADR-019)
|
||||
publicId: string; // ADR-019: public identifier
|
||||
revisionNumber: number;
|
||||
revisionLabel?: string; // e.g. "A", "00"
|
||||
subject: string;
|
||||
@@ -42,22 +39,20 @@ export interface CorrespondenceRevision {
|
||||
|
||||
// Nested Relation from Backend Refactor
|
||||
correspondence: {
|
||||
publicId: string;
|
||||
id?: number; // Excluded from API responses (ADR-019)
|
||||
publicId: string; // ADR-019: public identifier
|
||||
correspondenceNumber: string;
|
||||
projectId: number;
|
||||
originatorId?: number;
|
||||
isInternal: boolean;
|
||||
originator?: Organization;
|
||||
project?: { publicId: string; id?: number; projectName: string; projectCode: string };
|
||||
project?: { publicId: string; projectName: string; projectCode: string };
|
||||
type?: { id: number; typeName: string; typeCode: string };
|
||||
};
|
||||
}
|
||||
|
||||
// Keep explicit Correspondence for Detail View if needed, or merge concepts
|
||||
export interface Correspondence {
|
||||
publicId: string; // ADR-019: exposed as 'id' in API responses
|
||||
id?: number; // Excluded from API responses (ADR-019)
|
||||
publicId: string; // ADR-019: public identifier
|
||||
correspondenceNumber: string;
|
||||
projectId: number;
|
||||
originatorId?: number;
|
||||
@@ -67,7 +62,7 @@ export interface Correspondence {
|
||||
|
||||
// Relations
|
||||
originator?: Organization;
|
||||
project?: { publicId: string; id?: number; projectName: string; projectCode: string };
|
||||
project?: { publicId: string; projectName: string; projectCode: string };
|
||||
type?: { id: number; typeName: string; typeCode: string };
|
||||
revisions?: CorrespondenceRevision[]; // Nested revisions
|
||||
recipients?: {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Entity Interfaces
|
||||
export interface DrawingRevision {
|
||||
publicId: string; // ADR-019: exposed as 'id' in API responses
|
||||
revisionId?: number; // Excluded from API responses (ADR-019)
|
||||
publicId: string; // ADR-019: public identifier
|
||||
revisionNumber: string;
|
||||
title?: string; // Added
|
||||
legacyDrawingNumber?: string; // Added
|
||||
@@ -15,8 +14,7 @@ export interface DrawingRevision {
|
||||
}
|
||||
|
||||
export interface ContractDrawing {
|
||||
publicId: string; // ADR-019: exposed as 'id' in API responses
|
||||
id?: number; // Excluded from API responses (ADR-019)
|
||||
publicId: string; // ADR-019: public identifier
|
||||
contractDrawingNo: string;
|
||||
title: string;
|
||||
projectId: number;
|
||||
@@ -28,8 +26,7 @@ export interface ContractDrawing {
|
||||
}
|
||||
|
||||
export interface ShopDrawing {
|
||||
publicId: string; // ADR-019: exposed as 'id' in API responses
|
||||
id?: number; // Excluded from API responses (ADR-019)
|
||||
publicId: string; // ADR-019: public identifier
|
||||
drawingNumber: string;
|
||||
projectId: number;
|
||||
mainCategoryId: number;
|
||||
@@ -41,8 +38,7 @@ export interface ShopDrawing {
|
||||
}
|
||||
|
||||
export interface AsBuiltDrawing {
|
||||
publicId: string; // ADR-019: exposed as 'id' in API responses
|
||||
id?: number; // Excluded from API responses (ADR-019)
|
||||
publicId: string; // ADR-019: public identifier
|
||||
drawingNumber: string;
|
||||
projectId: number;
|
||||
mainCategoryId: number;
|
||||
@@ -54,8 +50,7 @@ export interface AsBuiltDrawing {
|
||||
|
||||
// Unified Type for List
|
||||
export interface Drawing {
|
||||
publicId?: string; // ADR-019: exposed as 'id' in API responses
|
||||
drawingId?: number; // Excluded from API responses (ADR-019)
|
||||
publicId?: string; // ADR-019: public identifier
|
||||
drawingNumber: string;
|
||||
title: string; // Display title (from current revision for Shop/AsBuilt)
|
||||
discipline?: string | { disciplineCode: string; disciplineName: string };
|
||||
|
||||
@@ -17,7 +17,6 @@ export interface Discipline {
|
||||
codeNameTh?: string;
|
||||
isActive: boolean;
|
||||
contract?: {
|
||||
id?: number;
|
||||
publicId?: string;
|
||||
contractCode: string;
|
||||
contractName: string;
|
||||
@@ -33,7 +32,6 @@ export interface RfaType {
|
||||
remark?: string;
|
||||
isActive: boolean;
|
||||
contract?: {
|
||||
id?: number;
|
||||
publicId?: string;
|
||||
contractCode: string;
|
||||
contractName: string;
|
||||
|
||||
@@ -28,8 +28,7 @@ export interface RFAItem {
|
||||
}
|
||||
|
||||
export interface RFA {
|
||||
publicId: string; // ADR-019: from correspondence.publicId
|
||||
id?: number; // Excluded from API responses (ADR-019)
|
||||
publicId: string; // ADR-019: public identifier (from correspondence.publicId)
|
||||
rfaTypeId: number;
|
||||
createdBy: number;
|
||||
disciplineId?: number;
|
||||
@@ -56,8 +55,7 @@ export interface RFA {
|
||||
};
|
||||
// Shared Correspondence Relation
|
||||
correspondence?: {
|
||||
publicId: string;
|
||||
id?: number; // Excluded from API responses (ADR-019)
|
||||
publicId: string; // ADR-019: public identifier
|
||||
correspondenceNumber: string;
|
||||
projectId: number;
|
||||
originatorId?: number;
|
||||
|
||||
Reference in New Issue
Block a user