// CHAKRA COMPONENTS import { Button, Stack, Flex, Field, NativeSelect, Input, HoverCard, Text, NumberInput, Box, useSlotRecipe, Combobox, Portal, useFilter, useListCollection } from "@chakra-ui/react"; // ICONS import { Plus, CircleMinus, Files, ClipboardPaste, Trash } from 'lucide-react'; // OTHER import { useState } from 'react'; import useDataFilterStore from '../../store/useDataFilterStore.jsx'; // ============================================================================ // 1. MAIN QUERY BUILDER (The Engine Wrapper) // ============================================================================ export default function MyQueryBuilder({ url, setUrl, allColumns, getColumns, pullTable, isLoading, isReadyRef }) { // STYLING const dataExplorerRecipe = useSlotRecipe({ key: "dataExplorer" }); const dataExplorerStyle = dataExplorerRecipe(); // THE SELECT DROPDOWN MENU const { contains } = useFilter({ sensitivity: "base" }) const { collection, filter } = useListCollection({ initialItems: tables, filter: contains, }) // STATE MANAGEMENT const [value, setValue] = useState([]); const addNewGroup = useDataFilterStore(state => state.addNewGroup); const filterGroups = useDataFilterStore(state => state.filterGroups); console.log("filter groups", filterGroups); return ( {/* Top Controls: Source & Execute */} filter(e.inputValue)} value={value} onValueChange={(e) => { setValue(e.value); const selectedView = e.value; setUrl(prev => ({ ...prev, source: selectedView })); // need to get all columns as default in param building const endpoint = "/api/v3/view_dash_event_search_columns"; getColumns(endpoint); }} width="320px" > Select Table No items found {collection.items.map((item) => ( {item.label} ))} {/* Filter Builder Engine */} {url.source && allColumns?.types && ( Filters {filterGroups.map((group) => ( ))} )} ); } // LIST OF TABLES USER CAN EXPLORE const tables = [ { label: "Events Table", value: "ViewDashEventSearch" }, ]; // ============================================================================ // 2. FILTERS GROUPS (The AND logic groups) // ============================================================================ function FilterGroup({ groupID, filters, columns }) { const removeGroup = useDataFilterStore(state => state.removeGroup); const addFilter = useDataFilterStore(state => state.addFilter); console.log("in filter group. GroupID: ", groupID, "filters: ", filters); return ( {filters?.map((filter) => ( ))} ); }; // ============================================================================ // 3. FILTER ROW (The individual criteria inputs) // ============================================================================ function FilterRow({ groupID, filterID, filter, columns }) { // STATE MANAGEMENT const removeFilter = useDataFilterStore(state => state.removeFilter); const updateFilterColumn = useDataFilterStore(state => state.updateFilterColumn); const updateFilterOp = useDataFilterStore(state => state.updateFilterOps); const updateFilterValue = useDataFilterStore(state => state.updateFilterValue); const copyFilter = useDataFilterStore(state => state.copyFilter); const pasteFilter = useDataFilterStore(state => state.pasteFilter); // CONSTANTS const types = { AutoField: ["=", "<", ">", "<=", ">="], IntegerField: ["=", "<", ">", "<=", ">="], CharField: ["=", "contains"], DateTimeField: ["range"], }; return ( {/* Remove button */} Remove Filter {/* Copy Button */} Copy Filter {/* paste button */} Paste Filter {/* Column selector */} updateFilterColumn(groupID, filterID, e.target.value, columns[e.target.value], null, null)} // e.target.value is the new column > {Object.keys(columns).map((colName) => ( ))} {/* Operator selector or start date for range */} {filter?.type === "DateTimeField" ? ( updateFilterValue(groupID, filterID, e.target.value, "s")} /> ) : ( updateFilterOp(groupID, filterID, e.target.value)}> {filter?.type && types[filter?.type].map((op) => )} {/* maps over the 'filter.type' corresponding ops from the types dictionary */} )} {/* Value input or end date for range */} {filter?.type === "DateTimeField" ? ( updateFilterValue(groupID, filterID, e.target.value, "e")} /> ) : filter?.type === "IntegerField" || filter?.type === "AutoField" ? ( updateFilterValue(groupID, filterID, e.value)}> ) : ( updateFilterValue(groupID, filterID, e.target.value)} /> )} ); };