Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(opensearch filters): Adjust opensearch filters for better UX #194

Merged
merged 19 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/services/ui/src/components/BreadCrumb/BreadCrumb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const BreadCrumb = ({
{showSeperator && <span>{seperator}</span>}

{active && (
<Link to={to} className="underline text-sky-600 hover:text-sky-800">
<Link to={to} className="underline text-sky-700 hover:text-sky-800">
{children}
</Link>
)}
Expand Down
6 changes: 3 additions & 3 deletions src/services/ui/src/components/Cards/OptionCard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Comment on lines +52 to +56
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoa we have tests? 🤯

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like Kevin wrote these!

});
test("description is rendered", () => {
renderOptionCard(false);
Expand Down
4 changes: 2 additions & 2 deletions src/services/ui/src/components/Cards/OptionCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ export const OptionCard = ({
} hover:bg-sky-100`}
>
<div>
<h3 className="text-lg text-sky-600 font-bold my-2">{title}</h3>
<h2 className="text-lg text-sky-700 font-bold my-2">{title}</h2>
<p className="my-2 text-slate-600">{description}</p>
</div>
<ChevronRight className="text-sky-600 w-8 h-8" />
<ChevronRight className="text-sky-700 w-8 h-8" />
</div>
</Link>
</label>
Expand Down
Original file line number Diff line number Diff line change
@@ -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";

Expand All @@ -19,23 +31,123 @@ type Props = Omit<

export function FilterableDateRange({ value, onChange, ...props }: Props) {
const [open, setOpen] = useState(false);
const [date, setDate] = useState<DateRange | undefined>({
const [selectedDate, setSelectedDate] = useState<DateRange | undefined>({
from: value?.gte ? new Date(value?.gte) : undefined,
to: value?.lte ? new Date(value?.lte) : undefined,
});
const [fromValue, setFromValue] = useState<string>(
value?.gte ? format(new Date(value?.gte), "MM/dd/yyyy") : ""
);
const [toValue, setToValue] = useState<string>(
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<HTMLInputElement>) => {
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<HTMLInputElement>) => {
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 (
<div className="flex items-center">
Expand All @@ -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}
/>
<div className="flex flex-row gap-4 w-[320px] p-2 m-auto">
<Input
onChange={onFromInput}
value={fromValue}
placeholder="mm/dd/yyyy"
className="text-md"
/>
<p>-</p>
<Input
onChange={onToInput}
value={toValue}
placeholder="mm/dd/yyyy"
className="text-md"
/>
</div>
<div className="flex gap-4 p-2 ml-4">
<Button onClick={() => setPresetRange("today")}>Today</Button>
<Button onClick={() => setPresetRange("week")}>Last 7 Days</Button>
<Button onClick={() => setPresetRange("month")}>
Month To Date
</Button>
<Button onClick={() => setPresetRange("quarter")}>
Quarter To Date
</Button>
</div>
</PopoverContent>
</Popover>
<Button
className="text-white"
onClick={() => {
setDate({ from: undefined, to: undefined });
setSelectedDate({ from: undefined, to: undefined });
onChange({ gte: undefined, lte: undefined });
setToValue("");
setFromValue("");
}}
>
Clear
Expand Down
4 changes: 2 additions & 2 deletions src/services/ui/src/components/Opensearch/Filtering/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const FILTER_GROUPS = (
value: [],
},
"planType.keyword": {
label: "Plan Type",
label: "Type",
field: "planType.keyword",
component: "multiCheck",
prefix: "must",
Expand Down Expand Up @@ -60,7 +60,7 @@ export const FILTER_GROUPS = (
value: { gte: undefined, lte: undefined },
},
raiReceivedDate: {
label: "RAI Response Date",
label: "Formal RAI Response",
field: "raiReceivedDate",
component: "dateRange",
prefix: "must",
Expand Down
13 changes: 11 additions & 2 deletions src/services/ui/src/components/Opensearch/Table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const OsTable: FC<{
};

return (
<UI.Table className="flex-1 border-[1px]">
<UI.Table className="flex-1 min-h-[calc(100vh-350px)]">
<UI.TableHeader className="sticky top-0 bg-white">
<UI.TableRow>
<UI.TableHead
Expand Down Expand Up @@ -77,7 +77,16 @@ export const OsTable: FC<{
<LoadingSpinner />
</div>
)}

{context.data && !context.data.hits.length && (
<UI.TableRow className="h-10">
<UI.TableCell className="flex">
<p className="font-medium whitespace-nowrap h-[20px]"> </p>
<p className="absolute right-[50%] top-[50%] translate-x-[50%] translate-y-[50%] font-medium text-lg text-gray-500">
No Results Found
</p>
</UI.TableCell>
</UI.TableRow>
)}
{context.data?.hits.map((DAT) => (
<UI.TableRow key={DAT._source.id}>
<UI.TableCell className="fixed" />
Expand Down
2 changes: 1 addition & 1 deletion src/services/ui/src/components/Opensearch/useOpensearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export const useOsAggregate = () => {
field: "leadAnalystName.keyword",
name: "leadAnalystName.keyword",
type: "terms",
size: 300,
size: 1000,
},
],
filters: DEFAULT_FILTERS[props.queryKey[0]].filters || [],
Expand Down
2 changes: 1 addition & 1 deletion src/services/ui/src/components/Table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const Table = React.forwardRef<
className?: string;
}
>(({ className, ...props }, ref) => (
<div className="w-full overflow-auto">
<div className="w-full border-[1px] overflow-auto">
<table
ref={ref}
className={cn("w-full caption-bottom text-sm", className)}
Expand Down
3 changes: 1 addition & 2 deletions src/services/ui/src/pages/dashboard/Lists/spas/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ export const SpasList = () => {
const context = useOsContext();
const params = useOsParams();
if (context.error) return <ErrorAlert error={context.error} />;
console.log(user, "user from spas");

const columns = TABLE_COLUMNS({ isCms: user?.isCms, user: user?.user });

return (
<section className="flex flex-col h-[calc(100vh-250px)]">
<section className="flex flex-col h-[calc(100vh-230px)]">
<OsFiltering />
<OsTable columns={columns} />
<Pagination
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const WaiversList = () => {
const columns = TABLE_COLUMNS({ isCms: user?.isCms, user: user?.user });

return (
<section className="flex flex-col h-[calc(100vh-250px)]">
<section className="flex flex-col h-[calc(100vh-230px)]">
<OsFiltering />
<OsTable columns={columns} />
<Pagination
Expand Down
4 changes: 2 additions & 2 deletions src/services/ui/src/pages/dashboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ export const Dashboard = () => {
>
<TabsList>
<TabsTrigger value="spas" className="px-6 py-2">
<h4 className="font-bold text-[1.3em]">SPAs</h4>
<h2 className="font-bold text-[1.3em]">SPAs</h2>
</TabsTrigger>
<TabsTrigger value="waivers" className="px-6 py-2">
<h4 className="font-bold text-[1.3em]">Waivers</h4>
<h2 className="font-bold text-[1.3em]">Waivers</h2>
</TabsTrigger>
</TabsList>
<TabsContent value="spas">
Expand Down
1 change: 0 additions & 1 deletion src/services/ui/src/pages/form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export function ExampleForm() {
console.log({ err });
}
);

return (
<div className="max-w-screen-xl mx-auto p-4 py-8 lg:px-8">
<Form {...form}>
Expand Down
Loading