Remove client-side isLoggedIn value
[ProtonMail-WebClient.git] / packages / mail / labels / index.ts
blobdcb5f082a9d9f909b62aef4730459fd80a666284
1 import { createSlice } from '@reduxjs/toolkit';
3 import { type ModelState, getInitialModelState, serverEvent } from '@proton/account';
4 import type { ProtonThunkArguments } from '@proton/redux-shared-store-types';
5 import { createAsyncModelThunk, handleAsyncModel, previousSelector } from '@proton/redux-utilities';
6 import { getContactGroup, getFolders, getLabels, getSystemFolders } from '@proton/shared/lib/api/labels';
7 import updateCollection, { sortCollection } from '@proton/shared/lib/helpers/updateCollection';
8 import type { Api, Category } from '@proton/shared/lib/interfaces';
10 const name = 'categories' as const;
12 const extractLabels = ({ Labels = [] }) => Labels;
14 const getLabelsModel = async (api: Api) => {
15     const [labels = [], folders = [], contactGroups = [], systemFolders = []] = await Promise.all([
16         api(getLabels()).then(extractLabels),
17         api(getFolders()).then(extractLabels),
18         api(getContactGroup()).then(extractLabels),
19         api(getSystemFolders()).then(extractLabels),
20     ]);
21     return sortCollection('Order', [...labels, ...folders, ...contactGroups, ...systemFolders]);
24 export interface CategoriesState {
25     [name]: ModelState<Category[]>;
28 type SliceState = CategoriesState[typeof name];
29 type Model = NonNullable<SliceState['value']>;
31 export const selectCategories = (state: CategoriesState) => state[name];
33 const modelThunk = createAsyncModelThunk<Model, CategoriesState, ProtonThunkArguments>(`${name}/fetch`, {
34     miss: async ({ extraArgument }) => {
35         return getLabelsModel(extraArgument.api);
36     },
37     previous: previousSelector(selectCategories),
38 });
40 const initialState = getInitialModelState<Model>();
41 const slice = createSlice({
42     name,
43     initialState,
44     reducers: {},
45     extraReducers: (builder) => {
46         handleAsyncModel(builder, modelThunk);
47         builder.addCase(serverEvent, (state, action) => {
48             if (state.value && action.payload.Labels) {
49                 state.value = sortCollection(
50                     'Order',
51                     updateCollection({
52                         model: state.value,
53                         events: action.payload.Labels,
54                         itemKey: 'Label',
55                         // Event updates don't return e.g. ParentID so it's better that the old value gets completely dropped instead of merged
56                         merge: (_, b) => b as Category,
57                     })
58                 );
59             }
60         });
61     },
62 });
64 export const categoriesReducer = { [name]: slice.reducer };
65 export const categoriesThunk = modelThunk.thunk;