Files
payload/src/admin/components/views/collections/List/Default.tsx
Alessio Gravili 9467074fb9 chore: update 2.0 branch from master (#3207)
Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
Co-authored-by: Alessio Gravili <alessio@gravili.de>
Co-authored-by: PatrikKozak <patrik@trbl.design>
Co-authored-by: Lucas Blancas <lablancas@gmail.com>
Co-authored-by: Stef Gootzen <37367280+stefgootzen@users.noreply.github.com>
Co-authored-by: Jarrod Flesch <30633324+JarrodMFlesch@users.noreply.github.com>
Co-authored-by: Jessica Chowdhury <67977755+JessChowdhury@users.noreply.github.com>
Co-authored-by: PatrikKozak <35232443+PatrikKozak@users.noreply.github.com>
Co-authored-by: Greg Willard <Wickett06@gmail.com>
Co-authored-by: James Mikrut <james@payloadcms.com>
Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
Co-authored-by: Elliot DeNolf <denolfe@gmail.com>
fix: WhereBuilder component does not accept all valid Where queries (#3087)
fix: passes in height to resizeOptions upload option to allow height resize (#3171)
2023-08-22 16:04:50 -04:00

243 lines
7.9 KiB
TypeScript

import React, { Fragment } from 'react';
import { useTranslation } from 'react-i18next';
import { useWindowInfo } from '@faceless-ui/window-info';
import Eyebrow from '../../../elements/Eyebrow';
import Paginator from '../../../elements/Paginator';
import ListControls from '../../../elements/ListControls';
import ListSelection from '../../../elements/ListSelection';
import Pill from '../../../elements/Pill';
import Button from '../../../elements/Button';
import { Table } from '../../../elements/Table';
import Meta from '../../../utilities/Meta';
import { Props } from './types';
import ViewDescription from '../../../elements/ViewDescription';
import PerPage from '../../../elements/PerPage';
import { Gutter } from '../../../elements/Gutter';
import { RelationshipProvider } from './RelationshipProvider';
import { getTranslation } from '../../../../../utilities/getTranslation';
import { StaggeredShimmers } from '../../../elements/ShimmerEffect';
import { SelectionProvider } from './SelectionProvider';
import EditMany from '../../../elements/EditMany';
import DeleteMany from '../../../elements/DeleteMany';
import PublishMany from '../../../elements/PublishMany';
import UnpublishMany from '../../../elements/UnpublishMany';
import formatFilesize from '../../../../../uploads/formatFilesize';
import './index.scss';
const baseClass = 'collection-list';
const DefaultList: React.FC<Props> = (props) => {
const {
collection,
collection: {
labels: {
singular: singularLabel,
plural: pluralLabel,
},
admin: {
description,
components: {
BeforeList,
BeforeListTable,
AfterListTable,
AfterList,
} = {},
} = {},
},
data,
newDocumentURL,
limit,
hasCreatePermission,
disableEyebrow,
modifySearchParams,
handleSortChange,
handleWhereChange,
handlePageChange,
handlePerPageChange,
customHeader,
resetParams,
} = props;
const { breakpoints: { s: smallBreak } } = useWindowInfo();
const { t, i18n } = useTranslation('general');
let formattedDocs = data.docs || [];
if (collection.upload) {
formattedDocs = formattedDocs?.map((doc) => {
return {
...doc,
filesize: formatFilesize(doc.filesize),
};
});
}
return (
<div className={baseClass}>
{Array.isArray(BeforeList) && BeforeList.map((Component, i) => (
<Component
key={i}
{...props}
/>
))}
<Meta
title={getTranslation(collection.labels.plural, i18n)}
/>
<SelectionProvider
docs={data.docs}
totalDocs={data.totalDocs}
>
{!disableEyebrow && (
<Eyebrow />
)}
<Gutter className={`${baseClass}__wrap`}>
<header className={`${baseClass}__header`}>
{customHeader && customHeader}
{!customHeader && (
<Fragment>
<h1>
{getTranslation(pluralLabel, i18n)}
</h1>
{hasCreatePermission && (
<Pill
to={newDocumentURL}
aria-label={t('createNewLabel', { label: getTranslation(singularLabel, i18n) })}
>
{t('createNew')}
</Pill>
)}
{!smallBreak && (
<ListSelection
label={getTranslation(collection.labels.plural, i18n)}
/>
)}
{description && (
<div className={`${baseClass}__sub-header`}>
<ViewDescription description={description} />
</div>
)}
</Fragment>
)}
</header>
<ListControls
collection={collection}
modifySearchQuery={modifySearchParams}
handleSortChange={handleSortChange}
handleWhereChange={handleWhereChange}
resetParams={resetParams}
/>
{Array.isArray(BeforeListTable) && BeforeListTable.map((Component, i) => (
<Component
key={i}
{...props}
/>
))}
{!data.docs && (
<StaggeredShimmers
className={[`${baseClass}__shimmer`, `${baseClass}__shimmer--rows`].join(' ')}
count={6}
/>
)}
{(data.docs && data.docs.length > 0) && (
<RelationshipProvider>
<Table data={formattedDocs} />
</RelationshipProvider>
)}
{data.docs && data.docs.length === 0 && (
<div className={`${baseClass}__no-results`}>
<p>
{t('noResults', { label: getTranslation(pluralLabel, i18n) })}
</p>
{hasCreatePermission && newDocumentURL && (
<Button
el="link"
to={newDocumentURL}
>
{t('createNewLabel', { label: getTranslation(singularLabel, i18n) })}
</Button>
)}
</div>
)}
{Array.isArray(AfterListTable) && AfterListTable.map((Component, i) => (
<Component
key={i}
{...props}
/>
))}
<div className={`${baseClass}__page-controls`}>
<Paginator
limit={data.limit}
totalPages={data.totalPages}
page={data.page}
hasPrevPage={data.hasPrevPage}
hasNextPage={data.hasNextPage}
prevPage={data.prevPage}
nextPage={data.nextPage}
numberOfNeighbors={1}
disableHistoryChange={modifySearchParams === false}
onChange={handlePageChange}
/>
{data?.totalDocs > 0 && (
<Fragment>
<div className={`${baseClass}__page-info`}>
{(data.page * data.limit) - (data.limit - 1)}
-
{data.totalPages > 1 && data.totalPages !== data.page ? (data.limit * data.page) : data.totalDocs}
{' '}
{t('of')}
{' '}
{data.totalDocs}
</div>
<PerPage
limits={collection?.admin?.pagination?.limits}
limit={limit}
modifySearchParams={modifySearchParams}
handleChange={handlePerPageChange}
resetPage={data.totalDocs <= data.pagingCounter}
/>
<div className={`${baseClass}__list-selection`}>
{smallBreak && (
<Fragment>
<ListSelection
label={getTranslation(collection.labels.plural, i18n)}
/>
<div className={`${baseClass}__list-selection-actions`}>
<EditMany
collection={collection}
resetParams={resetParams}
/>
<PublishMany
collection={collection}
resetParams={resetParams}
/>
<UnpublishMany
collection={collection}
resetParams={resetParams}
/>
<DeleteMany
collection={collection}
resetParams={resetParams}
/>
</div>
</Fragment>
)}
</div>
</Fragment>
)}
</div>
</Gutter>
</SelectionProvider>
{Array.isArray(AfterList) && AfterList.map((Component, i) => (
<Component
key={i}
{...props}
/>
))}
</div>
);
};
export default DefaultList;