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 */}
+
+ -
+
+ Field of Definition
+
+
+
+
+
{/* Action Buttons */}
@@ -203,11 +343,15 @@ function FilteredFamilies() {
{/* Results Table */}
+ {filtersApplied && }
Family Id>,
+ <>Family Name>,
+ <>Degree>,
+ <>Domain>,
+ <>Polynomial>,
+ <>Field>
]}
data={
families === null
@@ -226,6 +370,11 @@ function FilteredFamilies() {
,
x[1],
x[2],
+ <>
+ P1 {String.fromCharCode(8594)} P1
+ >,
+ formatFamilyPolynomial(x[4], x[2]),
+ x[6]
])
}
itemsPerPage={pagesPer}