recoil#selectorFamily TypeScript Examples

The following examples show how to use recoil#selectorFamily. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: groups.ts    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
groupMemberIDsToUsername = selectorFamily<{ [k: number]: string }, number>({
    key: "groupMemberIDsToUsername",
    get:
        (groupID) =>
        async ({ get }) => {
            const members = get(groupMembers(groupID));
            return members.reduce((map, member) => {
                map[member.user_id] = member.username;
                return map;
            }, {});
        },
})
Example #2
Source File: selectors.ts    From phosphor-home with MIT License 6 votes vote down vote up
singleCategoryQueryResultsSelector = selectorFamily<
  ReadonlyArray<IconEntry>,
  IconCategory
>({
  key: "singleCategoryQueryResultsSelector",
  get:
    (category: IconCategory) =>
    ({ get }) => {
      const filteredResults = get(filteredQueryResultsSelector);
      return new Promise((resolve) =>
        resolve(
          filteredResults.filter((icon) => icon.categories.includes(category))
        )
      );
    },
})
Example #3
Source File: results.state.ts    From nextclade with MIT License 6 votes vote down vote up
sortAnalysisResultsByKeyAtom = selectorFamily<undefined, { key: string; direction: SortDirection }>({
  key: 'sortAnalysisResultsByKey',

  get: () => () => undefined,

  set:
    ({ key, direction }) =>
    ({ get, set }, def: undefined | DefaultValue) => {
      const results = get(analysisResultsAtom)

      const resultsSorted = isDefaultValue(def)
        ? sortResults(results, { category: SortCategory.index, direction })
        : sortResultsByKey(results, { key, direction })

      const seqNamesSorted = resultsSorted.map((result) => result.seqName)
      set(seqNamesAtom, seqNamesSorted)
    },
})
Example #4
Source File: results.state.ts    From nextclade with MIT License 6 votes vote down vote up
sortAnalysisResultsAtom = selectorFamily<undefined, { category: SortCategory; direction: SortDirection }>({
  key: 'sortAnalysisResults',

  get: () => () => undefined,

  set:
    ({ category, direction }) =>
    ({ get, set }, def: undefined | DefaultValue) => {
      const results = get(analysisResultsAtom)

      let sortCategory = category
      if (isDefaultValue(def)) {
        sortCategory = SortCategory.index
      }

      const resultsSorted = sortResults(results, { category: sortCategory, direction })
      const seqNamesSorted = resultsSorted.map((result) => result.seqName)

      set(seqNamesAtom, seqNamesSorted)
    },
})
Example #5
Source File: results.state.ts    From nextclade with MIT License 6 votes vote down vote up
analysisResultAtom = selectorFamily<NextcladeResult, string>({
  key: 'analysisResult',

  get:
    (seqName: string) =>
    ({ get }): NextcladeResult => {
      return get(analysisResultInternalAtom(seqName))
    },

  set:
    (seqName) =>
    ({ set, reset }, result: NextcladeResult | DefaultValue) => {
      if (isDefaultValue(result)) {
        reset(analysisResultInternalAtom(seqName))
        reset(seqNamesAtom)
      } else {
        set(analysisResultInternalAtom(seqName), result)
        set(seqNamesAtom, (prev) => {
          if (result && !prev.includes(result.seqName)) {
            return [...prev, result.seqName]
          }
          return prev
        })
      }
    },
})
Example #6
Source File: transactions.ts    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
accountTransactions = selectorFamily<Array<Transaction>, ParamGroupAccount>({
    key: "accountTransactions",
    get:
        ({ groupID, accountID }) =>
        async ({ get }) => {
            return get(transactionsSeenByUser(groupID)).filter((transaction) =>
                transaction.account_balances.hasOwnProperty(accountID)
            );
        },
})
Example #7
Source File: transactions.ts    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
transactionById = selectorFamily<Transaction | undefined, ParamGroupTransaction>({
    key: "transactionById",
    get:
        ({ groupID, transactionID }) =>
        async ({ get }) => {
            const transactions = get(transactionsSeenByUser(groupID));
            return transactions?.find((transaction) => transaction.id === transactionID);
        },
})
Example #8
Source File: transactions.ts    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
transactionByIDMap = selectorFamily<{ [k: number]: Transaction }, number>({
    key: "transactionByIDMap",
    get:
        (groupID) =>
        async ({ get }) => {
            const transactions = get(transactionsSeenByUser(groupID));
            return transactions.reduce((map, curr) => {
                map[curr.id] = curr;
                return map;
            }, {});
        },
})
Example #9
Source File: transactions.ts    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
transactionsSeenByUser = selectorFamily<Array<Transaction>, number>({
    key: "transactionsSeenByUser",
    get:
        (groupID) =>
        async ({ get }) => {
            const transactions = get(groupTransactions(groupID));

            return transactions
                .filter((transaction) => {
                    return !(transaction.committed_details && transaction.committed_details.deleted);
                })
                .map((transaction) => {
                    const localDetailChanges = get(pendingTransactionDetailChanges(transaction.id));
                    const localPositionChanges = get(pendingTransactionPositionChanges(transaction.id));
                    return Transaction.fromBackendFormat(transaction, localDetailChanges, localPositionChanges);
                })
                .sort(transactionCompareFn);
        },
})
Example #10
Source File: mod-dependencies-state.ts    From ow-mod-manager with MIT License 6 votes vote down vote up
missingDependencyIdsState = selectorFamily({
  key: 'MissingDependencyIds',
  get: (mod: Mod) => ({ get }) => {
    // TODO isEnabled as family too?
    if (!mod.isEnabled) {
      return [];
    }
    const missingDependencies = [];
    for (let i = 0; i < mod.dependencies.length; i += 1) {
      const dependencyUniqueName = mod.dependencies[i];
      const dependency = get(localModMap)[dependencyUniqueName];
      if (!dependency?.isEnabled) {
        missingDependencies.push(dependency?.name ?? dependencyUniqueName);
      }
    }
    return missingDependencies;
  },
})
Example #11
Source File: groups.ts    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
currUserPermissions = selectorFamily<GroupMember, number>({
    key: "currUserPermissions",
    get:
        (groupID) =>
        async ({ get }) => {
            const members = get(groupMembers(groupID));
            const currUser = get(userData);
            return members.find((member) => member.user_id === currUser.id);
        },
})
Example #12
Source File: groups.ts    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
groupById = atomFamily({
    key: "groupById",
    default: selectorFamily({
        key: "groupById/default",
        get:
            (groupID) =>
            async ({ get }) => {
                const groups = get(groupList);
                return groups.find((group) => group.id === groupID);
            },
    }),
})
Example #13
Source File: accounts.ts    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
accountsOwnedByUser = selectorFamily<Array<AccountConsolidated>, ParamGroupUser>({
    key: "groupAccountByID",
    get:
        ({ groupID, userID }) =>
        async ({ get }) => {
            const accounts = get(accountsSeenByUser(groupID));
            return accounts.filter((account) => account.owning_user_id === userID);
        },
})
Example #14
Source File: accounts.ts    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
groupAccountByID = selectorFamily<AccountConsolidated | undefined, ParamGroupAccount>({
    key: "groupAccountByID",
    get:
        ({ groupID, accountID }) =>
        async ({ get }) => {
            const accounts = get(accountsSeenByUser(groupID));
            return accounts?.find((account) => account.id === accountID);
        },
})
Example #15
Source File: accounts.ts    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
clearingAccountsInvolvingUser = selectorFamily<Array<AccountConsolidated>, ParamGroupAccount>({
    key: "clearingAccountsInvolvingUser",
    get:
        ({ groupID, accountID }) =>
        async ({ get }) => {
            return get(clearingAccountsSeenByUser(groupID)).filter((account) =>
                account.clearing_shares.hasOwnProperty(accountID)
            );
        },
})
Example #16
Source File: accounts.ts    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
clearingAccountsSeenByUser = selectorFamily<Array<AccountConsolidated>, number>({
    key: "clearingAccountsSeenByUser",
    get:
        (groupID) =>
        async ({ get }) => {
            const accounts = get(accountsSeenByUser(groupID));
            return accounts.filter((account) => account.type === "clearing");
        },
})
Example #17
Source File: accounts.ts    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
personalAccountsSeenByUser = selectorFamily<Array<AccountConsolidated>, number>({
    key: "personalAccountsSeenByUser",
    get:
        (groupID) =>
        async ({ get }) => {
            const accounts = get(accountsSeenByUser(groupID));
            return accounts.filter((account) => account.type === "personal");
        },
})
Example #18
Source File: accounts.ts    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
accountIDsToName = selectorFamily<{ [k: number]: string }, number>({
    key: "accountIDsToName",
    get:
        (groupID) =>
        async ({ get }) => {
            const accounts = get(accountsSeenByUser(groupID));
            return accounts.reduce((map, acc) => {
                map[acc.id] = acc.name;
                return map;
            }, {});
        },
})
Example #19
Source File: accounts.ts    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
accountByIDMap = selectorFamily<{ [k: number]: AccountConsolidated }, number>({
    key: "accountByIDMap",
    get:
        (groupID) =>
        async ({ get }) => {
            const accounts = get(accountsSeenByUser(groupID));
            return accounts.reduce((map, curr) => {
                map[curr.id] = curr;
                return map;
            }, {});
        },
})
Example #20
Source File: transactions.ts    From abrechnung with GNU Affero General Public License v3.0 5 votes vote down vote up
accountBalanceHistory = selectorFamily<Array<BalanceHistoryEntry>, ParamGroupAccount>({
    key: "accountBalanceHistory",
    get:
        ({ groupID, accountID }) =>
        async ({ get }) => {
            const balances = get(accountBalances(groupID));
            const accounts = get(accountsSeenByUser(groupID));
            const clearingAccounts = accounts.filter((a) => a.type === "clearing");
            const unsortedTransactions = get(accountTransactions({ groupID: groupID, accountID: accountID }));
            const transactions = [...unsortedTransactions].sort(transactionCompareFn);

            if (transactions.length === 0) {
                return [];
            }

            let balanceChanges = [];
            for (const transaction of transactions) {
                const a = transaction.account_balances[accountID];
                balanceChanges.push({
                    date: transaction.last_changed.toSeconds(),
                    change: a.total,
                    changeOrigin: {
                        type: "transaction",
                        id: transaction.id,
                    },
                });
            }

            for (const account of clearingAccounts) {
                if (balances[account.id].clearingResolution.hasOwnProperty(accountID)) {
                    balanceChanges.push({
                        date: account.last_changed.toSeconds(),
                        change: balances[account.id].clearingResolution[accountID],
                        changeOrigin: {
                            type: "clearing",
                            id: account.id,
                        },
                    });
                }
            }
            balanceChanges.sort((a1, a2) => a1.date - a2.date);

            let accumulatedBalanceChanges: Array<BalanceHistoryEntry> = [];
            let currBalance = 0;
            for (const change of balanceChanges) {
                currBalance += change.change;
                accumulatedBalanceChanges.push({
                    ...change,
                    balance: currBalance,
                });
            }

            return accumulatedBalanceChanges;
        },
})
Example #21
Source File: accounts.ts    From abrechnung with GNU Affero General Public License v3.0 5 votes vote down vote up
accountsSeenByUser = selectorFamily<Array<AccountConsolidated>, number>({
    key: "accountsSeenByUser",
    get:
        (groupID) =>
        async ({ get }) => {
            const accounts = get(groupAccounts(groupID));

            return accounts
                .filter((account) => {
                    return !(account.committed_details && account.committed_details.deleted);
                })
                .map((account) => {
                    const details = account.pending_details ? account.pending_details : account.committed_details;
                    if (details === undefined) {
                        throw new Error(
                            "invalid account state: pending_details and committed_details should not be null at the same time"
                        );
                    }
                    const has_committed_changes = account.committed_details != null;
                    let mapped: AccountConsolidated = {
                        id: account.id,
                        type: account.type,
                        version: account.version,
                        last_changed: DateTime.fromISO(account.last_changed),
                        group_id: account.group_id,
                        is_wip: account.is_wip,
                        has_committed_changes: has_committed_changes,
                        ...details,
                        committed_at: details.committed_at != null ? DateTime.fromISO(details.committed_at) : null,
                    };

                    return mapped;
                })
                .sort((t1, t2) => {
                    return t1.type !== t2.type
                        ? accountTypeSortingLookup[t1.type] - accountTypeSortingLookup[t2.type]
                        : t1.name === t2.name
                        ? t1.id - t2.id
                        : t1.name.toLowerCase().localeCompare(t2.name.toLowerCase());
                });
        },
})
Example #22
Source File: transactions.ts    From abrechnung with GNU Affero General Public License v3.0 4 votes vote down vote up
accountBalances = selectorFamily<{ [k: number]: AccountBalance }, number>({
    key: "accountBalances",
    get:
        (groupID) =>
        async ({ get }) => {
            const transactions = get(transactionsSeenByUser(groupID));
            const accounts = get(accountsSeenByUser(groupID));
            let accountBalances = Object.fromEntries(
                accounts.map((account) => [
                    account.id,
                    {
                        balance: 0,
                        beforeClearing: 0,
                        totalConsumed: 0,
                        totalPaid: 0,
                        clearingResolution: {},
                    },
                ])
            );

            for (const transaction of transactions) {
                if (transaction.deleted) {
                    continue; // ignore deleted transactions
                }
                Object.entries(transaction.account_balances).forEach(([accountID, value]) => {
                    accountBalances[accountID].totalConsumed += value.positions + value.common_debitors;
                    accountBalances[accountID].totalPaid += value.common_creditors;
                    accountBalances[accountID].balance += value.total;
                    accountBalances[accountID].beforeClearing = accountBalances[accountID].balance;
                });
            }

            // linearize the account dependency graph to properly redistribute clearing accounts
            const shareMap: Map<number, ClearingShares> = accounts.reduce((map, acc) => {
                if (acc.clearing_shares != null && Object.keys(acc.clearing_shares).length) {
                    map.set(acc.id, acc.clearing_shares);
                }
                return map;
            }, new Map<number, ClearingShares>());
            let clearingDependencies: { [k: number]: Set<number> } = {};
            let inDegree = accounts.reduce((map: { [k: number]: number }, curr) => {
                map[curr.id] = 0;
                return map;
            }, {});
            shareMap.forEach((shares: ClearingShares, accountID: number) => {
                // TODO: maybe functionalize
                for (const nextAccountID of Object.keys(shares)) {
                    if (shareMap.hasOwnProperty(nextAccountID)) {
                        inDegree[parseInt(nextAccountID)] += 1;
                    }
                    if (clearingDependencies.hasOwnProperty(nextAccountID)) {
                        clearingDependencies[parseInt(nextAccountID)].add(accountID);
                    } else {
                        clearingDependencies[parseInt(nextAccountID)] = new Set<number>([accountID]);
                    }
                }
            });
            let zeroDegreeAccounts: Array<number> = [...shareMap.keys()].filter(
                (accountID) => inDegree[accountID] === 0
            );
            let sorting = [];

            while (zeroDegreeAccounts.length > 0) {
                const node = zeroDegreeAccounts.pop();
                if (node === undefined) {
                    throw new Error("error computing transaction balances");
                }
                const shares = shareMap.get(node);
                if (shares !== undefined) {
                    sorting.push(node);
                    for (const nextAccount of Object.keys(shares)) {
                        inDegree[parseInt(nextAccount)] -= 1;
                        if (inDegree[parseInt(nextAccount)] <= 0) {
                            zeroDegreeAccounts.push(parseInt(nextAccount));
                        }
                    }
                }
            }

            for (const clearing of sorting) {
                const clearingShares = shareMap.get(clearing);
                if (clearingShares === undefined || Object.keys(clearingShares).length === 0) {
                    continue;
                }

                const toSplit = accountBalances[clearing].balance;
                accountBalances[clearing].balance = 0;
                const totalShares = Object.values(clearingShares).reduce((acc: number, curr: number) => curr + acc, 0);
                for (const acc in clearingShares) {
                    const accShare = (toSplit * clearingShares[acc]) / totalShares;
                    if (accountBalances[clearing].clearingResolution.hasOwnProperty(acc)) {
                        accountBalances[clearing].clearingResolution[acc] += accShare;
                    } else {
                        accountBalances[clearing].clearingResolution[acc] = accShare;
                    }
                    accountBalances[acc].balance += accShare;
                    if (accShare > 0) {
                        accountBalances[acc].totalPaid += Math.abs(accShare);
                    } else {
                        accountBalances[acc].totalConsumed += Math.abs(accShare);
                    }
                }
            }

            return accountBalances;
        },
})