diff --git a/src/components/wallets/SelectWalletCategory.tsx b/src/components/wallets/SelectWalletCategory.tsx index ef68a33..4c642ea 100644 --- a/src/components/wallets/SelectWalletCategory.tsx +++ b/src/components/wallets/SelectWalletCategory.tsx @@ -1,7 +1,7 @@ // Copyright (c) 2020-2021 Drew Lemmy // This file is part of KristWeb 2 under GPL-3.0. // Full details: https://github.com/tmpim/KristWeb2/blob/master/LICENSE.txt -import React, { useState } from "react"; +import React, { FC, useState, useMemo } from "react"; import { Select, Input, Button, Typography, Divider } from "antd"; import { PlusOutlined } from "@ant-design/icons"; @@ -16,71 +16,117 @@ onNewCategory?: (name: string) => void; } -export function SelectWalletCategory({ onNewCategory }: Props): JSX.Element { +export const SelectWalletCategory: FC = ({ onNewCategory, ...props }): JSX.Element => { + const { t } = useTranslation(); + const [customCategory, setCustomCategory] = useState(); + // Required to fetch existing categories const { wallets } = useWallets(); - const existingCategories = [...new Set(Object.values(wallets) - .filter(w => w.category !== undefined && w.category !== "") - .map(w => w.category) as string[])]; - localeSort(existingCategories); + const categories = useMemo(() => { + // Get all the non-empty wallet categories and deduplicate them + const categorySet = new Set(Object.values(wallets) + .filter(w => w.category !== undefined && w.category !== "") + .map(w => w.category) as string[]); - const { t } = useTranslation(); - const [input, setInput] = useState(); - const [categories, setCategories] = useState(existingCategories); + // Add the custom category, if it exists, to our set of categories + if (customCategory) categorySet.add(customCategory); - function addCategory() { - if (!input) return; + // Convert the categories to an array and sort in a human-readable manner + const cats = [...categorySet]; + localeSort(cats); + return cats; + }, [wallets, customCategory]); - const categoryName = input.trim(); - if (!categoryName || categoryName.length > 32 - || categories.includes(categoryName)) return; + /** Adds a category. Returns whether or not the category input should be + * wiped (i.e. whether or not it was added successfully). */ + function addCategory(input?: string): boolean { + // Ignore invalid category names. Don't wipe the input. + const categoryName = input?.trim(); + if (!categoryName + || categoryName.length > 32 + || categories.includes(categoryName)) + return false; - const newCategories = [...categories, categoryName]; - localeSort(newCategories); - - setCategories(newCategories); - setInput(undefined); + setCustomCategory(categoryName); // FIXME: hitting enter will _sometimes_ not set the right category name on // the form - if (onNewCategory) onNewCategory(categoryName); + + return true; } - return + dropdownRender={menu => ( +
+ {/* The category select options */} + {menu} -
- - - maxLength={32} - onChange={e => setInput(e.target.value)} - onPressEnter={e => { e.preventDefault(); addCategory(); }} - - placeholder={t("addWallet.walletCategoryDropdownNewPlaceholder")} - - size="small" - style={{ flex: 1, height: 24 }} - /> - - - -
-
) - }> + {/* The textbox/button to add a new category */} + + ) + } + > + {/* "No category" option */} {t("addWallet.walletCategoryDropdownNone")} - {categories.map(c => - {c} - )} + {/* Render each category as an option */} + {categories.map(c => ( + + {c} + + ))} ; +}; + +interface AddCategoryInputProps { + addCategory: (input: string | undefined) => boolean; +} + +/** The textbox/button to input and add a new category. */ +function AddCategoryInput({ addCategory }: AddCategoryInputProps): JSX.Element { + const { t } = useTranslation(); + const [input, setInput] = useState(); + + return ( +
+ + setInput(e.target.value)} + onPressEnter={e => { + e.preventDefault(); + + // Wipe the input if the category was added successfully + if (addCategory(input)) setInput(undefined); + }} + + placeholder={t("addWallet.walletCategoryDropdownNewPlaceholder")} + + size="small" + style={{ flex: 1, height: 24 }} + /> + + + +
+ ); } diff --git a/src/pages/wallets/AddWalletModal.tsx b/src/pages/wallets/AddWalletModal.tsx index 97d33ef..434a93a 100644 --- a/src/pages/wallets/AddWalletModal.tsx +++ b/src/pages/wallets/AddWalletModal.tsx @@ -251,7 +251,9 @@ {/* Wallet category */} - {SelectWalletCategory({ onNewCategory: category => form.setFieldsValue({ category })})} + form.setFieldsValue({ category })} + />