mirror of
https://github.com/fosrl/pangolin.git
synced 2026-05-09 13:54:01 +00:00
add loading indicator to resources
This commit is contained in:
@@ -12,6 +12,7 @@ import type { ListResourcesResponse } from "@server/routers/resource";
|
|||||||
import type ResponseT from "@server/types/Response";
|
import type ResponseT from "@server/types/Response";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { isAxiosError } from "axios";
|
import { isAxiosError } from "axios";
|
||||||
|
import { Loader2 } from "lucide-react";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useParams } from "next/navigation";
|
import { useParams } from "next/navigation";
|
||||||
@@ -176,6 +177,8 @@ type OverviewColumnProps = {
|
|||||||
emptyLabel: string;
|
emptyLabel: string;
|
||||||
isForbidden: boolean;
|
isForbidden: boolean;
|
||||||
isFetching: boolean;
|
isFetching: boolean;
|
||||||
|
/** When there are no rows and the first fetch (no SSR initial data) is in flight. */
|
||||||
|
isLoading: boolean;
|
||||||
rows: OverviewRow[];
|
rows: OverviewRow[];
|
||||||
canShowMore: boolean;
|
canShowMore: boolean;
|
||||||
onShowMore: () => void;
|
onShowMore: () => void;
|
||||||
@@ -189,6 +192,7 @@ function OverviewColumn({
|
|||||||
emptyLabel,
|
emptyLabel,
|
||||||
isForbidden,
|
isForbidden,
|
||||||
isFetching,
|
isFetching,
|
||||||
|
isLoading,
|
||||||
rows,
|
rows,
|
||||||
canShowMore,
|
canShowMore,
|
||||||
onShowMore
|
onShowMore
|
||||||
@@ -231,10 +235,23 @@ function OverviewColumn({
|
|||||||
<div className="min-w-0 overflow-hidden rounded-lg border h-full flex flex-col">
|
<div className="min-w-0 overflow-hidden rounded-lg border h-full flex flex-col">
|
||||||
{header}
|
{header}
|
||||||
{rows.length === 0 ? (
|
{rows.length === 0 ? (
|
||||||
<div className="flex flex-1 items-center justify-center px-5 py-3">
|
<div className="flex flex-1 items-center justify-center px-5 py-3 min-h-24">
|
||||||
<p className="text-center text-sm text-muted-foreground">
|
{isLoading ? (
|
||||||
{emptyLabel}
|
<div
|
||||||
</p>
|
className="flex flex-col items-center justify-center gap-2"
|
||||||
|
role="status"
|
||||||
|
>
|
||||||
|
<Loader2
|
||||||
|
className="h-6 w-6 animate-spin text-muted-foreground"
|
||||||
|
aria-hidden
|
||||||
|
/>
|
||||||
|
<span className="sr-only">{t("loading")}</span>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<p className="text-center text-sm text-muted-foreground">
|
||||||
|
{emptyLabel}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
@@ -390,7 +407,14 @@ export default function SiteResourcesOverview({
|
|||||||
initialPrivateForbidden ||
|
initialPrivateForbidden ||
|
||||||
(privateQuery.isError && isForbidden(privateQuery.error));
|
(privateQuery.isError && isForbidden(privateQuery.error));
|
||||||
|
|
||||||
|
const waitingOnPublicList =
|
||||||
|
enabled && !publicForbidden && publicQuery.isPending;
|
||||||
|
const waitingOnPrivateList =
|
||||||
|
enabled && !privateForbidden && privateQuery.isPending;
|
||||||
|
|
||||||
const showEmptyPlaceholder =
|
const showEmptyPlaceholder =
|
||||||
|
!waitingOnPublicList &&
|
||||||
|
!waitingOnPrivateList &&
|
||||||
!publicForbidden &&
|
!publicForbidden &&
|
||||||
!privateForbidden &&
|
!privateForbidden &&
|
||||||
publicList.length === 0 &&
|
publicList.length === 0 &&
|
||||||
@@ -431,6 +455,17 @@ export default function SiteResourcesOverview({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const publicEmptyLoading =
|
||||||
|
enabled &&
|
||||||
|
!publicForbidden &&
|
||||||
|
publicRows.length === 0 &&
|
||||||
|
publicQuery.isPending;
|
||||||
|
const privateEmptyLoading =
|
||||||
|
enabled &&
|
||||||
|
!privateForbidden &&
|
||||||
|
privateRows.length === 0 &&
|
||||||
|
privateQuery.isPending;
|
||||||
|
|
||||||
const publicColumn = (
|
const publicColumn = (
|
||||||
<OverviewColumn
|
<OverviewColumn
|
||||||
key="public"
|
key="public"
|
||||||
@@ -441,6 +476,7 @@ export default function SiteResourcesOverview({
|
|||||||
emptyLabel={t("siteResourcesEmptyPublic")}
|
emptyLabel={t("siteResourcesEmptyPublic")}
|
||||||
isForbidden={publicForbidden}
|
isForbidden={publicForbidden}
|
||||||
isFetching={publicQuery.isFetching}
|
isFetching={publicQuery.isFetching}
|
||||||
|
isLoading={publicEmptyLoading}
|
||||||
rows={publicRows}
|
rows={publicRows}
|
||||||
canShowMore={publicList.length < publicTotal}
|
canShowMore={publicList.length < publicTotal}
|
||||||
onShowMore={() => setPublicPageSize((n) => n + LOAD_MORE_INCREMENT)}
|
onShowMore={() => setPublicPageSize((n) => n + LOAD_MORE_INCREMENT)}
|
||||||
@@ -457,6 +493,7 @@ export default function SiteResourcesOverview({
|
|||||||
emptyLabel={t("siteResourcesEmptyPrivate")}
|
emptyLabel={t("siteResourcesEmptyPrivate")}
|
||||||
isForbidden={privateForbidden}
|
isForbidden={privateForbidden}
|
||||||
isFetching={privateQuery.isFetching}
|
isFetching={privateQuery.isFetching}
|
||||||
|
isLoading={privateEmptyLoading}
|
||||||
rows={privateRows}
|
rows={privateRows}
|
||||||
canShowMore={privateList.length < privateTotal}
|
canShowMore={privateList.length < privateTotal}
|
||||||
onShowMore={() =>
|
onShowMore={() =>
|
||||||
|
|||||||
Reference in New Issue
Block a user