mirror of
https://github.com/quotefox/Hyper-Station-13.git
synced 2026-07-18 11:12:26 +01:00
refactoring for TGUI3, part 2
halfway there
This commit is contained in:
@@ -56,7 +56,7 @@
|
||||
/obj/machinery/computer/launchpad/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Launchpad", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, ui_key, "LaunchpadConsole", name, ui_x, ui_y, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/launchpad/ui_data(mob/user)
|
||||
|
||||
@@ -280,7 +280,7 @@
|
||||
/obj/item/launchpad_remote/ui_interact(mob/user, ui_key = "launchpad_remote", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Launchpad", "Briefcase Launchpad Remote", 300, 240, master_ui, state) //width, height
|
||||
ui = new(user, src, ui_key, "LaunchpadRemote", "Briefcase Launchpad Remote", 300, 240, master_ui, state) //width, height
|
||||
// ui.set_style("syndicate")
|
||||
ui.open()
|
||||
|
||||
|
||||
@@ -7,45 +7,58 @@ import { useBackend } from '../backend';
|
||||
|
||||
|
||||
export const CargoExpress = (props, context) => {
|
||||
const { config, data, act } = useBackend(context);
|
||||
const { ref } = config;
|
||||
const supplies = data.supplies || {};
|
||||
const { data, act } = useBackend(context);
|
||||
const {
|
||||
siliconUser,
|
||||
locked,
|
||||
points,
|
||||
usingBeacon,
|
||||
hasBeacon,
|
||||
beaconName,
|
||||
beaconzone,
|
||||
printMsg,
|
||||
canBuyBeacon,
|
||||
message,
|
||||
} = data;
|
||||
|
||||
const supplies = Object.values(data.supplies);
|
||||
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content>
|
||||
<InterfaceLockNoticeBox
|
||||
siliconUser={data.siliconUser}
|
||||
locked={data.locked}
|
||||
siliconUser={siliconUser}
|
||||
locked={locked}
|
||||
onLockStatusChange={() => act('lock')}
|
||||
accessText="a QM-level ID card" />
|
||||
{!data.locked && (
|
||||
{!locked && (
|
||||
<Fragment>
|
||||
<Section
|
||||
title="Cargo Express"
|
||||
buttons={(
|
||||
<Box inline bold>
|
||||
<AnimatedNumber value={Math.round(data.points)} /> credits
|
||||
<AnimatedNumber value={Math.round(points)} /> credits
|
||||
</Box>
|
||||
)}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Landing Location">
|
||||
<Button
|
||||
content="Cargo Bay"
|
||||
selected={!data.usingBeacon}
|
||||
selected={!usingBeacon}
|
||||
onClick={() => act('LZCargo')} />
|
||||
<Button
|
||||
selected={data.usingBeacon}
|
||||
disabled={!data.hasBeacon}
|
||||
selected={usingBeacon}
|
||||
disabled={!hasBeacon}
|
||||
onClick={() => act('LZBeacon')}>
|
||||
{data.beaconzone} ({data.beaconName})
|
||||
{beaconzone} ({beaconName})
|
||||
</Button>
|
||||
<Button
|
||||
content={data.printMsg}
|
||||
disabled={!data.canBuyBeacon}
|
||||
content={printMsg}
|
||||
disabled={!canBuyBeacon}
|
||||
onClick={() => act('printBeacon')} />
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Notice">
|
||||
{data.message}
|
||||
{message}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
|
||||
@@ -7,8 +7,7 @@ import { PackagingControls } from './ChemMaster/PackagingControls';
|
||||
import { useBackend } from '../backend';
|
||||
|
||||
export const ChemMaster = (props, context) => {
|
||||
const { config, data, act } = useBackend(context);
|
||||
const { ref } = config;
|
||||
const { data, act } = useBackend(context);
|
||||
const {
|
||||
screen,
|
||||
beakerContents = [],
|
||||
@@ -19,7 +18,9 @@ export const ChemMaster = (props, context) => {
|
||||
isPillBottleLoaded,
|
||||
pillBottleCurrentAmount,
|
||||
pillBottleMaxAmount,
|
||||
mode,
|
||||
} = data;
|
||||
|
||||
if (screen === "analyze") {
|
||||
return <AnalysisResults />;
|
||||
}
|
||||
@@ -28,7 +29,7 @@ export const ChemMaster = (props, context) => {
|
||||
<Window.Content>
|
||||
<Section
|
||||
title="Beaker"
|
||||
buttons={!!data.isBeakerLoaded && (
|
||||
buttons={!!isBeakerLoaded && (
|
||||
<Fragment>
|
||||
<Box inline color="label" mr={2}>
|
||||
<AnimatedNumber
|
||||
@@ -39,7 +40,7 @@ export const ChemMaster = (props, context) => {
|
||||
<Button
|
||||
icon="eject"
|
||||
content="Eject"
|
||||
onClick={() => act(ref, 'eject')} />
|
||||
onClick={() => act('eject')} />
|
||||
</Fragment>
|
||||
)}>
|
||||
{!isBeakerLoaded && (
|
||||
@@ -69,10 +70,10 @@ export const ChemMaster = (props, context) => {
|
||||
Mode:
|
||||
</Box>
|
||||
<Button
|
||||
color={data.mode ? 'good' : 'bad'}
|
||||
icon={data.mode ? 'exchange-alt' : 'times'}
|
||||
content={data.mode ? 'Transfer' : 'Destroy'}
|
||||
onClick={() => act(ref, 'toggleMode')} />
|
||||
color={mode ? 'good' : 'bad'}
|
||||
icon={mode ? 'exchange-alt' : 'times'}
|
||||
content={mode ? 'Transfer' : 'Destroy'}
|
||||
onClick={() => act('toggleMode')} />
|
||||
</Fragment>
|
||||
)}>
|
||||
{bufferContents.length === 0 && (
|
||||
@@ -104,7 +105,7 @@ export const ChemMaster = (props, context) => {
|
||||
<Button
|
||||
icon="eject"
|
||||
content="Eject"
|
||||
onClick={() => act(ref, 'ejectPillBottle')} />
|
||||
onClick={() => act('ejectPillBottle')} />
|
||||
</Fragment>
|
||||
)} />
|
||||
)}
|
||||
|
||||
@@ -2,8 +2,7 @@ import { useBackend } from '../../backend';
|
||||
import { Button, ColorBox, LabeledList, Section } from '../../components';
|
||||
|
||||
export const AnalysisResults = (props, context) => {
|
||||
const { config, data, act } = useBackend(context);
|
||||
const { ref } = config;
|
||||
const { data, act } = useBackend(context);
|
||||
const { analyzeVars, fermianalyze } = data;
|
||||
return (
|
||||
<Section
|
||||
@@ -12,7 +11,7 @@ export const AnalysisResults = (props, context) => {
|
||||
<Button
|
||||
icon="arrow-left"
|
||||
content="Back"
|
||||
onClick={() => act(ref, 'goScreen', {
|
||||
onClick={() => act('goScreen', {
|
||||
screen: 'home',
|
||||
})} />
|
||||
)}>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { act } from '../../byond';
|
||||
import { useBackend } from '../../backend';
|
||||
import { AnimatedNumber, Button, Table } from '../../components';
|
||||
|
||||
export const ChemicalBufferEntry = (props, context) => {
|
||||
const { state, chemical, transferTo } = props;
|
||||
const { ref } = state.config;
|
||||
const { act } = useBackend(context);
|
||||
const { chemical, transferTo } = props;
|
||||
|
||||
return (
|
||||
<Table.Row key={chemical.id}>
|
||||
<Table.Cell color="label">
|
||||
@@ -15,28 +16,28 @@ export const ChemicalBufferEntry = (props, context) => {
|
||||
<Table.Cell collapsing>
|
||||
<Button
|
||||
content="1"
|
||||
onClick={() => act(ref, 'transfer', {
|
||||
onClick={() => act('transfer', {
|
||||
id: chemical.id,
|
||||
amount: 1,
|
||||
to: transferTo,
|
||||
})} />
|
||||
<Button
|
||||
content="5"
|
||||
onClick={() => act(ref, 'transfer', {
|
||||
onClick={() => act('transfer', {
|
||||
id: chemical.id,
|
||||
amount: 5,
|
||||
to: transferTo,
|
||||
})} />
|
||||
<Button
|
||||
content="10"
|
||||
onClick={() => act(ref, 'transfer', {
|
||||
onClick={() => act('transfer', {
|
||||
id: chemical.id,
|
||||
amount: 10,
|
||||
to: transferTo,
|
||||
})} />
|
||||
<Button
|
||||
content="All"
|
||||
onClick={() => act(ref, 'transfer', {
|
||||
onClick={() => act('transfer', {
|
||||
id: chemical.id,
|
||||
amount: 1000,
|
||||
to: transferTo,
|
||||
@@ -44,7 +45,7 @@ export const ChemicalBufferEntry = (props, context) => {
|
||||
<Button
|
||||
icon="ellipsis-h"
|
||||
title="Custom amount"
|
||||
onClick={() => act(ref, 'transfer', {
|
||||
onClick={() => act('transfer', {
|
||||
id: chemical.id,
|
||||
amount: -1,
|
||||
to: transferTo,
|
||||
@@ -52,7 +53,7 @@ export const ChemicalBufferEntry = (props, context) => {
|
||||
<Button
|
||||
icon="question"
|
||||
title="Analyze"
|
||||
onClick={() => act(ref, 'analyze', {
|
||||
onClick={() => act('analyze', {
|
||||
id: chemical.id,
|
||||
})} />
|
||||
</Table.Cell>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Component } from 'inferno';
|
||||
import { useBackend } from '../../backend';
|
||||
import { act } from '../../byond';
|
||||
import { Box, Button, LabeledList, NumberInput } from '../../components';
|
||||
|
||||
@@ -16,14 +17,14 @@ export class PackagingControls extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { state, props } = this;
|
||||
const { ref } = props.state.config;
|
||||
const { props, context } = this;
|
||||
const { data, act } = useBackend(context);
|
||||
const {
|
||||
pillAmount, patchAmount, bottleAmount, packAmount, vialAmount, dartAmount,
|
||||
} = this.state;
|
||||
const {
|
||||
condi, chosenPillStyle, pillStyles = [],
|
||||
} = props.state.data;
|
||||
} = data;
|
||||
return (
|
||||
<LabeledList>
|
||||
{!condi && (
|
||||
@@ -35,7 +36,7 @@ export class PackagingControls extends Component {
|
||||
selected={pill.id === chosenPillStyle}
|
||||
textAlign="center"
|
||||
color="transparent"
|
||||
onClick={() => act(ref, 'pillStyle', { id: pill.id })}>
|
||||
onClick={() => act('pillStyle', { id: pill.id })}>
|
||||
<Box mx={-1} className={pill.className} />
|
||||
</Button>
|
||||
))}
|
||||
@@ -50,7 +51,7 @@ export class PackagingControls extends Component {
|
||||
onChangeAmount={(e, value) => this.setState({
|
||||
pillAmount: value,
|
||||
})}
|
||||
onCreate={() => act(ref, 'create', {
|
||||
onCreate={() => act('create', {
|
||||
type: 'pill',
|
||||
amount: pillAmount,
|
||||
volume: 'auto',
|
||||
@@ -65,7 +66,7 @@ export class PackagingControls extends Component {
|
||||
onChangeAmount={(e, value) => this.setState({
|
||||
patchAmount: value,
|
||||
})}
|
||||
onCreate={() => act(ref, 'create', {
|
||||
onCreate={() => act('create', {
|
||||
type: 'patch',
|
||||
amount: patchAmount,
|
||||
volume: 'auto',
|
||||
@@ -80,7 +81,7 @@ export class PackagingControls extends Component {
|
||||
onChangeAmount={(e, value) => this.setState({
|
||||
bottleAmount: value,
|
||||
})}
|
||||
onCreate={() => act(ref, 'create', {
|
||||
onCreate={() => act('create', {
|
||||
type: 'bottle',
|
||||
amount: bottleAmount,
|
||||
volume: 'auto',
|
||||
@@ -95,7 +96,7 @@ export class PackagingControls extends Component {
|
||||
onChangeAmount={(e, value) => this.setState({
|
||||
vialAmount: value,
|
||||
})}
|
||||
onCreate={() => act(ref, 'create', {
|
||||
onCreate={() => act('create', {
|
||||
type: 'hypoVial',
|
||||
amount: vialAmount,
|
||||
volume: 'auto',
|
||||
@@ -110,7 +111,7 @@ export class PackagingControls extends Component {
|
||||
onChangeAmount={(e, value) => this.setState({
|
||||
dartAmount: value,
|
||||
})}
|
||||
onCreate={() => act(ref, 'create', {
|
||||
onCreate={() => act('create', {
|
||||
type: 'smartDart',
|
||||
amount: dartAmount,
|
||||
volume: 'auto',
|
||||
@@ -125,7 +126,7 @@ export class PackagingControls extends Component {
|
||||
onChangeAmount={(e, value) => this.setState({
|
||||
packAmount: value,
|
||||
})}
|
||||
onCreate={() => act(ref, 'create', {
|
||||
onCreate={() => act('create', {
|
||||
type: 'condimentPack',
|
||||
amount: packAmount,
|
||||
volume: 'auto',
|
||||
@@ -140,7 +141,7 @@ export class PackagingControls extends Component {
|
||||
onChangeAmount={(e, value) => this.setState({
|
||||
bottleAmount: value,
|
||||
})}
|
||||
onCreate={() => act(ref, 'create', {
|
||||
onCreate={() => act('create', {
|
||||
type: 'condimentBottle',
|
||||
amount: bottleAmount,
|
||||
volume: 'auto',
|
||||
|
||||
@@ -14,9 +14,13 @@ export const EightBallVote = (props, context) => {
|
||||
|
||||
if (!shaking) {
|
||||
return (
|
||||
<NoticeBox>
|
||||
No question is currently being asked.
|
||||
</NoticeBox>
|
||||
<Window>
|
||||
<Window.Content>
|
||||
<NoticeBox>
|
||||
No question is currently being asked.
|
||||
</NoticeBox>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
import { useBackend } from '../backend';
|
||||
import { Button, Grid, Input, Section } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
import { LaunchpadButtonPad } from './Launchpad/LaunchpadButtonPad';
|
||||
import { LaunchTarget } from './Launchpad/LaunchTarget';
|
||||
|
||||
export const LaunchpadControl = (props, context) => {
|
||||
const { topLevel } = props;
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
const { pad_name } = data;
|
||||
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content>
|
||||
<Section
|
||||
title={(
|
||||
<Input
|
||||
value={pad_name}
|
||||
width="170px"
|
||||
onChange={(e, value) => act('rename', {
|
||||
name: value,
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
level={topLevel ? 1 : 2}
|
||||
buttons={(
|
||||
<Button
|
||||
icon="times"
|
||||
content="Remove"
|
||||
color="bad"
|
||||
onClick={() => act('remove')} />
|
||||
)}>
|
||||
<Grid>
|
||||
<Grid.Column>
|
||||
<Section title="Controls" level={2}>
|
||||
<LaunchpadButtonPad state={props.state} />
|
||||
</Section>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<LaunchTarget data={data} act={act} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Grid.Column>
|
||||
<Button
|
||||
fluid
|
||||
icon="upload"
|
||||
content="Launch"
|
||||
textAlign="center"
|
||||
onClick={() => act('launch')} />
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button
|
||||
fluid
|
||||
icon="download"
|
||||
content="Pull"
|
||||
textAlign="center"
|
||||
onClick={() => act('pull')} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { useBackend } from '../../backend';
|
||||
import { Box, NumberInput, Section } from '../../components';
|
||||
|
||||
export const LaunchTarget = (data, act) => {
|
||||
export const LaunchTarget = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { x, y, range } = data;
|
||||
|
||||
return (
|
||||
<Section title="Target" level={2}>
|
||||
<Box fontSize="26px">
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
import { useBackend } from '../../backend';
|
||||
import { Box, Button, Grid, NoticeBox, Section } from '../../components';
|
||||
import { LaunchpadControl } from '../Launchpad';
|
||||
|
||||
|
||||
export const LaunchpadConsole = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
const {
|
||||
launchpads = [], selected_id,
|
||||
} = data;
|
||||
|
||||
if (launchpads.length <= 0) {
|
||||
return (
|
||||
<NoticeBox>
|
||||
No Pads Connected
|
||||
</NoticeBox>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Section>
|
||||
<Grid>
|
||||
<Grid.Column size={0.6}>
|
||||
<Box
|
||||
style={{
|
||||
'border-right': '2px solid rgba(255, 255, 255, 0.1)',
|
||||
}}
|
||||
minHeight="190px"
|
||||
mr={1}>
|
||||
{launchpads.map(launchpad => (
|
||||
<Button
|
||||
fluid
|
||||
key={launchpad.name}
|
||||
content={launchpad.name}
|
||||
selected={selected_id === launchpad.id}
|
||||
color="transparent"
|
||||
onClick={() => act('select_pad', { id: launchpad.id })} />
|
||||
))}
|
||||
</Box>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
{selected_id ? (
|
||||
<LaunchpadControl state={props.state} />
|
||||
) : (
|
||||
<Box>
|
||||
Please select a pad
|
||||
</Box>
|
||||
)}
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
import { useBackend } from '../../backend';
|
||||
import { Button, Grid, Input, Section } from '../../components';
|
||||
import { LaunchpadButtonPad } from './LaunchpadButtonPad';
|
||||
import { LaunchTarget } from './LaunchTarget';
|
||||
|
||||
export const LaunchpadControl = (props, context) => {
|
||||
const { topLevel } = props;
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
const { pad_name } = data;
|
||||
|
||||
return (
|
||||
<Section
|
||||
title={(
|
||||
<Input
|
||||
value={pad_name}
|
||||
width="170px"
|
||||
onChange={(e, value) => act('rename', {
|
||||
name: value,
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
level={topLevel ? 1 : 2}
|
||||
buttons={(
|
||||
<Button
|
||||
icon="times"
|
||||
content="Remove"
|
||||
color="bad"
|
||||
onClick={() => act('remove')} />
|
||||
)}>
|
||||
<Grid>
|
||||
<Grid.Column>
|
||||
<Section title="Controls" level={2}>
|
||||
<LaunchpadButtonPad state={props.state} />
|
||||
</Section>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<LaunchTarget />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Grid.Column>
|
||||
<Button
|
||||
fluid
|
||||
icon="upload"
|
||||
content="Launch"
|
||||
textAlign="center"
|
||||
onClick={() => act('launch')} />
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button
|
||||
fluid
|
||||
icon="download"
|
||||
content="Pull"
|
||||
textAlign="center"
|
||||
onClick={() => act('pull')} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import { useBackend } from '../../backend';
|
||||
import { NoticeBox } from '../../components';
|
||||
import { LaunchpadControl } from '../Launchpad';
|
||||
|
||||
|
||||
export const LaunchpadRemote = (props, context) => {
|
||||
const { data } = useBackend(context);
|
||||
|
||||
const {
|
||||
has_pad, pad_closed,
|
||||
} = data;
|
||||
|
||||
if (!has_pad) {
|
||||
return (
|
||||
<NoticeBox>
|
||||
No Launchpad Connected
|
||||
</NoticeBox>
|
||||
);
|
||||
}
|
||||
|
||||
if (pad_closed) {
|
||||
return (
|
||||
<NoticeBox>
|
||||
Launchpad Closed
|
||||
</NoticeBox>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<LaunchpadControl topLevel state={props.state} />
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
import { useBackend } from '../backend';
|
||||
import { Box, Button, Grid, NoticeBox, Section } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
import { LaunchpadControl } from './Launchpad/LaunchpadControl';
|
||||
|
||||
export const LaunchpadConsole = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
const {
|
||||
launchpads = [], selected_id,
|
||||
} = data;
|
||||
|
||||
if (launchpads.length <= 0) {
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content>
|
||||
<NoticeBox>
|
||||
No Pads Connected
|
||||
</NoticeBox>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content>
|
||||
<Section>
|
||||
<Grid>
|
||||
<Grid.Column size={0.6}>
|
||||
<Box
|
||||
style={{
|
||||
'border-right': '2px solid rgba(255, 255, 255, 0.1)',
|
||||
}}
|
||||
minHeight="190px"
|
||||
mr={1}>
|
||||
{launchpads.map(launchpad => (
|
||||
<Button
|
||||
fluid
|
||||
key={launchpad.name}
|
||||
content={launchpad.name}
|
||||
selected={selected_id === launchpad.id}
|
||||
color="transparent"
|
||||
onClick={() => act('select_pad', { id: launchpad.id })} />
|
||||
))}
|
||||
</Box>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
{selected_id ? (
|
||||
<LaunchpadControl />
|
||||
) : (
|
||||
<Box>
|
||||
Please select a pad
|
||||
</Box>
|
||||
)}
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
import { useBackend } from '../backend';
|
||||
import { NoticeBox } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
import { LaunchpadControl } from './Launchpad/LaunchpadControl';
|
||||
|
||||
|
||||
export const LaunchpadRemote = (props, context) => {
|
||||
const { data } = useBackend(context);
|
||||
|
||||
const {
|
||||
has_pad, pad_closed,
|
||||
} = data;
|
||||
|
||||
if (!has_pad) {
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content>
|
||||
<NoticeBox>
|
||||
No Launchpad Connected
|
||||
</NoticeBox>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
}
|
||||
|
||||
if (pad_closed) {
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content>
|
||||
<NoticeBox>
|
||||
Launchpad Closed
|
||||
</NoticeBox>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<LaunchpadControl topLevel />
|
||||
);
|
||||
};
|
||||
@@ -19,9 +19,13 @@ export const NaniteChamberControl = (props, context) => {
|
||||
|
||||
if (status_msg) {
|
||||
return (
|
||||
<NoticeBox textAlign="center">
|
||||
{status_msg}
|
||||
</NoticeBox>
|
||||
<Window>
|
||||
<Window.Content>
|
||||
<NoticeBox textAlign="center">
|
||||
{status_msg}
|
||||
</NoticeBox>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import { NaniteCloudBackupList } from './NaniteCloudControl/NaniteCloudBackupLis
|
||||
import { NaniteDiskBox } from './NaniteCloudControl/NaniteDiskBox';
|
||||
|
||||
export const NaniteCloudControl = (props, context) => {
|
||||
const { state } = props;
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
has_disk,
|
||||
@@ -27,7 +26,7 @@ export const NaniteCloudControl = (props, context) => {
|
||||
disabled={!has_disk}
|
||||
onClick={() => act('eject')} />
|
||||
)}>
|
||||
<NaniteDiskBox state={state} />
|
||||
<NaniteDiskBox />
|
||||
</Section>
|
||||
<Section
|
||||
title="Cloud Storage"
|
||||
@@ -57,11 +56,11 @@ export const NaniteCloudControl = (props, context) => {
|
||||
</Fragment>
|
||||
)
|
||||
)}>
|
||||
{!data.current_view ? (
|
||||
<NaniteCloudBackupList state={state} />
|
||||
{/* {!data.current_view ? (
|
||||
<NaniteCloudBackupList />
|
||||
) : (
|
||||
<NaniteCloudBackupDetails state={state} />
|
||||
)}
|
||||
<NaniteCloudBackupDetails />
|
||||
)} */}
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useBackend } from '../../backend';
|
||||
import { NoticeBox } from '../../components';
|
||||
import { NaniteInfoBox } from "./NaniteInfoBox";
|
||||
|
||||
export const NaniteDiskBox = (props, context) => {
|
||||
const { state } = props;
|
||||
const { data } = state;
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
has_disk, has_program, disk,
|
||||
} = data;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { map } from 'common/collections';
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend } from '../backend';
|
||||
import { Button, LabeledList, NoticeBox, Section, Tabs } from '../components';
|
||||
import { useBackend, useLocalState } from '../backend';
|
||||
import { Button, Flex, LabeledList, NoticeBox, Section, Table, Tabs } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
export const NaniteProgramHub = (props, context) => {
|
||||
@@ -13,6 +13,12 @@ export const NaniteProgramHub = (props, context) => {
|
||||
has_program,
|
||||
programs = {},
|
||||
} = data;
|
||||
|
||||
const [activeCategoryKey, setActiveCategoryKey]
|
||||
= useLocalState(context, 'category', Object.keys(programs)[0]);
|
||||
|
||||
const activeCategory = programs[activeCategoryKey];
|
||||
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content>
|
||||
@@ -66,56 +72,62 @@ export const NaniteProgramHub = (props, context) => {
|
||||
</Fragment>
|
||||
)}>
|
||||
{programs !== null ? (
|
||||
<Tabs vertical>
|
||||
{map((cat_contents, category) => {
|
||||
const progs = cat_contents || [];
|
||||
// Backend was sending stupid data that would have been
|
||||
// annoying to fix
|
||||
const tabLabel = category.substring(0, category.length - 8);
|
||||
return (
|
||||
<Tabs.Tab
|
||||
key={category}
|
||||
label={tabLabel}>
|
||||
{detail_view ? (
|
||||
progs.map(program => (
|
||||
<Section
|
||||
key={program.id}
|
||||
title={program.name}
|
||||
level={2}
|
||||
buttons={(
|
||||
<Button
|
||||
icon="download"
|
||||
content="Download"
|
||||
disabled={!has_disk}
|
||||
onClick={() => act('download', {
|
||||
program_id: program.id,
|
||||
})} />
|
||||
)}>
|
||||
{program.desc}
|
||||
</Section>
|
||||
))
|
||||
) : (
|
||||
<LabeledList>
|
||||
{progs.map(program => (
|
||||
<LabeledList.Item
|
||||
key={program.id}
|
||||
label={program.name}
|
||||
buttons={(
|
||||
<Button
|
||||
icon="download"
|
||||
content="Download"
|
||||
disabled={!has_disk}
|
||||
onClick={() => act('download', {
|
||||
program_id: program.id,
|
||||
})} />
|
||||
)} />
|
||||
))}
|
||||
</LabeledList>
|
||||
)}
|
||||
</Tabs.Tab>
|
||||
);
|
||||
})(programs)}
|
||||
</Tabs>
|
||||
<Flex direction="row">
|
||||
<Flex.Item>
|
||||
<Tabs vertical>
|
||||
{map((cat_contents, category) => {
|
||||
const progs = cat_contents || [];
|
||||
const tabLabel = category.substring(0, category.length - 8);
|
||||
return (
|
||||
<Tabs.Tab
|
||||
key={category}
|
||||
selected={activeCategoryKey===category}
|
||||
onClick={() => setActiveCategoryKey(category)}>
|
||||
{tabLabel}
|
||||
</Tabs.Tab>
|
||||
);
|
||||
})(programs)}
|
||||
</Tabs>
|
||||
</Flex.Item>
|
||||
<Flex.Item grow={1} basis={0}>
|
||||
{detail_view ? (
|
||||
activeCategory.map(program => (
|
||||
<Section
|
||||
key={program.id}
|
||||
title={program.name}
|
||||
level={2}
|
||||
buttons={(
|
||||
<Button
|
||||
icon="download"
|
||||
content="Download"
|
||||
disabled={!has_disk}
|
||||
onClick={() => act('download', {
|
||||
program_id: program.id,
|
||||
})} />
|
||||
)}>
|
||||
{program.desc}
|
||||
</Section>
|
||||
))
|
||||
) : (
|
||||
<LabeledList>
|
||||
{activeCategory.map(program => (
|
||||
<LabeledList.Item
|
||||
key={program.id}
|
||||
label={program.name}
|
||||
buttons={(
|
||||
<Button
|
||||
icon="download"
|
||||
content="Download"
|
||||
disabled={!has_disk}
|
||||
onClick={() => act('download', {
|
||||
program_id: program.id,
|
||||
})} />
|
||||
)} />
|
||||
))}
|
||||
</LabeledList>
|
||||
)}
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
) : (
|
||||
<NoticeBox>
|
||||
No nanite programs are currently researched.
|
||||
@@ -125,4 +137,4 @@ export const NaniteProgramHub = (props, context) => {
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
};
|
||||
@@ -19,9 +19,13 @@ export const NaniteProgrammer = (props, context) => {
|
||||
|
||||
if (!has_disk) {
|
||||
return (
|
||||
<NoticeBox textAlign="center">
|
||||
Insert a nanite program disk
|
||||
</NoticeBox>
|
||||
<Window>
|
||||
<Window.Content>
|
||||
<NoticeBox textAlign="center">
|
||||
Insert a nanite program disk
|
||||
</NoticeBox>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,13 @@ export const NaniteRemote = (props, context) => {
|
||||
|
||||
if (locked) {
|
||||
return (
|
||||
<NoticeBox>
|
||||
This interface is locked.
|
||||
</NoticeBox>
|
||||
<Window>
|
||||
<Window.Content>
|
||||
<NoticeBox>
|
||||
This interface is locked.
|
||||
</NoticeBox>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend } from '../backend';
|
||||
import { useBackend, useLocalState } from '../backend';
|
||||
import { AnimatedNumber, Button, LabeledList, NoticeBox, ProgressBar, Section, Tabs } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
@@ -29,13 +29,28 @@ export const OperatingComputer = (props, context) => {
|
||||
procedures = [],
|
||||
patient = {},
|
||||
} = data;
|
||||
|
||||
const [tab, setTab] = useLocalState(context, 'tab', 'state');
|
||||
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content>
|
||||
<Tabs>
|
||||
<Tabs.Tab
|
||||
key="state"
|
||||
label="Patient State">
|
||||
selected={tab==='state'}
|
||||
onClick={() => setTab('state')}>
|
||||
Patient State
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
key="procedures"
|
||||
selected={tab==='procedures'}
|
||||
onClick={() => setTab('procedures')}>
|
||||
Surgery Procedures
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
{tab === 'state' && (
|
||||
<Fragment>
|
||||
{!table && (
|
||||
<NoticeBox>
|
||||
No Table Detected
|
||||
@@ -124,27 +139,117 @@ export const OperatingComputer = (props, context) => {
|
||||
)}
|
||||
</Section>
|
||||
</Section>
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
key="procedures"
|
||||
label="Surgery Procedures">
|
||||
<Section title="Advanced Surgery Procedures">
|
||||
<Button
|
||||
icon="download"
|
||||
content="Sync Research Database"
|
||||
onClick={() => act('sync')} />
|
||||
{surgeries.map(surgery => (
|
||||
<Section
|
||||
title={surgery.name}
|
||||
key={surgery.name}
|
||||
level={2}>
|
||||
{surgery.desc}
|
||||
</Section>
|
||||
))}
|
||||
</Section>
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
</Fragment>
|
||||
)}
|
||||
{tab === 'procedures' && (
|
||||
<Section title="Advanced Surgery Procedures">
|
||||
<Button
|
||||
icon="download"
|
||||
content="Sync Research Database"
|
||||
onClick={() => act('sync')} />
|
||||
{surgeries.map(surgery => (
|
||||
<Section
|
||||
title={surgery.name}
|
||||
key={surgery.name}
|
||||
level={2}>
|
||||
{surgery.desc}
|
||||
</Section>
|
||||
))}
|
||||
</Section>
|
||||
)}
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
{!table && (
|
||||
<NoticeBox>
|
||||
No Table Detected
|
||||
</NoticeBox>
|
||||
)}
|
||||
<Section>
|
||||
<Section
|
||||
title="Patient State"
|
||||
level={2}>
|
||||
{patient ? (
|
||||
<LabeledList>
|
||||
<LabeledList.Item
|
||||
label="State"
|
||||
color={patient.statstate}>
|
||||
{patient.stat}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Blood Type">
|
||||
{patient.blood_type}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Health">
|
||||
<ProgressBar
|
||||
value={patient.health}
|
||||
minValue={patient.minHealth}
|
||||
maxValue={patient.maxHealth}
|
||||
color={patient.health >= 0 ? 'good' : 'average'}
|
||||
content={(
|
||||
<AnimatedNumber value={patient.health} />
|
||||
)} />
|
||||
</LabeledList.Item>
|
||||
{damageTypes.map(type => (
|
||||
<LabeledList.Item key={type.type} label={type.label}>
|
||||
<ProgressBar
|
||||
value={patient[type.type] / patient.maxHealth}
|
||||
color="bad"
|
||||
content={(
|
||||
<AnimatedNumber value={patient[type.type]} />
|
||||
)} />
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
</LabeledList>
|
||||
) : (
|
||||
'No Patient Detected'
|
||||
)}
|
||||
</Section>
|
||||
<Section
|
||||
title="Initiated Procedures"
|
||||
level={2}>
|
||||
{procedures.length ? (
|
||||
procedures.map(procedure => (
|
||||
<Section
|
||||
key={procedure.name}
|
||||
title={procedure.name}
|
||||
level={3}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Next Step">
|
||||
{procedure.next_step}
|
||||
{procedure.chems_needed && (
|
||||
<Fragment>
|
||||
<b>
|
||||
Required Chemicals:
|
||||
</b>
|
||||
<br />
|
||||
{procedure.chems_needed}
|
||||
</Fragment>
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
{!!data.alternative_step && (
|
||||
<LabeledList.Item label="Alternative Step">
|
||||
{procedure.alternative_step}
|
||||
{procedure.alt_chems_needed && (
|
||||
<Fragment>
|
||||
<b>
|
||||
Required Chemicals:
|
||||
</b>
|
||||
<br />
|
||||
{procedure.alt_chems_needed}
|
||||
</Fragment>
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
</LabeledList>
|
||||
</Section>
|
||||
))
|
||||
) : (
|
||||
'No Active Procedures'
|
||||
)}
|
||||
</Section>
|
||||
</Section>
|
||||
*/
|
||||
@@ -1,17 +1,18 @@
|
||||
import { map } from 'common/collections';
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend } from '../backend';
|
||||
import { Box, Button, Dimmer, Icon, LabeledList, Section, Tabs } from '../components';
|
||||
import { Box, Button, Dimmer, Flex, Icon, LabeledList, Section, Tabs } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
|
||||
export const PersonalCrafting = (props, context) => {
|
||||
const { state } = props;
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
busy,
|
||||
display_craftable_only,
|
||||
display_compact,
|
||||
category,
|
||||
subcategory,
|
||||
} = data;
|
||||
|
||||
const craftingRecipes = map((subcategory, category) => {
|
||||
@@ -25,6 +26,10 @@ export const PersonalCrafting = (props, context) => {
|
||||
firstSubcatName,
|
||||
};
|
||||
})(data.crafting_recipes || {});
|
||||
|
||||
const currentCategory = craftingRecipes.find(recipeTab => {
|
||||
return recipeTab.category === category;
|
||||
});
|
||||
|
||||
// Shows an overlay when crafting an item
|
||||
const busyBox = !!busy && (
|
||||
@@ -59,44 +64,45 @@ export const PersonalCrafting = (props, context) => {
|
||||
</Fragment>
|
||||
)}>
|
||||
<Tabs>
|
||||
{craftingRecipes.map(recipe => (
|
||||
{craftingRecipes.map(recipeTab => (
|
||||
<Tabs.Tab
|
||||
key={recipe.category}
|
||||
label={recipe.category}
|
||||
key={recipeTab.category}
|
||||
onClick={() => act('set_category', {
|
||||
category: recipe.category,
|
||||
category: recipeTab.category,
|
||||
subcategory: recipeTab.firstSubcatName,
|
||||
// Backend expects "0" or "" to indicate no subcategory
|
||||
subcategory: recipe.firstSubcatName,
|
||||
})}>
|
||||
{() => !recipe.hasSubcats && (
|
||||
<CraftingList
|
||||
craftables={recipe.subcategory}
|
||||
state={state} />
|
||||
) || (
|
||||
<Tabs vertical>
|
||||
{map((value, name) => {
|
||||
if (name === "has_subcats") {
|
||||
return;
|
||||
}
|
||||
return (
|
||||
<Tabs.Tab
|
||||
label={name}
|
||||
onClick={() => act('set_category', {
|
||||
subcategory: name,
|
||||
})}>
|
||||
{() => (
|
||||
<CraftingList
|
||||
craftables={value}
|
||||
state={state} />
|
||||
)}
|
||||
</Tabs.Tab>
|
||||
);
|
||||
})(recipe.subcategory)}
|
||||
</Tabs>
|
||||
)}
|
||||
})}
|
||||
selected={category===recipeTab.category}>
|
||||
{recipeTab.category}
|
||||
</Tabs.Tab>
|
||||
))}
|
||||
</Tabs>
|
||||
{!currentCategory.hasSubcats && (
|
||||
<CraftingList craftables={currentCategory.subcategory} />
|
||||
)
|
||||
|| (
|
||||
<Flex direction="row">
|
||||
<Flex.Item>
|
||||
<Tabs vertical>
|
||||
{map((_, subcatName) => (subcatName !== 'has_subcats' && (
|
||||
<Tabs.Tab
|
||||
key={subcatName}
|
||||
onClick={() => act('set_category', {
|
||||
subcategory: subcatName,
|
||||
})}
|
||||
selected={subcategory===subcatName}>
|
||||
{subcatName}
|
||||
</Tabs.Tab>
|
||||
)
|
||||
))(currentCategory.subcategory)}
|
||||
{/* {JSON.stringify(currentCategory.subcategory, null, 2)} */}
|
||||
</Tabs>
|
||||
</Flex.Item>
|
||||
<Flex.Item grow={1} basis={0}>
|
||||
<CraftingList craftables={currentCategory.subcategory[subcategory]} />
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
)}
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
@@ -114,6 +120,7 @@ const CraftingList = (props, context) => {
|
||||
display_compact,
|
||||
display_craftable_only,
|
||||
} = data;
|
||||
|
||||
return craftables.map(craftable => {
|
||||
if (display_craftable_only && !craftability[craftable.ref]) {
|
||||
return null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { classes } from 'common/react';
|
||||
import { useBackend } from '../backend';
|
||||
import { useBackend, useLocalState } from '../backend';
|
||||
import { Box, Button, ColorBox, Flex, LabeledList, Section, Tabs } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
@@ -64,6 +64,11 @@ export const RapidPipeDispenser = (props, context) => {
|
||||
mode,
|
||||
} = data;
|
||||
const previews = data.preview_rows.flatMap(row => row.previews);
|
||||
const [tab, setTab] = useLocalState(context, 'tab', categories[0].cat_name);
|
||||
const activeCategory = categories.find(category => {
|
||||
return category.cat_name === tab;
|
||||
});
|
||||
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content>
|
||||
@@ -164,23 +169,24 @@ export const RapidPipeDispenser = (props, context) => {
|
||||
fluid
|
||||
key={category.cat_name}
|
||||
icon={ICON_BY_CATEGORY_NAME[category.cat_name]}
|
||||
label={category.cat_name}>
|
||||
{() => category.recipes.map(recipe => (
|
||||
<Button.Checkbox
|
||||
key={recipe.pipe_index}
|
||||
fluid
|
||||
ellipsis
|
||||
checked={recipe.selected}
|
||||
content={recipe.pipe_name}
|
||||
title={recipe.pipe_name}
|
||||
onClick={() => act('pipe_type', {
|
||||
pipe_type: recipe.pipe_index,
|
||||
category: category.cat_name,
|
||||
})} />
|
||||
))}
|
||||
onClick={() => setTab(category.cat_name)}>
|
||||
{category.cat_name}
|
||||
</Tabs.Tab>
|
||||
))}
|
||||
</Tabs>
|
||||
{activeCategory.recipes.map(recipe => (
|
||||
<Button.Checkbox
|
||||
key={recipe.pipe_index}
|
||||
fluid
|
||||
ellipsis
|
||||
checked={recipe.selected}
|
||||
content={recipe.pipe_name}
|
||||
title={recipe.pipe_name}
|
||||
onClick={() => act('pipe_type', {
|
||||
pipe_type: recipe.pipe_index,
|
||||
category: activeCategory.cat_name,
|
||||
})} />
|
||||
))}
|
||||
</Section>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { map } from 'common/collections';
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend } from '../backend';
|
||||
import { useBackend, useLocalState } from '../backend';
|
||||
import { Button, LabeledList, Section, Table, Tabs } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
@@ -10,191 +10,209 @@ export const ShuttleManipulator = (props, context) => {
|
||||
const templateObject = data.templates || {};
|
||||
const selected = data.selected || {};
|
||||
const existingShuttle = data.existing_shuttle || {};
|
||||
const [tab, setTab] = useLocalState(context, 'tab', 'status');
|
||||
const [activeTemplate, setActiveTemplate]
|
||||
= useLocalState(context, 'template', Object.keys(templateObject)[0]);
|
||||
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content>
|
||||
<Tabs>
|
||||
<Tabs.Tab
|
||||
key="status"
|
||||
label="Status">
|
||||
<Section>
|
||||
<Table>
|
||||
{shuttles.map(shuttle => (
|
||||
<Table.Row key={shuttle.id}>
|
||||
<Table.Cell>
|
||||
<Button
|
||||
content="JMP"
|
||||
key={shuttle.id}
|
||||
onClick={() => act('jump_to', {
|
||||
type: 'mobile',
|
||||
id: shuttle.id,
|
||||
})} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Button
|
||||
content="Fly"
|
||||
key={shuttle.id}
|
||||
disabled={!shuttle.can_fly}
|
||||
onClick={() => act('fly', {
|
||||
id: shuttle.id,
|
||||
})} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{shuttle.name}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{shuttle.id}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{shuttle.status}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{shuttle.mode}
|
||||
{!!shuttle.timer && (
|
||||
<Fragment>
|
||||
({shuttle.timeleft})
|
||||
<Button
|
||||
content="Fast Travel"
|
||||
key={shuttle.id}
|
||||
disabled={!shuttle.can_fast_travel}
|
||||
onClick={() => act('fast_travel', {
|
||||
id: shuttle.id,
|
||||
})} />
|
||||
</Fragment>
|
||||
)}
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table>
|
||||
</Section>
|
||||
selected={tab==='status'}
|
||||
onClick={() => setTab('status')}>
|
||||
Status
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
key="templates"
|
||||
label="Templates">
|
||||
<Section>
|
||||
<Tabs>
|
||||
{map((template, templateId) => {
|
||||
const templates = template.templates || [];
|
||||
return (
|
||||
<Tabs.Tab
|
||||
key={templateId}
|
||||
label={template.port_id}>
|
||||
{templates.map(actualTemplate => {
|
||||
const isSelected = (
|
||||
actualTemplate.shuttle_id === selected.shuttle_id
|
||||
);
|
||||
// Whoever made the structure being sent is an asshole
|
||||
return (
|
||||
<Section
|
||||
title={actualTemplate.name}
|
||||
level={2}
|
||||
key={actualTemplate.shuttle_id}
|
||||
buttons={(
|
||||
<Button
|
||||
content={isSelected ? 'Selected' : 'Select'}
|
||||
selected={isSelected}
|
||||
onClick={() => act('select_template', {
|
||||
shuttle_id: actualTemplate.shuttle_id,
|
||||
})} />
|
||||
)}>
|
||||
{(!!actualTemplate.description
|
||||
|| !!actualTemplate.admin_notes
|
||||
) && (
|
||||
<LabeledList>
|
||||
{!!actualTemplate.description && (
|
||||
<LabeledList.Item label="Description">
|
||||
{actualTemplate.description}
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
{!!actualTemplate.admin_notes && (
|
||||
<LabeledList.Item label="Admin Notes">
|
||||
{actualTemplate.admin_notes}
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
</LabeledList>
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
})}
|
||||
</Tabs.Tab>
|
||||
);
|
||||
})(templateObject)}
|
||||
</Tabs>
|
||||
</Section>
|
||||
selected={tab==='templates'}
|
||||
onClick={() => setTab('templates')}>
|
||||
Templates
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
key="modification"
|
||||
label="Modification">
|
||||
<Section>
|
||||
{selected ? (
|
||||
<Fragment>
|
||||
<Section
|
||||
level={2}
|
||||
title={selected.name}>
|
||||
{(!!selected.description || !!selected.admin_notes) && (
|
||||
<LabeledList>
|
||||
{!!selected.description && (
|
||||
<LabeledList.Item label="Description">
|
||||
{selected.description}
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
{!!selected.admin_notes && (
|
||||
<LabeledList.Item label="Admin Notes">
|
||||
{selected.admin_notes}
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
</LabeledList>
|
||||
)}
|
||||
</Section>
|
||||
{existingShuttle ? (
|
||||
<Section
|
||||
level={2}
|
||||
title={'Existing Shuttle: ' + existingShuttle.name}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item
|
||||
label="Status"
|
||||
buttons={(
|
||||
<Button
|
||||
content="Jump To"
|
||||
onClick={() => act('jump_to', {
|
||||
type: 'mobile',
|
||||
id: existingShuttle.id,
|
||||
})} />
|
||||
)}>
|
||||
{existingShuttle.status}
|
||||
{!!existingShuttle.timer && (
|
||||
<Fragment>
|
||||
({existingShuttle.timeleft})
|
||||
</Fragment>
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
) : (
|
||||
<Section
|
||||
level={2}
|
||||
title="Existing Shuttle: None" />
|
||||
)}
|
||||
<Section
|
||||
level={2}
|
||||
title="Status">
|
||||
<Button
|
||||
content="Preview"
|
||||
onClick={() => act('preview', {
|
||||
shuttle_id: selected.shuttle_id,
|
||||
})} />
|
||||
<Button
|
||||
content="Load"
|
||||
color="bad"
|
||||
onClick={() => act('load', {
|
||||
shuttle_id: selected.shuttle_id,
|
||||
})} />
|
||||
</Section>
|
||||
</Fragment>
|
||||
) : 'No shuttle selected'}
|
||||
</Section>
|
||||
selected={tab==='modification'}
|
||||
onClick={() => setTab('modification')}>
|
||||
Modification
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
{tab === 'status' && (
|
||||
<Section>
|
||||
<Table>
|
||||
{shuttles.map(shuttle => (
|
||||
<Table.Row key={shuttle.id}>
|
||||
<Table.Cell>
|
||||
<Button
|
||||
content="JMP"
|
||||
key={shuttle.id}
|
||||
onClick={() => act('jump_to', {
|
||||
type: 'mobile',
|
||||
id: shuttle.id,
|
||||
})} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Button
|
||||
content="Fly"
|
||||
key={shuttle.id}
|
||||
disabled={!shuttle.can_fly}
|
||||
onClick={() => act('fly', {
|
||||
id: shuttle.id,
|
||||
})} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{shuttle.name}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{shuttle.id}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{shuttle.status}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{shuttle.mode}
|
||||
{!!shuttle.timer && (
|
||||
<Fragment>
|
||||
({shuttle.timeleft})
|
||||
<Button
|
||||
content="Fast Travel"
|
||||
key={shuttle.id}
|
||||
disabled={!shuttle.can_fast_travel}
|
||||
onClick={() => act('fast_travel', {
|
||||
id: shuttle.id,
|
||||
})} />
|
||||
</Fragment>
|
||||
)}
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table>
|
||||
</Section>
|
||||
)}
|
||||
{tab === 'templates' && (
|
||||
<Section>
|
||||
<Tabs>
|
||||
{map((template, templateId) => {
|
||||
const templates = template.templates || [];
|
||||
return (
|
||||
<Tabs.Tab
|
||||
key={templateId}
|
||||
selected={activeTemplate===templateId}
|
||||
onClick={() => setActiveTemplate(templateId)}>
|
||||
{template.port_id}
|
||||
</Tabs.Tab>
|
||||
);
|
||||
})(templateObject)}
|
||||
</Tabs>
|
||||
{() => {
|
||||
const actualTemplate = templateObject[activeTemplate];
|
||||
const isSelected = (
|
||||
actualTemplate.shuttle_id === selected.shuttle_id
|
||||
);
|
||||
return (
|
||||
<Section
|
||||
title={actualTemplate.name}
|
||||
level={2}
|
||||
key={actualTemplate.shuttle_id}
|
||||
buttons={(
|
||||
<Button
|
||||
content={isSelected ? 'Selected' : 'Select'}
|
||||
selected={isSelected}
|
||||
onClick={() => act('select_template', {
|
||||
shuttle_id: actualTemplate.shuttle_id,
|
||||
})} />
|
||||
)}>
|
||||
{(!!actualTemplate.description
|
||||
|| !!actualTemplate.admin_notes
|
||||
) && (
|
||||
<LabeledList>
|
||||
{!!actualTemplate.description && (
|
||||
<LabeledList.Item label="Description">
|
||||
{actualTemplate.description}
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
{!!actualTemplate.admin_notes && (
|
||||
<LabeledList.Item label="Admin Notes">
|
||||
{actualTemplate.admin_notes}
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
</LabeledList>
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
}}
|
||||
</Section>
|
||||
)}
|
||||
{tab === 'modification' && (
|
||||
<Section>
|
||||
{selected ? (
|
||||
<Fragment>
|
||||
<Section
|
||||
level={2}
|
||||
title={selected.name}>
|
||||
{(!!selected.description || !!selected.admin_notes) && (
|
||||
<LabeledList>
|
||||
{!!selected.description && (
|
||||
<LabeledList.Item label="Description">
|
||||
{selected.description}
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
{!!selected.admin_notes && (
|
||||
<LabeledList.Item label="Admin Notes">
|
||||
{selected.admin_notes}
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
</LabeledList>
|
||||
)}
|
||||
</Section>
|
||||
{existingShuttle ? (
|
||||
<Section
|
||||
level={2}
|
||||
title={'Existing Shuttle: ' + existingShuttle.name}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item
|
||||
label="Status"
|
||||
buttons={(
|
||||
<Button
|
||||
content="Jump To"
|
||||
onClick={() => act('jump_to', {
|
||||
type: 'mobile',
|
||||
id: existingShuttle.id,
|
||||
})} />
|
||||
)}>
|
||||
{existingShuttle.status}
|
||||
{!!existingShuttle.timer && (
|
||||
<Fragment>
|
||||
({existingShuttle.timeleft})
|
||||
</Fragment>
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
) : (
|
||||
<Section
|
||||
level={2}
|
||||
title="Existing Shuttle: None" />
|
||||
)}
|
||||
<Section
|
||||
level={2}
|
||||
title="Status">
|
||||
<Button
|
||||
content="Preview"
|
||||
onClick={() => act('preview', {
|
||||
shuttle_id: selected.shuttle_id,
|
||||
})} />
|
||||
<Button
|
||||
content="Load"
|
||||
color="bad"
|
||||
onClick={() => act('load', {
|
||||
shuttle_id: selected.shuttle_id,
|
||||
})} />
|
||||
</Section>
|
||||
</Fragment>
|
||||
) : 'No shuttle selected'}
|
||||
</Section>
|
||||
)}
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend } from '../backend';
|
||||
import { useBackend, useLocalState } from '../backend';
|
||||
import { Button, LabeledList, NoticeBox, Section, Tabs, Input } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
@@ -13,6 +13,8 @@ export const TelecommsLogBrowser = (props, context) => {
|
||||
selected_logs,
|
||||
} = data;
|
||||
const operational = (selected && selected.status);
|
||||
const [tab, setTab] = useLocalState(context, 'tab', 'servers');
|
||||
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content>
|
||||
@@ -94,84 +96,91 @@ export const TelecommsLogBrowser = (props, context) => {
|
||||
<Tabs>
|
||||
<Tabs.Tab
|
||||
key="servers"
|
||||
label="Servers">
|
||||
<Section>
|
||||
{(servers && servers.length) ? (
|
||||
<LabeledList>
|
||||
{servers.map(server => {
|
||||
return (
|
||||
<LabeledList.Item
|
||||
key={server.name}
|
||||
label={`${server.ref}`}
|
||||
buttons={(
|
||||
<Button
|
||||
content="Connect"
|
||||
selected={data.selected
|
||||
&& (server.ref === data.selected.ref)}
|
||||
onClick={() => act('viewmachine', {
|
||||
'value': server.id,
|
||||
})} />
|
||||
)}>
|
||||
{`${server.name} (${server.id})`}
|
||||
</LabeledList.Item>
|
||||
);
|
||||
})}
|
||||
</LabeledList>
|
||||
) : (
|
||||
'404 Servers not found. Have you tried scanning the network?'
|
||||
)}
|
||||
</Section>
|
||||
selected={tab === 'servers'}
|
||||
onClick={() => setTab('servers')}>
|
||||
Servers
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
key="messages"
|
||||
label="Messages"
|
||||
disabled={!operational}>
|
||||
<Section title="Logs">
|
||||
{(operational && selected_logs) ? (
|
||||
selected_logs.map(logs => {
|
||||
return (
|
||||
<Section
|
||||
level={4}
|
||||
key={logs.ref}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item
|
||||
label="Filename"
|
||||
buttons={(
|
||||
<Button
|
||||
content="Delete"
|
||||
onClick={() => act('delete', {
|
||||
'value': logs.ref,
|
||||
})} />
|
||||
)}>
|
||||
{logs.name}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Data type">
|
||||
{logs.input_type}
|
||||
</LabeledList.Item>
|
||||
{logs.source && (
|
||||
<LabeledList.Item label="Source">
|
||||
{/* eslint-disable-next-line max-len */}
|
||||
{`[${logs.source.name}] (Job: [${logs.source.job}])`}
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
{logs.race && (
|
||||
<LabeledList.Item label="Class">
|
||||
{logs.race}
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
<LabeledList.Item label="Contents">
|
||||
{logs.message}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
"No server selected!"
|
||||
)}
|
||||
</Section>
|
||||
disabled={!operational}
|
||||
selected={tab === 'messages'}
|
||||
onClick={() => setTab('messages')}>
|
||||
Messages
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
{tab === 'servers' && (
|
||||
<Section>
|
||||
{(servers && servers.length) ? (
|
||||
<LabeledList>
|
||||
{servers.map(server => {
|
||||
return (
|
||||
<LabeledList.Item
|
||||
key={server.name}
|
||||
label={`${server.ref}`}
|
||||
buttons={(
|
||||
<Button
|
||||
content="Connect"
|
||||
selected={data.selected
|
||||
&& (server.ref === data.selected.ref)}
|
||||
onClick={() => act('viewmachine', {
|
||||
'value': server.id,
|
||||
})} />
|
||||
)}>
|
||||
{`${server.name} (${server.id})`}
|
||||
</LabeledList.Item>
|
||||
);
|
||||
})}
|
||||
</LabeledList>
|
||||
) : (
|
||||
'404 Servers not found. Have you tried scanning the network?'
|
||||
)}
|
||||
</Section>
|
||||
)}
|
||||
{tab === 'messages' && (
|
||||
<Section title="Logs">
|
||||
{(operational && selected_logs) ? (
|
||||
selected_logs.map(logs => {
|
||||
return (
|
||||
<Section
|
||||
level={4}
|
||||
key={logs.ref}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item
|
||||
label="Filename"
|
||||
buttons={(
|
||||
<Button
|
||||
content="Delete"
|
||||
onClick={() => act('delete', {
|
||||
'value': logs.ref,
|
||||
})} />
|
||||
)}>
|
||||
{logs.name}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Data type">
|
||||
{logs.input_type}
|
||||
</LabeledList.Item>
|
||||
{logs.source && (
|
||||
<LabeledList.Item label="Source">
|
||||
{`[${logs.source.name}] (Job: [${logs.source.job}])`}
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
{logs.race && (
|
||||
<LabeledList.Item label="Class">
|
||||
{logs.race}
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
<LabeledList.Item label="Contents">
|
||||
{logs.message}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
"No server selected!"
|
||||
)}
|
||||
</Section>
|
||||
)}
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user