This commit is contained in:
@@ -26,7 +26,7 @@ interface Category {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function ContractCategoriesPage() {
|
export default function ContractCategoriesPage() {
|
||||||
const [selectedProjectId, setSelectedProjectId] = useState<number | undefined>(undefined);
|
const [selectedProjectId, setSelectedProjectId] = useState<string | undefined>(undefined);
|
||||||
const { data: projects = [], isLoading: isLoadingProjects } = useProjects();
|
const { data: projects = [], isLoading: isLoadingProjects } = useProjects();
|
||||||
|
|
||||||
const columns: ColumnDef<Category>[] = [
|
const columns: ColumnDef<Category>[] = [
|
||||||
@@ -59,8 +59,8 @@ export default function ContractCategoriesPage() {
|
|||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<span className="text-sm font-medium">Project:</span>
|
<span className="text-sm font-medium">Project:</span>
|
||||||
<Select
|
<Select
|
||||||
value={selectedProjectId?.toString() ?? ''}
|
value={selectedProjectId ?? ''}
|
||||||
onValueChange={(v) => setSelectedProjectId(v ? parseInt(v) : undefined)}
|
onValueChange={(v) => setSelectedProjectId(v || undefined)}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="w-[300px]">
|
<SelectTrigger className="w-[300px]">
|
||||||
{isLoadingProjects ? (
|
{isLoadingProjects ? (
|
||||||
@@ -160,7 +160,7 @@ class MappingErrorBoundary extends React.Component<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function CategoryMappingSection({ projectId }: { projectId: number }) {
|
function CategoryMappingSection({ projectId }: { projectId: string }) {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<h2 className="text-xl font-semibold">Category Mappings (Map Sub-categories to Categories)</h2>
|
<h2 className="text-xl font-semibold">Category Mappings (Map Sub-categories to Categories)</h2>
|
||||||
@@ -174,7 +174,7 @@ function CategoryMappingSection({ projectId }: { projectId: number }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ManageMappings({ projectId }: { projectId: number }) {
|
function ManageMappings({ projectId }: { projectId: string }) {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const [selectedCat, setSelectedCat] = useState<string>('');
|
const [selectedCat, setSelectedCat] = useState<string>('');
|
||||||
const [selectedSubCat, setSelectedSubCat] = useState<string>('');
|
const [selectedSubCat, setSelectedSubCat] = useState<string>('');
|
||||||
@@ -210,7 +210,7 @@ function ManageMappings({ projectId }: { projectId: number }) {
|
|||||||
const mappings = Array.isArray(rawMappings) ? rawMappings : [];
|
const mappings = Array.isArray(rawMappings) ? rawMappings : [];
|
||||||
|
|
||||||
const createMutation = useMutation({
|
const createMutation = useMutation({
|
||||||
mutationFn: (data: { projectId: number; categoryId: number; subCategoryId: number }) =>
|
mutationFn: (data: { projectId: number | string; categoryId: number; subCategoryId: number }) =>
|
||||||
drawingMasterDataService.createContractMapping(data),
|
drawingMasterDataService.createContractMapping(data),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['contract-mappings'] });
|
queryClient.invalidateQueries({ queryKey: ['contract-mappings'] });
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ interface SubCategory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function ContractSubCategoriesPage() {
|
export default function ContractSubCategoriesPage() {
|
||||||
const [selectedProjectId, setSelectedProjectId] = useState<number | undefined>(undefined);
|
const [selectedProjectId, setSelectedProjectId] = useState<string | undefined>(undefined);
|
||||||
const { data: projects = [], isLoading: isLoadingProjects } = useProjects();
|
const { data: projects = [], isLoading: isLoadingProjects } = useProjects();
|
||||||
|
|
||||||
const columns: ColumnDef<SubCategory>[] = [
|
const columns: ColumnDef<SubCategory>[] = [
|
||||||
@@ -51,8 +51,8 @@ export default function ContractSubCategoriesPage() {
|
|||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<span className="text-sm font-medium">Project:</span>
|
<span className="text-sm font-medium">Project:</span>
|
||||||
<Select
|
<Select
|
||||||
value={selectedProjectId?.toString() ?? ''}
|
value={selectedProjectId ?? ''}
|
||||||
onValueChange={(v) => setSelectedProjectId(v ? parseInt(v) : undefined)}
|
onValueChange={(v) => setSelectedProjectId(v || undefined)}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="w-[300px]">
|
<SelectTrigger className="w-[300px]">
|
||||||
{isLoadingProjects ? (
|
{isLoadingProjects ? (
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ interface Volume {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function ContractVolumesPage() {
|
export default function ContractVolumesPage() {
|
||||||
const [selectedProjectId, setSelectedProjectId] = useState<number | undefined>(undefined);
|
const [selectedProjectId, setSelectedProjectId] = useState<string | undefined>(undefined);
|
||||||
const { data: projects = [], isLoading: isLoadingProjects } = useProjects();
|
const { data: projects = [], isLoading: isLoadingProjects } = useProjects();
|
||||||
|
|
||||||
const columns: ColumnDef<Volume>[] = [
|
const columns: ColumnDef<Volume>[] = [
|
||||||
@@ -63,8 +63,8 @@ export default function ContractVolumesPage() {
|
|||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<span className="text-sm font-medium">Project:</span>
|
<span className="text-sm font-medium">Project:</span>
|
||||||
<Select
|
<Select
|
||||||
value={selectedProjectId?.toString() ?? ""}
|
value={selectedProjectId ?? ''}
|
||||||
onValueChange={(v) => setSelectedProjectId(v ? parseInt(v) : undefined)}
|
onValueChange={(v) => setSelectedProjectId(v || undefined)}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="w-[300px]">
|
<SelectTrigger className="w-[300px]">
|
||||||
{isLoadingProjects ? (
|
{isLoadingProjects ? (
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ interface MainCategory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function ShopMainCategoriesPage() {
|
export default function ShopMainCategoriesPage() {
|
||||||
const [selectedProjectId, setSelectedProjectId] = useState<number | undefined>(undefined);
|
const [selectedProjectId, setSelectedProjectId] = useState<string | undefined>(undefined);
|
||||||
const { data: projects = [], isLoading: isLoadingProjects } = useProjects();
|
const { data: projects = [], isLoading: isLoadingProjects } = useProjects();
|
||||||
|
|
||||||
const columns: ColumnDef<MainCategory>[] = [
|
const columns: ColumnDef<MainCategory>[] = [
|
||||||
@@ -62,8 +62,8 @@ export default function ShopMainCategoriesPage() {
|
|||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<span className="text-sm font-medium">Project:</span>
|
<span className="text-sm font-medium">Project:</span>
|
||||||
<Select
|
<Select
|
||||||
value={selectedProjectId?.toString() ?? ''}
|
value={selectedProjectId ?? ''}
|
||||||
onValueChange={(v) => setSelectedProjectId(v ? parseInt(v) : undefined)}
|
onValueChange={(v) => setSelectedProjectId(v || undefined)}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="w-[300px]">
|
<SelectTrigger className="w-[300px]">
|
||||||
{isLoadingProjects ? (
|
{isLoadingProjects ? (
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ interface SubCategory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function ShopSubCategoriesPage() {
|
export default function ShopSubCategoriesPage() {
|
||||||
const [selectedProjectId, setSelectedProjectId] = useState<number | undefined>(undefined);
|
const [selectedProjectId, setSelectedProjectId] = useState<string | undefined>(undefined);
|
||||||
const { data: projects = [], isLoading: isLoadingProjects } = useProjects();
|
const { data: projects = [], isLoading: isLoadingProjects } = useProjects();
|
||||||
|
|
||||||
console.log('Projects Data:', projects);
|
console.log('Projects Data:', projects);
|
||||||
@@ -64,8 +64,8 @@ export default function ShopSubCategoriesPage() {
|
|||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<span className="text-sm font-medium">Project:</span>
|
<span className="text-sm font-medium">Project:</span>
|
||||||
<Select
|
<Select
|
||||||
value={selectedProjectId?.toString() ?? ''}
|
value={selectedProjectId ?? ''}
|
||||||
onValueChange={(v) => setSelectedProjectId(v ? parseInt(v) : undefined)}
|
onValueChange={(v) => setSelectedProjectId(v || undefined)}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="w-[300px]">
|
<SelectTrigger className="w-[300px]">
|
||||||
{isLoadingProjects ? (
|
{isLoadingProjects ? (
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export default function TagsPage() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const projectOptions = [
|
const projectOptions = [
|
||||||
{ label: "Global (All Projects)", value: "" },
|
{ label: "Global (All Projects)", value: "__none__" },
|
||||||
...(projectsData || []).map((p: Record<string, unknown>) => ({
|
...(projectsData || []).map((p: Record<string, unknown>) => ({
|
||||||
label: p.project_name || p.project_code || `Project ${p.id}`,
|
label: p.project_name || p.project_code || `Project ${p.id}`,
|
||||||
value: String(p.id),
|
value: String(p.id),
|
||||||
@@ -57,11 +57,9 @@ export default function TagsPage() {
|
|||||||
|
|
||||||
const formatPayload = (data: Record<string, unknown>) => {
|
const formatPayload = (data: Record<string, unknown>) => {
|
||||||
const payload = { ...data };
|
const payload = { ...data };
|
||||||
// Backend entity uses project_id (underscore) per ADR-017/018 schema
|
// ADR-019: project_id is now a UUID string or '__none__' for global
|
||||||
if (!payload.project_id || payload.project_id === "") {
|
if (!payload.project_id || payload.project_id === "__none__") {
|
||||||
payload.project_id = null;
|
payload.project_id = null;
|
||||||
} else {
|
|
||||||
payload.project_id = Number(payload.project_id);
|
|
||||||
}
|
}
|
||||||
return payload;
|
return payload;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export interface ContractVolume {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateContractVolumeDto {
|
export interface CreateContractVolumeDto {
|
||||||
projectId: number;
|
projectId: number | string;
|
||||||
volumeCode: string;
|
volumeCode: string;
|
||||||
volumeName: string;
|
volumeName: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
@@ -34,7 +34,7 @@ export interface ContractCategory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateContractCategoryDto {
|
export interface CreateContractCategoryDto {
|
||||||
projectId: number;
|
projectId: number | string;
|
||||||
catCode: string;
|
catCode: string;
|
||||||
catName: string;
|
catName: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
@@ -54,7 +54,7 @@ export interface ContractSubCategory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateContractSubCategoryDto {
|
export interface CreateContractSubCategoryDto {
|
||||||
projectId: number;
|
projectId: number | string;
|
||||||
subCatCode: string;
|
subCatCode: string;
|
||||||
subCatName: string;
|
subCatName: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
@@ -75,7 +75,7 @@ export interface ShopMainCategory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateShopMainCategoryDto {
|
export interface CreateShopMainCategoryDto {
|
||||||
projectId: number;
|
projectId: number | string;
|
||||||
mainCategoryCode: string;
|
mainCategoryCode: string;
|
||||||
mainCategoryName: string;
|
mainCategoryName: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
@@ -97,7 +97,7 @@ export interface ShopSubCategory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateShopSubCategoryDto {
|
export interface CreateShopSubCategoryDto {
|
||||||
projectId: number;
|
projectId: number | string;
|
||||||
subCategoryCode: string;
|
subCategoryCode: string;
|
||||||
subCategoryName: string;
|
subCategoryName: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
@@ -110,7 +110,7 @@ export interface CreateShopSubCategoryDto {
|
|||||||
// ===========================
|
// ===========================
|
||||||
export const drawingMasterDataService = {
|
export const drawingMasterDataService = {
|
||||||
// --- Contract Volumes ---
|
// --- Contract Volumes ---
|
||||||
async getContractVolumes(projectId: number): Promise<ContractVolume[]> {
|
async getContractVolumes(projectId: number | string): Promise<ContractVolume[]> {
|
||||||
const response = await apiClient.get(`/drawings/master-data/contract/volumes`, {
|
const response = await apiClient.get(`/drawings/master-data/contract/volumes`, {
|
||||||
params: { projectId },
|
params: { projectId },
|
||||||
});
|
});
|
||||||
@@ -132,7 +132,7 @@ export const drawingMasterDataService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// --- Contract Categories ---
|
// --- Contract Categories ---
|
||||||
async getContractCategories(projectId: number): Promise<ContractCategory[]> {
|
async getContractCategories(projectId: number | string): Promise<ContractCategory[]> {
|
||||||
const response = await apiClient.get(`/drawings/master-data/contract/categories`, {
|
const response = await apiClient.get(`/drawings/master-data/contract/categories`, {
|
||||||
params: { projectId },
|
params: { projectId },
|
||||||
});
|
});
|
||||||
@@ -154,7 +154,7 @@ export const drawingMasterDataService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// --- Contract Sub-categories ---
|
// --- Contract Sub-categories ---
|
||||||
async getContractSubCategories(projectId: number): Promise<ContractSubCategory[]> {
|
async getContractSubCategories(projectId: number | string): Promise<ContractSubCategory[]> {
|
||||||
const response = await apiClient.get(`/drawings/master-data/contract/sub-categories`, {
|
const response = await apiClient.get(`/drawings/master-data/contract/sub-categories`, {
|
||||||
params: { projectId },
|
params: { projectId },
|
||||||
});
|
});
|
||||||
@@ -180,7 +180,7 @@ export const drawingMasterDataService = {
|
|||||||
|
|
||||||
// --- Contract Category Mappings ---
|
// --- Contract Category Mappings ---
|
||||||
async getContractMappings(
|
async getContractMappings(
|
||||||
projectId: number,
|
projectId: number | string,
|
||||||
categoryId?: number
|
categoryId?: number
|
||||||
): Promise<{ id: number; subCategory: ContractSubCategory; category: ContractCategory }[]> {
|
): Promise<{ id: number; subCategory: ContractSubCategory; category: ContractCategory }[]> {
|
||||||
const response = await apiClient.get(`/drawings/master-data/contract/mappings`, {
|
const response = await apiClient.get(`/drawings/master-data/contract/mappings`, {
|
||||||
@@ -190,7 +190,7 @@ export const drawingMasterDataService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async createContractMapping(data: {
|
async createContractMapping(data: {
|
||||||
projectId: number;
|
projectId: number | string;
|
||||||
categoryId: number;
|
categoryId: number;
|
||||||
subCategoryId: number;
|
subCategoryId: number;
|
||||||
}): Promise<{ id: number }> {
|
}): Promise<{ id: number }> {
|
||||||
@@ -203,7 +203,7 @@ export const drawingMasterDataService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// --- Shop Main Categories ---
|
// --- Shop Main Categories ---
|
||||||
async getShopMainCategories(projectId: number): Promise<ShopMainCategory[]> {
|
async getShopMainCategories(projectId: number | string): Promise<ShopMainCategory[]> {
|
||||||
const response = await apiClient.get(`/drawings/master-data/shop/main-categories`, {
|
const response = await apiClient.get(`/drawings/master-data/shop/main-categories`, {
|
||||||
params: { projectId },
|
params: { projectId },
|
||||||
});
|
});
|
||||||
@@ -225,7 +225,7 @@ export const drawingMasterDataService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// --- Shop Sub-categories ---
|
// --- Shop Sub-categories ---
|
||||||
async getShopSubCategories(projectId: number, mainCategoryId?: number): Promise<ShopSubCategory[]> {
|
async getShopSubCategories(projectId: number | string, mainCategoryId?: number): Promise<ShopSubCategory[]> {
|
||||||
const response = await apiClient.get(`/drawings/master-data/shop/sub-categories`, {
|
const response = await apiClient.get(`/drawings/master-data/shop/sub-categories`, {
|
||||||
params: { projectId, mainCategoryId },
|
params: { projectId, mainCategoryId },
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user