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