diff --git a/src/services/ui/src/components/BreadCrumb/BreadCrumb.tsx b/src/services/ui/src/components/BreadCrumb/BreadCrumb.tsx index bbd3787738..ef3cb8bda4 100644 --- a/src/services/ui/src/components/BreadCrumb/BreadCrumb.tsx +++ b/src/services/ui/src/components/BreadCrumb/BreadCrumb.tsx @@ -61,7 +61,7 @@ export const BreadCrumb = ({ {showSeperator && {seperator}} {active && ( - + {children} )} diff --git a/src/services/ui/src/components/Cards/OptionCard.test.tsx b/src/services/ui/src/components/Cards/OptionCard.test.tsx index 78af99e2f4..62ae3f023a 100644 --- a/src/services/ui/src/components/Cards/OptionCard.test.tsx +++ b/src/services/ui/src/components/Cards/OptionCard.test.tsx @@ -49,11 +49,11 @@ describe("OptionCard Component System", () => { expect(innerWrapper.className.includes("bg-slate-100")).toBeTruthy(); expect(innerWrapper.className.includes("bg-white")).toBeFalsy(); }); - test("title is rendered as an h3 and styled", () => { + test("title is rendered as an h2 and styled", () => { renderOptionCard(false); - const header = screen.getByRole("heading", { level: 3 }); + const header = screen.getByRole("heading", { level: 2 }); expect(header).toHaveTextContent("Test Card Title"); - expect(header).toHaveClass("text-lg text-sky-600 font-bold my-2"); + expect(header).toHaveClass("text-lg text-sky-700 font-bold my-2"); }); test("description is rendered", () => { renderOptionCard(false); diff --git a/src/services/ui/src/components/Cards/OptionCard.tsx b/src/services/ui/src/components/Cards/OptionCard.tsx index 6c4963d1f1..61d9fc23ab 100644 --- a/src/services/ui/src/components/Cards/OptionCard.tsx +++ b/src/services/ui/src/components/Cards/OptionCard.tsx @@ -45,10 +45,10 @@ export const OptionCard = ({ } hover:bg-sky-100`} >
-

{title}

+

{title}

{description}

- + diff --git a/src/services/ui/src/components/Opensearch/Filtering/FilterableDateRange.tsx b/src/services/ui/src/components/Opensearch/Filtering/FilterableDateRange.tsx index b33fb248a8..8123029ab9 100644 --- a/src/services/ui/src/components/Opensearch/Filtering/FilterableDateRange.tsx +++ b/src/services/ui/src/components/Opensearch/Filtering/FilterableDateRange.tsx @@ -1,10 +1,22 @@ -import { useState, useMemo, useEffect } from "react"; -import { format } from "date-fns"; +import { useState, useMemo } from "react"; +import { + format, + isAfter, + isBefore, + isValid, + parse, + startOfQuarter, + startOfMonth, + sub, + getYear, + endOfDay, + startOfDay, +} from "date-fns"; import { Calendar as CalendarIcon } from "lucide-react"; import { DateRange } from "react-day-picker"; import { cn } from "@/lib/utils"; -import { Button, Calendar } from "@/components/Inputs"; +import { Button, Calendar, Input } from "@/components/Inputs"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/Popover"; import { OsRangeValue } from "shared-types"; @@ -19,23 +31,123 @@ type Props = Omit< export function FilterableDateRange({ value, onChange, ...props }: Props) { const [open, setOpen] = useState(false); - const [date, setDate] = useState({ + const [selectedDate, setSelectedDate] = useState({ from: value?.gte ? new Date(value?.gte) : undefined, to: value?.lte ? new Date(value?.lte) : undefined, }); + const [fromValue, setFromValue] = useState( + value?.gte ? format(new Date(value?.gte), "MM/dd/yyyy") : "" + ); + const [toValue, setToValue] = useState( + value?.lte ? format(new Date(value?.lte), "MM/dd/yyyy") : "" + ); const handleClose = (updateOpen: boolean) => { setOpen(updateOpen); }; + const checkSingleDateSelection = ( + from: Date | undefined, + to: Date | undefined + ) => { + if (from && !to) { + const rangeObject = getDateRange(from, endOfDay(from)); + onChange(rangeObject); + setFromValue(format(from, "MM/dd/yyyy")); + } + }; + + const onFromInput = (e: React.ChangeEvent) => { + const minValidYear = 1960; + const input = e.target.value; + + if (/^[0-9/]*$/.test(input)) { + setFromValue(e.target.value); + const date = parse(e.target.value, "MM/dd/yyyy", new Date()); + if ( + !isValid(date) || + getYear(date) < minValidYear || + isAfter(date, new Date()) + ) { + return setSelectedDate({ from: undefined, to: selectedDate?.to }); + } + if (selectedDate?.to && isAfter(date, selectedDate.to)) { + setSelectedDate({ from: date, to: undefined }); + setToValue(""); + } else { + setSelectedDate({ from: date, to: selectedDate?.to }); + onChange({ + gte: date.toISOString(), + lte: selectedDate?.to?.toISOString() || "", + }); + } + } + }; + + const onToInput = (e: React.ChangeEvent) => { + const minValidYear = 1960; + const inputValue = e.target.value; + + if (/^[0-9/]*$/.test(inputValue)) { + setToValue(e.target.value); + const date = parse(inputValue, "MM/dd/yyyy", new Date()); + + if ( + !isValid(date) || + getYear(date) < minValidYear || + isAfter(date, new Date()) + ) { + return setSelectedDate({ from: selectedDate?.from, to: undefined }); + } + + if (selectedDate?.from && isBefore(date, selectedDate.from)) { + setSelectedDate({ from: undefined, to: selectedDate.from }); + setFromValue(""); + } else { + setSelectedDate({ from: selectedDate?.from, to: date }); + onChange({ + gte: selectedDate?.from?.toISOString() || "", + lte: endOfDay(date).toISOString(), + }); + } + } + }; + + const getDateRange = (startDate: Date, endDate: Date): OsRangeValue => { + return { + gte: startDate.toISOString(), + lte: endDate.toISOString(), + }; + }; + + const setPresetRange = (range: string) => { + const today = startOfDay(new Date()); + let startDate = today; + if (range === "quarter") { + startDate = startOfQuarter(today); + } else if (range === "month") { + startDate = startOfMonth(today); + } else if (range === "week") { + startDate = sub(today, { days: 6 }); + } + + const rangeObject = getDateRange(startDate, endOfDay(today)); + onChange(rangeObject); + setSelectedDate({ from: startDate, to: today }); + setFromValue(format(startDate, "MM/dd/yyyy")); + setToValue(format(today, "MM/dd/yyyy")); + }; + const label = useMemo(() => { - const from = date?.from ? format(date.from, "LLL dd, y") : ""; - const to = date?.to ? format(date.to, "LLL dd, y") : ""; + const from = selectedDate?.from + ? format(selectedDate.from, "LLL dd, y") + : ""; + const to = selectedDate?.to ? format(selectedDate.to, "LLL dd, y") : ""; if (from && to) return `${from} - ${to}`; if (from) return `${from}`; return "Pick a date"; - }, [date]); + }, [selectedDate]); return (
@@ -57,28 +169,66 @@ export function FilterableDateRange({ value, onChange, ...props }: Props) { disabled={[{ after: new Date() }]} initialFocus mode="range" - defaultMonth={date?.from} - selected={date} + defaultMonth={selectedDate?.from} + selected={selectedDate} numberOfMonths={2} className="bg-white" onSelect={(d) => { - setDate(d); + setSelectedDate(d); if (!!d?.from && !!d.to) { onChange({ gte: d.from.toISOString(), - lte: d.to.toISOString(), + lte: endOfDay(d.to).toISOString(), + }); + setFromValue(format(d.from, "MM/dd/yyyy")); + setToValue(format(d.to, "MM/dd/yyyy")); + } else if (!d?.from && !d?.to) { + onChange({ + gte: "", + lte: "", }); + setFromValue(""); + setToValue(""); + } else { + checkSingleDateSelection(d.from, d.to); } }} {...props} /> +
+ +

-

+ +
+
+ + + + +
)} - + {context.data && !context.data.hits.length && ( + + +

+

+ No Results Found +

+
+
+ )} {context.data?.hits.map((DAT) => ( diff --git a/src/services/ui/src/components/Opensearch/useOpensearch.ts b/src/services/ui/src/components/Opensearch/useOpensearch.ts index 71d5e1ec38..db038b55d9 100644 --- a/src/services/ui/src/components/Opensearch/useOpensearch.ts +++ b/src/services/ui/src/components/Opensearch/useOpensearch.ts @@ -100,7 +100,7 @@ export const useOsAggregate = () => { field: "leadAnalystName.keyword", name: "leadAnalystName.keyword", type: "terms", - size: 300, + size: 1000, }, ], filters: DEFAULT_FILTERS[props.queryKey[0]].filters || [], diff --git a/src/services/ui/src/components/Table/index.tsx b/src/services/ui/src/components/Table/index.tsx index ee0bb8a2e6..244c69ea18 100644 --- a/src/services/ui/src/components/Table/index.tsx +++ b/src/services/ui/src/components/Table/index.tsx @@ -9,7 +9,7 @@ const Table = React.forwardRef< className?: string; } >(({ className, ...props }, ref) => ( -
+
{ const context = useOsContext(); const params = useOsParams(); if (context.error) return ; - console.log(user, "user from spas"); const columns = TABLE_COLUMNS({ isCms: user?.isCms, user: user?.user }); return ( -
+
{ const columns = TABLE_COLUMNS({ isCms: user?.isCms, user: user?.user }); return ( -
+
{ > -

SPAs

+

SPAs

-

Waivers

+

Waivers

diff --git a/src/services/ui/src/pages/form/index.tsx b/src/services/ui/src/pages/form/index.tsx index 42b164a33f..82f524a512 100644 --- a/src/services/ui/src/pages/form/index.tsx +++ b/src/services/ui/src/pages/form/index.tsx @@ -82,7 +82,6 @@ export function ExampleForm() { console.log({ err }); } ); - return (