feat: add configurable data table filtering and update API endpoints for the example module

This commit is contained in:
Firman Ramdhani
2026-07-23 13:24:08 +07:00
parent ddf11741e9
commit fa119deec2
7 changed files with 227 additions and 16 deletions
@@ -0,0 +1,37 @@
import { useEffect } from 'react';
import { SimpleGrid } from '@repo/ui/components';
import { FieldTextInput } from '@repo/ui/form';
import { UseFormReturn, useWatch } from 'react-hook-form';
export const FilterFormContent = ({ form, t }: { form: UseFormReturn<any>; t: any }) => {
const codeValue = useWatch({
control: form.control,
name: 'code',
});
useEffect(() => {
if (!codeValue) {
form.setValue('name', '');
form.clearErrors('name');
}
}, [codeValue, form]);
return (
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
<FieldTextInput
control={form.control}
name="code"
label={t('fields.code')}
placeholder={`Enter ${t('fields.code')}`}
/>
<FieldTextInput
control={form.control}
name="name"
label={t('fields.name')}
placeholder={`Enter ${t('fields.name')}`}
disabled={!codeValue}
/>
</SimpleGrid>
);
};
@@ -4,10 +4,27 @@ import {
EnterpriseDataTable,
} from '@repo/ui/foundations';
import { ColDef } from '@repo/ui/components';
import { z } from 'zod';
import { Trans } from '@repo/core-i18n';
import { Text } from '@repo/ui/components';
import { LayoutDashboard } from 'lucide-react';
import { useMemo } from 'react';
import { FilterFormContent } from '../components/filter-content';
const filterSchema = z
.object({
code: z.string().optional(),
name: z.string().optional(),
})
.superRefine((data, ctx) => {
if (data.code && !data.name) {
ctx.addIssue({
path: ['name'],
code: z.ZodIssueCode.custom,
message: 'Name is required when code is provided',
});
}
});
export default function FullPagePageIndex() {
const { t } = useEnterpriseModuleTranslationContext();
@@ -19,6 +36,16 @@ export default function FullPagePageIndex() {
];
}, [t]);
const filterConfig = useMemo(() => {
return {
schema: filterSchema,
renderBody: (form: any) => {
if (!form) return null;
return <FilterFormContent form={form} t={t} />;
},
};
}, [t]);
return (
<EnterpriseIndexPageProvider
pageHeaderProps={{
@@ -34,7 +61,7 @@ export default function FullPagePageIndex() {
],
}}
>
<EnterpriseDataTable columnDefs={columnDefs} />
<EnterpriseDataTable columnDefs={columnDefs} filterConfig={filterConfig} />
</EnterpriseIndexPageProvider>
);
}