Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…mako into finsoup
  • Loading branch information
pkim-gswell committed Nov 17, 2023
2 parents 1333188 + f767a24 commit 0a5fe46
Show file tree
Hide file tree
Showing 24 changed files with 660 additions and 219 deletions.
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 @@ -61,7 +61,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");
});
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
5 changes: 3 additions & 2 deletions src/services/ui/src/components/Inputs/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const FormLabel = React.forwardRef<
return (
<Label
ref={ref}
className={cn(error && "text-destructive", "font-bold", className)}
className={cn(error && "text-destructive", className)}
htmlFor={formItemId}
{...props}
/>
Expand Down Expand Up @@ -148,7 +148,8 @@ const FormMessage = React.forwardRef<
React.HTMLAttributes<HTMLParagraphElement> & { className?: string }
>(({ className, children, ...props }, ref) => {
const { error, formMessageId } = useFormField();
const body = error ? String(error?.message) : children;
const body =
error && !Array.isArray(error) ? String(error?.message) : children;

if (!body) {
return null;
Expand Down
33 changes: 21 additions & 12 deletions src/services/ui/src/components/Inputs/input.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
import * as React from "react";

import { cn } from "@/lib/utils";

export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}
extends React.InputHTMLAttributes<HTMLInputElement> {
icon?: string;
}

const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, type, ...props }, ref) => {
({ className, icon, ...props }, ref) => {
return (
<input
type={type}
className={cn(
"flex h-9 w-full rounded-sm border border-black bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
className
<div className="relative">
{icon && (
<span className="absolute inset-y-0 left-0 flex items-center pl-2 text-gray-500">
{icon}
</span>
)}
ref={ref}
id={props.name}
{...props}
/>
<input
className={cn(
"flex h-9 w-full rounded-sm border border-black bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
icon && "pl-6",
className
)}
ref={ref}
id={props.name}
{...props}
/>
</div>
);
}
);

Input.displayName = "Input";

export { Input };
2 changes: 1 addition & 1 deletion src/services/ui/src/components/Inputs/label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";

const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
"text-base leading-normal peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
);

const Label = React.forwardRef<
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 @@ -29,7 +29,7 @@ export const FILTER_GROUPS = (
value: [],
},
"planType.keyword": {
label: "Plan Type",
label: "Type",
field: "planType.keyword",
component: "multiCheck",
prefix: "must",
Expand Down Expand Up @@ -61,7 +61,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 @@ -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 || [],
Expand Down
Loading

0 comments on commit 0a5fe46

Please sign in to comment.