This commit is contained in:
@@ -308,7 +308,7 @@ export default function ContractsPage() {
|
||||
<SelectValue placeholder="Select Project" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{(projects as any[])?.map((p) => (
|
||||
{(projects as { id?: number; uuid?: string; projectCode: string; projectName: string }[])?.map((p) => (
|
||||
<SelectItem key={p.uuid || p.id} value={String(p.id || p.uuid)}>
|
||||
{p.projectCode} - {p.projectName}
|
||||
</SelectItem>
|
||||
|
||||
@@ -70,7 +70,7 @@ export default function ContractCategoriesPage() {
|
||||
)}
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{(projects as any[]).map((project) => (
|
||||
{(projects as { id?: number; uuid?: string; projectCode: string; projectName: string }[]).map((project) => (
|
||||
<SelectItem key={project.uuid || project.id} value={String(project.id || project.uuid)}>
|
||||
{project.projectCode} - {project.projectName}
|
||||
</SelectItem>
|
||||
@@ -103,9 +103,7 @@ export default function ContractCategoriesPage() {
|
||||
description="Manage main categories (หมวดหมู่หลัก) for contract drawings"
|
||||
queryKey={['contract-drawing-categories', String(selectedProjectId)]}
|
||||
fetchFn={async () => {
|
||||
console.log(`Fetching Contract Categories for project ${selectedProjectId}`);
|
||||
const data = await drawingMasterDataService.getContractCategories(selectedProjectId);
|
||||
console.log('Contract Categories Data:', data);
|
||||
return data;
|
||||
}}
|
||||
createFn={(data: Record<string, unknown>) => drawingMasterDataService.createContractCategory({ ...(data as unknown as CreateContractCategoryDto), projectId: selectedProjectId })}
|
||||
|
||||
@@ -62,7 +62,7 @@ export default function ContractSubCategoriesPage() {
|
||||
)}
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{(projects as any[]).map((project) => (
|
||||
{(projects as { id?: number; uuid?: string; projectCode: string; projectName: string }[]).map((project) => (
|
||||
<SelectItem key={project.uuid || project.id} value={String(project.id || project.uuid)}>
|
||||
{project.projectCode} - {project.projectName}
|
||||
</SelectItem>
|
||||
@@ -95,9 +95,7 @@ export default function ContractSubCategoriesPage() {
|
||||
description="Manage sub-categories (หมวดหมู่ย่อย) for contract drawings"
|
||||
queryKey={['contract-drawing-sub-categories', String(selectedProjectId)]}
|
||||
fetchFn={async () => {
|
||||
console.log(`Fetching Contract Sub-Categories for project ${selectedProjectId}`);
|
||||
const data = await drawingMasterDataService.getContractSubCategories(selectedProjectId);
|
||||
console.log('Contract Sub-Categories Data:', data);
|
||||
return data;
|
||||
}}
|
||||
createFn={(data: Record<string, unknown>) =>
|
||||
|
||||
@@ -74,7 +74,7 @@ export default function ContractVolumesPage() {
|
||||
)}
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{(projects as any[]).map((project) => (
|
||||
{(projects as { id?: number; uuid?: string; projectCode: string; projectName: string }[]).map((project) => (
|
||||
<SelectItem key={project.uuid || project.id} value={String(project.id || project.uuid)}>
|
||||
{project.projectCode} - {project.projectName}
|
||||
</SelectItem>
|
||||
|
||||
@@ -73,7 +73,7 @@ export default function ShopMainCategoriesPage() {
|
||||
)}
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{(projects as any[]).map((project) => (
|
||||
{(projects as { id?: number; uuid?: string; projectCode: string; projectName: string }[]).map((project) => (
|
||||
<SelectItem key={project.uuid || project.id} value={String(project.id || project.uuid)}>
|
||||
{project.projectCode} - {project.projectName}
|
||||
</SelectItem>
|
||||
@@ -106,9 +106,7 @@ export default function ShopMainCategoriesPage() {
|
||||
description="Manage main categories (หมวดหมู่หลัก) for shop drawings"
|
||||
queryKey={['shop-drawing-main-categories', String(selectedProjectId)]}
|
||||
fetchFn={async () => {
|
||||
console.log(`Fetching Shop Main Categories for project ${selectedProjectId}`);
|
||||
const data = await drawingMasterDataService.getShopMainCategories(selectedProjectId);
|
||||
console.log('Shop Main Categories Data:', data);
|
||||
return data;
|
||||
}}
|
||||
createFn={(data: Record<string, unknown>) =>
|
||||
|
||||
@@ -22,8 +22,6 @@ export default function ShopSubCategoriesPage() {
|
||||
const [selectedProjectId, setSelectedProjectId] = useState<string | undefined>(undefined);
|
||||
const { data: projects = [], isLoading: isLoadingProjects } = useProjects();
|
||||
|
||||
console.log('Projects Data:', projects);
|
||||
|
||||
const columns: ColumnDef<SubCategory>[] = [
|
||||
{
|
||||
accessorKey: 'subCategoryCode',
|
||||
@@ -75,7 +73,7 @@ export default function ShopSubCategoriesPage() {
|
||||
)}
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{(projects as any[]).map((project) => (
|
||||
{(projects as { id?: number; uuid?: string; projectCode: string; projectName: string }[]).map((project) => (
|
||||
<SelectItem key={project.uuid || project.id} value={String(project.id || project.uuid)}>
|
||||
{project.projectCode} - {project.projectName}
|
||||
</SelectItem>
|
||||
@@ -108,9 +106,7 @@ export default function ShopSubCategoriesPage() {
|
||||
description="Manage sub-categories (หมวดหมู่ย่อย) for shop drawings"
|
||||
queryKey={['shop-drawing-sub-categories', String(selectedProjectId)]}
|
||||
fetchFn={async () => {
|
||||
console.log(`Fetching Shop Sub-Categories for project ${selectedProjectId}`);
|
||||
const data = await drawingMasterDataService.getShopSubCategories(selectedProjectId);
|
||||
console.log('Shop Sub-Categories Data:', data);
|
||||
return data;
|
||||
}}
|
||||
createFn={(data: Record<string, unknown>) =>
|
||||
|
||||
@@ -42,7 +42,6 @@ export default function EditTemplatePage() {
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error('Failed to load template');
|
||||
console.error('[EditTemplatePage] fetchTemplate:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -57,7 +56,6 @@ export default function EditTemplatePage() {
|
||||
router.push('/admin/doc-control/numbering');
|
||||
} catch (error) {
|
||||
toast.error('Failed to update template');
|
||||
console.error('[EditTemplatePage] handleSave:', error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ export default function NewTemplatePage() {
|
||||
router.push("/admin/numbering");
|
||||
} catch (error) {
|
||||
toast.error('Failed to create template');
|
||||
console.error('[NewTemplatePage]', error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -15,6 +15,13 @@ import { toast } from 'sonner';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { useProjects, useCorrespondenceTypes, useContracts, useDisciplines } from '@/hooks/use-master-data';
|
||||
|
||||
interface ProjectItem {
|
||||
id: number | string;
|
||||
uuid?: string;
|
||||
projectName: string;
|
||||
projectCode: string;
|
||||
}
|
||||
|
||||
import { ManualOverrideForm } from '@/components/numbering/manual-override-form';
|
||||
import { MetricsDashboard } from '@/components/numbering/metrics-dashboard';
|
||||
import { AuditLogsTable } from '@/components/numbering/audit-logs-table';
|
||||
@@ -30,8 +37,8 @@ export default function NumberingPage() {
|
||||
|
||||
useEffect(() => {
|
||||
if (projects.length > 0 && !selectedProjectId) {
|
||||
const first = projects[0] as any;
|
||||
setSelectedProjectId(String(first.id ?? first.uuid));
|
||||
const first = projects[0] as ProjectItem;
|
||||
setSelectedProjectId(String(first.uuid ?? first.id));
|
||||
}
|
||||
}, [projects, selectedProjectId]);
|
||||
|
||||
@@ -41,14 +48,14 @@ export default function NumberingPage() {
|
||||
const [isTesting, setIsTesting] = useState(false);
|
||||
const [testTemplate, setTestTemplate] = useState<NumberingTemplate | null>(null);
|
||||
|
||||
const selectedProject = projects.find((p: any) => String(p.id ?? p.uuid) === selectedProjectId) as any;
|
||||
const selectedProject = (projects as ProjectItem[]).find((p) => String(p.uuid ?? p.id) === selectedProjectId);
|
||||
const selectedProjectName = selectedProject?.projectName || 'Unknown Project';
|
||||
|
||||
// Master Data
|
||||
const { data: correspondenceTypes = [] } = useCorrespondenceTypes();
|
||||
const { data: contracts = [] } = useContracts(selectedProjectId as any); // Passing UUID/ID string
|
||||
const firstContract = contracts[0] as any;
|
||||
const contractId = firstContract?.id || firstContract?.uuid;
|
||||
const { data: contracts = [] } = useContracts(selectedProjectId);
|
||||
const firstContract = contracts[0] as { id?: number; uuid?: string } | undefined;
|
||||
const contractId = firstContract?.uuid ?? firstContract?.id;
|
||||
const { data: disciplines = [] } = useDisciplines(contractId);
|
||||
|
||||
const { data: templateResponse, isLoading: isLoadingTemplates } = useTemplates();
|
||||
@@ -57,7 +64,7 @@ export default function NumberingPage() {
|
||||
// Extract templates array from response
|
||||
const templates: NumberingTemplate[] = Array.isArray(templateResponse)
|
||||
? templateResponse
|
||||
: ((templateResponse as any)?.data ?? []);
|
||||
: ((templateResponse as { data?: NumberingTemplate[] } | undefined)?.data ?? []);
|
||||
|
||||
const handleEdit = (template?: NumberingTemplate) => {
|
||||
setActiveTemplate(template);
|
||||
@@ -84,7 +91,7 @@ export default function NumberingPage() {
|
||||
<div className="p-6 max-w-4xl mx-auto animate-in fade-in slide-in-from-bottom-4">
|
||||
<TemplateEditor
|
||||
template={activeTemplate}
|
||||
projectId={selectedProjectId as any}
|
||||
projectId={selectedProjectId}
|
||||
projectName={selectedProjectName}
|
||||
correspondenceTypes={correspondenceTypes}
|
||||
disciplines={disciplines}
|
||||
@@ -108,8 +115,8 @@ export default function NumberingPage() {
|
||||
<SelectValue placeholder="Select Project" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{(projects as any[]).map((project) => (
|
||||
<SelectItem key={project.id ?? project.uuid} value={String(project.id ?? project.uuid)}>
|
||||
{(projects as ProjectItem[]).map((project) => (
|
||||
<SelectItem key={String(project.uuid ?? project.id)} value={String(project.uuid ?? project.id)}>
|
||||
{project.projectCode} - {project.projectName}
|
||||
</SelectItem>
|
||||
))}
|
||||
@@ -137,7 +144,7 @@ export default function NumberingPage() {
|
||||
<div className="lg:col-span-2 space-y-4">
|
||||
<div className="grid gap-4">
|
||||
{templates
|
||||
.filter((t: any) => !t.projectId || String(t.project?.id ?? t.project?.uuid) === selectedProjectId || t.project?.uuid === selectedProjectId)
|
||||
.filter((t) => !t.projectId || String(t.project?.id ?? t.project?.uuid) === selectedProjectId || t.project?.uuid === selectedProjectId)
|
||||
.map((template) => (
|
||||
<Card key={template.id} className="p-6 hover:shadow-md transition-shadow">
|
||||
<div className="flex justify-between items-start">
|
||||
@@ -202,11 +209,11 @@ export default function NumberingPage() {
|
||||
|
||||
<TabsContent value="tools" className="space-y-4">
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
<ManualOverrideForm projectId={selectedProjectId as any} />
|
||||
<VoidReplaceForm projectId={selectedProjectId as any} />
|
||||
<ManualOverrideForm projectId={selectedProjectId} />
|
||||
<VoidReplaceForm projectId={selectedProjectId} />
|
||||
<CancelNumberForm />
|
||||
<div className="md:col-span-2">
|
||||
<BulkImportForm projectId={selectedProjectId as any} />
|
||||
<BulkImportForm projectId={selectedProjectId} />
|
||||
</div>
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
@@ -58,12 +58,15 @@ export default function DisciplinesPage() {
|
||||
fetchFn={async () => {
|
||||
const items = await masterDataService.getDisciplines(selectedContractId ? selectedContractId : undefined);
|
||||
// ADR-019: Map contractId INT → contract UUID for edit mode select matching
|
||||
return (items as any[]).map((item: any) => ({
|
||||
...item,
|
||||
contractId: item.contract?.id || item.contract?.uuid || String(item.contractId),
|
||||
}));
|
||||
return (items as Record<string, unknown>[]).map((item) => {
|
||||
const rec = item as { contract?: { id?: number; uuid?: string }; contractId?: number };
|
||||
return {
|
||||
...item,
|
||||
contractId: rec.contract?.id || rec.contract?.uuid || String(rec.contractId),
|
||||
};
|
||||
});
|
||||
}}
|
||||
createFn={(data: Record<string, unknown>) => masterDataService.createDiscipline(data as any)}
|
||||
createFn={(data) => masterDataService.createDiscipline(data as unknown as Parameters<typeof masterDataService.createDiscipline>[0])}
|
||||
updateFn={(id, data) => Promise.reject('Not implemented yet')}
|
||||
deleteFn={(id) => masterDataService.deleteDiscipline(id)}
|
||||
columns={columns}
|
||||
|
||||
@@ -61,12 +61,15 @@ export default function RfaTypesPage() {
|
||||
fetchFn={async () => {
|
||||
const items = await masterDataService.getRfaTypes(selectedContractId ? selectedContractId : undefined);
|
||||
// ADR-019: Map contractId INT → contract UUID for edit mode select matching
|
||||
return (items as any[]).map((item: any) => ({
|
||||
...item,
|
||||
contractId: item.contract?.id || item.contract?.uuid || String(item.contractId),
|
||||
}));
|
||||
return (items as Record<string, unknown>[]).map((item) => {
|
||||
const rec = item as { contract?: { id?: number; uuid?: string }; contractId?: number };
|
||||
return {
|
||||
...item,
|
||||
contractId: rec.contract?.id || rec.contract?.uuid || String(rec.contractId),
|
||||
};
|
||||
});
|
||||
}}
|
||||
createFn={(data: Record<string, unknown>) => masterDataService.createRfaType(data as any)}
|
||||
createFn={(data) => masterDataService.createRfaType(data as unknown as Parameters<typeof masterDataService.createRfaType>[0])}
|
||||
updateFn={(id, data) => masterDataService.updateRfaType(id, data)}
|
||||
deleteFn={(id) => masterDataService.deleteRfaType(id)}
|
||||
columns={columns}
|
||||
|
||||
@@ -73,10 +73,13 @@ export default function TagsPage() {
|
||||
fetchFn={async () => {
|
||||
const items = await masterDataService.getTags();
|
||||
// ADR-019: Map project_id INT → project UUID for edit mode select matching
|
||||
return (items as any[]).map((item: any) => ({
|
||||
...item,
|
||||
project_id: item.project?.id || item.project?.uuid || (item.project_id ? String(item.project_id) : null),
|
||||
}));
|
||||
return (items as Record<string, unknown>[]).map((item) => {
|
||||
const rec = item as { project?: { id?: number; uuid?: string }; project_id?: number };
|
||||
return {
|
||||
...item,
|
||||
project_id: rec.project?.id || rec.project?.uuid || (rec.project_id ? String(rec.project_id) : null),
|
||||
};
|
||||
});
|
||||
}}
|
||||
createFn={(data: Record<string, unknown>) => masterDataService.createTag(formatPayload(data) as unknown as CreateTagDto)}
|
||||
updateFn={(id, data) => masterDataService.updateTag(id, formatPayload(data))}
|
||||
|
||||
@@ -71,7 +71,6 @@ export default function WorkflowEditPage() {
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error('Failed to save workflow');
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ export default function NewWorkflowPage() {
|
||||
router.push('/admin/doc-control/workflows');
|
||||
} catch (error) {
|
||||
toast.error('Failed to create workflow');
|
||||
console.error('[NewWorkflowPage]', error);
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ export default function SessionManagementPage() {
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.error('Failed to revoke session');
|
||||
console.error(error);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -86,8 +86,8 @@ export default function AdminPage() {
|
||||
</div>
|
||||
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{stats.map((stat, index) => (
|
||||
<Card key={index} className="hover:shadow-md transition-shadow">
|
||||
{stats.map((stat) => (
|
||||
<Card key={stat.title} className="hover:shadow-md transition-shadow">
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">{stat.title}</CardTitle>
|
||||
<stat.icon className={`h-4 w-4 ${stat.color}`} />
|
||||
@@ -111,8 +111,8 @@ export default function AdminPage() {
|
||||
<div>
|
||||
<h2 className="text-xl font-semibold mb-4">Quick Access</h2>
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{quickLinks.map((link, index) => (
|
||||
<Link key={index} href={link.href}>
|
||||
{quickLinks.map((link) => (
|
||||
<Link key={link.href} href={link.href}>
|
||||
<Card className="h-full hover:bg-muted/50 transition-colors cursor-pointer border-l-4 border-l-transparent hover:border-l-primary">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center text-lg">
|
||||
|
||||
Reference in New Issue
Block a user