This commit is contained in:
@@ -44,7 +44,7 @@ export default function UsersPage() {
|
||||
|
||||
const { data: users, isLoading } = useUsers({
|
||||
search: search || undefined,
|
||||
primaryOrganizationId: selectedOrgId ? parseInt(selectedOrgId) : undefined,
|
||||
primaryOrganizationId: selectedOrgId ?? undefined,
|
||||
});
|
||||
|
||||
const { data: organizations = [] } = useOrganizations();
|
||||
@@ -94,7 +94,7 @@ export default function UsersPage() {
|
||||
header: "Organization",
|
||||
cell: ({ row }) => {
|
||||
const orgId = row.original.primaryOrganizationId;
|
||||
const org = (organizations as Organization[]).find((o) => o.id === orgId);
|
||||
const org = (organizations as Organization[]).find((o) => (o.id ?? o.uuid) === orgId?.toString() || o.uuid === orgId?.toString());
|
||||
return org ? org.organizationCode : "-";
|
||||
},
|
||||
},
|
||||
@@ -186,7 +186,7 @@ export default function UsersPage() {
|
||||
<SelectContent>
|
||||
<SelectItem value="all">All Organizations</SelectItem>
|
||||
{Array.isArray(organizations) && (organizations as Organization[]).map((org) => (
|
||||
<SelectItem key={org.uuid} value={(org.id ?? org.uuid).toString()}>
|
||||
<SelectItem key={org.uuid} value={org.uuid}>
|
||||
{org.organizationCode} - {org.organizationName}
|
||||
</SelectItem>
|
||||
))}
|
||||
|
||||
@@ -14,7 +14,7 @@ function RFAsContent() {
|
||||
const page = parseInt(searchParams.get('page') || '1');
|
||||
const statusId = searchParams.get('status') ? parseInt(searchParams.get('status')!) : undefined;
|
||||
const search = searchParams.get('search') || undefined;
|
||||
const projectId = searchParams.get('projectId') ? parseInt(searchParams.get('projectId')!) : undefined;
|
||||
const projectId = searchParams.get('projectId') || undefined; // ADR-019: Pass UUID string directly
|
||||
|
||||
const revisionStatus = (searchParams.get('revisionStatus') as 'CURRENT' | 'ALL' | 'OLD') || 'CURRENT';
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ const userSchema = z.object({
|
||||
confirmPassword: z.string().optional(),
|
||||
isActive: z.boolean().optional(),
|
||||
lineId: z.string().optional(),
|
||||
primaryOrganizationId: z.number().optional(),
|
||||
primaryOrganizationId: z.string().optional(),
|
||||
roleIds: z.array(z.number()).optional(),
|
||||
}).refine((data) => {
|
||||
// If password is provided (creating or resetting), confirmPassword must match
|
||||
@@ -107,7 +107,7 @@ export function UserDialog({ open, onOpenChange, user }: UserDialogProps) {
|
||||
lastName: user.lastName,
|
||||
isActive: user.isActive,
|
||||
lineId: user.lineId || "",
|
||||
primaryOrganizationId: user.primaryOrganizationId,
|
||||
primaryOrganizationId: user.primaryOrganizationId?.toString(),
|
||||
roleIds: user.roles?.map((r: any) => r.roleId) || [],
|
||||
password: "",
|
||||
confirmPassword: ""
|
||||
@@ -221,22 +221,19 @@ export function UserDialog({ open, onOpenChange, user }: UserDialogProps) {
|
||||
<div>
|
||||
<Label>Primary Organization</Label>
|
||||
<Select
|
||||
value={watch("primaryOrganizationId")?.toString()}
|
||||
value={watch("primaryOrganizationId") ?? undefined}
|
||||
onValueChange={(val) =>
|
||||
setValue("primaryOrganizationId", parseInt(val))
|
||||
setValue("primaryOrganizationId", val)
|
||||
}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select Organization" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{/* TODO: ADR-019 — Backend DTO needs to accept UUID for primaryOrganization.
|
||||
Currently using org.id which is excluded from API responses.
|
||||
Temporary: org.id may still exist in some query responses. */}
|
||||
{organizations?.map((org: any) => (
|
||||
<SelectItem
|
||||
key={org.uuid ?? org.id}
|
||||
value={(org.id ?? 0).toString()}
|
||||
key={org.uuid}
|
||||
value={org.uuid}
|
||||
>
|
||||
{org.organizationCode} - {org.organizationName}
|
||||
</SelectItem>
|
||||
|
||||
@@ -80,7 +80,7 @@ export function DrawingUploadForm({ projectId = 1 }: DrawingUploadFormProps) {
|
||||
const router = useRouter();
|
||||
|
||||
// Hooks
|
||||
const { data: contractCategories } = useContractDrawingCategories();
|
||||
const { data: contractCategories } = useContractDrawingCategories(projectId);
|
||||
const { data: shopMainCats } = useShopMainCategories(projectId);
|
||||
|
||||
const [selectedShopMainCat, setSelectedShopMainCat] = useState<number | undefined>();
|
||||
@@ -202,7 +202,7 @@ export function DrawingUploadForm({ projectId = 1 }: DrawingUploadFormProps) {
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{contractCategories?.map((c: any) => (
|
||||
<SelectItem key={c.id} value={String(c.id)}>{c.name}</SelectItem>
|
||||
<SelectItem key={c.id} value={String(c.id)}>{c.catName || c.catCode || c.name}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
@@ -253,7 +253,7 @@ export function DrawingUploadForm({ projectId = 1 }: DrawingUploadFormProps) {
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{shopMainCats?.map((c: any) => (
|
||||
<SelectItem key={c.id} value={String(c.id)}>{c.name}</SelectItem>
|
||||
<SelectItem key={c.id} value={String(c.id)}>{c.mainCategoryName || c.mainCategoryCode || c.name}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
@@ -269,7 +269,7 @@ export function DrawingUploadForm({ projectId = 1 }: DrawingUploadFormProps) {
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{shopSubCats?.map((c: any) => (
|
||||
<SelectItem key={c.id} value={String(c.id)}>{c.name}</SelectItem>
|
||||
<SelectItem key={c.id} value={String(c.id)}>{c.subCategoryName || c.subCategoryCode || c.name}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
@@ -323,7 +323,7 @@ export function DrawingUploadForm({ projectId = 1 }: DrawingUploadFormProps) {
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{shopMainCats?.map((c: any) => (
|
||||
<SelectItem key={c.id} value={String(c.id)}>{c.name}</SelectItem>
|
||||
<SelectItem key={c.id} value={String(c.id)}>{c.mainCategoryName || c.mainCategoryCode || c.name}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
@@ -339,7 +339,7 @@ export function DrawingUploadForm({ projectId = 1 }: DrawingUploadFormProps) {
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{shopSubCats?.map((c: any) => (
|
||||
<SelectItem key={c.id} value={String(c.id)}>{c.name}</SelectItem>
|
||||
<SelectItem key={c.id} value={String(c.id)}>{c.subCategoryName || c.subCategoryCode || c.name}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
@@ -37,7 +37,7 @@ const VARIABLES = [
|
||||
|
||||
export interface TemplateEditorProps {
|
||||
template?: NumberingTemplate;
|
||||
projectId: number;
|
||||
projectId: number | string;
|
||||
projectName: string;
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
correspondenceTypes: any[];
|
||||
|
||||
@@ -30,14 +30,14 @@ const rfaItemSchema = z.object({
|
||||
unit: z.string().min(1, "Unit is required"),
|
||||
});
|
||||
const rfaSchema = z.object({
|
||||
contractId: z.number().min(1, "Contract is required"),
|
||||
contractId: z.string().min(1, "Contract is required"),
|
||||
disciplineId: z.number().min(1, "Discipline is required"),
|
||||
rfaTypeId: z.number().min(1, "Type is required"),
|
||||
subject: z.string().min(5, "Subject must be at least 5 characters"),
|
||||
description: z.string().optional(),
|
||||
body: z.string().optional(),
|
||||
remarks: z.string().optional(),
|
||||
toOrganizationId: z.number().min(1, "Please select To Organization"),
|
||||
toOrganizationId: z.string().min(1, "Please select To Organization"),
|
||||
dueDate: z.string().optional(),
|
||||
shopDrawingRevisionIds: z.array(z.number()).optional(),
|
||||
items: z.array(rfaItemSchema).min(1, "At least one item is required"),
|
||||
@@ -63,14 +63,14 @@ export function RFAForm() {
|
||||
} = useForm<RFAFormData>({
|
||||
resolver: zodResolver(rfaSchema),
|
||||
defaultValues: {
|
||||
contractId: 0,
|
||||
contractId: "",
|
||||
disciplineId: 0,
|
||||
rfaTypeId: 0,
|
||||
subject: "",
|
||||
description: "",
|
||||
body: "",
|
||||
remarks: "",
|
||||
toOrganizationId: 0,
|
||||
toOrganizationId: "",
|
||||
dueDate: "",
|
||||
shopDrawingRevisionIds: [],
|
||||
items: [{ itemNo: "1", description: "", quantity: 0, unit: "" }],
|
||||
@@ -182,7 +182,7 @@ export function RFAForm() {
|
||||
<div>
|
||||
<Label>Contract *</Label>
|
||||
<Select
|
||||
onValueChange={(val) => setValue("contractId", Number(val))}
|
||||
onValueChange={(val) => setValue("contractId", val)}
|
||||
disabled={isLoadingContracts}
|
||||
>
|
||||
<SelectTrigger>
|
||||
@@ -190,8 +190,8 @@ export function RFAForm() {
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{contracts?.map((c: any) => (
|
||||
<SelectItem key={c.id || c.contract_id} value={String(c.id || c.contract_id)}>
|
||||
{c.name || c.contract_no}
|
||||
<SelectItem key={c.id} value={String(c.id)}>
|
||||
{c.contractName || c.name || c.contractCode}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
|
||||
@@ -59,7 +59,7 @@ const itemSchema = z.object({
|
||||
|
||||
// Main form schema
|
||||
const formSchema = z.object({
|
||||
correspondenceId: z.number().min(1, "Correspondence is required"), // Linked correspondence (e.g. Originator Letter)
|
||||
correspondenceId: z.string().min(1, "Correspondence is required"), // ADR-019: UUID string
|
||||
subject: z.string().min(1, "Subject is required"),
|
||||
purpose: z.enum(["FOR_APPROVAL", "FOR_INFORMATION", "FOR_REVIEW", "OTHER"]),
|
||||
remarks: z.string().optional(),
|
||||
@@ -127,7 +127,7 @@ export function TransmittalForm() {
|
||||
|
||||
const selectedDocId = form.watch("correspondenceId");
|
||||
const selectedDoc = correspondences?.data?.find(
|
||||
(c: { id: number }) => c.id === selectedDocId
|
||||
(c: { uuid: string }) => c.uuid === selectedDocId
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -172,19 +172,19 @@ export function TransmittalForm() {
|
||||
<CommandEmpty>No document found.</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{correspondences?.data?.map(
|
||||
(doc: { id: number; correspondence_number: string }) => (
|
||||
(doc: { uuid: string; correspondence_number: string }) => (
|
||||
<CommandItem
|
||||
key={doc.id}
|
||||
key={doc.uuid}
|
||||
value={doc.correspondence_number}
|
||||
onSelect={() => {
|
||||
form.setValue("correspondenceId", doc.id);
|
||||
form.setValue("correspondenceId", doc.uuid);
|
||||
setDocOpen(false);
|
||||
}}
|
||||
>
|
||||
<Check
|
||||
className={cn(
|
||||
"mr-2 h-4 w-4",
|
||||
doc.id === field.value
|
||||
doc.uuid === field.value
|
||||
? "opacity-100"
|
||||
: "opacity-0"
|
||||
)}
|
||||
|
||||
@@ -104,10 +104,11 @@ export function useCorrespondenceTypes() {
|
||||
|
||||
// --- Drawing Categories Hooks ---
|
||||
|
||||
export function useContractDrawingCategories() {
|
||||
export function useContractDrawingCategories(projectId?: number | string) {
|
||||
return useQuery({
|
||||
queryKey: ['contract-drawing-categories'],
|
||||
queryFn: () => masterDataService.getContractDrawingCategories(),
|
||||
queryKey: ['contract-drawing-categories', projectId],
|
||||
queryFn: () => masterDataService.getContractDrawingCategories(projectId),
|
||||
enabled: !!projectId,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import apiClient from '@/lib/api/client';
|
||||
*/
|
||||
export interface NumberingTemplate {
|
||||
id: number;
|
||||
projectId: number;
|
||||
projectId: number | string;
|
||||
correspondenceTypeId: number | null; // null = Default Format for project
|
||||
correspondenceType?: {
|
||||
id: number;
|
||||
@@ -18,9 +18,10 @@ export interface NumberingTemplate {
|
||||
typeName: string;
|
||||
} | null;
|
||||
project?: {
|
||||
id: number;
|
||||
id: number | string;
|
||||
projectCode: string;
|
||||
projectName: string;
|
||||
uuid?: string;
|
||||
};
|
||||
formatTemplate: string;
|
||||
description?: string;
|
||||
|
||||
@@ -187,8 +187,10 @@ export const masterDataService = {
|
||||
|
||||
// --- Drawing Categories ---
|
||||
|
||||
getContractDrawingCategories: async () => {
|
||||
const response = await apiClient.get("/drawings/contract/categories");
|
||||
getContractDrawingCategories: async (projectId?: number | string) => {
|
||||
const response = await apiClient.get("/drawings/contract/categories", {
|
||||
params: { projectId }
|
||||
});
|
||||
return response.data.data || response.data;
|
||||
},
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ const mapWorkflow = (backendObj: any): Workflow => {
|
||||
workflowId: backendObj.id,
|
||||
workflowName: backendObj.dsl?.workflowName || backendObj.workflow_code,
|
||||
description: backendObj.description || backendObj.dsl?.description || '',
|
||||
workflowType: backendObj.workflow_code,
|
||||
workflowType: backendObj.workflow_code?.toUpperCase() || backendObj.workflow_code,
|
||||
version: backendObj.version || 1,
|
||||
isActive: backendObj.is_active,
|
||||
dslDefinition: typeof backendObj.dsl === 'string' ? backendObj.dsl : backendObj.dsl?.dslDefinition || JSON.stringify(backendObj.dsl, null, 2),
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
// --- Create ---
|
||||
export interface CreateRfaDto {
|
||||
/** ID ของโครงการ */
|
||||
projectId: number;
|
||||
/** ID or UUID ของโครงการ */
|
||||
projectId: number | string; // ADR-019: Accept UUID
|
||||
|
||||
/** ประเภท RFA (เช่น DWG, MAT) */
|
||||
rfaTypeId: number;
|
||||
@@ -20,8 +20,11 @@ export interface CreateRfaDto {
|
||||
/** หมายเหตุ */
|
||||
remarks?: string;
|
||||
|
||||
/** Contract UUID (optional) */
|
||||
contractId?: string; // ADR-019: Contract UUID
|
||||
|
||||
/** ส่งถึงใคร (สำหรับ Routing Step 1) */
|
||||
toOrganizationId: number;
|
||||
toOrganizationId: number | string; // ADR-019: Accept UUID
|
||||
|
||||
/** รายละเอียดเพิ่มเติม */
|
||||
description?: string;
|
||||
@@ -41,8 +44,8 @@ export type UpdateRfaDto = Partial<CreateRfaDto>;
|
||||
|
||||
// --- Search ---
|
||||
export interface SearchRfaDto {
|
||||
/** Filter by Project ID (optional to allow cross-project search) */
|
||||
projectId?: number;
|
||||
/** Filter by Project ID or UUID (optional to allow cross-project search) */
|
||||
projectId?: number | string; // ADR-019: Accept UUID
|
||||
|
||||
/** กรองตามประเภท RFA */
|
||||
rfaTypeId?: number;
|
||||
|
||||
@@ -9,12 +9,12 @@ export enum TransmittalPurpose {
|
||||
|
||||
// --- Create ---
|
||||
export interface CreateTransmittalDto {
|
||||
projectId?: number;
|
||||
recipientOrganizationId?: number;
|
||||
projectId?: number | string; // ADR-019: Accept UUID
|
||||
recipientOrganizationId?: number | string; // ADR-019: Accept UUID
|
||||
subject: string;
|
||||
purpose?: string;
|
||||
remarks?: string;
|
||||
correspondenceId: number; // For now linked correspondence
|
||||
correspondenceId: number | string; // ADR-019: Accept UUID
|
||||
items: CreateTransmittalItemDto[];
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ export type UpdateTransmittalDto = Partial<CreateTransmittalDto>;
|
||||
// --- Search ---
|
||||
export interface SearchTransmittalDto {
|
||||
/** บังคับระบุ Project */
|
||||
projectId: number;
|
||||
projectId: number | string; // ADR-019: Accept UUID
|
||||
|
||||
purpose?: TransmittalPurpose;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ export interface CreateUserDto {
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
lineId?: string;
|
||||
primaryOrganizationId?: number;
|
||||
primaryOrganizationId?: number | string; // ADR-019: Accept UUID
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,9 @@ export interface RFA {
|
||||
}
|
||||
|
||||
export interface CreateRFADto {
|
||||
projectId: number;
|
||||
projectId: number | string; // ADR-019: Accept UUID
|
||||
contractId?: string; // ADR-019: Contract UUID
|
||||
toOrganizationId?: number | string; // ADR-019: Recipient org UUID
|
||||
rfaTypeId: number;
|
||||
disciplineId?: number;
|
||||
subject: string;
|
||||
|
||||
@@ -20,7 +20,7 @@ export interface User {
|
||||
lastName: string;
|
||||
isActive: boolean;
|
||||
lineId?: string;
|
||||
primaryOrganizationId?: number;
|
||||
primaryOrganizationId?: number | string; // ADR-019: May be INT or UUID
|
||||
organization?: UserOrganization;
|
||||
roles?: Role[];
|
||||
|
||||
@@ -42,7 +42,7 @@ export interface CreateUserDto {
|
||||
password?: string;
|
||||
isActive: boolean;
|
||||
lineId?: string;
|
||||
primaryOrganizationId?: number;
|
||||
primaryOrganizationId?: number | string; // ADR-019: Accept UUID
|
||||
roleIds: number[];
|
||||
}
|
||||
|
||||
@@ -53,5 +53,5 @@ export interface SearchUserDto {
|
||||
limit?: number;
|
||||
search?: string;
|
||||
roleId?: number;
|
||||
primaryOrganizationId?: number;
|
||||
primaryOrganizationId?: number | string; // ADR-019: Accept UUID
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user