UNPKG

mantine-entity

Version:

A library combining Mantine, TanStack Query, and Mantine React Table for efficient entity management

68 lines (67 loc) 6.18 kB
/* eslint-disable @typescript-eslint/no-explicit-any */ "use client"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { Button, Group, Stack, Popover, Text, Table, ThemeIcon, ActionIcon, Box, Select, } from "@mantine/core"; import { useForm, useFieldArray, useWatch, Controller, } from "react-hook-form"; import { IconCheck, IconClearAll, IconFilter, IconPlus, IconTrash, } from "@tabler/icons-react"; import { useMemo } from "react"; import { RenderElements } from "../../lib/form-builder/render/render-elements"; const Filters = ({ columns, onApply, onClear, }) => { const columnOption = useMemo(() => columns?.map((c) => ({ label: c?.label || c?.placeholder || "", value: c.name, })), [columns]); const methods = useForm({ defaultValues: { filters: [], }, }); const { fields, append, remove } = useFieldArray({ control: methods?.control, name: "filters", }); const handleApplyFilters = (data) => { onApply(data.filters); }; const handleClearFilters = () => { methods.reset({ filters: [] }); onClear(); }; const addFilter = () => { append({ column: "", operator: "=", value: "" }); }; const activeFilters = useWatch({ control: methods?.control, name: "filters", defaultValue: [], }); console.log(methods?.watch()); return (_jsxs(Popover, { withArrow: true, shadow: "lg", position: "bottom-end", radius: "md", children: [_jsx(Popover.Target, { children: _jsx(Button, { size: "compact-sm", fz: 14, w: 116, leftSection: _jsx(IconFilter, { size: 14 }), rightSection: activeFilters.length > 0 && (_jsx(ThemeIcon, { size: 16, color: "white", fz: 11, c: "primary.7", fw: 600, radius: "100%", className: "flex justify-center items-center", children: activeFilters.length })), pl: 0, children: "Filters" }) }), _jsx(Popover.Dropdown, { children: _jsx("form", { onSubmit: methods.handleSubmit(handleApplyFilters), children: _jsxs(Stack, { gap: 4, children: [_jsx(Group, { children: "Filters" }), _jsx(Table, { captionSide: "top", withRowBorders: false, p: 0, classNames: { th: "p-0", td: " p-0 p-0.5", }, children: _jsx(Table.Tbody, { children: fields.map((filter, index) => (_jsxs(Table.Tr, { children: [_jsx(Table.Td, { children: _jsx(Controller, { control: methods.control, name: `filters.${index}.column`, render: ({ field }) => (_jsx(Select, { placeholder: "Select column", data: columnOption, ...field, required: true, size: "xs", comboboxProps: { withinPortal: false }, w: 100 })) }) }), _jsx(Table.Td, { children: _jsx(Controller, { control: methods.control, name: `filters.${index}.operator`, render: ({ field }) => (_jsx(Select, { placeholder: "Operator", size: "xs", data: columns ?.find((col) => col.name === methods.watch(`filters.${index}.column`)) ?.operators?.map((op) => ({ value: op, label: op, })) || [], ...field, required: true, comboboxProps: { withinPortal: false }, classNames: { root: "w-[76px] min-w-[1px]", wrapper: "w-[76px] min-w-[1px]", } })) }) }), _jsx(Table.Td, { children: _jsx(Box, { maw: 100, children: _jsx(RenderElements, { element: { ...columns?.find((col) => col.name === methods.watch(`filters.${index}.column`)), type: columns?.find((col) => col.name === methods.watch(`filters.${index}.column`))?.type ?? "text", name: `filters.${index}.value`, }, methods: methods }) }) }), _jsx(Table.Td, { children: _jsx(ActionIcon, { color: "red", variant: "transparent", size: "compact-xs", fz: 11, onClick: () => { if (activeFilters.length === 1) { remove(index); onClear(); } else { remove(index); } }, children: _jsx(IconTrash, { size: 16 }) }) })] }, filter.id))) }) }), _jsxs(Stack, { gap: 4, hidden: fields.length > 0, miw: 300, children: [_jsx(Text, { fw: 600, children: "No filters applied" }), _jsx(Text, { fz: 14, c: "dimmed", children: "Add filters to refine your results." })] }), _jsxs(Group, { justify: "apart", mt: "sm", children: [_jsx(Button, { type: "button", onClick: addFilter, size: "compact-sm", fz: 11, radius: "xl", color: "blue", leftSection: _jsx(IconPlus, { size: 13, stroke: 2 }), pl: 6, children: "Add Filter" }), _jsxs(Group, { gap: "xs", children: [_jsx(Button, { type: "submit", variant: "subtle", size: "compact-sm", fz: 11, color: "green", radius: "xl", leftSection: _jsx(IconCheck, { size: 12 }), pl: 6, hidden: fields.length <= 0, children: "Apply Filters" }), _jsx(Button, { type: "button", onClick: handleClearFilters, variant: "subtle", color: "red", size: "compact-sm", fz: 11, radius: "xl", pl: 6, leftSection: _jsx(IconClearAll, { size: 12 }), hidden: fields.length <= 0, children: "Clear Filters" })] })] })] }) }) })] })); }; export default Filters;