import { Head } from '@inertiajs/react'; import { Cell, ColumnDef, ColumnFiltersState, flexRender, getCoreRowModel, getFilteredRowModel, getSortedRowModel, Row, SortingState, useReactTable, VisibilityState, } from '@tanstack/react-table'; import { useLiveQuery } from 'dexie-react-hooks'; import { useMemo, useState } from 'react'; import { MoreHorizontal } from 'lucide-react'; import * as Icons from 'lucide-react'; import { index as automationRulesIndex } from '@/actions/App/Http/Controllers/Settings/AutomationRuleController'; import { CreateAutomationRuleDialog } from '@/components/automation-rules/create-automation-rule-dialog'; import { DeleteAutomationRuleDialog } from '@/components/automation-rules/delete-automation-rule-dialog'; import { EditAutomationRuleDialog } from '@/components/automation-rules/edit-automation-rule-dialog'; import HeadingSmall from '@/components/heading-small'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuLabel, ContextMenuTrigger, } from '@/components/ui/context-menu'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { Input } from '@/components/ui/input'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { useEncryptionKey } from '@/contexts/encryption-key-context'; import AppLayout from '@/layouts/app-layout'; import SettingsLayout from '@/layouts/settings/layout'; import { db } from '@/lib/dexie-db'; import { type BreadcrumbItem } from '@/types'; import { type AutomationRule, getRuleActions } from '@/types/automation-rule'; import { getCategoryColorClasses } from '@/types/category'; const breadcrumbs: BreadcrumbItem[] = [ { title: 'Automation rules settings', href: automationRulesIndex().url, }, ]; function AutomationRuleActions({ rule }: { rule: AutomationRule }) { const [editOpen, setEditOpen] = useState(false); const [deleteOpen, setDeleteOpen] = useState(false); return ( <> Actions setEditOpen(true)}> Edit setDeleteOpen(true)} variant="destructive" > Delete ); } function AutomationRuleRow({ row }: { row: Row }) { const rule = row.original; const [editOpen, setEditOpen] = useState(false); const [deleteOpen, setDeleteOpen] = useState(false); const [contextMenuOpen, setContextMenuOpen] = useState(false); return ( <> {row .getVisibleCells() .map((cell: Cell) => ( {flexRender( cell.column .columnDef .cell, cell.getContext(), )} ))} Actions setEditOpen(true)}> Edit setDeleteOpen(true)} variant="destructive" > Delete ); } export default function AutomationRules() { const { isKeySet } = useEncryptionKey(); const rawRules = useLiveQuery(() => db.automation_rules.toArray(), []) || []; const rules = useMemo( () => rawRules.map((rule) => ({ ...rule, rules_json: typeof rule.rules_json === 'string' ? JSON.parse(rule.rules_json) : rule.rules_json, })), [rawRules], ); const [sorting, setSorting] = useState([ { id: 'priority', desc: false, }, ]); const [columnFilters, setColumnFilters] = useState([]); const [columnVisibility, setColumnVisibility] = useState( {}, ); const columns: ColumnDef[] = [ { accessorKey: 'priority', header: 'Priority', cell: ({ row }) => { return (
{row.getValue('priority')}
); }, }, { accessorKey: 'title', header: 'Title', cell: ({ row }) => { return (
{row.getValue('title')}
); }, }, { id: 'actions_display', header: 'Actions', cell: ({ row }) => { const rule = row.original; const actions = getRuleActions(rule); if (actions.type === 'both') { const colorClasses = actions.category ? getCategoryColorClasses(actions.category.color) : null; const IconComponent = actions.category ? (Icons[ actions.category.icon as keyof typeof Icons ] as Icons.LucideIcon) : null; return (
{colorClasses && ( {IconComponent && ( )} {actions.category?.name} )} and add note
); } if (actions.type === 'category' && actions.category) { const colorClasses = getCategoryColorClasses( actions.category.color, ); const IconComponent = Icons[ actions.category.icon as keyof typeof Icons ] as Icons.LucideIcon; return ( {actions.category.name} ); } return ( Add note ); }, }, { id: 'actions', enableHiding: false, cell: ({ row }) => , }, ]; const table = useReactTable({ data: rules, columns, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), getFilteredRowModel: getFilteredRowModel(), onColumnVisibilityChange: setColumnVisibility, state: { sorting, columnFilters, columnVisibility, }, }); return (
table .getColumn('title') ?.setFilterValue(event.target.value) } className="max-w-sm" />
{table .getHeaderGroups() .map((headerGroup) => ( {headerGroup.headers.map( (header) => { return ( {header.isPlaceholder ? null : flexRender( header .column .columnDef .header, header.getContext(), )} ); }, )} ))} {table.getRowModel().rows?.length ? ( table.getRowModel().rows.map((row) => ( )) ) : ( No automation rules found. )}
{table.getFilteredRowModel().rows.length}{' '} rule(s) total.
); }