From 9ec038cf25c819f47f55a71ee1feb46eb822297b Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Fri, 25 Mar 2022 19:08:47 +0100 Subject: [PATCH] [MIRROR] Adds search to supply console [MDB IGNORE] (#12273) * Adds search to supply console (#65654) * Search for supply console * Adds search to supply console Co-authored-by: Tastyfish --- tgui/packages/tgui/interfaces/Cargo.js | 81 ++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 5 deletions(-) diff --git a/tgui/packages/tgui/interfaces/Cargo.js b/tgui/packages/tgui/interfaces/Cargo.js index 6cf9ee9ff9a..f1186f1dd45 100644 --- a/tgui/packages/tgui/interfaces/Cargo.js +++ b/tgui/packages/tgui/interfaces/Cargo.js @@ -1,5 +1,7 @@ +import { flow } from 'common/fp'; +import { filter, sortBy } from 'common/collections'; import { useBackend, useSharedState } from '../backend'; -import { AnimatedNumber, Box, Button, Flex, LabeledList, NoticeBox, Section, Table, Tabs } from '../components'; +import { AnimatedNumber, Box, Button, Flex, Icon, Input, LabeledList, NoticeBox, Section, Stack, Table, Tabs } from '../components'; import { formatMoney } from '../format'; import { Window } from '../layouts'; @@ -138,21 +140,52 @@ const CargoStatus = (props, context) => { ); }; +/** + * Take entire supplies tree + * and return a flat supply pack list that matches search, + * sorted by name and only the first page. + * @param {any[]} supplies Supplies list. + * @param {string} search The search term + * @returns {any[]} The flat list of supply packs. + */ +const searchForSupplies = (supplies, search) => { + search = search.toLowerCase(); + + return flow([ + categories => categories.flatMap(category => category.packs), + filter(pack => + pack.name?.toLowerCase().includes(search.toLowerCase()) + || pack.desc?.toLowerCase().includes(search.toLowerCase())), + sortBy(pack => pack.name), + packs => packs.slice(0, 25), + ])(supplies); +}; + export const CargoCatalog = (props, context) => { const { express } = props; const { act, data } = useBackend(context); + const { self_paid, app_cost, } = data; + const supplies = Object.values(data.supplies); + const [ activeSupplyName, setActiveSupplyName, ] = useSharedState(context, 'supply', supplies[0]?.name); - const activeSupply = supplies.find(supply => { - return supply.name === activeSupplyName; - }); + + const [ + searchText, + setSearchText, + ] = useSharedState(context, "search_text", ""); + + const activeSupply = activeSupplyName === "search_results" + ? { packs: searchForSupplies(supplies, searchText) } + : supplies.find(supply => supply.name === activeSupplyName); + return (
{ + + + + + + + { + if (value === searchText) { + return; + } + + if (value.length) { + // Start showing results + setActiveSupplyName("search_results"); + } else if (activeSupplyName === "search_results") { + // return to normal category + setActiveSupplyName(supplies[0]?.name); + } + setSearchText(value); + }} + onChange={(e, value) => { + // Allow edge cases like the X button to work + const onInput = e.target?.props?.onInput; + if (onInput) { + onInput(e, value); + } + }} /> + + + {supplies.map(supply => ( setActiveSupplyName(supply.name)}> + onClick={() => { + setActiveSupplyName(supply.name); + setSearchText(""); + }}> {supply.name} ({supply.packs.length}) ))}