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({
|
return useQuery({
|
||||||
queryKey: ['shop-main-categories', projectId],
|
queryKey: ['shop-main-categories', projectId],
|
||||||
queryFn: () => masterDataService.getShopMainCategories(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({
|
return useQuery({
|
||||||
queryKey: ['shop-sub-categories', projectId, mainCategoryId],
|
queryKey: ['shop-sub-categories', projectId, mainCategoryId],
|
||||||
queryFn: () => masterDataService.getShopSubCategories(projectId, mainCategoryId),
|
queryFn: () => masterDataService.getShopSubCategories(projectId, mainCategoryId),
|
||||||
|
|||||||
@@ -15,14 +15,39 @@ import {
|
|||||||
SearchOrganizationDto,
|
SearchOrganizationDto,
|
||||||
} from "@/types/dto/organization/organization.dto";
|
} 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 = {
|
export const masterDataService = {
|
||||||
// --- Tags Management ---
|
// --- Tags Management ---
|
||||||
|
|
||||||
/** ดึงรายการ Tags ทั้งหมด (Search & Pagination) */
|
/** ดึงรายการ Tags ทั้งหมด (Search & Pagination) */
|
||||||
getTags: async (params?: SearchTagDto) => {
|
getTags: async (params?: SearchTagDto) => {
|
||||||
const response = await apiClient.get("/master/tags", { params });
|
const response = await apiClient.get("/master/tags", { params });
|
||||||
// Support both wrapped and unwrapped scenarios
|
return unwrapArrayResponse(response.data);
|
||||||
return response.data.data || response.data;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/** สร้าง Tag ใหม่ */
|
/** สร้าง Tag ใหม่ */
|
||||||
@@ -48,27 +73,7 @@ export const masterDataService = {
|
|||||||
/** ดึงรายชื่อองค์กรทั้งหมด */
|
/** ดึงรายชื่อองค์กรทั้งหมด */
|
||||||
getOrganizations: async (params?: SearchOrganizationDto) => {
|
getOrganizations: async (params?: SearchOrganizationDto) => {
|
||||||
const response = await apiClient.get<Organization[] | { data: Organization[] }>("/organizations", { params });
|
const response = await apiClient.get<Organization[] | { data: Organization[] }>("/organizations", { params });
|
||||||
// Support paginated response
|
return unwrapArrayResponse(response.data as ApiEnvelope<Organization[]> | Organization[]);
|
||||||
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
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/** สร้างองค์กรใหม่ */
|
/** สร้างองค์กรใหม่ */
|
||||||
@@ -97,7 +102,7 @@ export const masterDataService = {
|
|||||||
const response = await apiClient.get("/master/disciplines", {
|
const response = await apiClient.get("/master/disciplines", {
|
||||||
params: { contractId }
|
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", {
|
const response = await apiClient.get("/master/sub-types", {
|
||||||
params: { contractId, correspondenceTypeId: typeId }
|
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", {
|
const response = await apiClient.get("/master/rfa-types", {
|
||||||
params: { contractId }
|
params: { contractId }
|
||||||
});
|
});
|
||||||
return response.data.data || response.data;
|
return unwrapArrayResponse(response.data);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** สร้างประเภท RFA ใหม่ */
|
/** สร้างประเภท RFA ใหม่ */
|
||||||
@@ -156,7 +161,7 @@ export const masterDataService = {
|
|||||||
// --- Correspondence Types Management ---
|
// --- Correspondence Types Management ---
|
||||||
getCorrespondenceTypes: async () => {
|
getCorrespondenceTypes: async () => {
|
||||||
const response = await apiClient.get("/master/correspondence-types");
|
const response = await apiClient.get("/master/correspondence-types");
|
||||||
return response.data.data || response.data;
|
return unwrapArrayResponse(response.data);
|
||||||
},
|
},
|
||||||
|
|
||||||
createCorrespondenceType: async (data: CreateCorrespondenceTypeDto) => {
|
createCorrespondenceType: async (data: CreateCorrespondenceTypeDto) => {
|
||||||
@@ -188,21 +193,21 @@ export const masterDataService = {
|
|||||||
// --- Drawing Categories ---
|
// --- Drawing Categories ---
|
||||||
|
|
||||||
getContractDrawingCategories: async (projectId?: number | string) => {
|
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 }
|
params: { projectId }
|
||||||
});
|
});
|
||||||
return response.data.data || response.data;
|
return unwrapArrayResponse(response.data);
|
||||||
},
|
},
|
||||||
|
|
||||||
getShopMainCategories: async (projectId: number) => {
|
getShopMainCategories: async (projectId: number | string) => {
|
||||||
const response = await apiClient.get("/drawings/shop/main-categories", { params: { projectId } });
|
const response = await apiClient.get("/drawings/master-data/shop/main-categories", { params: { projectId } });
|
||||||
return response.data.data || response.data;
|
return unwrapArrayResponse(response.data);
|
||||||
},
|
},
|
||||||
|
|
||||||
getShopSubCategories: async (projectId: number, mainCategoryId?: number) => {
|
getShopSubCategories: async (projectId: number | string, mainCategoryId?: number) => {
|
||||||
const response = await apiClient.get("/drawings/shop/sub-categories", {
|
const response = await apiClient.get("/drawings/master-data/shop/sub-categories", {
|
||||||
params: { projectId, mainCategoryId }
|
params: { projectId, mainCategoryId }
|
||||||
});
|
});
|
||||||
return response.data.data || response.data;
|
return unwrapArrayResponse(response.data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,32 @@ import {
|
|||||||
SearchOrganizationDto,
|
SearchOrganizationDto,
|
||||||
} from "@/types/dto/organization/organization.dto";
|
} 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 = {
|
export const organizationService = {
|
||||||
/**
|
/**
|
||||||
* Get all organizations (supports filtering by projectId)
|
* Get all organizations (supports filtering by projectId)
|
||||||
@@ -12,11 +38,7 @@ export const organizationService = {
|
|||||||
*/
|
*/
|
||||||
getAll: async (params?: SearchOrganizationDto) => {
|
getAll: async (params?: SearchOrganizationDto) => {
|
||||||
const response = await apiClient.get("/organizations", { params });
|
const response = await apiClient.get("/organizations", { params });
|
||||||
// Normalize response if wrapped in data.data or direct data
|
return unwrapArrayResponse(response.data);
|
||||||
if (response.data && Array.isArray(response.data.data)) {
|
|
||||||
return response.data.data;
|
|
||||||
}
|
|
||||||
return response.data.data || response.data;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,6 +6,32 @@ import {
|
|||||||
SearchProjectDto
|
SearchProjectDto
|
||||||
} from "@/types/dto/project/project.dto";
|
} 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 = {
|
export const projectService = {
|
||||||
// --- Basic CRUD ---
|
// --- Basic CRUD ---
|
||||||
|
|
||||||
@@ -16,11 +42,7 @@ export const projectService = {
|
|||||||
getAll: async (params?: SearchProjectDto) => {
|
getAll: async (params?: SearchProjectDto) => {
|
||||||
// GET /projects
|
// GET /projects
|
||||||
const response = await apiClient.get("/projects", { params });
|
const response = await apiClient.get("/projects", { params });
|
||||||
// Handle paginated response
|
return unwrapArrayResponse(response.data);
|
||||||
if (response.data && Array.isArray(response.data.data)) {
|
|
||||||
return response.data.data;
|
|
||||||
}
|
|
||||||
return response.data;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/** ดึงรายละเอียดโครงการตาม UUID */
|
/** ดึงรายละเอียดโครงการตาม UUID */
|
||||||
|
|||||||
Reference in New Issue
Block a user