这是indexloc提供的服务,不要输入任何密码
Skip to content

feat: Create a Shimmer Table Component #433

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

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
8 changes: 6 additions & 2 deletions hosting/src/app/(protected)/content/article/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {Suspense, useEffect, useState} from "react";
export default function DocumentTypeDocumentsPage() {
const {data: documentType} = useTanamDocumentType("article");
const {create, error: crudError} = useCrudTanamDocument();
const {data: documents, error: docsError} = useTanamDocuments("article");
const {data: documents, error: docsError, isLoading} = useTanamDocuments("article");
const [notification, setNotification] = useState<UserNotification | null>(null);
const router = useRouter();

Expand Down Expand Up @@ -53,7 +53,11 @@ export default function DocumentTypeDocumentsPage() {
)}

<Suspense fallback={<Loader />}>
{documentType ? <DocumentTypeGenericList documents={documents} documentType={documentType} /> : <Loader />}
{documentType ? (
<DocumentTypeGenericList isLoading={isLoading} documents={documents} documentType={documentType} />
) : (
<Loader />
)}
</Suspense>
</>
);
Expand Down
38 changes: 19 additions & 19 deletions hosting/src/components/DocumentType/DocumentTypeGenericList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,28 @@ import Link from "next/link";
interface TableOverviewGenericProps {
documentType: TanamDocumentTypeClient;
documents: TanamDocumentClient[];
isLoading?: boolean;
}

