fix: properly handle default group and filter (#1083)

This commit is contained in:
Daniel Lautzenheiser 2024-02-08 10:42:35 -05:00 committed by GitHub
parent ccd242c06f
commit 2c72215e2d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 174 additions and 157 deletions

View File

@ -145,6 +145,8 @@ function applyFolderCollectionDefaults(
): FolderCollectionWithDefaults { ): FolderCollectionWithDefaults {
const collection: FolderCollectionWithDefaults = { const collection: FolderCollectionWithDefaults = {
...originalCollection, ...originalCollection,
view_filters: undefined,
view_groups: undefined,
i18n: collectionI18n, i18n: collectionI18n,
}; };
@ -228,6 +230,8 @@ function applyFilesCollectionDefaults(
const collection: FilesCollectionWithDefaults = { const collection: FilesCollectionWithDefaults = {
...originalCollection, ...originalCollection,
i18n: collectionI18n, i18n: collectionI18n,
view_filters: undefined,
view_groups: undefined,
files: originalCollection.files.map(f => files: originalCollection.files.map(f =>
applyCollectionFileDefaults(f, originalCollection, collectionI18n, config), applyCollectionFileDefaults(f, originalCollection, collectionI18n, config),
), ),
@ -271,7 +275,7 @@ function applyCollectionDefaults(
collection.fields = setI18nDefaultsForFields(collection.fields, Boolean(collectionI18n)); collection.fields = setI18nDefaultsForFields(collection.fields, Boolean(collectionI18n));
} }
const { view_filters, view_groups } = collection; const { view_filters, view_groups } = originalCollection;
if (!collection.sortable_fields) { if (!collection.sortable_fields) {
collection.sortable_fields = { collection.sortable_fields = {
@ -280,7 +284,7 @@ function applyCollectionDefaults(
} }
collection.view_filters = { collection.view_filters = {
default: collection.view_filters?.default, default: originalCollection.view_filters?.default,
filters: (view_filters?.filters ?? []).map(filter => { filters: (view_filters?.filters ?? []).map(filter => {
return { return {
...filter, ...filter,
@ -290,7 +294,7 @@ function applyCollectionDefaults(
}; };
collection.view_groups = { collection.view_groups = {
default: collection.view_groups?.default, default: originalCollection.view_groups?.default,
groups: (view_groups?.groups ?? []).map(group => { groups: (view_groups?.groups ?? []).map(group => {
return { return {
...group, ...group,

View File

@ -44,11 +44,7 @@ import { Cursor } from '../lib/util';
import { getFields, updateFieldByKey } from '../lib/util/collection.util'; import { getFields, updateFieldByKey } from '../lib/util/collection.util';
import { createEmptyDraftData, createEmptyDraftI18nData } from '../lib/util/entry.util'; import { createEmptyDraftData, createEmptyDraftI18nData } from '../lib/util/entry.util';
import { selectCollectionEntriesCursor } from '../reducers/selectors/cursors'; import { selectCollectionEntriesCursor } from '../reducers/selectors/cursors';
import { import { selectIsFetching, selectPublishedSlugs } from '../reducers/selectors/entries';
selectEntriesSelectedSort,
selectIsFetching,
selectPublishedSlugs,
} from '../reducers/selectors/entries';
import { addSnackbar } from '../store/slices/snackbars'; import { addSnackbar } from '../store/slices/snackbars';
import { createAssetProxy } from '../valueObjects/AssetProxy'; import { createAssetProxy } from '../valueObjects/AssetProxy';
import createEntry from '../valueObjects/createEntry'; import createEntry from '../valueObjects/createEntry';
@ -73,7 +69,9 @@ import type {
SortDirection, SortDirection,
ValueOrNestedValue, ValueOrNestedValue,
ViewFilter, ViewFilter,
ViewFilterWithDefaults,
ViewGroup, ViewGroup,
ViewGroupWithDefaults,
} from '../interface'; } from '../interface';
import type { RootState } from '../store'; import type { RootState } from '../store';
import type AssetProxy from '../valueObjects/AssetProxy'; import type AssetProxy from '../valueObjects/AssetProxy';
@ -122,7 +120,10 @@ export function entriesLoading(collection: CollectionWithDefaults) {
} as const; } as const;
} }
export function filterEntriesRequest(collection: CollectionWithDefaults, filter: ViewFilter) { export function filterEntriesRequest(
collection: CollectionWithDefaults,
filter: ViewFilterWithDefaults,
) {
return { return {
type: FILTER_ENTRIES_REQUEST, type: FILTER_ENTRIES_REQUEST,
payload: { payload: {
@ -162,7 +163,10 @@ export function filterEntriesFailure(
} as const; } as const;
} }
export function groupEntriesRequest(collection: CollectionWithDefaults, group: ViewGroup) { export function groupEntriesRequest(
collection: CollectionWithDefaults,
group: ViewGroupWithDefaults,
) {
return { return {
type: GROUP_ENTRIES_REQUEST, type: GROUP_ENTRIES_REQUEST,
payload: { payload: {
@ -315,7 +319,7 @@ export function sortByField(
}; };
} }
export function filterByField(collection: CollectionWithDefaults, filter: ViewFilter) { export function filterByField(collection: CollectionWithDefaults, filter: ViewFilterWithDefaults) {
return async (dispatch: ThunkDispatch<RootState, {}, AnyAction>, getState: () => RootState) => { return async (dispatch: ThunkDispatch<RootState, {}, AnyAction>, getState: () => RootState) => {
const state = getState(); const state = getState();
// if we're already fetching we update the filter key, but skip loading entries // if we're already fetching we update the filter key, but skip loading entries
@ -334,17 +338,12 @@ export function filterByField(collection: CollectionWithDefaults, filter: ViewFi
}; };
} }
export function groupByField(collection: CollectionWithDefaults, group: ViewGroup) { export function groupByField(collection: CollectionWithDefaults, group: ViewGroupWithDefaults) {
return async (dispatch: ThunkDispatch<RootState, {}, AnyAction>, getState: () => RootState) => { return async (dispatch: ThunkDispatch<RootState, {}, AnyAction>, getState: () => RootState) => {
const state = getState(); const state = getState();
const isFetching = selectIsFetching(state, collection.name); const isFetching = selectIsFetching(state, collection.name);
dispatch({ dispatch(groupEntriesRequest(collection, group));
type: GROUP_ENTRIES_REQUEST,
payload: {
collection: collection.name,
group,
},
});
if (isFetching) { if (isFetching) {
return; return;
} }
@ -699,10 +698,6 @@ export function loadEntries(collection: CollectionWithDefaults, page = 0) {
return; return;
} }
const state = getState(); const state = getState();
const sortField = selectEntriesSelectedSort(state, collection.name);
if (sortField) {
return dispatch(sortByField(collection, sortField.key, sortField.direction));
}
const configState = state.config; const configState = state.config;
if (!configState.config) { if (!configState.config) {
@ -751,6 +746,7 @@ export function loadEntries(collection: CollectionWithDefaults, page = 0) {
); );
} catch (error: unknown) { } catch (error: unknown) {
console.error(error); console.error(error);
if (error instanceof Error) { if (error instanceof Error) {
dispatch( dispatch(
addSnackbar({ addSnackbar({

View File

@ -7,16 +7,16 @@ import GroupControl from './GroupControl';
import MobileCollectionControls from './mobile/MobileCollectionControls'; import MobileCollectionControls from './mobile/MobileCollectionControls';
import SortControl from './SortControl'; import SortControl from './SortControl';
import type { ViewStyle } from '@staticcms/core/constants/views';
import type { import type {
FilterMap, FilterMap,
GroupMap, GroupMap,
SortableField, SortableField,
SortDirection, SortDirection,
SortMap, SortMap,
ViewFilter, ViewFilterWithDefaults,
ViewGroup, ViewGroupWithDefaults,
} from '@staticcms/core'; } from '@staticcms/core';
import type { ViewStyle } from '@staticcms/core/constants/views';
import type { FC } from 'react'; import type { FC } from 'react';
interface CollectionControlsProps { interface CollectionControlsProps {
@ -26,11 +26,11 @@ interface CollectionControlsProps {
onSortClick?: (key: string, direction?: SortDirection) => Promise<void>; onSortClick?: (key: string, direction?: SortDirection) => Promise<void>;
sort?: SortMap | undefined; sort?: SortMap | undefined;
filter?: Record<string, FilterMap>; filter?: Record<string, FilterMap>;
viewFilters?: ViewFilter[]; viewFilters?: ViewFilterWithDefaults[];
onFilterClick?: (filter: ViewFilter) => void; onFilterClick?: (filter: ViewFilterWithDefaults) => void;
group?: Record<string, GroupMap>; group?: Record<string, GroupMap>;
viewGroups?: ViewGroup[]; viewGroups?: ViewGroupWithDefaults[];
onGroupClick?: (filter: ViewGroup) => void; onGroupClick?: (filter: ViewGroupWithDefaults) => void;
} }
const CollectionControls: FC<CollectionControlsProps> = ({ const CollectionControls: FC<CollectionControlsProps> = ({

View File

@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import React, { useCallback, useMemo } from 'react';
import { import {
changeViewStyle, changeViewStyle,
@ -6,7 +6,6 @@ import {
groupByField, groupByField,
sortByField, sortByField,
} from '@staticcms/core/actions/entries'; } from '@staticcms/core/actions/entries';
import { SORT_DIRECTION_ASCENDING } from '@staticcms/core/constants';
import useTranslate from '@staticcms/core/lib/hooks/useTranslate'; import useTranslate from '@staticcms/core/lib/hooks/useTranslate';
import { import {
getSortableFields, getSortableFields,
@ -28,8 +27,13 @@ import CollectionHeader from './CollectionHeader';
import EntriesCollection from './entries/EntriesCollection'; import EntriesCollection from './entries/EntriesCollection';
import EntriesSearch from './entries/EntriesSearch'; import EntriesSearch from './entries/EntriesSearch';
import type {
CollectionWithDefaults,
SortDirection,
ViewFilterWithDefaults,
ViewGroupWithDefaults,
} from '@staticcms/core';
import type { ViewStyle } from '@staticcms/core/constants/views'; import type { ViewStyle } from '@staticcms/core/constants/views';
import type { CollectionWithDefaults, SortDirection, ViewFilter, ViewGroup } from '@staticcms/core';
import type { FC } from 'react'; import type { FC } from 'react';
import './Collection.css'; import './Collection.css';
@ -70,13 +74,6 @@ const CollectionView: FC<CollectionViewProps> = ({
const filter = useAppSelector(state => selectEntriesFilter(state, collection?.name)); const filter = useAppSelector(state => selectEntriesFilter(state, collection?.name));
const group = useAppSelector(state => selectEntriesGroup(state, collection?.name)); const group = useAppSelector(state => selectEntriesGroup(state, collection?.name));
const [readyToLoad, setReadyToLoad] = useState(false);
const [prevCollection, setPrevCollection] = useState<CollectionWithDefaults | null>();
useEffect(() => {
setPrevCollection(collection);
}, [collection]);
const searchResultKey = useMemo( const searchResultKey = useMemo(
() => `collection.collectionTop.searchResults${isSingleSearchResult ? 'InCollection' : ''}`, () => `collection.collectionTop.searchResults${isSingleSearchResult ? 'InCollection' : ''}`,
[isSingleSearchResult], [isSingleSearchResult],
@ -110,12 +107,7 @@ const CollectionView: FC<CollectionViewProps> = ({
} }
return ( return (
<EntriesCollection <EntriesCollection collection={collection} viewStyle={viewStyle} filterTerm={filterTerm} />
collection={collection}
viewStyle={viewStyle}
filterTerm={filterTerm}
readyToLoad={readyToLoad && collection === prevCollection}
/>
); );
}, [ }, [
collection, collection,
@ -123,8 +115,6 @@ const CollectionView: FC<CollectionViewProps> = ({
filterTerm, filterTerm,
isSearchResults, isSearchResults,
isSingleSearchResult, isSingleSearchResult,
prevCollection,
readyToLoad,
searchTerm, searchTerm,
viewStyle, viewStyle,
]); ]);
@ -137,14 +127,14 @@ const CollectionView: FC<CollectionViewProps> = ({
); );
const onFilterClick = useCallback( const onFilterClick = useCallback(
async (filter: ViewFilter) => { async (filter: ViewFilterWithDefaults) => {
collection && (await dispatch(filterByField(collection, filter))); collection && (await dispatch(filterByField(collection, filter)));
}, },
[collection, dispatch], [collection, dispatch],
); );
const onGroupClick = useCallback( const onGroupClick = useCallback(
async (group: ViewGroup) => { async (group: ViewGroupWithDefaults) => {
collection && (await dispatch(groupByField(collection, group))); collection && (await dispatch(groupByField(collection, group)));
}, },
[collection, dispatch], [collection, dispatch],
@ -157,80 +147,6 @@ const CollectionView: FC<CollectionViewProps> = ({
[dispatch], [dispatch],
); );
useEffect(() => {
if (prevCollection === collection) {
if (!readyToLoad) {
setReadyToLoad(true);
}
return;
}
if (sort?.[0]?.key) {
if (!readyToLoad) {
setReadyToLoad(true);
}
return;
}
const defaultSort = collection?.sortable_fields?.default;
const defaultViewGroupName = collection?.view_groups?.default;
const defaultViewFilterName = collection?.view_filters?.default;
if (!defaultViewGroupName && !defaultViewFilterName && (!defaultSort || !defaultSort.field)) {
if (!readyToLoad) {
setReadyToLoad(true);
}
return;
}
setReadyToLoad(false);
let alive = true;
const sortGroupFilterEntries = () => {
setTimeout(async () => {
if (defaultSort && defaultSort.field) {
await onSortClick(defaultSort.field, defaultSort.direction ?? SORT_DIRECTION_ASCENDING);
}
if (defaultViewGroupName) {
const defaultViewGroup = viewGroups?.groups.find(g => g.name === defaultViewGroupName);
if (defaultViewGroup) {
await onGroupClick(defaultViewGroup);
}
}
if (defaultViewFilterName) {
const defaultViewFilter = viewFilters?.filters.find(
f => f.name === defaultViewFilterName,
);
if (defaultViewFilter) {
await onFilterClick(defaultViewFilter);
}
}
if (alive) {
setReadyToLoad(true);
}
});
};
sortGroupFilterEntries();
return () => {
alive = false;
};
}, [
collection,
onFilterClick,
onGroupClick,
onSortClick,
prevCollection,
readyToLoad,
sort,
viewFilters?.filters,
viewGroups?.groups,
]);
const collectionDescription = collection?.description; const collectionDescription = collection?.description;
return ( return (

View File

@ -7,8 +7,8 @@ import Menu from '../common/menu/Menu';
import MenuGroup from '../common/menu/MenuGroup'; import MenuGroup from '../common/menu/MenuGroup';
import MenuItemButton from '../common/menu/MenuItemButton'; import MenuItemButton from '../common/menu/MenuItemButton';
import type { FilterMap, ViewFilter } from '@staticcms/core'; import type { FilterMap, ViewFilterWithDefaults } from '@staticcms/core';
import type { MouseEvent, FC } from 'react'; import type { FC, MouseEvent } from 'react';
import './FilterControl.css'; import './FilterControl.css';
@ -24,9 +24,9 @@ export const classes = generateClassNames('FilterControl', [
export interface FilterControlProps { export interface FilterControlProps {
filter: Record<string, FilterMap> | undefined; filter: Record<string, FilterMap> | undefined;
viewFilters: ViewFilter[] | undefined; viewFilters: ViewFilterWithDefaults[] | undefined;
variant?: 'menu' | 'list'; variant?: 'menu' | 'list';
onFilterClick: ((viewFilter: ViewFilter) => void) | undefined; onFilterClick: ((viewFilter: ViewFilterWithDefaults) => void) | undefined;
} }
const FilterControl: FC<FilterControlProps> = ({ const FilterControl: FC<FilterControlProps> = ({
@ -40,7 +40,7 @@ const FilterControl: FC<FilterControlProps> = ({
const anyActive = useMemo(() => Object.keys(filter).some(key => filter[key]?.active), [filter]); const anyActive = useMemo(() => Object.keys(filter).some(key => filter[key]?.active), [filter]);
const handleFilterClick = useCallback( const handleFilterClick = useCallback(
(viewFilter: ViewFilter) => (event: MouseEvent) => { (viewFilter: ViewFilterWithDefaults) => (event: MouseEvent) => {
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
onFilterClick?.(viewFilter); onFilterClick?.(viewFilter);

View File

@ -7,7 +7,7 @@ import Menu from '../common/menu/Menu';
import MenuGroup from '../common/menu/MenuGroup'; import MenuGroup from '../common/menu/MenuGroup';
import MenuItemButton from '../common/menu/MenuItemButton'; import MenuItemButton from '../common/menu/MenuItemButton';
import type { GroupMap, ViewGroup } from '@staticcms/core'; import type { GroupMap, ViewGroupWithDefaults } from '@staticcms/core';
import type { FC, MouseEvent } from 'react'; import type { FC, MouseEvent } from 'react';
import './GroupControl.css'; import './GroupControl.css';
@ -25,9 +25,9 @@ export const classes = generateClassNames('GroupControl', [
export interface GroupControlProps { export interface GroupControlProps {
group: Record<string, GroupMap> | undefined; group: Record<string, GroupMap> | undefined;
viewGroups: ViewGroup[] | undefined; viewGroups: ViewGroupWithDefaults[] | undefined;
variant?: 'menu' | 'list'; variant?: 'menu' | 'list';
onGroupClick: ((viewGroup: ViewGroup) => void) | undefined; onGroupClick: ((viewGroup: ViewGroupWithDefaults) => void) | undefined;
} }
const GroupControl: FC<GroupControlProps> = ({ const GroupControl: FC<GroupControlProps> = ({
@ -41,7 +41,7 @@ const GroupControl: FC<GroupControlProps> = ({
const activeGroup = useMemo(() => Object.values(group).find(f => f.active === true), [group]); const activeGroup = useMemo(() => Object.values(group).find(f => f.active === true), [group]);
const handleGroupClick = useCallback( const handleGroupClick = useCallback(
(viewGroup: ViewGroup) => (event: MouseEvent) => { (viewGroup: ViewGroupWithDefaults) => (event: MouseEvent) => {
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
onGroupClick?.(viewGroup); onGroupClick?.(viewGroup);

View File

@ -15,8 +15,8 @@ import Button from '../../common/button/Button';
import Entries from './Entries'; import Entries from './Entries';
import entriesClasses from './Entries.classes'; import entriesClasses from './Entries.classes';
import type { ViewStyle } from '@staticcms/core/constants/views';
import type { CollectionWithDefaults, Entry, GroupOfEntries } from '@staticcms/core'; import type { CollectionWithDefaults, Entry, GroupOfEntries } from '@staticcms/core';
import type { ViewStyle } from '@staticcms/core/constants/views';
import type { RootState } from '@staticcms/core/store'; import type { RootState } from '@staticcms/core/store';
import type { FC } from 'react'; import type { FC } from 'react';
import type { t } from 'react-polyglot'; import type { t } from 'react-polyglot';
@ -65,13 +65,11 @@ const EntriesCollection: FC<EntriesCollectionProps> = ({
cursor, cursor,
page, page,
entriesLoaded, entriesLoaded,
readyToLoad,
}) => { }) => {
const t = useTranslate(); const t = useTranslate();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const [prevReadyToLoad, setPrevReadyToLoad] = useState(false);
const [prevCollection, setPrevCollection] = useState(collection); const [prevCollection, setPrevCollection] = useState(collection);
const groups = useGroups(collection.name); const groups = useGroups(collection.name);
@ -89,26 +87,12 @@ const EntriesCollection: FC<EntriesCollectionProps> = ({
}, [collection, entries, filterTerm]); }, [collection, entries, filterTerm]);
useEffect(() => { useEffect(() => {
if ( if (collection && !entriesLoaded && prevCollection !== collection) {
collection &&
!entriesLoaded &&
readyToLoad &&
(!prevReadyToLoad || prevCollection !== collection)
) {
dispatch(loadEntries(collection)); dispatch(loadEntries(collection));
} }
setPrevReadyToLoad(readyToLoad);
setPrevCollection(collection); setPrevCollection(collection);
}, [ }, [collection, dispatch, entriesLoaded, prevCollection, useWorkflow]);
collection,
dispatch,
entriesLoaded,
prevCollection,
prevReadyToLoad,
readyToLoad,
useWorkflow,
]);
const handleCursorActions = useCallback( const handleCursorActions = useCallback(
(action: string) => { (action: string) => {
@ -182,7 +166,6 @@ const EntriesCollection: FC<EntriesCollectionProps> = ({
interface EntriesCollectionOwnProps { interface EntriesCollectionOwnProps {
collection: CollectionWithDefaults; collection: CollectionWithDefaults;
viewStyle: ViewStyle; viewStyle: ViewStyle;
readyToLoad: boolean;
filterTerm: string; filterTerm: string;
} }

View File

@ -89,9 +89,9 @@ export type SortMap = Record<string, SortObject>;
export type Sort = Record<string, SortMap>; export type Sort = Record<string, SortMap>;
export type FilterMap = ViewFilter & { active?: boolean }; export type FilterMap = ViewFilterWithDefaults & { active?: boolean };
export type GroupMap = ViewGroup & { active?: boolean }; export type GroupMap = ViewGroupWithDefaults & { active?: boolean };
export type Filter = Record<string, Record<string, FilterMap>>; // collection.field.active export type Filter = Record<string, Record<string, FilterMap>>; // collection.field.active
@ -305,6 +305,8 @@ export interface BaseCollection {
export interface BaseCollectionWithDefaults extends Omit<BaseCollection, 'i18n'> { export interface BaseCollectionWithDefaults extends Omit<BaseCollection, 'i18n'> {
i18n?: I18nInfo; i18n?: I18nInfo;
view_filters?: ViewFiltersWithDefaults;
view_groups?: ViewGroupsWithDefaults;
} }
export interface FilesCollection<EF extends BaseField = UnknownField> extends BaseCollection { export interface FilesCollection<EF extends BaseField = UnknownField> extends BaseCollection {
@ -958,11 +960,19 @@ export interface ViewFilter {
pattern: string | boolean | number; pattern: string | boolean | number;
} }
export interface ViewFilterWithDefaults extends ViewFilter {
id: string;
}
export interface ViewFilters { export interface ViewFilters {
default?: string; default?: string;
filters: ViewFilter[]; filters: ViewFilter[];
} }
export interface ViewFiltersWithDefaults extends ViewFilters {
filters: ViewFilterWithDefaults[];
}
export interface ViewGroup { export interface ViewGroup {
id?: string; id?: string;
name: string; name: string;
@ -971,11 +981,19 @@ export interface ViewGroup {
pattern?: string; pattern?: string;
} }
export interface ViewGroupWithDefaults extends ViewGroup {
id: string;
}
export interface ViewGroups { export interface ViewGroups {
default?: string; default?: string;
groups: ViewGroup[]; groups: ViewGroup[];
} }
export interface ViewGroupsWithDefaults extends ViewGroups {
groups: ViewGroupWithDefaults[];
}
export type SortDirection = export type SortDirection =
| typeof SORT_DIRECTION_ASCENDING | typeof SORT_DIRECTION_ASCENDING
| typeof SORT_DIRECTION_DESCENDING | typeof SORT_DIRECTION_DESCENDING

View File

@ -3,6 +3,7 @@ import sortBy from 'lodash/sortBy';
import { import {
CHANGE_VIEW_STYLE, CHANGE_VIEW_STYLE,
CONFIG_SUCCESS,
ENTRIES_FAILURE, ENTRIES_FAILURE,
ENTRIES_REQUEST, ENTRIES_REQUEST,
ENTRIES_SUCCESS, ENTRIES_SUCCESS,
@ -18,6 +19,7 @@ import {
GROUP_ENTRIES_REQUEST, GROUP_ENTRIES_REQUEST,
GROUP_ENTRIES_SUCCESS, GROUP_ENTRIES_SUCCESS,
SEARCH_ENTRIES_SUCCESS, SEARCH_ENTRIES_SUCCESS,
SORT_DIRECTION_ASCENDING,
SORT_ENTRIES_FAILURE, SORT_ENTRIES_FAILURE,
SORT_ENTRIES_REQUEST, SORT_ENTRIES_REQUEST,
SORT_ENTRIES_SUCCESS, SORT_ENTRIES_SUCCESS,
@ -25,6 +27,7 @@ import {
import { VIEW_STYLES, VIEW_STYLE_TABLE } from '../constants/views'; import { VIEW_STYLES, VIEW_STYLE_TABLE } from '../constants/views';
import set from '../lib/util/set.util'; import set from '../lib/util/set.util';
import type { ConfigAction } from '../actions/config';
import type { EntriesAction } from '../actions/entries'; import type { EntriesAction } from '../actions/entries';
import type { SearchAction } from '../actions/search'; import type { SearchAction } from '../actions/search';
import type { ViewStyle } from '../constants/views'; import type { ViewStyle } from '../constants/views';
@ -124,9 +127,70 @@ export type EntriesState = {
function entries( function entries(
state: EntriesState = { entries: {}, pages: {}, sort: loadSort(), viewStyle: loadViewStyle() }, state: EntriesState = { entries: {}, pages: {}, sort: loadSort(), viewStyle: loadViewStyle() },
action: EntriesAction | SearchAction, action: EntriesAction | SearchAction | ConfigAction,
): EntriesState { ): EntriesState {
switch (action.type) { switch (action.type) {
case CONFIG_SUCCESS: {
const config = action.payload.config;
const sort: EntriesState['sort'] = {};
const group: EntriesState['group'] = {};
const filter: EntriesState['filter'] = {};
for (const collection of config.collections) {
if (collection.sortable_fields && collection.sortable_fields.default) {
const key = collection.sortable_fields.default.field;
sort[collection.name] = {
[key]: {
key,
direction: collection.sortable_fields.default.direction ?? SORT_DIRECTION_ASCENDING,
},
} as SortMap;
}
if (collection.view_filters && collection.view_filters.default) {
const defaultViewFilterName = collection.view_filters.default;
const defaultViewFilter = collection.view_filters.filters.find(
f => f.name === defaultViewFilterName,
);
const collectionFilters: Record<string, FilterMap> = {};
if (defaultViewFilter) {
collectionFilters[defaultViewFilter.id] = {
...defaultViewFilter,
active: true,
};
}
filter[collection.name] = collectionFilters;
}
if (collection.view_groups && collection.view_groups.default) {
const defaultViewGroupName = collection.view_groups.default;
const defaultViewGroup = collection.view_groups.groups.find(
g => g.name === defaultViewGroupName,
);
const collectionGroups: Record<string, GroupMap> = {};
if (defaultViewGroup) {
collectionGroups[defaultViewGroup.id] = {
...defaultViewGroup,
active: true,
};
}
group[collection.name] = collectionGroups;
}
}
return {
...state,
sort,
group,
filter,
};
}
case ENTRY_REQUEST: { case ENTRY_REQUEST: {
const payload = action.payload; const payload = action.payload;

View File

@ -4,7 +4,6 @@ import get from 'lodash/get';
import { SORT_DIRECTION_NONE } from '@staticcms/core/constants'; import { SORT_DIRECTION_NONE } from '@staticcms/core/constants';
import { filterNullish } from '@staticcms/core/lib/util/null.util'; import { filterNullish } from '@staticcms/core/lib/util/null.util';
import type { ViewStyle } from '@staticcms/core/constants/views';
import type { import type {
Entries, Entries,
Entry, Entry,
@ -14,6 +13,7 @@ import type {
SortMap, SortMap,
SortObject, SortObject,
} from '@staticcms/core'; } from '@staticcms/core';
import type { ViewStyle } from '@staticcms/core/constants/views';
import type { RootState } from '@staticcms/core/store'; import type { RootState } from '@staticcms/core/store';
export const selectEntriesFilters = (entries: RootState) => { export const selectEntriesFilters = (entries: RootState) => {

View File

@ -46,6 +46,24 @@ export const createMockFolderCollectionWithDefaults = <EF extends BaseField>(
): FolderCollectionWithDefaults<EF> => ({ ): FolderCollectionWithDefaults<EF> => ({
...createMockFolderCollection(extra, ...fields), ...createMockFolderCollection(extra, ...fields),
i18n: extra.i18n, i18n: extra.i18n,
view_filters: extra.view_filters
? {
...extra.view_filters,
filters: extra.view_filters.filters.map(f => ({
...f,
id: `${f.field}__${f.pattern}`,
})),
}
: undefined,
view_groups: extra.view_groups
? {
...extra.view_groups,
groups: extra.view_groups.groups.map(g => ({
...g,
id: `${g.field}__${g.pattern}`,
})),
}
: undefined,
}); });
export const createMockCollectionFile = <EF extends BaseField>( export const createMockCollectionFile = <EF extends BaseField>(
@ -102,4 +120,22 @@ export const createMockFilesCollectionWithDefaults = <EF extends BaseField>(
...createMockFilesCollection(extra), ...createMockFilesCollection(extra),
i18n: extra.i18n, i18n: extra.i18n,
files: extra.files, files: extra.files,
view_filters: extra.view_filters
? {
...extra.view_filters,
filters: extra.view_filters.filters.map(f => ({
...f,
id: `${f.field}__${f.pattern}`,
})),
}
: undefined,
view_groups: extra.view_groups
? {
...extra.view_groups,
groups: extra.view_groups.groups.map(g => ({
...g,
id: `${g.field}__${g.pattern}`,
})),
}
: undefined,
}); });