chore(root): migrate to biome
This commit is contained in:
@@ -16,7 +16,7 @@ export function OriginFilter() {
|
||||
},
|
||||
{
|
||||
staleTime: 1000 * 60 * 60,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (!data || data.length === 0) {
|
||||
@@ -32,7 +32,7 @@ export function OriginFilter() {
|
||||
variant="outline"
|
||||
icon={GlobeIcon}
|
||||
className={cn(
|
||||
originFilter?.value.includes(item.origin) && 'border-foreground'
|
||||
originFilter?.value.includes(item.origin) && 'border-foreground',
|
||||
)}
|
||||
onClick={() => setFilter('origin', [item.origin], 'is')}
|
||||
>
|
||||
|
||||
@@ -125,7 +125,7 @@ export function FilterOptionEvent({
|
||||
setFilter: (
|
||||
name: string,
|
||||
value: IChartEventFilterValue,
|
||||
operator: IChartEventFilterOperator
|
||||
operator: IChartEventFilterOperator,
|
||||
) => void;
|
||||
}) {
|
||||
const { interval, range } = useOverviewOptions();
|
||||
@@ -172,7 +172,7 @@ export function FilterOptionProfile({
|
||||
setFilter: (
|
||||
name: string,
|
||||
value: IChartEventFilterValue,
|
||||
operator: IChartEventFilterOperator
|
||||
operator: IChartEventFilterOperator,
|
||||
) => void;
|
||||
}) {
|
||||
const values = useProfileValues(projectId, filter.name);
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { OverviewFiltersDrawerContentProps } from './overview-filters-drawe
|
||||
import { OverviewFiltersDrawerContent } from './overview-filters-drawer-content';
|
||||
|
||||
export function OverviewFiltersDrawer(
|
||||
props: OverviewFiltersDrawerContentProps
|
||||
props: OverviewFiltersDrawerContentProps,
|
||||
) {
|
||||
return (
|
||||
<Sheet>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { useRef, useState } from 'react';
|
||||
import { TooltipComplete } from '@/components/tooltip-complete';
|
||||
import {
|
||||
Tooltip,
|
||||
@@ -12,6 +11,7 @@ import useWS from '@/hooks/useWS';
|
||||
import { cn } from '@/utils/cn';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useRef, useState } from 'react';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
export interface LiveCounterProps {
|
||||
@@ -34,7 +34,7 @@ export default function LiveCounter({ data = 0, projectId }: LiveCounterProps) {
|
||||
const lastRefresh = useRef(Date.now());
|
||||
|
||||
useWS<number>(`/live/visitors/${projectId}`, (value) => {
|
||||
if (!isNaN(value)) {
|
||||
if (!Number.isNaN(value)) {
|
||||
counter.set(value);
|
||||
if (Date.now() - lastRefresh.current > FIFTEEN_SECONDS) {
|
||||
lastRefresh.current = Date.now();
|
||||
@@ -57,13 +57,13 @@ export default function LiveCounter({ data = 0, projectId }: LiveCounterProps) {
|
||||
<div
|
||||
className={cn(
|
||||
'h-3 w-3 animate-ping rounded-full bg-emerald-500 opacity-100 transition-all',
|
||||
counter.debounced === 0 && 'bg-destructive opacity-0'
|
||||
counter.debounced === 0 && 'bg-destructive opacity-0',
|
||||
)}
|
||||
/>
|
||||
<div
|
||||
className={cn(
|
||||
'absolute left-0 top-0 h-3 w-3 rounded-full bg-emerald-500 transition-all',
|
||||
counter.debounced === 0 && 'bg-destructive'
|
||||
counter.debounced === 0 && 'bg-destructive',
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Dispatch, SetStateAction } from 'react';
|
||||
import { BarChartIcon, LineChartIcon } from 'lucide-react';
|
||||
import type { Dispatch, SetStateAction } from 'react';
|
||||
|
||||
import type { IChartType } from '@openpanel/validation';
|
||||
|
||||
|
||||
@@ -69,18 +69,16 @@ export function OverviewLiveHistogram({
|
||||
const liveCount = countRes.data?.series[0]?.metrics?.sum ?? 0;
|
||||
|
||||
if (res.isInitialLoading || countRes.isInitialLoading) {
|
||||
// prettier-ignore
|
||||
const staticArray = [
|
||||
10, 25, 30, 45, 20, 5, 55, 18, 40, 12,
|
||||
50, 35, 8, 22, 38, 42, 15, 28, 52, 5,
|
||||
48, 14, 32, 58, 7, 19, 33, 56, 24, 5
|
||||
10, 25, 30, 45, 20, 5, 55, 18, 40, 12, 50, 35, 8, 22, 38, 42, 15, 28, 52,
|
||||
5, 48, 14, 32, 58, 7, 19, 33, 56, 24, 5,
|
||||
];
|
||||
|
||||
return (
|
||||
<Wrapper count={0}>
|
||||
{staticArray.map((percent, i) => (
|
||||
<div
|
||||
key={i}
|
||||
key={i as number}
|
||||
className="flex-1 animate-pulse rounded-t bg-def-200"
|
||||
style={{ height: `${percent}%` }}
|
||||
/>
|
||||
@@ -102,7 +100,7 @@ export function OverviewLiveHistogram({
|
||||
<div
|
||||
className={cn(
|
||||
'flex-1 rounded-t transition-all ease-in-out hover:scale-110',
|
||||
minute.count === 0 ? 'bg-def-200' : 'bg-highlight'
|
||||
minute.count === 0 ? 'bg-def-200' : 'bg-highlight',
|
||||
)}
|
||||
style={{
|
||||
height:
|
||||
|
||||
@@ -197,10 +197,11 @@ export default function OverviewMetrics({ projectId }: OverviewMetricsProps) {
|
||||
<div className="card mb-2 grid grid-cols-4 overflow-hidden rounded-md">
|
||||
{reports.map((report, index) => (
|
||||
<button
|
||||
key={index}
|
||||
type="button"
|
||||
key={report.id}
|
||||
className={cn(
|
||||
'col-span-2 flex-1 shadow-[0_0_0_0.5px] shadow-border md:col-span-1',
|
||||
index === metric && 'bg-def-100'
|
||||
index === metric && 'bg-def-100',
|
||||
)}
|
||||
onClick={() => {
|
||||
setMetric(index);
|
||||
@@ -211,7 +212,7 @@ export default function OverviewMetrics({ projectId }: OverviewMetricsProps) {
|
||||
))}
|
||||
<div
|
||||
className={cn(
|
||||
'col-span-4 min-h-16 flex-1 p-4 pb-0 shadow-[0_0_0_0.5px] shadow-border max-md:row-start-1 md:col-span-2'
|
||||
'col-span-4 min-h-16 flex-1 p-4 pb-0 shadow-[0_0_0_0.5px] shadow-border max-md:row-start-1 md:col-span-2',
|
||||
)}
|
||||
>
|
||||
<OverviewLiveHistogram projectId={projectId} />
|
||||
|
||||
@@ -31,8 +31,8 @@ export function OverviewShare({ data }: OverviewShareProps) {
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button icon={data && data.public ? Globe2Icon : LockIcon} responsive>
|
||||
{data && data.public ? 'Public' : 'Private'}
|
||||
<Button icon={data?.public ? Globe2Icon : LockIcon} responsive>
|
||||
{data?.public ? 'Public' : 'Private'}
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState } from 'react';
|
||||
import { api } from '@/trpc/client';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { Pagination } from '../pagination';
|
||||
import { Tooltiper } from '../ui/tooltip';
|
||||
@@ -23,7 +23,7 @@ const OverviewTopBots = ({ projectId }: Props) => {
|
||||
{ projectId, cursor },
|
||||
{
|
||||
keepPreviousData: true,
|
||||
}
|
||||
},
|
||||
);
|
||||
const data = res.data?.data ?? [];
|
||||
const count = res.data?.count ?? 0;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useEventQueryFilters } from '@/hooks/useEventQueryFilters';
|
||||
import { cn } from '@/utils/cn';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { NOT_SET_VALUE } from '@openpanel/constants';
|
||||
import type { IChartType } from '@openpanel/validation';
|
||||
@@ -295,6 +295,7 @@ export default function OverviewTopDevices({
|
||||
<WidgetButtons>
|
||||
{widgets.map((w) => (
|
||||
<button
|
||||
type="button"
|
||||
key={w.key}
|
||||
onClick={() => setWidget(w.key)}
|
||||
className={cn(w.key === widget.key && 'active')}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { ReportChart } from '@/components/report-chart';
|
||||
import { useEventQueryFilters } from '@/hooks/useEventQueryFilters';
|
||||
import { cn } from '@/utils/cn';
|
||||
import { useState } from 'react';
|
||||
|
||||
import type { IChartType } from '@openpanel/validation';
|
||||
|
||||
@@ -155,6 +155,7 @@ export default function OverviewTopEvents({
|
||||
.filter((item) => item.hide !== true)
|
||||
.map((w) => (
|
||||
<button
|
||||
type="button"
|
||||
key={w.key}
|
||||
onClick={() => setWidget(w.key)}
|
||||
className={cn(w.key === widget.key && 'active')}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useEventQueryFilters } from '@/hooks/useEventQueryFilters';
|
||||
import { getCountry } from '@/translations/countries';
|
||||
import { cn } from '@/utils/cn';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { NOT_SET_VALUE } from '@openpanel/constants';
|
||||
import type { IChartType } from '@openpanel/validation';
|
||||
@@ -158,6 +158,7 @@ export default function OverviewTopGeo({ projectId }: OverviewTopGeoProps) {
|
||||
<WidgetButtons>
|
||||
{widgets.map((w) => (
|
||||
<button
|
||||
type="button"
|
||||
key={w.key}
|
||||
onClick={() => setWidget(w.key)}
|
||||
className={cn(w.key === widget.key && 'active')}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useEventQueryFilters } from '@/hooks/useEventQueryFilters';
|
||||
import { cn } from '@/utils/cn';
|
||||
import { ExternalLinkIcon, FilterIcon, Globe2Icon } from 'lucide-react';
|
||||
import { parseAsBoolean, useQueryState } from 'nuqs';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { NOT_SET_VALUE } from '@openpanel/constants';
|
||||
import type { IChartType } from '@openpanel/validation';
|
||||
@@ -180,6 +180,7 @@ export default function OverviewTopPages({ projectId }: OverviewTopPagesProps) {
|
||||
<WidgetButtons>
|
||||
{widgets.map((w) => (
|
||||
<button
|
||||
type="button"
|
||||
key={w.key}
|
||||
onClick={() => setWidget(w.key)}
|
||||
className={cn(w.key === widget.key && 'active')}
|
||||
@@ -225,7 +226,7 @@ export default function OverviewTopPages({ projectId }: OverviewTopPagesProps) {
|
||||
<WidgetFooter>
|
||||
<OverviewDetailsButton chart={widget.chart.report} />
|
||||
<OverviewChartToggle {...{ chartType, setChartType }} />
|
||||
<div className="flex-1"></div>
|
||||
<div className="flex-1" />
|
||||
<Button
|
||||
variant={'ghost'}
|
||||
onClick={() => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useEventQueryFilters } from '@/hooks/useEventQueryFilters';
|
||||
import { cn } from '@/utils/cn';
|
||||
import { useState } from 'react';
|
||||
|
||||
import type { IChartType } from '@openpanel/validation';
|
||||
|
||||
@@ -301,6 +301,7 @@ export default function OverviewTopSources({
|
||||
<WidgetButtons>
|
||||
{widgets.map((w) => (
|
||||
<button
|
||||
type="button"
|
||||
key={w.key}
|
||||
onClick={() => setWidget(w.key)}
|
||||
className={cn(w.key === widget.key && 'active')}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
'use client';
|
||||
|
||||
import { Children, useEffect, useRef, useState } from 'react';
|
||||
import { useThrottle } from '@/hooks/useThrottle';
|
||||
import { cn } from '@/utils/cn';
|
||||
import { ChevronsUpDownIcon } from 'lucide-react';
|
||||
import { last } from 'ramda';
|
||||
import { Children, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import {
|
||||
DropdownMenu,
|
||||
@@ -21,7 +21,7 @@ export function WidgetHead({ className, ...props }: WidgetHeadProps) {
|
||||
<WidgetHeadBase
|
||||
className={cn(
|
||||
'flex flex-col rounded-t-xl p-0 [&_.title]:flex [&_.title]:items-center [&_.title]:justify-between [&_.title]:p-4 [&_.title]:font-semibold',
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
@@ -43,11 +43,11 @@ export function WidgetButtons({
|
||||
if (sizes.current.length === 0) {
|
||||
// Get buttons
|
||||
const buttons: HTMLButtonElement[] = Array.from(
|
||||
container.current.querySelectorAll(`button`)
|
||||
container.current.querySelectorAll('button'),
|
||||
);
|
||||
// Get sizes and cache them
|
||||
sizes.current = buttons.map(
|
||||
(button) => Math.ceil(button.offsetWidth) + gap
|
||||
(button) => Math.ceil(button.offsetWidth) + gap,
|
||||
);
|
||||
}
|
||||
const containerWidth = container.current.offsetWidth;
|
||||
@@ -62,7 +62,7 @@ export function WidgetButtons({
|
||||
}
|
||||
return { index, size: acc.size + size };
|
||||
},
|
||||
{ index: 0, size: 0 }
|
||||
{ index: 0, size: 0 },
|
||||
);
|
||||
|
||||
setSlice(res.index);
|
||||
@@ -86,7 +86,7 @@ export function WidgetButtons({
|
||||
ref={container}
|
||||
className={cn(
|
||||
'-mb-px -mt-2 flex flex-wrap justify-start self-stretch px-4 transition-opacity [&_button.active]:border-b-2 [&_button.active]:border-black [&_button.active]:opacity-100 dark:[&_button.active]:border-white [&_button]:whitespace-nowrap [&_button]:py-1 [&_button]:text-sm [&_button]:opacity-50',
|
||||
className
|
||||
className,
|
||||
)}
|
||||
style={{ gap }}
|
||||
{...props}
|
||||
@@ -96,7 +96,7 @@ export function WidgetButtons({
|
||||
<div
|
||||
className={cn(
|
||||
'flex [&_button]:leading-normal',
|
||||
slice < index ? hidden : 'opacity-100'
|
||||
slice < index ? hidden : 'opacity-100',
|
||||
)}
|
||||
>
|
||||
{child}
|
||||
@@ -106,9 +106,10 @@ export function WidgetButtons({
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
'flex select-none items-center gap-1',
|
||||
sizes.current.length - 1 === slice ? hidden : 'opacity-50'
|
||||
sizes.current.length - 1 === slice ? hidden : 'opacity-50',
|
||||
)}
|
||||
>
|
||||
More <ChevronsUpDownIcon size={12} />
|
||||
@@ -138,7 +139,7 @@ export function WidgetFooter({
|
||||
<div
|
||||
className={cn(
|
||||
'flex rounded-b-md border-t bg-def-100 p-2 py-1',
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
|
||||
@@ -19,17 +19,17 @@ const nuqsOptions = { history: 'push' } as const;
|
||||
export function useOverviewOptions() {
|
||||
const [startDate, setStartDate] = useQueryState(
|
||||
'start',
|
||||
parseAsString.withOptions(nuqsOptions)
|
||||
parseAsString.withOptions(nuqsOptions),
|
||||
);
|
||||
const [endDate, setEndDate] = useQueryState(
|
||||
'end',
|
||||
parseAsString.withOptions(nuqsOptions)
|
||||
parseAsString.withOptions(nuqsOptions),
|
||||
);
|
||||
const [range, setRange] = useQueryState(
|
||||
'range',
|
||||
parseAsStringEnum(mapKeys(timeWindows))
|
||||
.withDefault('7d')
|
||||
.withOptions(nuqsOptions)
|
||||
.withOptions(nuqsOptions),
|
||||
);
|
||||
|
||||
const interval =
|
||||
@@ -38,7 +38,7 @@ export function useOverviewOptions() {
|
||||
|
||||
const [metric, setMetric] = useQueryState(
|
||||
'metric',
|
||||
parseAsInteger.withDefault(0).withOptions(nuqsOptions)
|
||||
parseAsInteger.withDefault(0).withOptions(nuqsOptions),
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -9,14 +9,14 @@ export function useOverviewWidget<T extends string>(
|
||||
widgets: Record<
|
||||
T,
|
||||
{ title: string; btn: string; chart: ReportChartProps; hide?: boolean }
|
||||
>
|
||||
>,
|
||||
) {
|
||||
const keys = Object.keys(widgets) as T[];
|
||||
const [widget, setWidget] = useQueryState<T>(
|
||||
key,
|
||||
parseAsStringEnum(keys)
|
||||
.withDefault(keys[0]!)
|
||||
.withOptions({ history: 'push' })
|
||||
.withOptions({ history: 'push' }),
|
||||
);
|
||||
return [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user