Skip to content

Commit 4494bbb

Browse files
authored
refactor: consistent reusable component wrappers across view (#524)
* refactor: consistent table wrapper across view * refactor: consistent select component across view * refactor: consistent dialog component across view
1 parent a85730d commit 4494bbb

File tree

30 files changed

+1626
-1212
lines changed

30 files changed

+1626
-1212
lines changed

api/api/versions.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{
44
"version": "v1",
55
"status": "active",
6-
"release_date": "2025-10-21T22:39:41.363939+05:30",
6+
"release_date": "2025-10-22T08:48:21.923083+05:30",
77
"end_of_life": "0001-01-01T00:00:00Z",
88
"changes": [
99
"Initial API version"

view/app/activities/page.tsx

Lines changed: 57 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,13 @@
22

33
import React from 'react';
44
import { useTranslation } from '@/hooks/use-translation';
5-
import {
6-
Select,
7-
SelectContent,
8-
SelectItem,
9-
SelectTrigger,
10-
SelectValue
11-
} from '@/components/ui/select';
5+
import { SelectWrapper } from '@/components/ui/select-wrapper';
126
import { formatDistanceToNow } from 'date-fns';
137
import { Loader2 } from 'lucide-react';
148
import { TypographySmall, TypographyMuted } from '@/components/ui/typography';
159
import { DahboardUtilityHeader } from '@/components/layout/dashboard-page-header';
1610
import PaginationWrapper from '@/components/ui/pagination';
17-
import {
18-
Table,
19-
TableBody,
20-
TableCell,
21-
TableHead,
22-
TableHeader,
23-
TableRow
24-
} from '@/components/ui/table';
11+
import { DataTable, TableColumn } from '@/components/ui/data-table';
2512
import { ActivityMessage } from '@/redux/types/audit';
2613
import useActivities, {
2714
ActivityListProps,
@@ -77,18 +64,13 @@ function ActivityList({
7764
searchPlaceHolder="Search activities..."
7865
>
7966
{showFilters && (
80-
<Select value={resourceType} onValueChange={handleResourceTypeChange}>
81-
<SelectTrigger className="w-full sm:w-48">
82-
<SelectValue placeholder="Filter by resource" />
83-
</SelectTrigger>
84-
<SelectContent>
85-
{resourceTypeOptions.map((option) => (
86-
<SelectItem key={option.value} value={option.value}>
87-
{option.label}
88-
</SelectItem>
89-
))}
90-
</SelectContent>
91-
</Select>
67+
<SelectWrapper
68+
value={resourceType}
69+
onValueChange={handleResourceTypeChange}
70+
options={resourceTypeOptions}
71+
placeholder="Filter by resource"
72+
className="w-full sm:w-48"
73+
/>
9274
)}
9375
</DahboardUtilityHeader>
9476
{isLoading ? (
@@ -102,38 +84,7 @@ function ActivityList({
10284
</div>
10385
) : activities.length > 0 ? (
10486
<>
105-
<div className="rounded-md border">
106-
<Table>
107-
<TableHeader>
108-
<TableRow>
109-
<TableHead className="w-[50px]"></TableHead>
110-
<TableHead>Message</TableHead>
111-
<TableHead>Timestamp</TableHead>
112-
</TableRow>
113-
</TableHeader>
114-
<TableBody>
115-
{activities.map((activity: ActivityMessage) => (
116-
<TableRow key={activity.id}>
117-
<TableCell>
118-
<div
119-
className={`h-3 w-3 rounded-full ${getActionColor(activity.action_color)}`}
120-
></div>
121-
</TableCell>
122-
<TableCell className="max-w-md">
123-
<TypographySmall className="text-foreground">
124-
{activity.message}
125-
</TypographySmall>
126-
</TableCell>
127-
<TableCell>
128-
<TypographyMuted className="text-xs">
129-
{formatDistanceToNow(new Date(activity.timestamp), { addSuffix: true })}
130-
</TypographyMuted>
131-
</TableCell>
132-
</TableRow>
133-
))}
134-
</TableBody>
135-
</Table>
136-
</div>
87+
<ActivitiesTable activities={activities} />
13788

13889
{totalPages > 1 && (
13990
<div className="mt-6 flex justify-center">
@@ -155,3 +106,50 @@ function ActivityList({
155106
</div>
156107
);
157108
}
109+
110+
function ActivitiesTable({ activities }: { activities: ActivityMessage[] }) {
111+
const columns: TableColumn<ActivityMessage>[] = [
112+
{
113+
key: 'indicator',
114+
title: '',
115+
width: '50px',
116+
render: (_, activity) => (
117+
<div
118+
className={`h-3 w-3 rounded-full ${getActionColor(activity.action_color)}`}
119+
/>
120+
)
121+
},
122+
{
123+
key: 'message',
124+
title: 'Message',
125+
dataIndex: 'message',
126+
className: 'max-w-md',
127+
render: (message) => (
128+
<TypographySmall className="text-foreground">
129+
{message}
130+
</TypographySmall>
131+
)
132+
},
133+
{
134+
key: 'timestamp',
135+
title: 'Timestamp',
136+
dataIndex: 'timestamp',
137+
render: (timestamp) => (
138+
<TypographyMuted className="text-xs">
139+
{formatDistanceToNow(new Date(timestamp), { addSuffix: true })}
140+
</TypographyMuted>
141+
)
142+
}
143+
];
144+
145+
return (
146+
<div className="rounded-md border">
147+
<DataTable
148+
data={activities}
149+
columns={columns}
150+
showBorder={false}
151+
hoverable={false}
152+
/>
153+
</div>
154+
);
155+
}

view/app/containers/[id]/components/images.tsx

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
import { Button } from '@/components/ui/button';
22
import { Card, CardContent } from '@/components/ui/card';
33
import { Skeleton } from '@/components/ui/skeleton';
4-
import {
5-
Table,
6-
TableBody,
7-
TableCell,
8-
TableHead,
9-
TableHeader,
10-
TableRow
11-
} from '@/components/ui/table';
4+
import { DataTable, TableColumn } from '@/components/ui/data-table';
125
import { useTranslation } from '@/hooks/use-translation';
136
import { formatBytes, formatDate } from '@/lib/utils';
147
import { useGetImagesQuery } from '@/redux/services/container/imagesApi';
15-
import { Loader2 } from 'lucide-react';
168

179
interface Image {
1810
id: string;
@@ -33,39 +25,42 @@ export function Images({ containerId, imagePrefix }: { containerId: string; imag
3325
return <ImagesSectionSkeleton />;
3426
}
3527

28+
const columns: TableColumn<Image>[] = [
29+
{
30+
key: 'id',
31+
title: t('containers.images.id'),
32+
dataIndex: 'id',
33+
render: (id) => <span className="font-mono">{id.slice(0, 12)}</span>
34+
},
35+
{
36+
key: 'tags',
37+
title: t('containers.images.tags'),
38+
dataIndex: 'repo_tags',
39+
render: (tags) => tags?.join(', ') || '<none>'
40+
},
41+
{
42+
key: 'created',
43+
title: t('containers.images.created'),
44+
dataIndex: 'created',
45+
render: (created) => formatDate(new Date(created * 1000))
46+
},
47+
{
48+
key: 'size',
49+
title: t('containers.images.size'),
50+
dataIndex: 'size',
51+
render: (size) => formatBytes(size)
52+
}
53+
];
54+
3655
return (
37-
<Card>
38-
<CardContent>
39-
<Table>
40-
<TableHeader>
41-
<TableRow>
42-
<TableHead>{t('containers.images.id')}</TableHead>
43-
<TableHead>{t('containers.images.tags')}</TableHead>
44-
<TableHead>{t('containers.images.created')}</TableHead>
45-
<TableHead>{t('containers.images.size')}</TableHead>
46-
</TableRow>
47-
</TableHeader>
48-
<TableBody>
49-
{isLoading ? (
50-
<TableRow>
51-
<TableCell colSpan={5} className="text-center">
52-
<Loader2 className="mx-auto h-6 w-6 animate-spin" />
53-
</TableCell>
54-
</TableRow>
55-
) : (
56-
images?.map((image: Image) => (
57-
<TableRow key={image.id}>
58-
<TableCell className="font-mono">{image.id.slice(0, 12)}</TableCell>
59-
<TableCell>{image.repo_tags?.join(', ') || '<none>'}</TableCell>
60-
<TableCell>{formatDate(new Date(image.created * 1000))}</TableCell>
61-
<TableCell>{formatBytes(image.size)}</TableCell>
62-
</TableRow>
63-
))
64-
)}
65-
</TableBody>
66-
</Table>
67-
</CardContent>
68-
</Card>
56+
<DataTable
57+
data={images}
58+
columns={columns}
59+
loading={isLoading}
60+
loadingRows={5}
61+
showBorder={true}
62+
hoverable={false}
63+
/>
6964
);
7065
}
7166

0 commit comments

Comments
 (0)