From 542ba9ab7828909b8f9ab61bf501b060ea93c95d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Wed, 6 Nov 2024 13:06:41 +0100 Subject: [PATCH] pl-fe: backups, polls reducers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-api/lib/client.ts | 2 - packages/pl-fe/src/actions/backups.ts | 52 ++++++++++++++++--- packages/pl-fe/src/actions/notifications.ts | 1 - packages/pl-fe/src/actions/statuses.ts | 4 +- packages/pl-fe/src/components/polls/poll.tsx | 2 +- packages/pl-fe/src/features/backups/index.tsx | 8 +-- packages/pl-fe/src/reducers/backups.ts | 19 +++---- packages/pl-fe/src/reducers/polls.ts | 15 ++---- packages/pl-fe/src/selectors/index.ts | 2 +- 9 files changed, 64 insertions(+), 41 deletions(-) diff --git a/packages/pl-api/lib/client.ts b/packages/pl-api/lib/client.ts index 03c636356..76f30aa99 100644 --- a/packages/pl-api/lib/client.ts +++ b/packages/pl-api/lib/client.ts @@ -2765,8 +2765,6 @@ class PlApiClient { return response.json as {}; }, - - }; /** diff --git a/packages/pl-fe/src/actions/backups.ts b/packages/pl-fe/src/actions/backups.ts index 4a3d85994..68e4f6dde 100644 --- a/packages/pl-fe/src/actions/backups.ts +++ b/packages/pl-fe/src/actions/backups.ts @@ -1,5 +1,6 @@ import { getClient } from '../api'; +import type { Backup } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; const BACKUPS_FETCH_REQUEST = 'BACKUPS_FETCH_REQUEST' as const; @@ -10,27 +11,63 @@ const BACKUPS_CREATE_REQUEST = 'BACKUPS_CREATE_REQUEST' as const; const BACKUPS_CREATE_SUCCESS = 'BACKUPS_CREATE_SUCCESS' as const; const BACKUPS_CREATE_FAIL = 'BACKUPS_CREATE_FAIL' as const; +interface BackupsFetchRequestAction { + type: typeof BACKUPS_FETCH_REQUEST; +} + +interface BackupsFetchSuccessAction { + type: typeof BACKUPS_FETCH_SUCCESS; + backups: Array; +} + +interface BackupsFetchFailAction { + type: typeof BACKUPS_FETCH_FAIL; + error: unknown; +} + const fetchBackups = () => (dispatch: AppDispatch, getState: () => RootState) => { - dispatch({ type: BACKUPS_FETCH_REQUEST }); + dispatch({ type: BACKUPS_FETCH_REQUEST }); return getClient(getState).settings.getBackups().then((backups) => - dispatch({ type: BACKUPS_FETCH_SUCCESS, backups }), + dispatch({ type: BACKUPS_FETCH_SUCCESS, backups }), ).catch(error => { - dispatch({ type: BACKUPS_FETCH_FAIL, error }); + dispatch({ type: BACKUPS_FETCH_FAIL, error }); }); }; + interface BackupsCreateRequestAction { + type: typeof BACKUPS_CREATE_REQUEST; + } + + interface BackupsCreateSuccessAction { + type: typeof BACKUPS_CREATE_SUCCESS; + backups: Array; + } + + interface BackupsCreateFailAction { + type: typeof BACKUPS_CREATE_FAIL; + error: unknown; + } + const createBackup = () => (dispatch: AppDispatch, getState: () => RootState) => { - dispatch({ type: BACKUPS_CREATE_REQUEST }); - return getClient(getState).settings.createBackup().then((backups) => - dispatch({ type: BACKUPS_CREATE_SUCCESS, backups }), + dispatch({ type: BACKUPS_CREATE_REQUEST }); + return getClient(getState).settings.createBackup().then((backup) => + dispatch({ type: BACKUPS_CREATE_SUCCESS, backups: [backup] }), ).catch(error => { - dispatch({ type: BACKUPS_CREATE_FAIL, error }); + dispatch({ type: BACKUPS_CREATE_FAIL, error }); }); }; +type BackupsAction = + | BackupsFetchRequestAction + | BackupsFetchSuccessAction + | BackupsFetchFailAction + | BackupsCreateRequestAction + | BackupsCreateSuccessAction + | BackupsCreateFailAction; + export { BACKUPS_FETCH_REQUEST, BACKUPS_FETCH_SUCCESS, @@ -40,4 +77,5 @@ export { BACKUPS_CREATE_FAIL, fetchBackups, createBackup, + type BackupsAction, }; diff --git a/packages/pl-fe/src/actions/notifications.ts b/packages/pl-fe/src/actions/notifications.ts index fa2250c36..c03e37e97 100644 --- a/packages/pl-fe/src/actions/notifications.ts +++ b/packages/pl-fe/src/actions/notifications.ts @@ -76,7 +76,6 @@ const updateNotifications = (notification: BaseNotification) => statuses: [getNotificationStatus(notification)], })); - if (showInColumn) { const normalizedNotification = normalizeNotification(notification); diff --git a/packages/pl-fe/src/actions/statuses.ts b/packages/pl-fe/src/actions/statuses.ts index 3c12145a0..e90b572a5 100644 --- a/packages/pl-fe/src/actions/statuses.ts +++ b/packages/pl-fe/src/actions/statuses.ts @@ -97,7 +97,7 @@ const editStatus = (statusId: string) => (dispatch: AppDispatch, getState: () => const state = getState(); const status = state.statuses[statusId]!; - const poll = status.poll_id ? state.polls.get(status.poll_id) : undefined; + const poll = status.poll_id ? state.polls[status.poll_id] : undefined; dispatch({ type: STATUS_FETCH_SOURCE_REQUEST }); @@ -134,7 +134,7 @@ const deleteStatus = (statusId: string, withRedraft = false) => const state = getState(); const status = state.statuses[statusId]!; - const poll = status.poll_id ? state.polls.get(status.poll_id) : undefined; + const poll = status.poll_id ? state.polls[status.poll_id] : undefined; dispatch({ type: STATUS_DELETE_REQUEST, params: status }); diff --git a/packages/pl-fe/src/components/polls/poll.tsx b/packages/pl-fe/src/components/polls/poll.tsx index efe4fdff0..72aab6c93 100644 --- a/packages/pl-fe/src/components/polls/poll.tsx +++ b/packages/pl-fe/src/components/polls/poll.tsx @@ -30,7 +30,7 @@ const Poll: React.FC = ({ id, status }): JSX.Element | null => { const intl = useIntl(); const isLoggedIn = useAppSelector((state) => state.me); - const poll = useAppSelector((state) => state.polls.get(id)); + const poll = useAppSelector((state) => state.polls[id]); const [selected, setSelected] = useState({} as Selected); diff --git a/packages/pl-fe/src/features/backups/index.tsx b/packages/pl-fe/src/features/backups/index.tsx index 952ffe0b1..d64858534 100644 --- a/packages/pl-fe/src/features/backups/index.tsx +++ b/packages/pl-fe/src/features/backups/index.tsx @@ -65,7 +65,7 @@ const Backups = () => { const intl = useIntl(); const dispatch = useAppDispatch(); - const backups = useAppSelector((state) => state.backups.toList().sortBy((backup) => backup.inserted_at)); + const backups = useAppSelector((state) => Object.values(state.backups).toSorted((a, b) => a.inserted_at.localeCompare(b.inserted_at))); const [isLoading, setIsLoading] = useState(true); @@ -80,7 +80,7 @@ const Backups = () => { }).catch(() => {}); }, []); - const showLoading = isLoading && backups.count() === 0; + const showLoading = isLoading && backups.length === 0; const emptyMessage = ( @@ -96,11 +96,11 @@ const Backups = () => { ); - const body = showLoading ? : backups.isEmpty() ? emptyMessage : ( + const body = showLoading ? : backups.length ? (
{backups.map((backup) => )}
- ); + ) : emptyMessage; return ( diff --git a/packages/pl-fe/src/reducers/backups.ts b/packages/pl-fe/src/reducers/backups.ts index 4279b9ff7..1aff50580 100644 --- a/packages/pl-fe/src/reducers/backups.ts +++ b/packages/pl-fe/src/reducers/backups.ts @@ -1,25 +1,18 @@ -import { Map as ImmutableMap } from 'immutable'; +import { create } from 'mutative'; -import { BACKUPS_FETCH_SUCCESS, BACKUPS_CREATE_SUCCESS } from '../actions/backups'; +import { BACKUPS_FETCH_SUCCESS, BACKUPS_CREATE_SUCCESS, type BackupsAction } from '../actions/backups'; import type { Backup } from 'pl-api'; -import type { AnyAction } from 'redux'; -type State = ImmutableMap; +type State = Record; -const initialState: State = ImmutableMap(); +const initialState: State = {}; -const importBackup = (state: State, backup: Backup) => state.set(backup.inserted_at, backup); - -const importBackups = (state: State, backups: Array) => state.withMutations(mutable => { - backups.forEach(backup => importBackup(mutable, backup)); -}); - -const backups = (state = initialState, action: AnyAction) => { +const backups = (state = initialState, action: BackupsAction) => { switch (action.type) { case BACKUPS_FETCH_SUCCESS: case BACKUPS_CREATE_SUCCESS: - return importBackups(state, action.backups); + return create(state, (draft) => action.backups.forEach((backup) => draft[backup.inserted_at] = backup)); default: return state; } diff --git a/packages/pl-fe/src/reducers/polls.ts b/packages/pl-fe/src/reducers/polls.ts index 3ad2489a9..f5557958d 100644 --- a/packages/pl-fe/src/reducers/polls.ts +++ b/packages/pl-fe/src/reducers/polls.ts @@ -1,22 +1,17 @@ -import { Map as ImmutableMap } from 'immutable'; +import { create } from 'mutative'; import { POLLS_IMPORT, type ImporterAction } from 'pl-fe/actions/importer'; -import type { Poll, Status } from 'pl-api'; +import type { Poll } from 'pl-api'; -type State = ImmutableMap; +type State = Record; -const importPolls = (state: State, polls: Array>) => - state.withMutations(map => - polls.forEach(poll => map.set(poll.id, poll)), - ); - -const initialState: State = ImmutableMap(); +const initialState: State = {}; const polls = (state: State = initialState, action: ImporterAction): State => { switch (action.type) { case POLLS_IMPORT: - return importPolls(state, action.polls); + return create(state, (draft) => action.polls.forEach(poll => draft[poll.id] = poll)); default: return state; } diff --git a/packages/pl-fe/src/selectors/index.ts b/packages/pl-fe/src/selectors/index.ts index e6c729dd0..cdbce3e65 100644 --- a/packages/pl-fe/src/selectors/index.ts +++ b/packages/pl-fe/src/selectors/index.ts @@ -135,7 +135,7 @@ const makeGetStatus = () => createSelector( if (group) return state.entities[Entities.GROUPS]?.store[group] as Group; return undefined; }, - (state: RootState, { id }: APIStatus) => state.polls.get(id) || null, + (state: RootState, { id }: APIStatus) => state.polls[id] || null, (_state: RootState, { username }: APIStatus) => username, getFilters, (state: RootState) => state.me,