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

feat(ui): add loaders on layers page #234

Merged
merged 2 commits into from
Jan 30, 2024
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
30 changes: 30 additions & 0 deletions ui/src/components/loaders/CardLoader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from "react";
import { twMerge } from "tailwind-merge";

export interface CardLoaderProps {
className?: string;
variant: "light" | "dark";
}

const CardLoader: React.FC<CardLoaderProps> = ({ className, variant }) => {
const style = {
light: `bg-[linear-gradient(270deg,_#D8EBFF_0%,_#ECF5FF_100%)]
shadow-light`,
dark: `bg-[linear-gradient(270deg,_#252525_0%,_rgba(68,_67,_67,_0.24)_100%)]
shadow-dark`,
};

return (
<div
className={twMerge(
`h-[275px]
rounded-2xl
animate-pulse
${style[variant]}`,
className
)}
></div>
);
};

export default CardLoader;
28 changes: 28 additions & 0 deletions ui/src/components/loaders/TableLoader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react";
import { twMerge } from "tailwind-merge";

export interface TableLoaderProps {
className?: string;
variant: "light" | "dark";
}

const TableLoader: React.FC<TableLoaderProps> = ({ className, variant }) => {
const style = {
light: `bg-[linear-gradient(270deg,_#D8EBFF_0%,_#ECF5FF_100%)]`,
dark: `bg-[linear-gradient(270deg,_#252525_0%,_rgba(68,_67,_67,_0.24)_100%)]`,
};

return (
<div
className={twMerge(
`h-4
rounded-full
animate-pulse
${style[variant]}`,
className
)}
></div>
);
};

export default TableLoader;
196 changes: 129 additions & 67 deletions ui/src/components/tables/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { Tooltip } from "react-tooltip";

import Tag from "@/components/tags/Tag";
import TableLoader from "@/components/loaders/TableLoader";
import ChiliLight from "@/assets/illustrations/ChiliLight";
import ChiliDark from "@/assets/illustrations/ChiliDark";
import CodeBranchIcon from "@/assets/icons/CodeBranchIcon";
Expand All @@ -19,12 +20,14 @@ import { Layer, LayerState } from "@/clients/layers/types";
export interface TableProps {
className?: string;
variant?: "light" | "dark";
isLoading?: boolean;
data: Layer[];
}

