690329:1537 Fixing bugs uuid by Kimi K2.5 #06
CI / CD Pipeline / build (push) Successful in 11m14s
CI / CD Pipeline / deploy (push) Successful in 8m15s

This commit is contained in:
2026-03-29 15:37:05 +07:00
parent a44d9296b5
commit 2074654c18
5 changed files with 121 additions and 23 deletions
@@ -1,5 +1,6 @@
'use client';
import { useState } from 'react';
import { GenericCrudTable } from '@/components/admin/reference/generic-crud-table';
import { masterDataService } from '@/lib/services/master-data.service';
import { projectService } from '@/lib/services/project.service';
@@ -7,30 +8,37 @@ import { CreateTagDto } from '@/types/dto/master/tag.dto';
import { ColumnDef } from '@tanstack/react-table';
import { useQuery } from '@tanstack/react-query';
import { Tag } from '@/types/master-data';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
export default function TagsPage() {
const [selectedProjectId, setSelectedProjectId] = useState<string>('all');
const { data: projectsData } = useQuery({
queryKey: ['projects'],
queryFn: () => projectService.getAll(),
});
const projectOptions = [
{ label: 'Global (All Projects)', value: '__none__' },
...(projectsData || []).map((p: { id?: number; publicId?: string; projectName?: string; projectCode?: string }) => ({
label: (p.projectName || p.projectCode || `Project ${p.publicId || p.id}`) as string,
value: String(p.publicId ?? p.id ?? ''), // ADR-019: publicId is the UUID exposed in API
})),
];
const projectItems = (projectsData || [])
.map((p: { publicId?: string; projectName?: string; projectCode?: string }) => ({
label: (p.projectName || p.projectCode || p.publicId || 'Unknown Project') as string,
value: String(p.publicId || ''),
}))
.filter((option: { label: string; value: string }) => option.value !== '');
const projectScopeOptions = [{ label: 'Global (All Projects)', value: '__none__' }, ...projectItems];
const columns: ColumnDef<Tag>[] = [
{
accessorKey: 'projectId',
header: 'Project',
cell: ({ row }) => {
const item = row.original as Tag & { project?: { id?: number | string; publicId?: string; projectName?: string; projectCode?: string } };
const item = row.original as Tag & {
project?: { publicId?: string; projectName?: string; projectCode?: string };
};
const project = item.project;
if (!project) return <span className="text-muted-foreground italic">Global</span>;
return (project.projectName || project.projectCode || `Project ${project.publicId || project.id}`) as React.ReactNode;
return (project.projectName || project.projectCode || project.publicId || 'Unknown Project') as React.ReactNode;
},
},
{
@@ -70,15 +78,21 @@ export default function TagsPage() {
title="Tags"
description="Manage system tags, multi-tenant capable."
entityName="Tag"
queryKey={['tags']}
queryKey={['tags', selectedProjectId]}
fetchFn={async () => {
const items = await masterDataService.getTags();
// ADR-019: Map projectId INT → project UUID for edit mode select matching
const items = await masterDataService.getTags(
selectedProjectId !== 'all' ? { projectId: selectedProjectId } : undefined
);
return items.map((item) => {
const rec = item as Tag & { project?: { id?: number | string; publicId?: string }; projectId?: number | string };
const rec = item as Tag & {
project?: { publicId?: string };
projectId?: number | string | null;
};
return {
...item,
projectId: rec.project?.publicId || rec.project?.id || (rec.projectId ? String(rec.projectId) : null),
projectId: rec.project?.publicId || (typeof rec.projectId === 'string' ? rec.projectId : null),
} as Tag;
});
}}
@@ -88,12 +102,30 @@ export default function TagsPage() {
updateFn={(id, data) => masterDataService.updateTag(id, formatPayload(data))}
deleteFn={(id) => masterDataService.deleteTag(id)}
columns={columns}
filters={
<div className="w-full max-w-xs space-y-2">
<Label htmlFor="tag-project-filter">Project Filter</Label>
<Select value={selectedProjectId} onValueChange={setSelectedProjectId}>
<SelectTrigger id="tag-project-filter">
<SelectValue placeholder="All projects" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">All Projects</SelectItem>
{projectItems.map((option: { label: string; value: string }) => (
<SelectItem key={option.value} value={String(option.value)}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
}
fields={[
{
name: 'projectId',
label: 'Project Scope',
type: 'select',
options: projectOptions,
options: projectScopeOptions,
required: false,
},
{