I am building a simple budget tracker, and I'd like to let user to filter by apps name.
Below is my code.
[
{
"status": "on",
"id": "NZMwD83Nxg",
"name": "GTA_UA_UAC_Android_01_DAU",
"dailyBudget": 800,
"apps": [
{
"name": "app 1",
"icon": "https://marketing-0-7-0-85-220.png/230x0w.webp"
},
{
"name": "app 2",
"icon": "https://marketing-0-7-0-99-220.png/230x0w.webp"
}
],
"currency": "USD",
},
{
"status": "on",
"id": "aXly0x0vX6",
"name": "GTA_UA_UAC_Android_02_DAU",
"dailyBudget": 65,
"apps": [
{
"name": "app 3",
"icon": "https://marketing-0-7-0-85-220.png/230x0w.webp"
}
],
"currency": "USD",
}
]
And this is my column type.
type AppsType = {
name: string;
icon: string;
};
export type MainCampaign = {
id: string;
name: string;
status: string;
apps: AppsType[];
dailyBudget: number;
currency: string;
};
export const columns: ColumnDef<MainCampaign>[] = [
{
accessorKey: "icon",
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
Apps
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
),
cell: ({ row }) => {
const apps: AppsType[] = row.getValue("apps");
return (
<div style={{ display: "flex", gap: "10px" }}>
{apps.map((app, index) => (
<Avatar key={index}>
<AvatarImage src={app.icon} alt={app.name} />
<AvatarFallback>{app.name}</AvatarFallback>
</Avatar>
))}
</div>
);
},
},
{
accessorKey: "apps",
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
App Names
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
),
cell: ({ row }) => {
const apps: AppsType[] = row.getValue("apps");
return apps.map((app, index) => <div key={index}>{app.name}</div>);
},
},
{
accessorKey: "name",
header: ({ column }) => {
return (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
Campaign Name
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
},
},
...
]
This is my Input inside data-table for now, and it's worked when using apps, no result after typing.
<div className="flex items-center py-4">
<Input
id="filter-app"
placeholder="Filter App..."
value={table.getColumn("apps")?.getFilterValue()?.toString() ?? ""}
onChange={(event) =>
table.getColumn("apps")?.setFilterValue(event.target.value)
}
className="max-w-sm"
/>
</div>
I have logged the app names, and the result looks like this: ["app1", "app2"], ["app3"]. My initial thought was to check if they include the filter value, then return the string, but I got stuck when implementing the function.
Would really appreciate your guidance.
I have solved the problem, below is my implementation.
And then this is my data-table
I did a bit of cleanup, extracted my filter function in util.ts
so it would be like this.