export function DocumentTypeGenericList({documents, documentType}: TableOverviewGenericProps) {
export function DocumentTypeGenericList({documents, documentType, isLoading}: TableOverviewGenericProps) {
return (
<>
<Table
headers={["Title", "Created", "Status"]}
rows={documents.map((document, key) => [
<Link key={`${key}-${document.id}-id`} href={`/content/${document.documentType}/${document.id}`}>
<p className="font-medium text-black dark:text-white">{document.data[documentType.titleField] as string}</p>
</Link>,
<p key={`${key}-${document.id}-date`} className="text-black dark:text-white">
{document.createdAt?.toDate().toUTCString()}
</p>,
<Table
isLoading={isLoading}
headers={["Title", "Created", "Status"]}
rows={documents.map((document, key) => [
<Link key={`${key}-${document.id}-id`} href={`/content/${document.documentType}/${document.id}`}>
<p className="font-medium text-black dark:text-white">{document.data[documentType.titleField] as string}</p>
</Link>,
<p key={`${key}-${document.id}-date`} className="text-black dark:text-white">
{document.createdAt?.toDate().toUTCString()}
</p>,

<TableRowLabel
key={`${key}-${document.id}-status`}
title={document.status}
status={document.status === "published" ? "success" : "info"}
/>,
])}
/>
</>
<TableRowLabel
key={`${key}-${document.id}-status`}
title={document.status}
status={document.status === "published" ? "success" : "info"}
/>,
])}
/>
);
}
44 changes: 33 additions & 11 deletions hosting/src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from "react";
import React, {FC} from "react";

interface TableProps {
headers: string[];
rows: React.ReactNode[][];
isLoading?: boolean;
}

/**
Expand All @@ -22,13 +23,14 @@ interface TableProps {
* onDownload={() => console.log("Download", document)}
* />,
* ])}
* isLoading={true}
* />
* ```
*
* @param {TableProps} param0 Table parameters
* @return {JSX.Element} Table component
*/
export function Table({headers, rows}: TableProps): JSX.Element {
export function Table({headers, rows, isLoading = false}: TableProps): JSX.Element {
return (
<div className="rounded-sm border border-stroke bg-white shadow-default dark:border-strokedark dark:bg-boxdark">
<div className="max-w-full overflow-x-auto">
Expand All @@ -43,18 +45,38 @@ export function Table({headers, rows}: TableProps): JSX.Element {
</tr>
</thead>
<tbody>
{rows.map((row, rowIndex) => (
<tr key={rowIndex} className="border-b border-[#eee] dark:border-strokedark">
{row.map((col, colIndex) => (
<td key={`r${rowIndex}c${colIndex}`} className="px-4 py-5 dark:border-strokedark">
{col}
</td>
))}
</tr>
))}
{isLoading
? Array.from({length: 20}).map((_, rowIndex) => <TableRowShimmer key={rowIndex} headers={headers} />)
: rows.map((row, rowIndex) => <TableRow key={rowIndex} row={row} />)}
</tbody>
</table>
</div>
</div>
);
}

const TableRowShimmer: FC<{
headers: string[];
rowIndex?: number;
}> = ({headers, rowIndex}) => (
<tr className="border-b border-[#eee] dark:border-strokedark">
{headers.map((_, colIndex) => (
<td key={`r${rowIndex}c${colIndex}`} className="px-4 py-5 dark:border-strokedark">
<div className="h-5 bg-zinc-200 rounded-md animate-pulse dark:bg-gray-700"></div>
</td>
))}
</tr>
);

const TableRow: FC<{
row: React.ReactNode[];
rowIndex?: number;
}> = ({row, rowIndex}) => (
<tr className="border-b border-[#eee] dark:border-strokedark">
{row.map((col, colIndex) => (
<td key={`r${rowIndex}c${colIndex}`} className="px-4 py-5 dark:border-strokedark">
{col}
</td>
))}
</tr>
);
16 changes: 13 additions & 3 deletions hosting/src/hooks/useTanamDocuments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {useEffect, useState} from "react";
interface UseTanamDocumentsResult {
data: TanamDocumentClient[];
error: UserNotification | null;
isLoading: boolean;
}

/**
Expand All @@ -20,10 +21,12 @@ interface UseTanamDocumentsResult {
export function useTanamDocuments(documentTypeId?: string): UseTanamDocumentsResult {
const [data, setData] = useState<TanamDocumentClient[]>([]);
const [error, setError] = useState<UserNotification | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(true);

useEffect(() => {
if (!documentTypeId) {
setError(new UserNotification("error", "Missing parameter", "Content type parameter is missing"));
setIsLoading(false);
return;
}

Expand All @@ -35,48 +38,55 @@ export function useTanamDocuments(documentTypeId?: string): UseTanamDocumentsRes
(snapshot) => {
const documents = snapshot.docs.map((doc) => TanamDocumentClient.fromFirestore(doc));
setData(documents);
setIsLoading(false);
},
(err) => {
setError(new UserNotification("error", "Error fetching data", err.message));
setIsLoading(false);
},
);

// Cleanup subscription on unmount
return () => unsubscribe();
}, [documentTypeId]);

return {data, error};
return {data, error, isLoading};
}

interface UseTanamDocumentResult {
data: TanamDocumentClient | null;
changeStatus: (status: TanamPublishStatus) => Promise<void>;
error: UserNotification | null;
isLoading: boolean;
}

/**
* Hook to get a subscription for a single document
*
* @param {string?} documentId Document id
* @return {UseTanamDocumentsResult} Hook for document subscription
* @return {UseTanamDocumentResult} Hook for document subscription
*/
export function useTanamDocument(documentId?: string): UseTanamDocumentResult {
const [data, setData] = useState<TanamDocumentClient | null>(null);
const [error, setError] = useState<UserNotification | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(true);

useEffect(() => {
if (!documentId) {
setError(new UserNotification("error", "Missing parameter", "Document id parameter is missing"));
setIsLoading(false);
return;
}
const docRef = doc(firestore, "tanam-documents", documentId);
const unsubscribe = onSnapshot(
docRef,
(snapshot) => {
setData(TanamDocumentClient.fromFirestore(snapshot));
setIsLoading(false);
},
(err) => {
setError(new UserNotification("error", "Error fetching data", err.message));
setIsLoading(false);
},
);

Expand Down Expand Up @@ -109,7 +119,7 @@ export function useTanamDocument(documentId?: string): UseTanamDocumentResult {
}
}

return {data, changeStatus, error};
return {data, changeStatus, error, isLoading};
}

export function useCrudTanamDocument() {
Expand Down