690526:1239 ADR-023-229 dynamic prompt #03
This commit is contained in:
@@ -80,7 +80,7 @@ export default function OrganizationsPage() {
|
|||||||
header: 'Role',
|
header: 'Role',
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const roleId = row.getValue('roleId') as number;
|
const roleId = row.getValue('roleId') as number;
|
||||||
const role = ORGANIZATION_ROLES.find((r) => r.value === roleId?.toString());
|
const role = Array.isArray(ORGANIZATION_ROLES) ? ORGANIZATION_ROLES.find((r) => r.value === roleId?.toString()) : undefined;
|
||||||
return role ? role.label : '-';
|
return role ? role.label : '-';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -99,9 +99,9 @@ export default function UsersPage() {
|
|||||||
return 'All Organizations';
|
return 'All Organizations';
|
||||||
}
|
}
|
||||||
|
|
||||||
const org = organizationList.find(
|
const org = Array.isArray(organizationList) ? organizationList.find(
|
||||||
(o) => (o.id ?? o.publicId) === orgId?.toString() || o.publicId === orgId?.toString()
|
(o) => (o.id ?? o.publicId) === orgId?.toString() || o.publicId === orgId?.toString()
|
||||||
);
|
) : undefined;
|
||||||
return org ? org.organizationCode : 'All Organizations';
|
return org ? org.organizationCode : 'All Organizations';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ function ManageMappings({ projectId }: { projectId: string }) {
|
|||||||
{subCategories
|
{subCategories
|
||||||
.filter(
|
.filter(
|
||||||
(s: ContractSubCategory) =>
|
(s: ContractSubCategory) =>
|
||||||
!mappings.find((m: Record<string, unknown>) => {
|
!Array.isArray(mappings) || !mappings.find((m: Record<string, unknown>) => {
|
||||||
const sub = m.subCategory as { id?: number } | undefined;
|
const sub = m.subCategory as { id?: number } | undefined;
|
||||||
return sub?.id === s.id;
|
return sub?.id === s.id;
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -31,10 +31,11 @@ export default function EditTemplatePage() {
|
|||||||
const contractId = getContractPublicId(firstContract);
|
const contractId = getContractPublicId(firstContract);
|
||||||
const { data: disciplines = [] } = useDisciplines(contractId);
|
const { data: disciplines = [] } = useDisciplines(contractId);
|
||||||
|
|
||||||
const selectedProjectName =
|
const selectedProjectName = Array.isArray(projects)
|
||||||
(projects as Array<{ id?: number; publicId?: string; projectCode: string; projectName: string }>).find((p) =>
|
? (projects as Array<{ id?: number; publicId?: string; projectCode: string; projectName: string }>).find((p) =>
|
||||||
String(p.publicId ?? p.id) === String(projectId))
|
String(p.publicId ?? p.id) === String(projectId))
|
||||||
?.projectName || 'LCBP3';
|
?.projectName || 'LCBP3'
|
||||||
|
: 'LCBP3';
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchTemplate = async () => {
|
const fetchTemplate = async () => {
|
||||||
|
|||||||
@@ -21,9 +21,10 @@ export default function NewTemplatePage() {
|
|||||||
const contractId = getContractPublicId(firstContract);
|
const contractId = getContractPublicId(firstContract);
|
||||||
const { data: disciplines = [] } = useDisciplines(contractId);
|
const { data: disciplines = [] } = useDisciplines(contractId);
|
||||||
|
|
||||||
const selectedProjectName =
|
const selectedProjectName = Array.isArray(projects)
|
||||||
(projects as Array<{ id?: number; publicId?: string; projectName: string }>).find((p) =>
|
? (projects as Array<{ id?: number; publicId?: string; projectName: string }>).find((p) =>
|
||||||
String(p.publicId ?? p.id) === String(projectId))?.projectName || 'LCBP3';
|
String(p.publicId ?? p.id) === String(projectId))?.projectName || 'LCBP3'
|
||||||
|
: 'LCBP3';
|
||||||
|
|
||||||
const handleSave = async (data: Partial<NumberingTemplate>) => {
|
const handleSave = async (data: Partial<NumberingTemplate>) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export default function NumberingPage() {
|
|||||||
const [isTesting, setIsTesting] = useState(false);
|
const [isTesting, setIsTesting] = useState(false);
|
||||||
const [testTemplate, setTestTemplate] = useState<NumberingTemplate | null>(null);
|
const [testTemplate, setTestTemplate] = useState<NumberingTemplate | null>(null);
|
||||||
|
|
||||||
const selectedProject = (projects as ProjectItem[]).find((p) => String(p.publicId) === selectedProjectId);
|
const selectedProject = Array.isArray(projects) ? (projects as ProjectItem[]).find((p) => String(p.publicId) === selectedProjectId) : undefined;
|
||||||
const selectedProjectName = selectedProject?.projectName || 'Unknown Project';
|
const selectedProjectName = selectedProject?.projectName || 'Unknown Project';
|
||||||
|
|
||||||
// Master Data
|
// Master Data
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// - 2026-05-25: Created OcrSandboxPromptManager component for dynamic prompt editing, version control, and sandbox testing (ADR-029)
|
// - 2026-05-25: Created OcrSandboxPromptManager component for dynamic prompt editing, version control, and sandbox testing (ADR-029)
|
||||||
// - 2026-05-25: Extracted inline strings to i18n keys via useTranslations() (Obs #1 fix)
|
// - 2026-05-25: Extracted inline strings to i18n keys via useTranslations() (Obs #1 fix)
|
||||||
// - 2026-05-25: Refactored sandbox polling to useSandboxRun hook (Obs #2 fix)
|
// - 2026-05-25: Refactored sandbox polling to useSandboxRun hook (Obs #2 fix)
|
||||||
|
// - 2026-05-26: เพิ่มการตรวจสอบ versionsQuery.data แบบทนทานเพื่อป้องกัน Error N.find is not a function ในกรณีที่ API ส่งข้อมูลแบบ wrapped object มา
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
@@ -43,7 +44,12 @@ export default function OcrSandboxPromptManager() {
|
|||||||
deleteMutation,
|
deleteMutation,
|
||||||
updateNoteMutation,
|
updateNoteMutation,
|
||||||
} = useAiPrompts(promptType);
|
} = useAiPrompts(promptType);
|
||||||
const versions = versionsQuery.data ?? [];
|
const versionsData = versionsQuery.data;
|
||||||
|
const versions = Array.isArray(versionsData)
|
||||||
|
? versionsData
|
||||||
|
: (versionsData && typeof versionsData === 'object' && 'data' in versionsData && Array.isArray((versionsData as { data: unknown }).data))
|
||||||
|
? (versionsData as { data: AiPrompt[] }).data
|
||||||
|
: [];
|
||||||
const activePrompt = versions.find((v) => v.isActive);
|
const activePrompt = versions.find((v) => v.isActive);
|
||||||
const [templateText, setTemplateText] = useState<string>('');
|
const [templateText, setTemplateText] = useState<string>('');
|
||||||
const [ocrFile, setOcrFile] = useState<File | null>(null);
|
const [ocrFile, setOcrFile] = useState<File | null>(null);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// File: frontend/lib/services/ai-prompts.service.ts
|
// File: frontend/lib/services/ai-prompts.service.ts
|
||||||
// Change Log
|
// Change Log
|
||||||
// - 2026-05-25: Created aiPromptsService for prompt versioning and sandbox operations (ADR-029)
|
// - 2026-05-25: Created aiPromptsService for prompt versioning and sandbox operations (ADR-029)
|
||||||
|
// - 2026-05-26: แก้ไขการ unwrap ข้อมูลจาก TransformInterceptor ที่ซ้อนกันหลายชั้นเพื่อป้องกันข้อผิดพลาด N.find is not a function
|
||||||
|
|
||||||
import api from '../api/client';
|
import api from '../api/client';
|
||||||
import { AiPrompt } from '../../types/ai-prompts';
|
import { AiPrompt } from '../../types/ai-prompts';
|
||||||
@@ -12,6 +13,17 @@ const extractData = <T>(value: unknown): T => {
|
|||||||
return value as T;
|
return value as T;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันช่วย unwrap ข้อมูลจาก API Response ที่อาจจะถูก wrap ซ้อนกันหลายชั้นโดย TransformInterceptor
|
||||||
|
*/
|
||||||
|
const unwrapResponse = <T>(value: unknown): T => {
|
||||||
|
const extracted = extractData<T>(value);
|
||||||
|
if (extracted && typeof extracted === 'object' && 'data' in extracted) {
|
||||||
|
return (extracted as { data: T }).data;
|
||||||
|
}
|
||||||
|
return extracted;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service สำหรับเรียก API ในการจัดการ AI prompt templates ทางฝั่งหน้าบ้าน
|
* Service สำหรับเรียก API ในการจัดการ AI prompt templates ทางฝั่งหน้าบ้าน
|
||||||
*/
|
*/
|
||||||
@@ -21,7 +33,7 @@ export const aiPromptsService = {
|
|||||||
*/
|
*/
|
||||||
listVersions: async (promptType: string): Promise<AiPrompt[]> => {
|
listVersions: async (promptType: string): Promise<AiPrompt[]> => {
|
||||||
const { data } = await api.get(`/ai/prompts/${encodeURIComponent(promptType)}`);
|
const { data } = await api.get(`/ai/prompts/${encodeURIComponent(promptType)}`);
|
||||||
return extractData<AiPrompt[]>(data);
|
return unwrapResponse<AiPrompt[]>(data);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,7 +41,7 @@ export const aiPromptsService = {
|
|||||||
*/
|
*/
|
||||||
createVersion: async (promptType: string, template: string): Promise<AiPrompt> => {
|
createVersion: async (promptType: string, template: string): Promise<AiPrompt> => {
|
||||||
const { data } = await api.post(`/ai/prompts/${encodeURIComponent(promptType)}`, { template });
|
const { data } = await api.post(`/ai/prompts/${encodeURIComponent(promptType)}`, { template });
|
||||||
return extractData<AiPrompt>(data);
|
return unwrapResponse<AiPrompt>(data);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,7 +51,7 @@ export const aiPromptsService = {
|
|||||||
const { data } = await api.post(
|
const { data } = await api.post(
|
||||||
`/ai/prompts/${encodeURIComponent(promptType)}/${versionNumber}/activate`
|
`/ai/prompts/${encodeURIComponent(promptType)}/${versionNumber}/activate`
|
||||||
);
|
);
|
||||||
return extractData<AiPrompt>(data);
|
return unwrapResponse<AiPrompt>(data);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,6 +73,7 @@ export const aiPromptsService = {
|
|||||||
`/ai/prompts/${encodeURIComponent(promptType)}/${versionNumber}/note`,
|
`/ai/prompts/${encodeURIComponent(promptType)}/${versionNumber}/note`,
|
||||||
{ manualNote }
|
{ manualNote }
|
||||||
);
|
);
|
||||||
return extractData<AiPrompt>(data);
|
return unwrapResponse<AiPrompt>(data);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user