const Table: React.FC<TableProps> = ({
className,
variant = "light",
isLoading,
data,
}) => {
const columnHelper = createColumnHelper<Layer>();
Expand Down Expand Up @@ -211,78 +214,137 @@ const Table: React.FC<TableProps> = ({
))}
</thead>
<tbody>
{table.getRowModel().rows.map((row) => (
<tr
key={row.id}
className={twMerge(
`h-full
${styles.row.base[variant]}`,
row.original.isRunning &&
`rounded-2xl
outline
outline-4
-outline-offset-4
${styles.row.running[variant]}`
)}
>
{row.getVisibleCells().map((cell, index) => (
<td
key={cell.id}
{isLoading
? Array.from({ length: 100 }).map((_, index) => (
<tr
key={index}
className={twMerge(
`relative
text-left
h-full
text-base
font-semibold
px-6
py-4`,
cell.row.original.isRunning &&
"first:rounded-l-2xl last:rounded-r-2xl"
`h-full
${styles.row.base[variant]}`
)}
data-tooltip-id="table-tooltip"
data-tooltip-content={
cell.column.id === "lastResult" &&
cell.row.original.isRunning
? (cell.getValue() as string)
: null
}
>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
{index === 0 ? (
<hr
className={`
absolute
right-0
bottom-0
w-[calc(100%_-_25px)]
${styles.separator[variant]}
`}
/>
) : index === row.getVisibleCells().length - 1 ? (
<hr
className={`
absolute
left-0
bottom-0
w-[calc(100%_-_25px)]
${styles.separator[variant]}
`}
/>
) : (
<hr
className={`
absolute
bottom-0
left-0
w-full
${styles.separator[variant]}
`}
/>
{table.getAllColumns().map((_, index) => (
<td
key={index}
className={`relative
text-left
h-full
text-base
font-semibold
px-6
py-4`}
>
<TableLoader variant={variant} />
{index === 0 ? (
<hr
className={`
absolute
right-0
bottom-0
w-[calc(100%_-_25px)]
${styles.separator[variant]}
`}
/>
) : index === table.getAllColumns().length - 1 ? (
<hr
className={`
absolute
left-0
bottom-0
w-[calc(100%_-_25px)]
${styles.separator[variant]}
`}
/>
) : (
<hr
className={`
absolute
bottom-0
left-0
w-full
${styles.separator[variant]}
`}
/>
)}
</td>
))}
</tr>
))
: table.getRowModel().rows.map((row) => (
<tr
key={row.id}
className={twMerge(
`h-full
${styles.row.base[variant]}`,
row.original.isRunning &&
`rounded-2xl
outline
outline-4
-outline-offset-4
${styles.row.running[variant]}`
)}
</td>
>
{row.getVisibleCells().map((cell, index) => (
<td
key={cell.id}
className={twMerge(
`relative
text-left
h-full
text-base
font-semibold
px-6
py-4`,
cell.row.original.isRunning &&
"first:rounded-l-2xl last:rounded-r-2xl"
)}
data-tooltip-id="table-tooltip"
data-tooltip-content={
cell.column.id === "lastResult" &&
cell.row.original.isRunning
? (cell.getValue() as string)
: null
}
>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
{index === 0 ? (
<hr
className={`
absolute
right-0
bottom-0
w-[calc(100%_-_25px)]
${styles.separator[variant]}
`}
/>
) : index === row.getVisibleCells().length - 1 ? (
<hr
className={`
absolute
left-0
bottom-0
w-[calc(100%_-_25px)]
${styles.separator[variant]}
`}
/>
) : (
<hr
className={`
absolute
bottom-0
left-0
w-full
${styles.separator[variant]}
`}
/>
)}
</td>
))}
</tr>
))}
</tr>
))}
</tbody>
</table>
<Tooltip
Expand Down
51 changes: 37 additions & 14 deletions ui/src/pages/layers/Layers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { LayerState } from "@/clients/layers/types";
import SearchIcon from "@/assets/icons/SearchIcon";
import AppsIcon from "@/assets/icons/AppsIcon";
import BarsIcon from "@/assets/icons/BarsIcon";
import CardLoader from "@/components/loaders/CardLoader";

const Layers: React.FC = () => {
const { theme } = useContext(ThemeContext);
Expand Down Expand Up @@ -230,21 +231,43 @@ const Layers: React.FC = () => {
</div>
</div>
</div>
<div className="relative overflow-auto">
{layersQuery.isLoading && <></>}
{layersQuery.isError && <></>}
{layersQuery.isSuccess &&
(view === "grid" ? (
<div className="grid grid-cols-[repeat(auto-fit,_minmax(400px,_1fr))] p-6 pt-3 gap-6">
{layersQuery.data.results.map((layer, index) => (
<div
className={`
relative
${layersQuery.isSuccess ? "overflow-auto" : "overflow-hidden"}
`}
>
{view === "grid" ? (
<div className="grid grid-cols-[repeat(auto-fit,_minmax(400px,_1fr))] p-6 pt-3 gap-6">
{layersQuery.isLoading ? (
Array.from({ length: 100 }).map((_, index) => (
<CardLoader key={index} variant={theme} />
))
) : layersQuery.isError ? (
<span>An error has occurred</span>
) : layersQuery.isSuccess ? (
layersQuery.data.results.map((layer, index) => (
<Card key={index} variant={theme} layer={layer} />
))}
</div>
) : view === "table" ? (
<Table variant={theme} data={layersQuery.data.results} />
) : (
<></>
))}
))
) : (
<></>
)}
</div>
) : view === "table" ? (
<div>
{layersQuery.isLoading ? (
<Table variant={theme} isLoading data={[]} />
) : layersQuery.isError ? (
<span>An error has occurred</span>
) : layersQuery.isSuccess ? (
<Table variant={theme} data={layersQuery.data.results} />
) : (
<></>
)}
</div>
) : (
<></>
)}
</div>
</div>
);
Expand Down
Loading