diff --git a/apps/web/src/app/play/checker/_components/checker-form.tsx b/apps/web/src/app/play/checker/_components/checker-form.tsx index bdaf17a55..b210ddba0 100644 --- a/apps/web/src/app/play/checker/_components/checker-form.tsx +++ b/apps/web/src/app/play/checker/_components/checker-form.tsx @@ -66,7 +66,7 @@ const FloatingActionNoSSR = dynamic( { ssr: false, loading: () => <>, - } + }, ); /** @@ -190,7 +190,7 @@ export function CheckerForm({ defaultValues, defaultData }: CheckerFormProps) { `Checking ${regionFormatter(_result[0].region, "long")} (${latencyFormatter(_result[0].latency)})`, { id: toastId, - } + }, ); } } diff --git a/apps/web/src/app/play/checker/_components/global-monitoring.tsx b/apps/web/src/app/play/checker/_components/global-monitoring.tsx index b22137507..8de9288ef 100644 --- a/apps/web/src/app/play/checker/_components/global-monitoring.tsx +++ b/apps/web/src/app/play/checker/_components/global-monitoring.tsx @@ -18,9 +18,9 @@ const features: { }[] = [ { icon: "gauge", - catchline: "Speed Test for Websites", + catchline: "Speed Test", description: - "Enter your URL and get a website speed check. Get insights on page load, header details and timing phases (DNS, Connect, TLS, TTFB) of the response.", + "Enter your URL and get a website speed check. Get insights on page load, header details and timing phases (DNS, Connect, TLS, TTFB, Transfer) of the response.", }, { icon: "globe", @@ -32,7 +32,7 @@ const features: { icon: "link", catchline: "Share the Results", description: - "Quickly share the results of your website speed test with your team or clients. We share the results for 7 days, so you can easily collaborate on performance.", + "Quickly share the results of your website speed test with your team or clients. The results expire after 7 days, so you can easily collaborate on performance.", }, ]; export const GlobalMonitoring = () => { diff --git a/apps/web/src/components/data-table/data-table-column-header.tsx b/apps/web/src/components/data-table/data-table-column-header.tsx index 68b1fea9d..4620e2fdc 100644 --- a/apps/web/src/components/data-table/data-table-column-header.tsx +++ b/apps/web/src/components/data-table/data-table-column-header.tsx @@ -1,18 +1,11 @@ import type { Column } from "@tanstack/react-table"; -import { ArrowDown, ArrowUp, ChevronsUpDown } from "lucide-react"; +import { ChevronDown, ChevronUp } from "lucide-react"; -import { - Button, - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from "@openstatus/ui"; +import { Button, type ButtonProps } from "@openstatus/ui"; import { cn } from "@/lib/utils"; -interface DataTableColumnHeaderProps - extends React.HTMLAttributes { +interface DataTableColumnHeaderProps extends ButtonProps { column: Column; title: string; } @@ -21,46 +14,41 @@ export function DataTableColumnHeader({ column, title, className, + ...props }: DataTableColumnHeaderProps) { if (!column.getCanSort()) { return
{title}
; } return ( -
- - - - - - column.toggleSorting(false)}> - - Asc - - column.toggleSorting(true)}> - - Desc - - {/* - column.toggleVisibility(false)}> - - Hide - */} - - -
+ ); } diff --git a/apps/web/src/components/marketing/card.tsx b/apps/web/src/components/marketing/card.tsx index bde4ee924..dfdd69df4 100644 --- a/apps/web/src/components/marketing/card.tsx +++ b/apps/web/src/components/marketing/card.tsx @@ -96,15 +96,15 @@ export function CardFeature(props: FeatureDescription) { const FeatureIcon = Icons[props.icon]; return (
  • -

    - - +

    +

    + {props.catchline.replace(".", "")} {" "} - +

    {props.description} -

    +
    {props.badge ? ( {props.badge} diff --git a/apps/web/src/components/marketing/hero.tsx b/apps/web/src/components/marketing/hero.tsx index 074e4e92b..981d08d90 100644 --- a/apps/web/src/components/marketing/hero.tsx +++ b/apps/web/src/components/marketing/hero.tsx @@ -29,7 +29,7 @@ export function Hero() {

    A better way to monitor your services. diff --git a/apps/web/src/components/ping-response-analysis/columns.tsx b/apps/web/src/components/ping-response-analysis/columns.tsx index a4d59f03a..2de2ab731 100644 --- a/apps/web/src/components/ping-response-analysis/columns.tsx +++ b/apps/web/src/components/ping-response-analysis/columns.tsx @@ -6,9 +6,9 @@ import { continentFormatter, latencyFormatter, regionFormatter, - timestampFormatter, } from "./utils"; +import { flyRegionsDict } from "@openstatus/utils"; import { format } from "date-fns"; import { utcToZonedTime } from "date-fns-tz"; import { DataTableColumnHeader } from "../data-table/data-table-column-header"; @@ -26,6 +26,7 @@ export const columns: ColumnDef[] = [ }, { accessorKey: "region", + accessorFn: (row) => row.region, header: "Region", cell: ({ row }) => { return ( @@ -34,15 +35,11 @@ export const columns: ColumnDef[] = [ ); }, - }, - { - id: "continent", - accessorFn: (row) => continentFormatter(row.region), - header: ({ column }) => { - return ; - }, - cell: ({ row }) => { - return
    {row.getValue("continent")}
    ; + filterFn: (row, _id, filterValue) => { + const region = regionFormatter(row.original.region, "long").toLowerCase(); + const continent = + flyRegionsDict[row.original.region].continent.toLocaleLowerCase(); + return `${region} ${continent}`.includes(filterValue.toLowerCase()); }, }, { @@ -55,85 +52,141 @@ export const columns: ColumnDef[] = [ { id: "DNS", header: ({ column }) => { - return ; + return ( + + ); }, accessorFn: (row) => `${row.timing.dnsDone - row.timing.dnsStart}`, cell: ({ row, column }) => { return ( -
    +
    {latencyFormatter(row.getValue(column.id))}
    ); }, + meta: { + headerClassName: "text-right", + }, }, { id: "connect", accessorFn: (row) => `${row.timing.connectDone - row.timing.connectStart}`, header: ({ column }) => { - return ; + return ( + + ); }, cell: ({ row, column }) => { return ( -
    +
    {latencyFormatter(row.getValue(column.id))}
    ); }, + meta: { + headerClassName: "text-right", + }, }, { id: "TLS", - accessorFn: (row) => `${row.timing.tlsHandshakeDone - row.timing.tlsHandshakeStart}`, header: ({ column }) => { - return ; + return ( + + ); }, cell: ({ row, column }) => { return ( -
    +
    {latencyFormatter(row.getValue(column.id))}
    ); }, + meta: { + headerClassName: "text-right", + }, }, { id: "TTFB", accessorFn: (row) => `${row.timing.firstByteDone - row.timing.firstByteStart}`, header: ({ column }) => { - return ; + return ( + + ); }, cell: ({ row, column }) => { return ( -
    +
    {latencyFormatter(row.getValue(column.id))}
    ); }, + meta: { + headerClassName: "text-right", + }, }, { - accessorKey: "latency", + accessorKey: "transfer", + accessorFn: (row) => + `${row.timing.transferDone - row.timing.transferStart}`, header: ({ column }) => { - return ; + return ( + + ); }, - cell: ({ row }) => { + cell: ({ row, column }) => { return ( -
    - {latencyFormatter(row.original.latency)} +
    + {latencyFormatter(row.getValue(column.id))}
    ); }, + meta: { + headerClassName: "text-right", + }, }, { - id: "Time (UTC)", - accessorFn: (row) => row.time, + accessorKey: "latency", + header: ({ column }) => { + return ( + + ); + }, cell: ({ row }) => { - const date = format( - utcToZonedTime(row.original.time, "UTC"), - "dd LLL hh:mm a", + return ( +
    + {latencyFormatter(row.original.latency)} +
    ); - - return
    {date}
    ; + }, + meta: { + headerClassName: "text-right", }, }, ]; diff --git a/apps/web/src/components/ping-response-analysis/multi-region-table.tsx b/apps/web/src/components/ping-response-analysis/multi-region-table.tsx index dce23a494..b06951177 100644 --- a/apps/web/src/components/ping-response-analysis/multi-region-table.tsx +++ b/apps/web/src/components/ping-response-analysis/multi-region-table.tsx @@ -10,8 +10,10 @@ import { TableRow, } from "@openstatus/ui/src/components/table"; +import { Input } from "@openstatus/ui"; import { type ColumnDef, + type ColumnFiltersState, type ExpandedState, type Row, type SortingState, @@ -19,6 +21,7 @@ import { flexRender, getCoreRowModel, getExpandedRowModel, + getFilteredRowModel, getSortedRowModel, useReactTable, } from "@tanstack/react-table"; @@ -47,10 +50,8 @@ export function MultiRegionTable({ { id: "latency", desc: false }, ]); const [expanded, setExpanded] = useState({}); - const [columnVisibility, setColumnVisibility] = useState({ - continent: false, - "Time (UTC)": false, - }); + const [columnVisibility, setColumnVisibility] = useState({}); + const [columnFilters, setColumnFilters] = useState([]); const table = useReactTable({ data, @@ -58,24 +59,32 @@ export function MultiRegionTable({ onSortingChange: setSorting, onExpandedChange: setExpanded, onColumnVisibilityChange: setColumnVisibility, + onColumnFiltersChange: setColumnFilters, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), getExpandedRowModel: getExpandedRowModel(), + getFilteredRowModel: getFilteredRowModel(), getRowCanExpand, autoResetExpanded, state: { sorting, expanded, columnVisibility, + columnFilters, }, }); return (
    -

    - Select a row to expand the response details. -

    + + table.getColumn("region")?.setFilterValue(event.target.value) + } + className="h-8 max-w-[325px] truncate" + />
    @@ -96,7 +105,7 @@ export function MultiRegionTable({ ? null : flexRender( header.column.columnDef.header, - header.getContext() + header.getContext(), )} ); @@ -119,7 +128,7 @@ export function MultiRegionTable({ {flexRender( cell.column.columnDef.cell, - cell.getContext() + cell.getContext(), )} ))} diff --git a/apps/web/src/components/ping-response-analysis/multi-region-tabs.tsx b/apps/web/src/components/ping-response-analysis/multi-region-tabs.tsx index 4565176e8..d17f98cdd 100644 --- a/apps/web/src/components/ping-response-analysis/multi-region-tabs.tsx +++ b/apps/web/src/components/ping-response-analysis/multi-region-tabs.tsx @@ -20,10 +20,14 @@ export function MultiRegionTabs({ }) { return ( -
    - - Table - Chart +
    + + + Table + + + Chart + i.region)} @@ -31,12 +35,12 @@ export function MultiRegionTabs({ size="sm" />
    - + selectedRegions?.includes(i.region))} /> - + selectedRegions?.includes(i.region))} columns={columns}