mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
[MIRROR] Work on phasing out tgui collections.ts (#10059)
Co-authored-by: ShadowLarkens <shadowlarkens@gmail.com> Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
d887a54728
commit
56759cb95b
@@ -82,7 +82,7 @@
|
||||
/obj/item/stack/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Stack", name)
|
||||
ui = new(user, src, "MaterialStack", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/stack/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
|
||||
@@ -4,12 +4,10 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { map } from 'common/collections';
|
||||
|
||||
export const selectChat = (state) => state.chat;
|
||||
|
||||
export const selectChatPages = (state) =>
|
||||
map(state.chat.pages, (id: string) => state.chat.pageById[id]);
|
||||
state.chat.pages.map((id: string) => state.chat.pageById[id]);
|
||||
|
||||
export const selectCurrentChatPage = (state) =>
|
||||
state.chat.pageById[state.chat.currentPageId];
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { sortBy } from 'common/collections';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
import { Button, Section, Table } from 'tgui-core/components';
|
||||
@@ -35,11 +34,20 @@ export const ShuttleList = (props) => {
|
||||
|
||||
const { shuttles, overmap_ships } = data;
|
||||
|
||||
shuttles.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
overmap_ships.sort((a, b) => {
|
||||
let a_cmp = a.name?.toLowerCase() || a.name || a.ref;
|
||||
let b_cmp = a.name?.toLowerCase() || a.name || a.ref;
|
||||
|
||||
return a_cmp.localeCompare(b_cmp);
|
||||
});
|
||||
|
||||
return (
|
||||
<Section noTopPadding>
|
||||
<Section title="Classic Shuttles">
|
||||
<Table>
|
||||
{sortBy(shuttles, (f: Shuttle) => f.name).map((shuttle) => (
|
||||
{shuttles.map((shuttle) => (
|
||||
<Table.Row key={shuttle.ref}>
|
||||
<Table.Cell collapsing>
|
||||
<Button
|
||||
@@ -66,10 +74,7 @@ export const ShuttleList = (props) => {
|
||||
</Section>
|
||||
<Section title="Overmap Ships">
|
||||
<Table>
|
||||
{sortBy(
|
||||
overmap_ships,
|
||||
(f: OvermapShip) => f.name?.toLowerCase() || f.name || f.ref,
|
||||
).map((ship) => (
|
||||
{overmap_ships.map((ship) => (
|
||||
<Table.Row key={ship.ref}>
|
||||
<Table.Cell collapsing>
|
||||
<Button onClick={() => act('adminobserve', { ref: ship.ref })}>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { sortBy } from 'common/collections';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Section, Stack } from 'tgui-core/components';
|
||||
|
||||
import { Data, species, styles } from './types';
|
||||
import { Data, species } from './types';
|
||||
|
||||
export const AppearanceChangerSpecies = (props) => {
|
||||
const { act, data } = useBackend<Data>();
|
||||
const { species, specimen } = data;
|
||||
|
||||
const sortedSpecies = sortBy(species || [], (val: species) => val.specimen);
|
||||
const sortedSpecies = (species || []).sort((a: species, b: species) =>
|
||||
a.specimen.localeCompare(b.specimen),
|
||||
);
|
||||
|
||||
return (
|
||||
<Section title="Species" fill scrollable>
|
||||
@@ -65,6 +66,10 @@ export const AppearanceChangerEars = (props) => {
|
||||
|
||||
const { ear_style, ear_styles } = data;
|
||||
|
||||
ear_styles.sort((a, b) =>
|
||||
a.name.toLowerCase().localeCompare(b.name.toLowerCase()),
|
||||
);
|
||||
|
||||
return (
|
||||
<Stack vertical fill>
|
||||
<Stack.Item grow>
|
||||
@@ -75,8 +80,7 @@ export const AppearanceChangerEars = (props) => {
|
||||
>
|
||||
-- Not Set --
|
||||
</Button>
|
||||
{sortBy(ear_styles, (e: styles) => e.name.toLowerCase()).map(
|
||||
(ear) => (
|
||||
{ear_styles.map((ear) => (
|
||||
<Button
|
||||
key={ear.instance}
|
||||
onClick={() => act('ear', { ref: ear.instance })}
|
||||
@@ -84,8 +88,7 @@ export const AppearanceChangerEars = (props) => {
|
||||
>
|
||||
{ear.name}
|
||||
</Button>
|
||||
),
|
||||
)}
|
||||
))}
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
@@ -96,8 +99,7 @@ export const AppearanceChangerEars = (props) => {
|
||||
>
|
||||
-- Not Set --
|
||||
</Button>
|
||||
{sortBy(ear_styles, (e: styles) => e.name.toLowerCase()).map(
|
||||
(ear) => (
|
||||
{ear_styles.map((ear) => (
|
||||
<Button
|
||||
key={ear.instance}
|
||||
onClick={() => act('ear_secondary', { ref: ear.instance })}
|
||||
@@ -105,8 +107,7 @@ export const AppearanceChangerEars = (props) => {
|
||||
>
|
||||
{ear.name}
|
||||
</Button>
|
||||
),
|
||||
)}
|
||||
))}
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
@@ -118,6 +119,10 @@ export const AppearanceChangerTails = (props) => {
|
||||
|
||||
const { tail_style, tail_styles } = data;
|
||||
|
||||
tail_styles.sort((a, b) =>
|
||||
a.name.toLowerCase().localeCompare(b.name.toLowerCase()),
|
||||
);
|
||||
|
||||
return (
|
||||
<Section title="Tails" fill scrollable>
|
||||
<Button
|
||||
@@ -126,7 +131,7 @@ export const AppearanceChangerTails = (props) => {
|
||||
>
|
||||
-- Not Set --
|
||||
</Button>
|
||||
{sortBy(tail_styles, (e: styles) => e.name.toLowerCase()).map((tail) => (
|
||||
{tail_styles.map((tail) => (
|
||||
<Button
|
||||
key={tail.instance}
|
||||
onClick={() => act('tail', { ref: tail.instance })}
|
||||
@@ -143,6 +148,9 @@ export const AppearanceChangerWings = (props) => {
|
||||
const { act, data } = useBackend<Data>();
|
||||
|
||||
const { wing_style, wing_styles } = data;
|
||||
wing_styles.sort((a, b) =>
|
||||
a.name.toLowerCase().localeCompare(b.name.toLowerCase()),
|
||||
);
|
||||
|
||||
return (
|
||||
<Section title="Wings" fill scrollable>
|
||||
@@ -152,7 +160,7 @@ export const AppearanceChangerWings = (props) => {
|
||||
>
|
||||
-- Not Set --
|
||||
</Button>
|
||||
{sortBy(wing_styles, (e: styles) => e.name.toLowerCase()).map((wing) => (
|
||||
{wing_styles.map((wing) => (
|
||||
<Button
|
||||
key={wing.instance}
|
||||
onClick={() => act('wing', { ref: wing.instance })}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { sortBy } from 'common/collections';
|
||||
import { useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { NanoMap } from 'tgui/components';
|
||||
@@ -32,9 +31,8 @@ export const AtmosControl = (props) => {
|
||||
export const AtmosControlContent = (props) => {
|
||||
const { act, data, config } = useBackend<Data>();
|
||||
|
||||
let sortedAlarms = sortBy(data.alarms || [], (alarm: alarm) => alarm.name);
|
||||
|
||||
// sortedAlarms = sortedAlarms.slice(1, 3);
|
||||
const { alarms } = data;
|
||||
alarms.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
const [tabIndex, setTabIndex] = useState(0);
|
||||
const [zoom, setZoom] = useState(1);
|
||||
@@ -44,7 +42,7 @@ export const AtmosControlContent = (props) => {
|
||||
if (tabIndex === 0) {
|
||||
body = (
|
||||
<Section title="Alarms">
|
||||
{sortedAlarms.map((alarm) => (
|
||||
{alarms.map((alarm) => (
|
||||
<Button
|
||||
key={alarm.name}
|
||||
color={
|
||||
@@ -64,7 +62,7 @@ export const AtmosControlContent = (props) => {
|
||||
body = (
|
||||
<Box height="526px" mb="0.5rem" overflow="hidden">
|
||||
<NanoMap zoomScale={data.zoomScale} onZoom={(v) => setZoom(v)}>
|
||||
{sortedAlarms
|
||||
{alarms
|
||||
.filter((x) => ~~x.z === ~~config.mapZLevel)
|
||||
.map((cm) => (
|
||||
<NanoMap.Marker
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { filter, sortBy } from 'common/collections';
|
||||
import { useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
@@ -10,7 +9,6 @@ import {
|
||||
Section,
|
||||
Stack,
|
||||
} from 'tgui-core/components';
|
||||
import { flow } from 'tgui-core/fp';
|
||||
import { BooleanLike, classes } from 'tgui-core/react';
|
||||
import { createSearch } from 'tgui-core/string';
|
||||
|
||||
@@ -57,31 +55,24 @@ export const selectCameras = (
|
||||
networkFilter: string = '',
|
||||
): camera[] => {
|
||||
const testSearch = createSearch(searchText, (camera: camera) => camera.name);
|
||||
return flow([
|
||||
(cameras: camera[]) =>
|
||||
// Null camera filter
|
||||
filter(cameras, (camera) => notEmpty(camera?.name)),
|
||||
(cameras: camera[]) => {
|
||||
// Optional search term
|
||||
|
||||
return cameras
|
||||
.filter((camera) => notEmpty(camera?.name))
|
||||
.filter((camera) => {
|
||||
if (!searchText) {
|
||||
return cameras;
|
||||
return true;
|
||||
} else {
|
||||
return filter(cameras, testSearch);
|
||||
return testSearch(camera);
|
||||
}
|
||||
},
|
||||
(cameras: camera[]) => {
|
||||
// Optional network filter
|
||||
})
|
||||
.filter((camera) => {
|
||||
if (!networkFilter) {
|
||||
return cameras;
|
||||
return true;
|
||||
} else {
|
||||
return filter(cameras, (camera) =>
|
||||
camera.networks.includes(networkFilter),
|
||||
);
|
||||
return camera.networks.includes(networkFilter);
|
||||
}
|
||||
},
|
||||
// Slightly expensive, but way better than sorting in BYOND
|
||||
(cameras: camera[]) => sortBy(cameras, (camera) => camera.name),
|
||||
])(cameras);
|
||||
})
|
||||
.sort((a, b) => a.name.localeCompare(b.name));
|
||||
};
|
||||
|
||||
export const CameraConsole = (props) => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { filter } from 'common/collections';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Box, LabeledList, Section } from 'tgui-core/components';
|
||||
import { decodeHtmlEntities, toTitleCase } from 'tgui-core/string';
|
||||
@@ -16,13 +15,14 @@ export const CommunicatorWeatherTab = (props) => {
|
||||
<Section title="Weather">
|
||||
<Section title="Current Conditions">
|
||||
<LabeledList>
|
||||
{filter(
|
||||
aircontents,
|
||||
{aircontents
|
||||
.filter(
|
||||
(i: AirContent) =>
|
||||
i.val !== '0' ||
|
||||
i.entry === 'Pressure' ||
|
||||
i.entry === 'Temperature',
|
||||
).map((item: AirContent) => (
|
||||
)
|
||||
.map((item: AirContent) => (
|
||||
<LabeledList.Item
|
||||
key={item.entry}
|
||||
label={item.entry}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { sortBy } from 'common/collections';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Box, Icon, Tabs } from 'tgui-core/components';
|
||||
import { flow } from 'tgui-core/fp';
|
||||
|
||||
import { CrewMonitorCrew } from './CrewMonitorCrew';
|
||||
import { CrewMonitorMapView } from './CrewMonitorMapView';
|
||||
import { crewmember, Data } from './types';
|
||||
import { Data } from './types';
|
||||
|
||||
export const CrewMonitorContent = (props: {
|
||||
tabIndex: number;
|
||||
@@ -17,19 +15,12 @@ export const CrewMonitorContent = (props: {
|
||||
|
||||
const { crewmembers = [] } = data;
|
||||
|
||||
const crew: crewmember[] = flow([
|
||||
(crewmembers: crewmember[]) => sortBy(crewmembers, (cm) => cm.name),
|
||||
(crewmembers: crewmember[]) => sortBy(crewmembers, (cm) => cm?.x),
|
||||
(crewmembers: crewmember[]) => sortBy(crewmembers, (cm) => cm?.y),
|
||||
(crewmembers: crewmember[]) => sortBy(crewmembers, (cm) => cm?.realZ),
|
||||
])(crewmembers);
|
||||
|
||||
const tab: React.JSX.Element[] = [];
|
||||
// Data view
|
||||
// Please note, if you ever change the zoom values,
|
||||
// you MUST update styles/components/Tooltip.scss
|
||||
// and change the @for scss to match.
|
||||
tab[0] = <CrewMonitorCrew crew={crew} />;
|
||||
tab[0] = <CrewMonitorCrew crew={crewmembers} />;
|
||||
|
||||
tab[1] = <CrewMonitorMapView zoom={props.zoom} onZoom={props.onZoom} />;
|
||||
|
||||
|
||||
@@ -88,7 +88,13 @@ export function getSortedCrew(
|
||||
return flow([
|
||||
(shownCrew: crewmember[]) => {
|
||||
if (sortType === 'name') {
|
||||
const sorted = shownCrew.sort((a, b) => a.name.localeCompare(b.name));
|
||||
const sorted = shownCrew.sort(
|
||||
(a, b) =>
|
||||
a.name.localeCompare(b.name) ||
|
||||
a.realZ - b.realZ ||
|
||||
a.x - b.x ||
|
||||
a.y - b.y,
|
||||
);
|
||||
if (nameSortOrder) {
|
||||
return sorted.reverse();
|
||||
}
|
||||
@@ -100,7 +106,9 @@ export function getSortedCrew(
|
||||
(shownCrew: crewmember[]) => {
|
||||
if (sortType === 'damage') {
|
||||
const sorted = shownCrew.sort(
|
||||
(a, b) => getTotalDamage(a) - getTotalDamage(b),
|
||||
(a, b) =>
|
||||
getTotalDamage(a) - getTotalDamage(b) ||
|
||||
a.name.localeCompare(b.name),
|
||||
);
|
||||
if (damageSortOrder) {
|
||||
return sorted.reverse();
|
||||
@@ -112,29 +120,13 @@ export function getSortedCrew(
|
||||
},
|
||||
(shownCrew: crewmember[]) => {
|
||||
if (sortType === 'location') {
|
||||
const sorted = shownCrew.sort((a, b) => a.x - b.x);
|
||||
if (locationSortOrder) {
|
||||
return sorted.reverse();
|
||||
}
|
||||
return sorted;
|
||||
} else {
|
||||
return shownCrew;
|
||||
}
|
||||
},
|
||||
(shownCrew: crewmember[]) => {
|
||||
if (sortType === 'location') {
|
||||
const sorted = shownCrew.sort((a, b) => a.y - b.y);
|
||||
if (locationSortOrder) {
|
||||
return sorted.reverse();
|
||||
}
|
||||
return sorted;
|
||||
} else {
|
||||
return shownCrew;
|
||||
}
|
||||
},
|
||||
(shownCrew: crewmember[]) => {
|
||||
if (sortType === 'location') {
|
||||
const sorted = shownCrew.sort((a, b) => a.realZ - b.realZ);
|
||||
const sorted = shownCrew.sort(
|
||||
(a, b) =>
|
||||
a.realZ - b.realZ ||
|
||||
a.x - b.x ||
|
||||
a.y - b.y ||
|
||||
a.name.localeCompare(b.name),
|
||||
);
|
||||
if (locationSortOrder) {
|
||||
return sorted.reverse();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { sortBy } from 'common/collections';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
import { Button, Section } from 'tgui-core/components';
|
||||
@@ -13,13 +12,13 @@ export const FileCabinet = (props) => {
|
||||
const { contents } = data;
|
||||
|
||||
// Wow, the filing cabinets sort themselves in 2320.
|
||||
const sortedContents = sortBy(contents || [], (val: content) => val.name);
|
||||
contents.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
return (
|
||||
<Window width={350} height={300}>
|
||||
<Window.Content scrollable>
|
||||
<Section>
|
||||
{sortedContents.map((item) => (
|
||||
{contents.map((item) => (
|
||||
<Button
|
||||
key={item.ref}
|
||||
fluid
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { filter } from 'common/collections';
|
||||
import { flow } from 'tgui-core/fp';
|
||||
import { createSearch } from 'tgui-core/string';
|
||||
|
||||
@@ -27,7 +26,7 @@ export function selectRecords(records: record[], searchText = ''): record[] {
|
||||
if (!searchText) {
|
||||
return records;
|
||||
} else {
|
||||
return filter(records, (record) => {
|
||||
return records.filter((record) => {
|
||||
return nameSearch(record) || idSearch(record) || dnaSearch(record);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Currently not used!
|
||||
|
||||
import { map, sortBy } from 'common/collections';
|
||||
import { vecLength, vecSubtract } from 'common/vector';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
@@ -16,7 +15,7 @@ import { flow } from 'tgui-core/fp';
|
||||
import { clamp } from 'tgui-core/math';
|
||||
import { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
const coordsToVec = (coords) => map(coords.split(', '), parseFloat);
|
||||
const coordsToVec = (coords: string) => coords.split(', ').map(parseFloat);
|
||||
|
||||
type Data = {
|
||||
currentArea: string;
|
||||
@@ -31,16 +30,25 @@ type Data = {
|
||||
type signal = {
|
||||
entrytag: string;
|
||||
coords: string;
|
||||
dist: number;
|
||||
dist?: number;
|
||||
degrees: number;
|
||||
};
|
||||
|
||||
function sortSignal(a: signal, b: signal) {
|
||||
if (a.dist === undefined && b.dist === undefined) return 0;
|
||||
if (a.dist === undefined) return 1;
|
||||
if (b.dist === undefined) return -1;
|
||||
if (a.dist < b.dist) return -1;
|
||||
if (a.dist > b.dist) return 1;
|
||||
else return a.entrytag.localeCompare(b.entrytag);
|
||||
}
|
||||
|
||||
export const Gps = (props) => {
|
||||
const { act, data } = useBackend<Data>();
|
||||
const { currentArea, currentCoords, globalmode, power, tag, updating } = data;
|
||||
const signals: signal[] = flow([
|
||||
(signals: signal[]) =>
|
||||
map(signals, (signal, index) => {
|
||||
signals.map((signal, index) => {
|
||||
// Calculate distance to the target. BYOND distance is capped to 127,
|
||||
// that's why we roll our own calculations here.
|
||||
const dist =
|
||||
@@ -55,14 +63,7 @@ export const Gps = (props) => {
|
||||
);
|
||||
return { ...signal, dist, index };
|
||||
}),
|
||||
(signals: signal[]) =>
|
||||
sortBy(
|
||||
signals,
|
||||
// Signals with distance metric go first
|
||||
(signal) => signal.dist === undefined,
|
||||
// Sort alphabetically
|
||||
(signal) => signal.entrytag,
|
||||
),
|
||||
(signals: signal[]) => signals.sort((a, b) => sortSignal(a, b)),
|
||||
])(data.signals || []);
|
||||
return (
|
||||
<Window title="Global Positioning System" width={470} height={700}>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/* eslint react/no-danger: "off" */
|
||||
import { sortBy } from 'common/collections';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
import { Box, Button, LabeledList, Section } from 'tgui-core/components';
|
||||
@@ -24,6 +23,8 @@ export const GuestPass = (props) => {
|
||||
|
||||
const { area, giver, giveName, reason, duration, mode, log, uid } = data;
|
||||
|
||||
area.sort((a, b) => a.area_name.localeCompare(b.area_name));
|
||||
|
||||
return (
|
||||
<Window width={500} height={520}>
|
||||
<Window.Content scrollable>
|
||||
@@ -80,7 +81,7 @@ export const GuestPass = (props) => {
|
||||
Issue Pass
|
||||
</Button.Confirm>
|
||||
<Section title="Access">
|
||||
{sortBy(area, (a: area) => a.area_name).map((a) => (
|
||||
{area.map((a) => (
|
||||
<Button.Checkbox
|
||||
checked={a.on}
|
||||
key={a.area}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { filter, sortBy } from 'common/collections';
|
||||
import { useBackend, useSharedState } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
import {
|
||||
@@ -95,17 +94,18 @@ const ICPrinterCategories = (props) => {
|
||||
'',
|
||||
);
|
||||
|
||||
const selectedCategory = filter(
|
||||
categories,
|
||||
const selectedCategory = categories.filter(
|
||||
(cat: category) => cat.name === categoryTarget,
|
||||
)[0];
|
||||
|
||||
categories.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
return (
|
||||
<Section fill title="Circuits">
|
||||
<Stack fill>
|
||||
<Stack.Item mr={2} basis="20%">
|
||||
<Tabs vertical>
|
||||
{sortBy(categories, (cat: category) => cat.name).map((cat) => (
|
||||
{categories.map((cat) => (
|
||||
<Tabs.Tab
|
||||
selected={categoryTarget === cat.name}
|
||||
onClick={() => setcategoryTarget(cat.name)}
|
||||
@@ -120,8 +120,9 @@ const ICPrinterCategories = (props) => {
|
||||
{selectedCategory ? (
|
||||
<Section fill scrollable>
|
||||
<LabeledList>
|
||||
{sortBy(selectedCategory.items, (item: item) => item.name).map(
|
||||
(item) => (
|
||||
{selectedCategory.items
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.map((item) => (
|
||||
<LabeledList.Item
|
||||
key={item.name}
|
||||
label={item.name}
|
||||
@@ -138,8 +139,7 @@ const ICPrinterCategories = (props) => {
|
||||
>
|
||||
{item.desc}
|
||||
</LabeledList.Item>
|
||||
),
|
||||
)}
|
||||
))}
|
||||
</LabeledList>
|
||||
</Section>
|
||||
) : (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { sortBy } from 'common/collections';
|
||||
import { Fragment } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
@@ -276,13 +275,21 @@ export const IdentificationComputerRegions = (props: { actName: string }) => {
|
||||
|
||||
const { regions } = data;
|
||||
|
||||
if (regions) {
|
||||
regions.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
for (let region of regions) {
|
||||
region.accesses.sort((a, b) => a.desc.localeCompare(b.desc));
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack wrap="wrap">
|
||||
{regions &&
|
||||
sortBy(regions, (r) => r.name).map((region) => (
|
||||
regions.map((region) => (
|
||||
<Stack.Item mb={1} basis="content" grow key={region.name}>
|
||||
<Section title={region.name} height="100%">
|
||||
{sortBy(region.accesses, (a) => a.desc).map((access) => (
|
||||
{region.accesses.map((access) => (
|
||||
<Box key={access.ref}>
|
||||
<Button
|
||||
fluid
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { filter } from 'common/collections';
|
||||
import { useBackend, useSharedState } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
import {
|
||||
@@ -579,7 +578,7 @@ const prepareSearch = (
|
||||
if (!searchText) {
|
||||
return laws;
|
||||
} else {
|
||||
return filter(laws, testSearch);
|
||||
return laws.filter(testSearch);
|
||||
}
|
||||
},
|
||||
])(laws);
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
import { useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
import { Box, Button, Collapsible, Section, Table } from 'tgui-core/components';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Collapsible,
|
||||
Input,
|
||||
Section,
|
||||
Stack,
|
||||
Table,
|
||||
} from 'tgui-core/components';
|
||||
import { createSearch } from 'tgui-core/string';
|
||||
|
||||
type Data = { amount: number; recipes: recipe[] };
|
||||
type Data = { amount: number; recipes: Record<string, recipe>[] };
|
||||
|
||||
type recipe = {
|
||||
res_amount: number;
|
||||
@@ -11,27 +21,49 @@ type recipe = {
|
||||
ref: string;
|
||||
};
|
||||
|
||||
export const Stack = (props) => {
|
||||
export const MaterialStack = (props) => {
|
||||
const { data } = useBackend<Data>();
|
||||
|
||||
const { amount, recipes } = data;
|
||||
const [searchText, setSearchText] = useState('');
|
||||
|
||||
return (
|
||||
<Window width={400} height={600}>
|
||||
<Window.Content scrollable>
|
||||
<Section title={'Amount: ' + amount}>
|
||||
<RecipeList recipes={recipes} />
|
||||
<Stack vertical>
|
||||
<Stack.Item>
|
||||
<Input
|
||||
fluid
|
||||
placeholder="Search for recipe..."
|
||||
value={searchText}
|
||||
onInput={(e, val) => setSearchText(val)}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<RecipeList recipes={recipes} searchText={searchText} />
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
const RecipeList = (props: { recipes: recipe[] }) => {
|
||||
const { recipes } = props;
|
||||
const RecipeList = (props: {
|
||||
recipes: Record<string, recipe>[];
|
||||
searchText: string;
|
||||
}) => {
|
||||
const { recipes, searchText } = props;
|
||||
|
||||
const sortedKeys = Object.keys(recipes).sort();
|
||||
|
||||
const searcher = createSearch(searchText, (recipe: string) => {
|
||||
return recipe;
|
||||
});
|
||||
|
||||
const filteredKeys = sortedKeys.filter(searcher);
|
||||
|
||||
// Shunt all categories to the top.
|
||||
// We're not using this for now, keeping it here in case someone really hates color coding later.
|
||||
// let nonCategories = sortedKeys.filter(item => recipes[item].ref !== undefined);
|
||||
@@ -41,7 +73,7 @@ const RecipeList = (props: { recipes: recipe[] }) => {
|
||||
|
||||
// let newSortedKeys = nonCategories.concat(categories);
|
||||
|
||||
return sortedKeys.map((title, index) => {
|
||||
return filteredKeys.map((title, index) => {
|
||||
// if (title === "--DIVIDER--") {
|
||||
// return (
|
||||
// <Box mt={1} mb={1}>
|
||||
@@ -54,7 +86,7 @@ const RecipeList = (props: { recipes: recipe[] }) => {
|
||||
return (
|
||||
<Collapsible key={index} ml={1} mb={-0.7} color="label" title={title}>
|
||||
<Box ml={1}>
|
||||
<RecipeList recipes={recipe} />
|
||||
<RecipeList recipes={recipe} searchText={searchText} />
|
||||
</Box>
|
||||
</Collapsible>
|
||||
);
|
||||
@@ -1,4 +1,3 @@
|
||||
import { filter } from 'common/collections';
|
||||
import { flow } from 'tgui-core/fp';
|
||||
import { createSearch } from 'tgui-core/string';
|
||||
|
||||
@@ -23,7 +22,7 @@ export function prepareSearch<T extends SearchObject>(
|
||||
if (!searchText) {
|
||||
return objects as any;
|
||||
} else {
|
||||
return filter(objects, testSearch) as any;
|
||||
return objects.filter(testSearch) as any;
|
||||
}
|
||||
},
|
||||
])(objects);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { filter } from 'common/collections';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { NtosWindow } from 'tgui/layouts';
|
||||
import { Button, LabeledList, Section, Table } from 'tgui-core/components';
|
||||
@@ -63,8 +62,7 @@ const WarrantList = (props) => {
|
||||
|
||||
const { allwarrants = [] } = data;
|
||||
|
||||
const ourWarrants = filter(
|
||||
allwarrants,
|
||||
const ourWarrants = allwarrants.filter(
|
||||
(w: warrant) => w.arrestsearch === type,
|
||||
);
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { filter } from 'common/collections';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Box, LabeledList } from 'tgui-core/components';
|
||||
import { decodeHtmlEntities } from 'tgui-core/string';
|
||||
@@ -38,13 +37,14 @@ export const pda_atmos_scan = (props) => {
|
||||
return (
|
||||
<Box>
|
||||
<LabeledList>
|
||||
{filter(
|
||||
aircontents,
|
||||
{aircontents
|
||||
.filter(
|
||||
(i: aircontent) =>
|
||||
i.val !== '0' ||
|
||||
i.entry === 'Pressure' ||
|
||||
i.entry === 'Temperature',
|
||||
).map((item) => (
|
||||
)
|
||||
.map((item) => (
|
||||
<LabeledList.Item
|
||||
key={item.entry}
|
||||
label={item.entry}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { filter } from 'common/collections';
|
||||
import { ReactNode, useEffect, useRef, useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Box, Button, Image, LabeledList, Section } from 'tgui-core/components';
|
||||
@@ -290,8 +289,9 @@ const ActiveConversationASCII = (props: {
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{filter(messages, (im: message) => im.target === active_conversation).map(
|
||||
(im, i) => (
|
||||
{messages
|
||||
.filter((im: message) => im.target === active_conversation)
|
||||
.map((im, i) => (
|
||||
<Box
|
||||
key={i}
|
||||
className={
|
||||
@@ -300,8 +300,7 @@ const ActiveConversationASCII = (props: {
|
||||
>
|
||||
{im.sent ? 'You:' : 'Them:'} {decodeHtmlEntities(im.message)}
|
||||
</Box>
|
||||
),
|
||||
)}
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { filter } from 'common/collections';
|
||||
import { useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
@@ -96,12 +95,12 @@ export const PersonalCrafting = (props) => {
|
||||
|
||||
const shownRecipes: uiRecipe[] = flow([
|
||||
(recipes: uiRecipe[]) =>
|
||||
filter(recipes, (recipe) => recipe.category === tab),
|
||||
recipes.filter((recipe) => recipe.category === tab),
|
||||
(recipes: uiRecipe[]) => {
|
||||
if (!searchText) {
|
||||
return recipes;
|
||||
} else {
|
||||
return filter(recipes, testSearch);
|
||||
return recipes.filter(testSearch);
|
||||
}
|
||||
},
|
||||
])(recipes);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { sortBy } from 'common/collections';
|
||||
import { useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import {
|
||||
@@ -33,6 +32,7 @@ export const PowerMonitorFocus = (props: { focus: sensor }) => {
|
||||
...history.supply,
|
||||
...history.demand,
|
||||
);
|
||||
|
||||
// Process area data
|
||||
const areas: area[] = flow([
|
||||
(areas: area[]) =>
|
||||
@@ -45,24 +45,24 @@ export const PowerMonitorFocus = (props: { focus: sensor }) => {
|
||||
if (sortByField !== 'name') {
|
||||
return areas;
|
||||
} else {
|
||||
return sortBy(areas, (area) => area.name);
|
||||
return areas.sort((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
},
|
||||
(areas: area[]) => {
|
||||
if (sortByField !== 'charge') {
|
||||
return areas;
|
||||
} else {
|
||||
return sortBy(areas, (area) => -area.charge);
|
||||
return areas.sort((a, b) => b.charge - a.charge);
|
||||
}
|
||||
},
|
||||
(areas: area[]) => {
|
||||
if (sortByField !== 'draw') {
|
||||
return areas;
|
||||
} else {
|
||||
return sortBy(
|
||||
areas,
|
||||
(area) => -powerRank(area.load),
|
||||
(area) => -parseFloat(area.load),
|
||||
return areas.sort(
|
||||
(a, b) =>
|
||||
powerRank(b.load) - powerRank(a.load) ||
|
||||
parseFloat(b.load) - parseFloat(a.load),
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -70,17 +70,18 @@ export const PowerMonitorFocus = (props: { focus: sensor }) => {
|
||||
if (sortByField !== 'problems') {
|
||||
return areas;
|
||||
} else {
|
||||
return sortBy(
|
||||
areas,
|
||||
(area) => area.eqp,
|
||||
(area) => area.lgt,
|
||||
(area) => area.env,
|
||||
(area) => area.charge,
|
||||
(area) => area.name,
|
||||
return areas.sort(
|
||||
(a, b) =>
|
||||
a.eqp - b.eqp ||
|
||||
a.lgt - b.lgt ||
|
||||
a.env - b.env ||
|
||||
a.charge - b.charge ||
|
||||
a.name.localeCompare(b.name),
|
||||
);
|
||||
}
|
||||
},
|
||||
])(focus.areas);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Section
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { binaryInsertWith, sortBy } from 'common/collections';
|
||||
import { binaryInsertWith } from 'common/collections';
|
||||
import { ReactNode, useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import {
|
||||
@@ -25,8 +25,13 @@ const binaryInsertPreference = (
|
||||
value: PreferenceChild,
|
||||
) => binaryInsertWith(collection, value, (child) => child.name);
|
||||
|
||||
function sortPref(k: [string, PreferenceChild[]]) {
|
||||
k[1].sort((a, b) => a.name.localeCompare(b.name));
|
||||
return k;
|
||||
}
|
||||
|
||||
const sortByName = (array: [string, PreferenceChild[]][]) =>
|
||||
sortBy(array, ([name]) => name);
|
||||
array.map((k, _) => sortPref(k)).sort((a, b) => a[0].localeCompare(b[0]));
|
||||
|
||||
export const GamePreferencesPage = (props) => {
|
||||
const { act, data } = useBackend<PreferencesMenuData>();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { sortBy } from 'common/collections';
|
||||
import {
|
||||
ComponentType,
|
||||
createElement,
|
||||
@@ -6,6 +5,7 @@ import {
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import React from 'react';
|
||||
import { sendAct, useBackend } from 'tgui/backend';
|
||||
import {
|
||||
Box,
|
||||
@@ -21,8 +21,12 @@ import { BooleanLike } from 'tgui-core/react';
|
||||
import { createSetPreference, PreferencesMenuData } from '../../data';
|
||||
import { ServerPreferencesFetcher } from '../../ServerPreferencesFetcher';
|
||||
|
||||
export const sortChoices = (array: [string, ReactNode][]) =>
|
||||
sortBy(array, ([name]) => name);
|
||||
function sortNode(...node: [string, ReactNode][]) {
|
||||
node.sort((a, b) => a[0].localeCompare(b[0]));
|
||||
return node;
|
||||
}
|
||||
|
||||
export const sortChoices = (array: [string, ReactNode][]) => sortNode(...array);
|
||||
|
||||
export type Feature<
|
||||
TReceiving,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { filter } from 'common/collections';
|
||||
import { useBackend, useSharedState } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
import { Box, Button, LabeledList, Section, Tabs } from 'tgui-core/components';
|
||||
@@ -194,8 +193,9 @@ const ResearchServerData = (props: { server: server }) => {
|
||||
))}
|
||||
</Section>
|
||||
<Section title="Designs">
|
||||
{filter(server.designs, (design: techDes) => !!design.name).map(
|
||||
(design) => (
|
||||
{server.designs
|
||||
.filter((design: techDes) => !!design.name)
|
||||
.map((design) => (
|
||||
<LabeledList.Item
|
||||
label={design.name}
|
||||
key={design.name}
|
||||
@@ -215,8 +215,7 @@ const ResearchServerData = (props: { server: server }) => {
|
||||
</Button.Confirm>
|
||||
}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
))}
|
||||
</Section>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { filter } from 'common/collections';
|
||||
import { flow } from 'tgui-core/fp';
|
||||
import { createSearch } from 'tgui-core/string';
|
||||
|
||||
@@ -33,14 +32,14 @@ export function robotSpriteSearcher(
|
||||
if (!searchText) {
|
||||
return sprites;
|
||||
} else {
|
||||
return filter(sprites, testSearch);
|
||||
return sprites.filter(testSearch);
|
||||
}
|
||||
},
|
||||
(sprites: spriteOption[]) => {
|
||||
if (!subtypes.length) {
|
||||
return sprites;
|
||||
} else {
|
||||
return filter(sprites, (sprite) => subtypes.includes(sprite.type));
|
||||
return sprites.filter((sprite) => subtypes.includes(sprite.type));
|
||||
}
|
||||
},
|
||||
])(sprites);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { sortBy } from 'common/collections';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
import {
|
||||
@@ -39,13 +38,15 @@ export const SeedStorage = (props) => {
|
||||
|
||||
const { seeds } = data;
|
||||
|
||||
const sortedSeeds = sortBy(seeds, (seed: seed) => seed.name.toLowerCase());
|
||||
seeds.sort((a, b) =>
|
||||
a.name.toLowerCase().localeCompare(b.name.toLowerCase()),
|
||||
);
|
||||
|
||||
return (
|
||||
<Window width={600} height={760}>
|
||||
<Window.Content scrollable>
|
||||
<Section title="Seeds">
|
||||
{sortedSeeds.map((seed) => (
|
||||
{seeds.map((seed) => (
|
||||
<Stack mt={-1} key={seed.name + seed.uid}>
|
||||
<Stack.Item basis="60%">
|
||||
<Collapsible title={toTitleCase(seed.name) + ' #' + seed.uid}>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { filter, sortBy } from 'common/collections';
|
||||
import { useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Box, Button, Section, Stack } from 'tgui-core/components';
|
||||
import { flow } from 'tgui-core/fp';
|
||||
|
||||
import { Data, supplyPack } from './types';
|
||||
|
||||
@@ -13,15 +11,19 @@ export const SupplyConsoleMenuOrder = (props) => {
|
||||
|
||||
const [activeCategory, setActiveCategory] = useState<string | null>(null);
|
||||
|
||||
const viewingPacks: supplyPack[] = flow([
|
||||
(supply_packs: supplyPack[]) =>
|
||||
filter(supply_packs, (val) => val.group === activeCategory),
|
||||
(supply_packs: supplyPack[]) =>
|
||||
filter(supply_packs, (val) => !val.contraband || !!contraband),
|
||||
(supply_packs: supplyPack[]) => sortBy(supply_packs, (val) => val.name),
|
||||
(supply_packs: supplyPack[]) =>
|
||||
sortBy(supply_packs, (val) => val.cost > supply_points),
|
||||
])(supply_packs);
|
||||
function sortPack(a: supplyPack, b: supplyPack) {
|
||||
if (a.cost < supply_points && b.cost > supply_points) return -1;
|
||||
if (a.cost > supply_points && b.cost < supply_points) return 1;
|
||||
|
||||
return a.name.localeCompare(b.name);
|
||||
}
|
||||
|
||||
const viewingPacks: supplyPack[] = supply_packs
|
||||
.filter(
|
||||
(pack) =>
|
||||
(pack.group === activeCategory && !pack.contraband) || !!contraband,
|
||||
)
|
||||
.sort((a, b) => sortPack(a, b));
|
||||
|
||||
// const viewingPacks = sortBy(val => val.name)(supply_packs).filter(val => val.group === activeCategory);
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { sortBy } from 'common/collections';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
import {
|
||||
@@ -73,6 +72,10 @@ export const TelesciConsoleContent = (props) => {
|
||||
lastTeleData,
|
||||
} = data;
|
||||
|
||||
if (sectorOptions) {
|
||||
sectorOptions.sort();
|
||||
}
|
||||
|
||||
return (
|
||||
<Section
|
||||
title="Telepad Controls"
|
||||
@@ -120,7 +123,7 @@ export const TelesciConsoleContent = (props) => {
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Sector">
|
||||
{sectorOptions &&
|
||||
sortBy(sectorOptions, (v) => v).map((z) => (
|
||||
sectorOptions.map((z) => (
|
||||
<Button
|
||||
key={z}
|
||||
icon="check-circle"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { filter } from 'common/collections';
|
||||
import { useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
@@ -208,7 +207,7 @@ export const prepareSearch = (
|
||||
if (!searchText) {
|
||||
return products;
|
||||
} else {
|
||||
return filter(products, testSearch);
|
||||
return products.filter(testSearch);
|
||||
}
|
||||
},
|
||||
])(products);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { filter } from 'common/collections';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
import { LabeledList, Section } from 'tgui-core/components';
|
||||
@@ -47,13 +46,14 @@ export const pAIAtmos = (props) => {
|
||||
<Window.Content scrollable>
|
||||
<Section>
|
||||
<LabeledList>
|
||||
{filter(
|
||||
aircontents,
|
||||
{aircontents
|
||||
.filter(
|
||||
(i: aircontent) =>
|
||||
i.val !== '0' ||
|
||||
i.entry === 'Pressure' ||
|
||||
i.entry === 'Temperature',
|
||||
).map((item: aircontent) => (
|
||||
)
|
||||
.map((item: aircontent) => (
|
||||
<LabeledList.Item
|
||||
key={item.entry}
|
||||
label={item.entry}
|
||||
|
||||
Reference in New Issue
Block a user