Skip to content

Commit

Permalink
Fix select content (#2342)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fosol authored Nov 22, 2024
1 parent f4ac25c commit 1f1e680
Show file tree
Hide file tree
Showing 13 changed files with 101 additions and 21 deletions.
7 changes: 2 additions & 5 deletions app/subscriber/src/components/content-list/ContentList.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { AxiosError } from 'axios';
import { castToSearchResult } from 'features/utils';
import { IContentSearchResult } from 'features/utils/interfaces';
import _ from 'lodash';
import React from 'react';
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
import { useNavigate } from 'react-router-dom';
Expand Down Expand Up @@ -135,11 +134,9 @@ export const ContentList: React.FC<IContentListProps> = ({
array = [];
}
if (array.length !== selected?.length) {
array = _.uniq([...array, ...selected.map((i) => i.id)]);
localStorage.setItem('selected', JSON.stringify(array));
} else if (!existing) {
localStorage.setItem('selected', JSON.stringify(array));
array = selected.map((i) => i.id);
}
localStorage.setItem('selected', JSON.stringify(array));
// only want to fire when selected changes
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selected]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const ContentActionBar: React.FC<IContentActionBarProps> = ({
</Show>
{showActionsItems && (
<div className="content-buttons">
<Row>
<Row flex="1">
{onReset && <ResetFilters onReset={onReset} />}
<ShareMenu content={content} />
{disableAddToFolder ? null : <AddToFolderMenu onClear={onClear} content={content} />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,17 @@ export const ContentActionBar = styled(Row)<{ viewingContent?: boolean }>`
}
.content-buttons {
flex: 1;
color: ${(props) => props.theme.css.btnBkPrimary};
width: ${(props) => (props.viewingContent ? '100%' : 'auto')};
animation: fade-in 0.5s linear;
margin-right: 1rem;
@media (max-width: 768px) {
span {
display: none;
}
}
animation: fade-in 0.5s linear;
}
.editor-button {
margin-left: auto;
Expand Down
6 changes: 5 additions & 1 deletion app/subscriber/src/features/manage-folder/ManageFolder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,11 @@ export const ManageFolder: React.FC = () => {
<div className="main-manage">
<ContentListActionBar
content={selected}
onSelectAll={(e) => (e.target.checked ? setSelected(items) : setSelected([]))}
onSelectAll={(e) => {
const values = items.map((c) => c.id);
const oldSelected = selected.filter((s) => !values.includes(s.id));
e.target.checked ? setSelected([...selected, ...items]) : setSelected(oldSelected);
}}
onClear={() => setSelected([])}
removeFolderItem={() => removeItems(selected)}
disableAddToFolder={true}
Expand Down
6 changes: 5 additions & 1 deletion app/subscriber/src/features/my-minister/MyMinister.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,11 @@ export const MyMinister: React.FC = () => {
<ContentListActionBar
content={selected}
onClear={() => setSelected([])}
onSelectAll={(e) => (e.target.checked ? setSelected(content) : setSelected([]))}
onSelectAll={(e) => {
const values = content.map((c) => c.id);
const oldSelected = selected.filter((s) => !values.includes(s.id));
e.target.checked ? setSelected([...selected, ...content]) : setSelected(oldSelected);
}}
/>
<DateFilter
date={filter.startDate}
Expand Down
6 changes: 5 additions & 1 deletion app/subscriber/src/features/press-gallery/PressGallery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,11 @@ export const PressGallery: React.FC = () => {
<ContentListActionBar
content={selected}
onClear={() => setSelected([])}
onSelectAll={(e) => (e.target.checked ? setSelected(content) : setSelected([]))}
onSelectAll={(e) => {
const values = content.map((c) => c.id);
const oldSelected = selected.filter((s) => !values.includes(s.id));
e.target.checked ? setSelected([...selected, ...content]) : setSelected(oldSelected);
}}
/>
<Row className="tool-bar">
<Select
Expand Down
54 changes: 44 additions & 10 deletions app/subscriber/src/features/search-page/SearchPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { castToSearchResult } from 'features/utils';
import { IContentSearchResult } from 'features/utils/interfaces';
import moment, { Moment } from 'moment';
import React from 'react';
import { FaBookmark } from 'react-icons/fa6';
import { FaBookmark, FaCaretLeft, FaCaretRight } from 'react-icons/fa6';
import { useLocation, useParams } from 'react-router-dom';
import { toast } from 'react-toastify';
import { useApp, useContent, useFilters, useLookup } from 'store/hooks';
Expand Down Expand Up @@ -50,15 +50,14 @@ export const SearchPage: React.FC<ISearchType> = ({ showAdvanced, showDate: init
const { width } = useWindowSize();
const genQuery = useElastic();
const [, { getFilter }] = useFilters();
const [{ filter: activeFilter }, { storeFilter }] = useProfileStore();
const [{ from, filter: activeFilter }, { storeFrom, storeFilter }] = useProfileStore();
const { pathname } = useLocation();
const [{ requests }] = useApp();

const [init, setInit] = React.useState(true); // React hooks are horrible...
const [currDateResults, setCurrDateResults] = React.useState<IContentSearchResult[]>([]);
const [prevDateResults, setPrevDateResults] = React.useState<IContentSearchResult[]>([]);
const [selected, setSelected] = React.useState<IContentModel[]>([]);
const [totalResults, setTotalResults] = React.useState(0);
const { expanded } = useSearchPageContext();
const [startDate, setStartDate] = React.useState<Moment>(moment());
const [filterId, setFilterId] = React.useState(0);
Expand Down Expand Up @@ -106,7 +105,6 @@ export const SearchPage: React.FC<ISearchType> = ({ showAdvanced, showDate: init
});
setCurrDateResults(currDateResults);
setPrevDateResults(prevDateResults);
setTotalResults(currDateResults.length);
if (!groupStoredContent) {
if (
(typeof res.hits.total === 'number' && res.hits.total === 0) ||
Expand Down Expand Up @@ -203,6 +201,7 @@ export const SearchPage: React.FC<ISearchType> = ({ showAdvanced, showDate: init
let res;
let groupStoredContent = false;
if (!storedContent) {
storeFrom(query.from ?? 0);
res = await findContentWithElasticsearch(query, filter.searchUnpublished, 'search');
} else {
res = storedContent;
Expand Down Expand Up @@ -268,18 +267,53 @@ export const SearchPage: React.FC<ISearchType> = ({ showAdvanced, showDate: init
<FilterOptions filterStoreName={'searchResults'} />
<ViewOptions />
</Row>
{!!totalResults && (
<p className="result-total">{`${totalResults} stories found`}</p>
)}
<Row gap="1rem" className="search-results">
{!!currDateResults.length && (
<p className="result-total">{`${currDateResults.length} stories found`}</p>
)}
<Row className="search-results-paging">
{!!from && (
<FaCaretLeft
className="btn"
title="Previous Page"
onClick={() => {
const position = from ? from - filter.size : 0;
const newFilter = {
...filter,
from: position > 0 ? position : undefined,
};
fetchResults(newFilter);
}}
/>
)}
p.
{from >= filter.size ? Math.floor(from / filter.size) + 1 : 1}
{filter.size === currDateResults.length && (
<FaCaretRight
className="btn"
title="Next Page"
onClick={() => {
const position = from + filter.size;
const newFilter = { ...filter, from: position };
fetchResults(newFilter);
}}
/>
)}
</Row>
</Row>
</Col>
}
>
<ContentListActionBar
content={selected}
onClear={() => setSelected([])}
onSelectAll={(e) =>
e.target.checked ? setSelected(currDateResults) : setSelected([])
}
onSelectAll={(e) => {
const values = currDateResults.map((c) => c.id);
const oldSelected = selected.filter((s) => !values.includes(s.id));
e.target.checked
? setSelected([...selected, ...currDateResults])
: setSelected(oldSelected);
}}
className="search"
/>
<Show visible={dateVisible}>
Expand Down
18 changes: 18 additions & 0 deletions app/subscriber/src/features/search-page/styled/SearchPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,24 @@ export const SearchPage = styled.div<{ expanded: boolean }>`
.header-col {
width: 100%;
.search-results {
gap: 1rem;
align-items: center;
.search-results-paging {
font-size: 1rem;
color: ${(props) => props.theme.css.fPrimaryColor};
align-items: center;
svg.btn {
color: ${(props) => props.theme.css.iconPrimaryColor};
width: 16px;
height: 16px;
cursor: pointer;
}
}
}
}
.header-row {
width: 100%;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export const filterFormat = (filter: IFilterSettingsModel) => {
dateOffset: filter.dateOffset,
edition: filter.edition ?? '',
featured: filter.featured ?? false,
from: 0,
inByline: filter.inByline ?? false,
inHeadline: filter.inHeadline ?? false,
inProgram: filter.inProgram ?? false,
Expand All @@ -24,6 +23,7 @@ export const filterFormat = (filter: IFilterSettingsModel) => {
section: filter.section ?? '',
sentiment: filter.sentiment ?? [],
seriesIds: filter.seriesIds ?? [],
from: filter.from,
size: filter.size,
sourceIds: filter.sourceIds ?? [],
startDate: !!filter.startDate ? filter.startDate : undefined,
Expand Down
1 change: 1 addition & 0 deletions app/subscriber/src/features/top-stories/TopStories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export const TopStories: React.FC = () => {
const handleSelectAll = React.useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const dateKey = filter.startDate || moment().startOf('day').toISOString();

setStateByDate((prevState) => ({
...prevState,
[dateKey]: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
export interface IProfileState {
impersonate?: ISubscriberUserModel;
profile?: ISubscriberUserModel;
/** Paging position for filter. */
from: number;
filter?: IFilterModel;
myFilters: IFilterModel[];
myFolders: IFolderModel[];
Expand Down
5 changes: 5 additions & 0 deletions app/subscriber/src/store/slices/profile/profileSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { IProfileState } from './interfaces';

export const initialProfileState: IProfileState = {
from: 0,
contributors: [],
myFilters: [],
myFolders: [],
Expand Down Expand Up @@ -45,6 +46,9 @@ export const profileSlice = createSlice({
) {
state.impersonate = action.payload;
},
storeFrom(state: IProfileState, action: PayloadAction<number>) {
state.from = action.payload;
},
storeFilter(state: IProfileState, action: PayloadAction<IFilterModel | undefined>) {
state.filter = action.payload;
},
Expand Down Expand Up @@ -92,6 +96,7 @@ export const profileSlice = createSlice({
export const {
storeMyProfile,
storeImpersonate,
storeFrom,
storeFilter,
storeMyFilters,
storeMyFolders,
Expand Down
8 changes: 8 additions & 0 deletions app/subscriber/src/store/slices/profile/useProfileStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { storeContributors } from '../lookup';
import {
storeFilter,
storeFrom,
storeImpersonate,
storeMyColleagues,
storeMyFilters,
Expand All @@ -39,6 +40,7 @@ export interface IProfileStore {
storeContributors: (
contributors: IContributorModel[] | ActionDelegate<IContributorModel[]>,
) => void;
storeFrom: (from: number | ActionDelegate<number>) => void;
storeFilter: (filter: IFilterModel | ActionDelegate<IFilterModel | undefined>) => void;
storeMyFilters: (filters: IFilterModel[] | ActionDelegate<IFilterModel[]>) => void;
storeMyFolders: (folders: IFolderModel[] | ActionDelegate<IFolderModel[]>) => void;
Expand Down Expand Up @@ -79,6 +81,11 @@ export const useProfileStore = (): [IProfileState, IProfileStore] => {
dispatch(storeImpersonate(user(state.impersonate)));
} else dispatch(storeImpersonate(user));
},
storeFrom: (from: number | ActionDelegate<number>) => {
if (typeof from === 'function') {
dispatch(storeFrom(from(state.from)));
} else dispatch(storeFrom(from));
},
storeFilter: (filter: IFilterModel | ActionDelegate<IFilterModel | undefined>) => {
if (typeof filter === 'function') {
dispatch(storeFilter(filter(state.filter)));
Expand Down Expand Up @@ -156,6 +163,7 @@ export const useProfileStore = (): [IProfileState, IProfileStore] => {
dispatch,
state.profile,
state.impersonate,
state.from,
state.filter,
state.myFilters,
state.myFolders,
Expand Down

0 comments on commit 1f1e680

Please sign in to comment.