This commit is contained in:
@@ -112,7 +112,7 @@ export function useContractDrawingCategories(projectId?: number | string) {
|
||||
});
|
||||
}
|
||||
|
||||
export function useShopMainCategories(projectId: number) {
|
||||
export function useShopMainCategories(projectId: number | string) {
|
||||
return useQuery({
|
||||
queryKey: ['shop-main-categories', projectId],
|
||||
queryFn: () => masterDataService.getShopMainCategories(projectId),
|
||||
@@ -120,7 +120,7 @@ export function useShopMainCategories(projectId: number) {
|
||||
});
|
||||
}
|
||||
|
||||
export function useShopSubCategories(projectId: number, mainCategoryId?: number) {
|
||||
export function useShopSubCategories(projectId: number | string, mainCategoryId?: number) {
|
||||
return useQuery({
|
||||
queryKey: ['shop-sub-categories', projectId, mainCategoryId],
|
||||
queryFn: () => masterDataService.getShopSubCategories(projectId, mainCategoryId),
|
||||
|
||||
@@ -15,14 +15,39 @@ import {
|
||||
SearchOrganizationDto,
|
||||
} from "@/types/dto/organization/organization.dto";
|
||||
|
||||
type ApiEnvelope<T> = {
|
||||
data?: ApiEnvelope<T> | T;
|
||||
message?: string;
|
||||
statusCode?: number;
|
||||
};
|
||||
|
||||
function unwrapApiData<T>(payload: ApiEnvelope<T> | T): ApiEnvelope<T> | T | null {
|
||||
let current: ApiEnvelope<T> | T | null = payload;
|
||||
|
||||
while (
|
||||
current &&
|
||||
typeof current === "object" &&
|
||||
"data" in current &&
|
||||
current.data !== undefined
|
||||
) {
|
||||
current = current.data;
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
function unwrapArrayResponse<T>(payload: ApiEnvelope<T[]> | T[]): T[] {
|
||||
const unwrapped = unwrapApiData(payload);
|
||||
return Array.isArray(unwrapped) ? unwrapped : [];
|
||||
}
|
||||
|
||||
export const masterDataService = {
|
||||
// --- Tags Management ---
|
||||
|
||||
/** ดึงรายการ Tags ทั้งหมด (Search & Pagination) */
|
||||
getTags: async (params?: SearchTagDto) => {
|
||||
const response = await apiClient.get("/master/tags", { params });
|
||||
// Support both wrapped and unwrapped scenarios
|
||||
return response.data.data || response.data;
|
||||
return unwrapArrayResponse(response.data);
|
||||
},
|
||||
|
||||
/** สร้าง Tag ใหม่ */
|
||||
@@ -48,27 +73,7 @@ export const masterDataService = {
|
||||
/** ดึงรายชื่อองค์กรทั้งหมด */
|
||||
getOrganizations: async (params?: SearchOrganizationDto) => {
|
||||
const response = await apiClient.get<Organization[] | { data: Organization[] }>("/organizations", { params });
|
||||
// Support paginated response
|
||||
if (response.data && Array.isArray((response.data as { data: Organization[] }).data)) {
|
||||
return (response.data as { data: Organization[] }).data;
|
||||
}
|
||||
// If response.data itself is an array
|
||||
if (Array.isArray(response.data)) {
|
||||
return response.data;
|
||||
}
|
||||
// If we're here, it might be { data: [], total: ... } but data is missing? or empty?
|
||||
// Or it returned the object but data.data check failed (shouldn't happen if it follows schema).
|
||||
// Let's default to [] if we can't find an array, because callers expect array.
|
||||
// However, if we return [] we lose data if it was there but not recognized.
|
||||
|
||||
// Fallback: Check if response.data is object?
|
||||
// If it's the paginated object, return the data array if it exists
|
||||
if (response.data && (response.data as { data: Organization[] }).data) {
|
||||
// Maybe it's not an array?
|
||||
return Array.isArray((response.data as { data: Organization[] }).data) ? (response.data as { data: Organization[] }).data : [];
|
||||
}
|
||||
|
||||
return []; // Return empty array to prevent map errors
|
||||
return unwrapArrayResponse(response.data as ApiEnvelope<Organization[]> | Organization[]);
|
||||
},
|
||||
|
||||
/** สร้างองค์กรใหม่ */
|
||||
@@ -97,7 +102,7 @@ export const masterDataService = {
|
||||
const response = await apiClient.get("/master/disciplines", {
|
||||
params: { contractId }
|
||||
});
|
||||
return response.data.data || response.data;
|
||||
return unwrapArrayResponse(response.data);
|
||||
},
|
||||
|
||||
/** สร้างสาขางานใหม่ */
|
||||
@@ -119,7 +124,7 @@ export const masterDataService = {
|
||||
const response = await apiClient.get("/master/sub-types", {
|
||||
params: { contractId, correspondenceTypeId: typeId }
|
||||
});
|
||||
return response.data.data || response.data;
|
||||
return unwrapArrayResponse(response.data);
|
||||
},
|
||||
|
||||
/** สร้างประเภทย่อยใหม่ */
|
||||
@@ -135,7 +140,7 @@ export const masterDataService = {
|
||||
const response = await apiClient.get("/master/rfa-types", {
|
||||
params: { contractId }
|
||||
});
|
||||
return response.data.data || response.data;
|
||||
return unwrapArrayResponse(response.data);
|
||||
},
|
||||
|
||||
/** สร้างประเภท RFA ใหม่ */
|
||||
@@ -156,7 +161,7 @@ export const masterDataService = {
|
||||
// --- Correspondence Types Management ---
|
||||
getCorrespondenceTypes: async () => {
|
||||
const response = await apiClient.get("/master/correspondence-types");
|
||||
return response.data.data || response.data;
|
||||
return unwrapArrayResponse(response.data);
|
||||
},
|
||||
|
||||
createCorrespondenceType: async (data: CreateCorrespondenceTypeDto) => {
|
||||
@@ -188,21 +193,21 @@ export const masterDataService = {
|
||||
// --- Drawing Categories ---
|
||||
|
||||
getContractDrawingCategories: async (projectId?: number | string) => {
|
||||
const response = await apiClient.get("/drawings/contract/categories", {
|
||||
const response = await apiClient.get("/drawings/master-data/contract/categories", {
|
||||
params: { projectId }
|
||||
});
|
||||
return response.data.data || response.data;
|
||||
return unwrapArrayResponse(response.data);
|
||||
},
|
||||
|
||||
getShopMainCategories: async (projectId: number) => {
|
||||
const response = await apiClient.get("/drawings/shop/main-categories", { params: { projectId } });
|
||||
return response.data.data || response.data;
|
||||
getShopMainCategories: async (projectId: number | string) => {
|
||||
const response = await apiClient.get("/drawings/master-data/shop/main-categories", { params: { projectId } });
|
||||
return unwrapArrayResponse(response.data);
|
||||
},
|
||||
|
||||
getShopSubCategories: async (projectId: number, mainCategoryId?: number) => {
|
||||
const response = await apiClient.get("/drawings/shop/sub-categories", {
|
||||
getShopSubCategories: async (projectId: number | string, mainCategoryId?: number) => {
|
||||
const response = await apiClient.get("/drawings/master-data/shop/sub-categories", {
|
||||
params: { projectId, mainCategoryId }
|
||||
});
|
||||
return response.data.data || response.data;
|
||||
return unwrapArrayResponse(response.data);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,6 +5,32 @@ import {
|
||||
SearchOrganizationDto,
|
||||
} from "@/types/dto/organization/organization.dto";
|
||||
|
||||
type ApiEnvelope<T> = {
|
||||
data?: ApiEnvelope<T> | T;
|
||||
message?: string;
|
||||
statusCode?: number;
|
||||
};
|
||||
|
||||
function unwrapApiData<T>(payload: ApiEnvelope<T> | T): ApiEnvelope<T> | T | null {
|
||||
let current: ApiEnvelope<T> | T | null = payload;
|
||||
|
||||
while (
|
||||
current &&
|
||||
typeof current === "object" &&
|
||||
"data" in current &&
|
||||
current.data !== undefined
|
||||
) {
|
||||
current = current.data;
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
function unwrapArrayResponse<T>(payload: ApiEnvelope<T[]> | T[]): T[] {
|
||||
const unwrapped = unwrapApiData(payload);
|
||||
return Array.isArray(unwrapped) ? unwrapped : [];
|
||||
}
|
||||
|
||||
export const organizationService = {
|
||||
/**
|
||||
* Get all organizations (supports filtering by projectId)
|
||||
@@ -12,11 +38,7 @@ export const organizationService = {
|
||||
*/
|
||||
getAll: async (params?: SearchOrganizationDto) => {
|
||||
const response = await apiClient.get("/organizations", { params });
|
||||
// Normalize response if wrapped in data.data or direct data
|
||||
if (response.data && Array.isArray(response.data.data)) {
|
||||
return response.data.data;
|
||||
}
|
||||
return response.data.data || response.data;
|
||||
return unwrapArrayResponse(response.data);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,6 +6,32 @@ import {
|
||||
SearchProjectDto
|
||||
} from "@/types/dto/project/project.dto";
|
||||
|
||||
type ApiEnvelope<T> = {
|
||||
data?: ApiEnvelope<T> | T;
|
||||
message?: string;
|
||||
statusCode?: number;
|
||||
};
|
||||
|
||||
function unwrapApiData<T>(payload: ApiEnvelope<T> | T): ApiEnvelope<T> | T | null {
|
||||
let current: ApiEnvelope<T> | T | null = payload;
|
||||
|
||||
while (
|
||||
current &&
|
||||
typeof current === "object" &&
|
||||
"data" in current &&
|
||||
current.data !== undefined
|
||||
) {
|
||||
current = current.data;
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
function unwrapArrayResponse<T>(payload: ApiEnvelope<T[]> | T[]): T[] {
|
||||
const unwrapped = unwrapApiData(payload);
|
||||
return Array.isArray(unwrapped) ? unwrapped : [];
|
||||
}
|
||||
|
||||
export const projectService = {
|
||||
// --- Basic CRUD ---
|
||||
|
||||
@@ -16,11 +42,7 @@ export const projectService = {
|
||||
getAll: async (params?: SearchProjectDto) => {
|
||||
// GET /projects
|
||||
const response = await apiClient.get("/projects", { params });
|
||||
// Handle paginated response
|
||||
if (response.data && Array.isArray(response.data.data)) {
|
||||
return response.data.data;
|
||||
}
|
||||
return response.data;
|
||||
return unwrapArrayResponse(response.data);
|
||||
},
|
||||
|
||||
/** ดึงรายละเอียดโครงการตาม UUID */
|
||||
|
||||
Reference in New Issue
Block a user