Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ coverage/
.temp/
storybook-static/
.nx
.claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,23 @@ function Entries({
getWorkflowStatus,
getUnpublishedEntries,
filterTerm,
sortFields,
showPublishedEntries = true,
showUnpublishedEntries = true,
}) {
const loadingMessages = [
t('collection.entries.loadingEntries'),
t('collection.entries.cachingEntries'),
t('collection.entries.longerLoading'),
];

if (isFetching && page === undefined) {
if (showPublishedEntries && isFetching && page === undefined) {
return <Loader active>{loadingMessages}</Loader>;
}

const hasEntries = (entries && entries.size > 0) || cursor?.actions?.has('append_next');
if (hasEntries) {
const hasEntries =
showPublishedEntries && ((entries && entries.size > 0) || cursor?.actions?.has('append_next'));
if (hasEntries || !showPublishedEntries) {
return (
<>
<EntryListing
Expand All @@ -55,8 +59,11 @@ function Entries({
getWorkflowStatus={getWorkflowStatus}
getUnpublishedEntries={getUnpublishedEntries}
filterTerm={filterTerm}
sortFields={sortFields}
showPublishedEntries={showPublishedEntries}
showUnpublishedEntries={showUnpublishedEntries}
/>
{isFetching && page !== undefined && entries.size > 0 ? (
{showPublishedEntries && isFetching && page !== undefined && entries.size > 0 ? (
<PaginationMessage>{t('collection.entries.loadingEntries')}</PaginationMessage>
) : null}
</>
Expand All @@ -78,6 +85,9 @@ Entries.propTypes = {
getWorkflowStatus: PropTypes.func,
getUnpublishedEntries: PropTypes.func,
filterTerm: PropTypes.string,
sortFields: PropTypes.array,
showPublishedEntries: PropTypes.bool,
showUnpublishedEntries: PropTypes.bool,
};

export default translate()(Entries);
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
selectEntriesLoaded,
selectIsFetching,
selectGroups,
selectEntriesSortFields,
} from '../../../reducers/entries';
import { selectUnpublishedEntry, selectUnpublishedEntriesByStatus } from '../../../reducers';
import { selectCollectionEntriesCursor } from '../../../reducers/cursors';
Expand Down Expand Up @@ -54,7 +55,10 @@ function withGroups(groups, entries, EntriesToRender, t) {
return (
<GroupContainer key={group.id} id={group.id}>
<GroupHeading>{title}</GroupHeading>
<EntriesToRender entries={getGroupEntries(entries, group.paths)} />
<EntriesToRender
entries={getGroupEntries(entries, group.paths)}
showUnpublishedEntries={false}
/>
</GroupContainer>
);
});
Expand Down Expand Up @@ -144,9 +148,18 @@ export class EntriesCollection extends React.Component {
getWorkflowStatus,
getUnpublishedEntries,
filterTerm,
sortFields,
} = this.props;

const EntriesToRender = ({ entries }) => {
const EntriesToRender = ({ entries, showPublishedEntries, showUnpublishedEntries }) => {
const visibilityProps = {};
if (showPublishedEntries !== undefined) {
visibilityProps.showPublishedEntries = showPublishedEntries;
}
if (showUnpublishedEntries !== undefined) {
visibilityProps.showUnpublishedEntries = showUnpublishedEntries;
}

return (
<Entries
collections={collection}
Expand All @@ -160,12 +173,19 @@ export class EntriesCollection extends React.Component {
getWorkflowStatus={getWorkflowStatus}
getUnpublishedEntries={getUnpublishedEntries}
filterTerm={filterTerm}
sortFields={sortFields}
{...visibilityProps}
/>
);
};

if (groups && groups.length > 0) {
return withGroups(groups, entries, EntriesToRender, t);
return (
<React.Fragment>
{withGroups(groups, entries, EntriesToRender, t)}
<EntriesToRender entries={entries} showPublishedEntries={false} />
</React.Fragment>
);
}

return <EntriesToRender entries={entries} />;
Expand Down Expand Up @@ -206,6 +226,7 @@ function mapStateToProps(state, ownProps) {

let entries = selectEntries(state.entries, collection);
const groups = selectGroups(state.entries, collection);
const sortFields = selectEntriesSortFields(state.entries, collection.get('name'));

if (collection.has('nested')) {
const collectionFolder = collection.get('folder');
Expand Down Expand Up @@ -233,6 +254,7 @@ function mapStateToProps(state, ownProps) {
page,
entries,
groups,
sortFields,
entriesLoaded,
isFetching,
viewStyle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled from '@emotion/styled';
import { Waypoint } from 'react-waypoint';
import { Map, List } from 'immutable';
import { Map, List, fromJS } from 'immutable';
import { translate } from 'react-polyglot';
import orderBy from 'lodash/orderBy';
import { colors, lengths } from 'decap-cms-ui-default';

import { selectFields, selectInferredField } from '../../../reducers/collections';
import {
selectFields,
selectInferredField,
selectSortDataPath,
} from '../../../reducers/collections';
import { filterNestedEntries } from './EntriesCollection';
import { SortDirection } from '../../../types/redux';
import EntryCard from './EntryCard';

const CardsGrid = styled.ul`
Expand All @@ -18,6 +26,20 @@ const CardsGrid = styled.ul`
margin-bottom: 16px;
`;

const SectionSeparator = styled.div`
width: ${lengths.topCardWidth};
margin: 24px 0 16px 12px;
padding-top: 16px;
border-top: 2px solid ${colors.textFieldBorder};
`;

const SectionHeading = styled.p`
font-size: 16px;
font-weight: 600;
color: ${colors.textLead};
margin: 0 0 8px;
`;

class EntryListing extends React.Component {
static propTypes = {
collections: ImmutablePropTypes.iterable.isRequired,
Expand All @@ -29,6 +51,15 @@ class EntryListing extends React.Component {
getUnpublishedEntries: PropTypes.func.isRequired,
getWorkflowStatus: PropTypes.func.isRequired,
filterTerm: PropTypes.string,
sortFields: PropTypes.array,
showPublishedEntries: PropTypes.bool,
showUnpublishedEntries: PropTypes.bool,
t: PropTypes.func.isRequired,
};

static defaultProps = {
showPublishedEntries: true,
showUnpublishedEntries: true,
};

componentDidMount() {
Expand Down Expand Up @@ -58,18 +89,30 @@ class EntryListing extends React.Component {
return { titleField, descriptionField, imageField, remainingFields };
};

getAllEntries = () => {
const { entries, collections, filterTerm } = this.props;
sortEntries = (entries, sortFields, collections) => {
if (!sortFields || sortFields.length === 0) {
return entries;
}

const keys = sortFields.map(v => selectSortDataPath(collections, v.get('key')));
const orders = sortFields.map(v =>
v.get('direction') === SortDirection.Ascending ? 'asc' : 'desc',
);
return fromJS(orderBy(entries.toJS(), keys, orders));
};

getUnpublishedEntriesList = () => {
const { entries, collections, filterTerm, sortFields } = this.props;
const collectionName = Map.isMap(collections) ? collections.get('name') : null;

if (!collectionName) {
return entries;
return List();
}

const unpublishedEntries = this.props.getUnpublishedEntries(collectionName);

if (!unpublishedEntries || unpublishedEntries.length === 0) {
return entries;
return List();
}

let unpublishedList = List(unpublishedEntries.map(entry => entry));
Expand All @@ -91,31 +134,91 @@ class EntryListing extends React.Component {
publishedSlugs.has(entry.get('slug')),
);

return entries.concat(uniqueUnpublished);
return this.sortEntries(uniqueUnpublished, sortFields, collections);
};

renderCardsForSingleCollection = () => {
const { collections, viewStyle } = this.props;
const allEntries = this.getAllEntries();
const {
collections,
viewStyle,
entries,
page,
t,
showPublishedEntries,
showUnpublishedEntries,
} = this.props;
const inferredFields = this.inferFields(collections);
const entryCardProps = { collection: collections, inferredFields, viewStyle };

return allEntries.map((entry, idx) => {
const publishedCards = showPublishedEntries
? entries.map((entry, idx) => {
const workflowStatus = this.props.getWorkflowStatus(
collections.get('name'),
entry.get('slug'),
);

return (
<EntryCard
{...entryCardProps}
entry={entry}
workflowStatus={workflowStatus}
key={`published-${idx}`}
/>
);
})
: List();

const unpublishedEntries = showUnpublishedEntries ? this.getUnpublishedEntriesList() : List();

if (unpublishedEntries.size === 0) {
if (!showPublishedEntries) {
return null;
}

return (
<CardsGrid>
{publishedCards}
{this.hasMore() && <Waypoint key={page} onEnter={this.handleLoadMore} />}
</CardsGrid>
);
}

const unpublishedCards = unpublishedEntries.map((entry, idx) => {
const workflowStatus = this.props.getWorkflowStatus(
collections.get('name'),
entry.get('slug'),
);

return (
<EntryCard {...entryCardProps} entry={entry} workflowStatus={workflowStatus} key={idx} />
<EntryCard
{...entryCardProps}
entry={entry}
workflowStatus={workflowStatus}
key={`unpublished-${idx}`}
/>
);
});

return (
<React.Fragment>
{showPublishedEntries && (
<CardsGrid>
{publishedCards}
{this.hasMore() && <Waypoint key={page} onEnter={this.handleLoadMore} />}
</CardsGrid>
)}
<SectionSeparator>
<SectionHeading>{t('collection.entries.unpublishedHeader')}</SectionHeading>
</SectionSeparator>
<CardsGrid>{unpublishedCards}</CardsGrid>
</React.Fragment>
);
};

renderCardsForMultipleCollections = () => {
const { collections, entries } = this.props;
const { collections, entries, page } = this.props;
const isSingleCollectionInList = collections.size === 1;
return entries.map((entry, idx) => {
const entryCards = entries.map((entry, idx) => {
const collectionName = entry.get('collection');
const collection = collections.find(coll => coll.get('name') === collectionName);
const collectionLabel = !isSingleCollectionInList && collection.get('label');
Expand All @@ -130,22 +233,26 @@ class EntryListing extends React.Component {
};
return <EntryCard {...entryCardProps} key={idx} />;
});

return (
<CardsGrid>
{entryCards}
{this.hasMore() && <Waypoint key={page} onEnter={this.handleLoadMore} />}
</CardsGrid>
);
};

render() {
const { collections, page } = this.props;
const { collections } = this.props;

return (
<div>
<CardsGrid>
{Map.isMap(collections)
? this.renderCardsForSingleCollection()
: this.renderCardsForMultipleCollections()}
{this.hasMore() && <Waypoint key={page} onEnter={this.handleLoadMore} />}
</CardsGrid>
{Map.isMap(collections)
? this.renderCardsForSingleCollection()
: this.renderCardsForMultipleCollections()}
</div>
);
}
}

export default EntryListing;
export default translate()(EntryListing);
Loading