diff --git a/Backend/postgres_connector.py b/Backend/postgres_connector.py index 6b9be662..b7f7fdb9 100644 --- a/Backend/postgres_connector.py +++ b/Backend/postgres_connector.py @@ -656,5 +656,25 @@ def build_family_where_text(self, filters): # Single value conditions.append(f'degree = {int(values)}') + elif fil == 'dimension': + # families_dim_1_nf only contains dimension 1 objects + dims = values if isinstance(values, list) else [values] + dims = [int(d) for d in dims] + if 1 not in dims: + # Requested dimension is not present in this table + conditions.append('1 = 0') + + elif fil == 'is_polynomial': + # Same style as system filter: IN (...) + conditions.append( + 'is_polynomial IN (' + ', '.join(str(v) for v in values) + ')' + ) + + elif fil == 'base_field_label': + # Partial match, case-insensitive + conditions.append( + f"base_field_label ILIKE '%' || TRIM('{values}') || '%'" + ) + filter_text += ' AND '.join(conditions) return filter_text diff --git a/Frontend/src/api/routes.js b/Frontend/src/api/routes.js index abb8ac9e..9d10963a 100644 --- a/Frontend/src/api/routes.js +++ b/Frontend/src/api/routes.js @@ -21,7 +21,7 @@ export const get_families = () => api.get("/get_all_families"); export const get_family = (familyId) => api.post("/get_family", { id: familyId }); // dreyes: used to filter families based on the filters selected in the UI -export const get_filtered_families = (filtered) => api.post("/get_filtered_familes", filters); +export const get_filtered_families = (filters) => api.post("/get_filtered_families", filters); export const get_rational_periodic_data = (functionId) => api.post("/get_rational_periodic_data", { function_id: functionId }); diff --git a/Frontend/src/components/PaginatedDataTable.js b/Frontend/src/components/PaginatedDataTable.js index 9dd13f8f..7292e92f 100644 --- a/Frontend/src/components/PaginatedDataTable.js +++ b/Frontend/src/components/PaginatedDataTable.js @@ -52,7 +52,7 @@ export default function PaginatedDataTable({ labels, data, itemsPerPage, current {item.map((element, id) => ( - {id === 3 ? renderExponent(element) :element} + {id === 3 && typeof element === 'string' ? renderExponent(element) : element} ))} diff --git a/Frontend/src/context/FilterContext.js b/Frontend/src/context/FilterContext.js index 3c52126f..bc1b9c81 100644 --- a/Frontend/src/context/FilterContext.js +++ b/Frontend/src/context/FilterContext.js @@ -30,7 +30,13 @@ export const FilterProvider = ({ children }) => { // dreyes: Family page filters family_id: "", family_name: "", - family_degree: [] + family_degree: [], + + //dreyes: added more filters for domain, polynomial, and field labels + family_dimension: [], + family_custom_dimension: "", + family_is_polynomial: [], + family_base_field_label: "" }); return ( diff --git a/Frontend/src/pages/FilteredFamilies.js b/Frontend/src/pages/FilteredFamilies.js index f2f3f6ec..c9bab24d 100644 --- a/Frontend/src/pages/FilteredFamilies.js +++ b/Frontend/src/pages/FilteredFamilies.js @@ -7,6 +7,8 @@ import Divider from "@mui/material/Divider"; import { useFilters } from '../context/FilterContext'; import { useNavigate } from 'react-router-dom'; import Button from 'react-bootstrap/Button'; +import HelpBox from "../components/FunctionDetail/HelpBox"; //dreyes: renders tooltips for labels. +import ActiveFiltersBanner from '../components/ActiveFiltersBanner'; //dreyes: shows active filters above the results table, only renders if there are active filters // dreyes: this is the new family page, it allows you to filter the families based on the filters on the left // sidebar, and then shows the results in a table on the right, you can click on the family id to go to the family details page @@ -17,16 +19,25 @@ function FilteredFamilies() { const [pagesPer] = useState('20'); const [page, setPage] = useState(1); const [triggerFetch, setTriggerFetch] = useState(false); + const [filtersApplied, setFiltersApplied] = useState([]); // Fetch families with current filters const fetchFilteredFamilies = async () => { try { - const result = await get_filtered_families({ + const familyFilters = { family_id: filters.family_id, name: filters.family_name, - degree: filters.family_degree - }); + degree: filters.family_degree, + + dimension: filters.family_custom_dimension === "" + ? filters.family_dimension + : [...filters.family_dimension, Number(filters.family_custom_dimension)], + is_polynomial: filters.family_is_polynomial, + base_field_label: filters.family_base_field_label + }; + const result = await get_filtered_families(familyFilters); setFamilies(result.data); + setFiltersApplied({ ...familyFilters }); } catch (error) { console.log(error); } @@ -66,7 +77,11 @@ function FilteredFamilies() { ...filters, family_id: "", family_name: "", - family_degree: [] + family_degree: [], + family_dimension: [], + family_custom_dimension: "", + family_is_polynomial: [], + family_base_field_label: "" }); setTriggerFetch(prev => !prev); setPage(1); @@ -96,6 +111,60 @@ function FilteredFamilies() { marginRight: "12px", }; + const smallStyles = { + inlineHelpLabel: { + fontSize: "0.9rem", + whiteSpace: "nowrap", + display: "inline-block", + verticalAlign: "middle" + } + }; + + const buildMonomials = (degree) => { + const mon = []; + for (let i = 0; i <= degree; i++) { + if (i === 0) mon.push(`x^${degree}`); + else if (i === degree) mon.push(`y^${degree}`); + else if (degree - i === 1 && i === 1) mon.push("xy"); + else if (i === 1) mon.push(`x^${degree - i}y`); + else if (degree - i === 1) mon.push(`xy^${i}`); + else mon.push(`x^${degree - i}y^${i}`); + } + return mon; + }; + + const formatFamilyPolynomial = (coeffs, degree) => { + if (!Array.isArray(coeffs) || coeffs.length < 2 || !Number.isInteger(Number(degree))) { + return "N/A"; + } + + const d = Number(degree); + const mon = buildMonomials(d); + + const formatOnePoly = (polyCoeffs) => { + if (!Array.isArray(polyCoeffs)) return "N/A"; + let out = ""; + let firstTerm = true; + + for (let i = 0; i <= d && i < polyCoeffs.length; i++) { + const c = String(polyCoeffs[i]); + if (c === "0") continue; + + if (!firstTerm && !c.startsWith("-")) out += "+"; + if (c === "1") out += mon[i]; + else if (c === "-1") out += `-${mon[i]}`; + else out += `${c}${mon[i]}`; + firstTerm = false; + } + + return out || "0"; + }; + + const left = formatOnePoly(coeffs[0]); + const right = formatOnePoly(coeffs[1]); + return `[${left} : ${right}]`; + }; + return ( <>
@@ -175,6 +244,77 @@ function FilteredFamilies() { + {/* Dimension Filter */} + + + {/* Polynomial Type Filter */} + + + {/* Field Label Filter */} + +
{/* Action Buttons */}