Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / packages / pass / store / selectors / shares.ts
blob59471060bb194067a106325357310d6db818a76b
1 import type { Selector } from '@reduxjs/toolkit';
2 import { createSelector } from '@reduxjs/toolkit';
4 import { isActive } from '@proton/pass/lib/items/item.predicates';
5 import { isVaultShare } from '@proton/pass/lib/shares/share.predicates';
6 import {
7     hasNewUserInvitesReady,
8     isOwnVault,
9     isSharedVault,
10     isWritableVault,
11 } from '@proton/pass/lib/vaults/vault.predicates';
12 import type { Maybe, MaybeNull, ShareType } from '@proton/pass/types';
13 import { first } from '@proton/pass/utils/array/first';
14 import { prop } from '@proton/pass/utils/fp/lens';
15 import { and, not } from '@proton/pass/utils/fp/predicates';
16 import { sortOn } from '@proton/pass/utils/fp/sort';
18 import type { ShareItem, VaultShareItem } from '../reducers';
19 import type { State } from '../types';
20 import { SelectorError } from './errors';
21 import { selectAllItems, selectItems } from './items';
23 export const selectShares = ({ shares }: State) => shares;
25 export const selectAllShares = createSelector(selectShares, (shares) => Object.values(shares));
27 /* vaults returned from this selector are always
28  * sorted alphabetically by ascending vault name  */
29 export const selectAllVaults = createSelector([selectAllShares], (shares) =>
30     shares.filter(isVaultShare).sort((a, b) => a.content.name.localeCompare(b.content.name))
33 export const selectWritableVaults = createSelector([selectAllVaults], (vaults) => vaults.filter(isWritableVault));
34 export const selectNonOwnedVaults = createSelector([selectAllVaults], (vaults) => vaults.filter(not(isOwnVault)));
35 export const selectOwnWritableVaults = createSelector([selectAllVaults], (vaults) =>
36     vaults.filter(and(isWritableVault, isOwnVault))
38 export const selectOwnReadOnlyVaults = createSelector([selectAllVaults], (vaults) =>
39     vaults.filter(and(not(isWritableVault), isOwnVault))
42 export const selectWritableSharedVaults = createSelector([selectAllVaults], (vaults) =>
43     vaults.filter(and(isWritableVault, isSharedVault))
46 const createVaultsWithItemsCountSelector = (vaultSelector: Selector<State, VaultShareItem[]>) =>
47     createSelector([vaultSelector, selectItems], (shares, itemsByShareId) =>
48         shares.map((share) => ({
49             ...share,
50             count: Object.values(itemsByShareId?.[share.shareId] ?? {}).filter(isActive).length,
51         }))
52     );
54 export const selectVaultsWithItemsCount = createVaultsWithItemsCountSelector(selectAllVaults);
55 export const selectWritableVaultsWithItemsCount = createVaultsWithItemsCountSelector(selectWritableVaults);
56 export const selectWritableSharedVaultsWithItemsCount = createVaultsWithItemsCountSelector(selectWritableSharedVaults);
58 export const selectShare =
59     <T extends ShareType = ShareType>(shareId?: MaybeNull<string>) =>
60     ({ shares }: State) =>
61         (shareId ? shares?.[shareId] : undefined) as Maybe<ShareItem<T>>;
63 export const selectIsWritableShare =
64     (shareId: string) =>
65     (state: State): boolean => {
66         const share = selectShare(shareId)(state);
67         return Boolean(share && isWritableVault(share));
68     };
70 export const selectShareOrThrow =
71     <T extends ShareType = ShareType>(shareId: string) =>
72     (state: State): ShareItem<T> => {
73         const share = selectShare<T>(shareId)(state);
74         if (!share) throw new SelectorError(`Share ${shareId} not found`);
76         return share;
77     };
79 export const selectVaultItemsCount = (shareId: MaybeNull<string>) =>
80     createSelector(
81         selectShare<ShareType.Vault>(shareId),
82         selectItems,
83         (share, itemsByShareId): MaybeNull<number> =>
84             share ? Object.values(itemsByShareId?.[share?.shareId] ?? {}).filter(isActive).length : null
85     );
87 export const selectVaultSharedWithEmails = (shareId: string) =>
88     createSelector(
89         selectShare<ShareType.Vault>(shareId),
90         (vault): Set<string> =>
91             new Set(
92                 (vault?.members?.map(prop('email')) ?? [])
93                     .concat(vault?.invites?.map(prop('invitedEmail')) ?? [])
94                     .concat(vault?.newUserInvites?.map(prop('invitedEmail')) ?? [])
95             )
96     );
98 /* The default vault should be the oldest vault I own and can write to */
99 export const selectDefaultVault = createSelector(
100     selectOwnWritableVaults,
101     (ownWritableVaults): Maybe<VaultShareItem> => first(ownWritableVaults.sort(sortOn('createTime', 'ASC')))
104 /** Resolves the most recently used vault:
105  * - Returns shareId of the latest item in user's writable vaults, sorted by creation time
106  * - Falls back to user's default vault shareId if no writable items found */
107 export const selectMostRecentVaultShareID = createSelector(
108     [selectOwnWritableVaults, selectAllItems, selectDefaultVault],
109     (vaults, items, defaultVault): Maybe<string> => {
110         const shareIds = new Set(vaults.map(prop('shareId')));
111         return (
112             items.filter((item) => shareIds.has(item.shareId)).sort(sortOn('createTime'))?.[0]?.shareId ??
113             defaultVault?.shareId
114         );
115     }
118 export const selectVaultsWithNewUserInvites = createSelector([selectOwnWritableVaults], (vaults) =>
119     vaults.filter(hasNewUserInvitesReady)