chore: migrate eslint and prettier to biome and fix all linting errors
This commit is contained in:
parent
82413a8212
commit
9bcf233d2c
22 changed files with 397 additions and 481 deletions
20
src/App.tsx
20
src/App.tsx
|
@ -9,22 +9,10 @@ import "./app.css";
|
|||
const App: Component = () => {
|
||||
return (
|
||||
<>
|
||||
<Route
|
||||
path="/"
|
||||
component={Home}
|
||||
/>
|
||||
<Route
|
||||
path="/overview"
|
||||
component={Overview}
|
||||
/>
|
||||
<Route
|
||||
path="/dm/:dmid"
|
||||
component={DmId}
|
||||
/>
|
||||
<Route
|
||||
path="/group/:groupid"
|
||||
component={GroupId}
|
||||
/>
|
||||
<Route path="/" component={Home} />
|
||||
<Route path="/overview" component={Overview} />
|
||||
<Route path="/dm/:dmid" component={DmId} />
|
||||
<Route path="/group/:groupid" component={GroupId} />
|
||||
<Route
|
||||
path="/test"
|
||||
component={() => {
|
||||
|
|
|
@ -101,9 +101,7 @@
|
|||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
font-feature-settings:
|
||||
"rlig" 1,
|
||||
"calt" 1;
|
||||
font-feature-settings: "rlig" 1, "calt" 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,8 +94,11 @@ const BaseChart: Component<ChartProps> = (rawProps) => {
|
|||
on(
|
||||
() => props.data,
|
||||
() => {
|
||||
chart()!.data = props.data;
|
||||
chart()!.update();
|
||||
const currentChart = chart();
|
||||
if (currentChart) {
|
||||
currentChart.data = props.data;
|
||||
currentChart.update();
|
||||
}
|
||||
},
|
||||
{ defer: true },
|
||||
),
|
||||
|
@ -105,8 +108,11 @@ const BaseChart: Component<ChartProps> = (rawProps) => {
|
|||
on(
|
||||
() => props.options,
|
||||
() => {
|
||||
chart()!.options = props.options;
|
||||
chart()!.update();
|
||||
const currentChart = chart();
|
||||
if (currentChart) {
|
||||
currentChart.options = props.options;
|
||||
currentChart.update();
|
||||
}
|
||||
},
|
||||
{ defer: true },
|
||||
),
|
||||
|
@ -116,7 +122,10 @@ const BaseChart: Component<ChartProps> = (rawProps) => {
|
|||
on(
|
||||
[() => props.width, () => props.height],
|
||||
() => {
|
||||
chart()!.resize(props.width, props.height);
|
||||
const currentChart = chart();
|
||||
if (currentChart) {
|
||||
currentChart.resize(props.width, props.height);
|
||||
}
|
||||
},
|
||||
{ defer: true },
|
||||
),
|
||||
|
@ -126,10 +135,13 @@ const BaseChart: Component<ChartProps> = (rawProps) => {
|
|||
on(
|
||||
() => props.type,
|
||||
() => {
|
||||
const dimensions = [chart()!.width, chart()!.height];
|
||||
chart()!.destroy();
|
||||
init();
|
||||
chart()!.resize(...dimensions);
|
||||
const currentChart = chart();
|
||||
if (currentChart) {
|
||||
const dimensions = [currentChart.width, currentChart.height];
|
||||
currentChart.destroy();
|
||||
init();
|
||||
currentChart.resize(...dimensions);
|
||||
}
|
||||
},
|
||||
{ defer: true },
|
||||
),
|
||||
|
@ -141,13 +153,7 @@ const BaseChart: Component<ChartProps> = (rawProps) => {
|
|||
});
|
||||
|
||||
Chart.register(Colors, Filler, Legend, Tooltip);
|
||||
return (
|
||||
<canvas
|
||||
ref={mergeRefs(props.ref, (el) => setCanvasRef(el))}
|
||||
height={props.height}
|
||||
width={props.width}
|
||||
/>
|
||||
);
|
||||
return <canvas ref={mergeRefs(props.ref, (el) => setCanvasRef(el))} height={props.height} width={props.width} />;
|
||||
};
|
||||
|
||||
function showTooltip(context: ChartContext) {
|
||||
|
@ -245,13 +251,7 @@ function createTypedChart(type: ChartType, components: ChartComponent[]): Compon
|
|||
};
|
||||
|
||||
Chart.register(...components);
|
||||
return (props) => (
|
||||
<BaseChart
|
||||
type={type}
|
||||
options={options}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
return (props) => <BaseChart type={type} options={options} {...props} />;
|
||||
}
|
||||
|
||||
const BarChart = /* #__PURE__ */ createTypedChart("bar", [BarController, BarElement, CategoryScale, LinearScale]);
|
||||
|
|
|
@ -13,10 +13,7 @@ type CheckboxRootProps<T extends ValidComponent = "div"> = CheckboxPrimitive.Che
|
|||
const Checkbox = <T extends ValidComponent = "div">(props: PolymorphicProps<T, CheckboxRootProps<T>>) => {
|
||||
const [local, others] = splitProps(props as CheckboxRootProps, ["class"]);
|
||||
return (
|
||||
<CheckboxPrimitive.Root
|
||||
class={cn("items-top group relative flex space-x-2", local.class)}
|
||||
{...others}
|
||||
>
|
||||
<CheckboxPrimitive.Root class={cn("items-top group relative flex space-x-2", local.class)} {...others}>
|
||||
<CheckboxPrimitive.Input class="peer" />
|
||||
<CheckboxPrimitive.Control class="size-4 shrink-0 rounded-sm border border-primary ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 peer-focus-visible:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2 data-[checked]:border-none data-[indeterminate]:border-none data-[checked]:bg-primary data-[indeterminate]:bg-primary data-[checked]:text-primary-foreground data-[indeterminate]:text-primary-foreground">
|
||||
<CheckboxPrimitive.Indicator>
|
||||
|
|
|
@ -8,7 +8,7 @@ const Label: Component<ComponentProps<"label">> = (props) => {
|
|||
return (
|
||||
<label
|
||||
class={cn(
|
||||
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||
"font-medium text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||
local.class,
|
||||
)}
|
||||
{...others}
|
||||
|
|
|
@ -7,42 +7,24 @@ const Table: Component<ComponentProps<"table">> = (props) => {
|
|||
const [local, others] = splitProps(props, ["class"]);
|
||||
return (
|
||||
<div class="relative w-full overflow-auto">
|
||||
<table
|
||||
class={cn("w-full caption-bottom text-sm", local.class)}
|
||||
{...others}
|
||||
/>
|
||||
<table class={cn("w-full caption-bottom text-sm", local.class)} {...others} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const TableHeader: Component<ComponentProps<"thead">> = (props) => {
|
||||
const [local, others] = splitProps(props, ["class"]);
|
||||
return (
|
||||
<thead
|
||||
class={cn("[&_tr]:border-b", local.class)}
|
||||
{...others}
|
||||
/>
|
||||
);
|
||||
return <thead class={cn("[&_tr]:border-b", local.class)} {...others} />;
|
||||
};
|
||||
|
||||
const TableBody: Component<ComponentProps<"tbody">> = (props) => {
|
||||
const [local, others] = splitProps(props, ["class"]);
|
||||
return (
|
||||
<tbody
|
||||
class={cn("[&_tr:last-child]:border-0", local.class)}
|
||||
{...others}
|
||||
/>
|
||||
);
|
||||
return <tbody class={cn("[&_tr:last-child]:border-0", local.class)} {...others} />;
|
||||
};
|
||||
|
||||
const TableFooter: Component<ComponentProps<"tfoot">> = (props) => {
|
||||
const [local, others] = splitProps(props, ["class"]);
|
||||
return (
|
||||
<tfoot
|
||||
class={cn("bg-primary font-medium text-primary-foreground", local.class)}
|
||||
{...others}
|
||||
/>
|
||||
);
|
||||
return <tfoot class={cn("bg-primary font-medium text-primary-foreground", local.class)} {...others} />;
|
||||
};
|
||||
|
||||
const TableRow: Component<ComponentProps<"tr">> = (props) => {
|
||||
|
@ -70,22 +52,12 @@ const TableHead: Component<ComponentProps<"th">> = (props) => {
|
|||
|
||||
const TableCell: Component<ComponentProps<"td">> = (props) => {
|
||||
const [local, others] = splitProps(props, ["class"]);
|
||||
return (
|
||||
<td
|
||||
class={cn("p-2 align-middle [&:has([role=checkbox])]:pr-0", local.class)}
|
||||
{...others}
|
||||
/>
|
||||
);
|
||||
return <td class={cn("p-2 align-middle [&:has([role=checkbox])]:pr-0", local.class)} {...others} />;
|
||||
};
|
||||
|
||||
const TableCaption: Component<ComponentProps<"caption">> = (props) => {
|
||||
const [local, others] = splitProps(props, ["class"]);
|
||||
return (
|
||||
<caption
|
||||
class={cn("mt-4 text-sm text-muted-foreground", local.class)}
|
||||
{...others}
|
||||
/>
|
||||
);
|
||||
return <caption class={cn("mt-4 text-muted-foreground text-sm", local.class)} {...others} />;
|
||||
};
|
||||
|
||||
export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
|
||||
|
|
|
@ -13,12 +13,7 @@ type TextFieldRootProps<T extends ValidComponent = "div"> = TextFieldPrimitive.T
|
|||
|
||||
const TextField = <T extends ValidComponent = "div">(props: PolymorphicProps<T, TextFieldRootProps<T>>) => {
|
||||
const [local, others] = splitProps(props as TextFieldRootProps, ["class"]);
|
||||
return (
|
||||
<TextFieldPrimitive.Root
|
||||
class={cn("flex flex-col gap-1", local.class)}
|
||||
{...others}
|
||||
/>
|
||||
);
|
||||
return <TextFieldPrimitive.Root class={cn("flex flex-col gap-1", local.class)} {...others} />;
|
||||
};
|
||||
|
||||
type TextFieldInputProps<T extends ValidComponent = "input"> = TextFieldPrimitive.TextFieldInputProps<T> & {
|
||||
|
@ -55,7 +50,7 @@ const TextFieldInput = <T extends ValidComponent = "input">(rawProps: Polymorphi
|
|||
<TextFieldPrimitive.Input
|
||||
type={local.type}
|
||||
class={cn(
|
||||
"flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[invalid]:border-error-foreground data-[invalid]:text-error-foreground",
|
||||
"flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:font-medium file:text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[invalid]:border-error-foreground data-[invalid]:text-error-foreground",
|
||||
local.class,
|
||||
)}
|
||||
{...others}
|
||||
|
@ -104,12 +99,7 @@ type TextFieldLabelProps<T extends ValidComponent = "label"> = TextFieldPrimitiv
|
|||
|
||||
const TextFieldLabel = <T extends ValidComponent = "label">(props: PolymorphicProps<T, TextFieldLabelProps<T>>) => {
|
||||
const [local, others] = splitProps(props as TextFieldLabelProps, ["class"]);
|
||||
return (
|
||||
<TextFieldPrimitive.Label
|
||||
class={cn(labelVariants(), local.class)}
|
||||
{...others}
|
||||
/>
|
||||
);
|
||||
return <TextFieldPrimitive.Label class={cn(labelVariants(), local.class)} {...others} />;
|
||||
};
|
||||
|
||||
type TextFieldDescriptionProps<T extends ValidComponent = "div"> = TextFieldPrimitive.TextFieldDescriptionProps<T> & {
|
||||
|
@ -121,10 +111,7 @@ const TextFieldDescription = <T extends ValidComponent = "div">(
|
|||
) => {
|
||||
const [local, others] = splitProps(props as TextFieldDescriptionProps, ["class"]);
|
||||
return (
|
||||
<TextFieldPrimitive.Description
|
||||
class={cn(labelVariants({ variant: "description" }), local.class)}
|
||||
{...others}
|
||||
/>
|
||||
<TextFieldPrimitive.Description class={cn(labelVariants({ variant: "description" }), local.class)} {...others} />
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -136,12 +123,7 @@ const TextFieldErrorMessage = <T extends ValidComponent = "div">(
|
|||
props: PolymorphicProps<T, TextFieldErrorMessageProps<T>>,
|
||||
) => {
|
||||
const [local, others] = splitProps(props as TextFieldErrorMessageProps, ["class"]);
|
||||
return (
|
||||
<TextFieldPrimitive.ErrorMessage
|
||||
class={cn(labelVariants({ variant: "error" }), local.class)}
|
||||
{...others}
|
||||
/>
|
||||
);
|
||||
return <TextFieldPrimitive.ErrorMessage class={cn(labelVariants({ variant: "error" }), local.class)} {...others} />;
|
||||
};
|
||||
|
||||
export { TextField, TextFieldDescription, TextFieldErrorMessage, TextFieldInput, TextFieldLabel, TextFieldTextArea };
|
||||
|
|
|
@ -90,6 +90,7 @@ const allThreadsOverviewQueryRaw = kyselyDb()
|
|||
"groups.title",
|
||||
"message_count",
|
||||
"thread.date as last_message_date",
|
||||
"recipient.nickname_joined_name",
|
||||
])
|
||||
.where("message_count", ">", 0)
|
||||
.$narrowType<{
|
||||
|
@ -119,7 +120,12 @@ export const overallSentMessagesQuery = cached(overallSentMessagesQueryRaw);
|
|||
const dmPartnerRecipientQueryRaw = (dmId: number) =>
|
||||
kyselyDb()
|
||||
.selectFrom("recipient")
|
||||
.select(["recipient._id", "recipient.system_joined_name", "recipient.profile_joined_name"])
|
||||
.select([
|
||||
"recipient._id",
|
||||
"recipient.system_joined_name",
|
||||
"recipient.profile_joined_name",
|
||||
"recipient.nickname_joined_name",
|
||||
])
|
||||
.innerJoin("thread", "recipient._id", "thread.recipient_id")
|
||||
.where((eb) => eb.and([eb("thread._id", "=", dmId), eb("recipient._id", "!=", SELF_ID)]))
|
||||
.$narrowType<{
|
||||
|
|
17
src/lib/getNameFromRecipient.ts
Normal file
17
src/lib/getNameFromRecipient.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
export const getNameFromRecipient = (
|
||||
joinedNickname: string | null,
|
||||
joinedSystemName: string | null,
|
||||
joinedProfileName: string | null,
|
||||
) => {
|
||||
let name = "Could not determine name";
|
||||
|
||||
if (joinedNickname !== null) {
|
||||
name = joinedNickname;
|
||||
} else if (joinedSystemName !== null && joinedSystemName !== "") {
|
||||
name = joinedSystemName;
|
||||
} else if (joinedProfileName !== null) {
|
||||
name = joinedProfileName;
|
||||
}
|
||||
|
||||
return name;
|
||||
};
|
|
@ -6,6 +6,7 @@ import { type ChartData } from "chart.js";
|
|||
import { LineChart, WordCloudChart } from "~/components/ui/charts";
|
||||
|
||||
import { dmPartnerRecipientQuery, dmSentMessagesPerPersonOverviewQuery, SELF_ID, threadMostUsedWordsQuery } from "~/db";
|
||||
import { getNameFromRecipient } from "~/lib/getNameFromRecipient";
|
||||
|
||||
export const DmId: Component<RouteSectionProps> = (props) => {
|
||||
const dmId = () => Number(props.params.dmid);
|
||||
|
@ -17,10 +18,11 @@ export const DmId: Component<RouteSectionProps> = (props) => {
|
|||
if (dmPartner) {
|
||||
return {
|
||||
id: dmPartner._id,
|
||||
name: /* can be empty string */ !dmPartner.system_joined_name
|
||||
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
dmPartner.profile_joined_name!
|
||||
: dmPartner.system_joined_name,
|
||||
name: getNameFromRecipient(
|
||||
dmPartner.nickname_joined_name,
|
||||
dmPartner.system_joined_name,
|
||||
dmPartner.profile_joined_name,
|
||||
),
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
|
@ -3,6 +3,8 @@ import type { RouteSectionProps } from "@solidjs/router";
|
|||
|
||||
export const GroupId: Component<RouteSectionProps> = (props) => {
|
||||
const groupId = () => Number(props.params.groupid);
|
||||
|
||||
return groupId();
|
||||
};
|
||||
|
||||
export default GroupId;
|
||||
|
|
|
@ -23,11 +23,7 @@ export const Home: Component<RouteSectionProps> = () => {
|
|||
|
||||
return (
|
||||
<div>
|
||||
<input
|
||||
type="file"
|
||||
accept=".sqlite"
|
||||
onChange={onFileChange}
|
||||
></input>
|
||||
<input type="file" accept=".sqlite" onChange={onFileChange}></input>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@ import type { RouteSectionProps } from "@solidjs/router";
|
|||
import { allThreadsOverviewQuery, overallSentMessagesQuery, SELF_ID } from "~/db";
|
||||
|
||||
import { OverviewTable, type RoomOverview } from "./overview-table";
|
||||
import { getNameFromRecipient } from "~/lib/getNameFromRecipient";
|
||||
|
||||
export const Overview: Component<RouteSectionProps> = () => {
|
||||
const [allSelfSentMessagesCount] = createResource(() => overallSentMessagesQuery(SELF_ID));
|
||||
|
@ -12,14 +13,13 @@ export const Overview: Component<RouteSectionProps> = () => {
|
|||
return (await allThreadsOverviewQuery()).rows.map((row) => {
|
||||
const isGroup = row.title !== null;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const name = (
|
||||
isGroup
|
||||
? row.title
|
||||
: /* seems possible that it is an empty string */ !row.system_joined_name
|
||||
? row.profile_joined_name
|
||||
: row.system_joined_name
|
||||
)!;
|
||||
let name = "";
|
||||
|
||||
if (row.title !== null) {
|
||||
name = row.title;
|
||||
} else {
|
||||
name = getNameFromRecipient(row.nickname_joined_name, row.system_joined_name, row.profile_joined_name);
|
||||
}
|
||||
|
||||
return {
|
||||
threadId: row.thread_id,
|
||||
|
@ -36,12 +36,8 @@ export const Overview: Component<RouteSectionProps> = () => {
|
|||
return (
|
||||
<div>
|
||||
<p>All messages: {allSelfSentMessagesCount()?.messageCount as number}</p>
|
||||
<Show
|
||||
when={!roomOverview.loading}
|
||||
fallback="Loading..."
|
||||
>
|
||||
{/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */}
|
||||
<OverviewTable data={roomOverview()!} />;
|
||||
<Show when={!roomOverview.loading && roomOverview()} fallback="Loading...">
|
||||
{(currentRoomOverview) => <OverviewTable data={currentRoomOverview()} />}
|
||||
</Show>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -76,11 +76,7 @@ export const columns = [
|
|||
}}
|
||||
>
|
||||
Name
|
||||
<SortingDisplay
|
||||
sorting={sorting()}
|
||||
class="ml-2 h-4 w-4"
|
||||
activeClass="text-info-foreground"
|
||||
/>
|
||||
<SortingDisplay sorting={sorting()} class="ml-2 h-4 w-4" activeClass="text-info-foreground" />
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
|
@ -94,18 +90,12 @@ export const columns = [
|
|||
<Show when={isArchived || isGroup}>
|
||||
<div class="ml-auto flex flex-row gap-2">
|
||||
<Show when={isArchived}>
|
||||
<Badge
|
||||
variant="outline"
|
||||
class="ml-auto"
|
||||
>
|
||||
<Badge variant="outline" class="ml-auto">
|
||||
Archived
|
||||
</Badge>
|
||||
</Show>
|
||||
<Show when={isGroup}>
|
||||
<Badge
|
||||
variant="outline"
|
||||
class="ml-auto"
|
||||
>
|
||||
<Badge variant="outline" class="ml-auto">
|
||||
Group
|
||||
</Badge>
|
||||
</Show>
|
||||
|
@ -128,11 +118,7 @@ export const columns = [
|
|||
}}
|
||||
>
|
||||
Number of messages
|
||||
<SortingDisplay
|
||||
sorting={sorting()}
|
||||
class="ml-2 h-4 w-4"
|
||||
activeClass="text-info-foreground"
|
||||
/>
|
||||
<SortingDisplay sorting={sorting()} class="ml-2 h-4 w-4" activeClass="text-info-foreground" />
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
|
@ -150,11 +136,7 @@ export const columns = [
|
|||
}}
|
||||
>
|
||||
Date of last message
|
||||
<SortingDisplay
|
||||
sorting={sorting()}
|
||||
class="ml-2 h-4 w-4"
|
||||
activeClass="text-info-foreground"
|
||||
/>
|
||||
<SortingDisplay sorting={sorting()} class="ml-2 h-4 w-4" activeClass="text-info-foreground" />
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
|
@ -252,10 +234,7 @@ export const OverviewTable = (props: OverviewTableProps) => {
|
|||
value={(table.getColumn("name")?.getFilterValue() as string | undefined) ?? ""}
|
||||
onChange={(value) => table.getColumn("name")?.setFilterValue(value)}
|
||||
>
|
||||
<TextFieldInput
|
||||
placeholder="Filter by name..."
|
||||
class="max-w-sm"
|
||||
/>
|
||||
<TextFieldInput placeholder="Filter by name..." class="max-w-sm" />
|
||||
</TextField>
|
||||
</div>
|
||||
<div class="flex items-start space-x-2">
|
||||
|
@ -277,7 +256,7 @@ export const OverviewTable = (props: OverviewTableProps) => {
|
|||
<For each={headerGroup.headers}>
|
||||
{(header) => (
|
||||
<TableHead
|
||||
class="border-b border-r border-t first-of-type:rounded-tl-md first-of-type:border-l last-of-type:rounded-tr-md"
|
||||
class="border-t border-r border-b first-of-type:rounded-tl-md first-of-type:border-l last-of-type:rounded-tr-md"
|
||||
colSpan={header.colSpan}
|
||||
>
|
||||
<Show when={!header.isPlaceholder}>
|
||||
|
@ -297,7 +276,7 @@ export const OverviewTable = (props: OverviewTableProps) => {
|
|||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={columns.length}
|
||||
class="h-24 border-b border-r text-center first-of-type:rounded-tl-md first-of-type:border-l last-of-type:rounded-br-md"
|
||||
class="h-24 border-r border-b text-center first-of-type:rounded-tl-md first-of-type:border-l last-of-type:rounded-br-md"
|
||||
>
|
||||
No results.
|
||||
</TableCell>
|
||||
|
@ -318,7 +297,7 @@ export const OverviewTable = (props: OverviewTableProps) => {
|
|||
>
|
||||
<For each={row.getVisibleCells()}>
|
||||
{(cell) => (
|
||||
<TableCell class="border-b border-r first-of-type:border-l">
|
||||
<TableCell class="border-r border-b first-of-type:border-l">
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</TableCell>
|
||||
)}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue