mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-20 05:05:47 +01:00
parent
187226a30f
commit
9697a82e0c
@ -239,9 +239,12 @@ export function refreshTheme(): void {
|
|||||||
},
|
},
|
||||||
MuiIconButton: {
|
MuiIconButton: {
|
||||||
styleOverrides: {
|
styleOverrides: {
|
||||||
root: {
|
root: ({ ownerState }) => ({
|
||||||
color: Settings.theme.primary,
|
color: Settings.theme.primary,
|
||||||
},
|
...(ownerState.disableRipple && {
|
||||||
|
p: 0,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
MuiTooltip: {
|
MuiTooltip: {
|
||||||
|
@ -1,21 +1,68 @@
|
|||||||
/**
|
import type { WorkerScript } from "../../Netscript/WorkerScript";
|
||||||
* Root React Component for the "Active Scripts" UI page. This page displays
|
import React, { useState } from "react";
|
||||||
* and provides information about all of the player's scripts that are currently running
|
|
||||||
*/
|
import { MenuItem, Typography, Select, SelectChangeEvent, TextField, IconButton, List } from "@mui/material";
|
||||||
import React from "react";
|
import { FirstPage, KeyboardArrowLeft, KeyboardArrowRight, LastPage, Search } from "@mui/icons-material";
|
||||||
|
|
||||||
import { ScriptProduction } from "./ScriptProduction";
|
import { ScriptProduction } from "./ScriptProduction";
|
||||||
import { ServerAccordions } from "./ServerAccordions";
|
import { ServerAccordion } from "./ServerAccordion";
|
||||||
|
|
||||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
import { workerScripts } from "../../Netscript/WorkerScripts";
|
||||||
|
import { getRecordEntries } from "../../Types/Record";
|
||||||
|
import { Settings } from "../../Settings/Settings";
|
||||||
|
import { isPositiveInteger } from "../../types";
|
||||||
|
|
||||||
import Typography from "@mui/material/Typography";
|
export function ActiveScriptsPage(): React.ReactElement {
|
||||||
|
const [scriptsPerPage, setScriptsPerPage] = useState(Settings.ActiveScriptsScriptPageSize);
|
||||||
|
const [serversPerPage, setServersPerPage] = useState(Settings.ActiveScriptsServerPageSize);
|
||||||
|
const [filter, setFilter] = useState("");
|
||||||
|
const [page, setPage] = useState(0);
|
||||||
|
|
||||||
interface IProps {
|
function changeScriptsPerPage(e: SelectChangeEvent<number>) {
|
||||||
workerScripts: Map<number, WorkerScript>;
|
const n = parseInt(e.target.value as string);
|
||||||
}
|
if (!isPositiveInteger(n)) return;
|
||||||
|
Settings.ActiveScriptsScriptPageSize = n;
|
||||||
|
setScriptsPerPage(n);
|
||||||
|
}
|
||||||
|
function changeServersPerPage(e: SelectChangeEvent<number>) {
|
||||||
|
const n = parseInt(e.target.value as string);
|
||||||
|
if (!isPositiveInteger(n)) return;
|
||||||
|
Settings.ActiveScriptsServerPageSize = n;
|
||||||
|
setServersPerPage(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
const serverData: [string, WorkerScript[]][] = (() => {
|
||||||
|
const tempData: Record<string, WorkerScript[]> = {};
|
||||||
|
if (filter) {
|
||||||
|
// Only check filtering if a filter exists (performance)
|
||||||
|
for (const ws of workerScripts.values()) {
|
||||||
|
if (!ws.hostname.includes(filter) && !ws.scriptRef.filename.includes(filter)) continue;
|
||||||
|
const hostname = ws.hostname;
|
||||||
|
if (tempData[hostname]) tempData[hostname].push(ws);
|
||||||
|
else tempData[hostname] = [ws];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const ws of workerScripts.values()) {
|
||||||
|
const hostname = ws.hostname;
|
||||||
|
if (tempData[hostname]) tempData[hostname].push(ws);
|
||||||
|
else tempData[hostname] = [ws];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getRecordEntries(tempData);
|
||||||
|
})();
|
||||||
|
|
||||||
|
const lastPage = Math.max(Math.ceil(serverData.length / serversPerPage) - 1, 0);
|
||||||
|
function changePage(n: number) {
|
||||||
|
if (!Number.isInteger(n) || n > lastPage || n < 0) return;
|
||||||
|
setPage(n);
|
||||||
|
}
|
||||||
|
if (page > lastPage) changePage(lastPage);
|
||||||
|
|
||||||
|
const adjustedIndex = page * serversPerPage;
|
||||||
|
const dataToShow = serverData.slice(adjustedIndex, adjustedIndex + serversPerPage);
|
||||||
|
const firstServerNumber = serverData.length === 0 ? 0 : adjustedIndex + 1;
|
||||||
|
const lastServerNumber = serverData.length === 0 ? 0 : adjustedIndex + dataToShow.length;
|
||||||
|
|
||||||
export function ActiveScriptsPage(props: IProps): React.ReactElement {
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Typography>
|
<Typography>
|
||||||
@ -25,7 +72,50 @@ export function ActiveScriptsPage(props: IProps): React.ReactElement {
|
|||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<ScriptProduction />
|
<ScriptProduction />
|
||||||
<ServerAccordions {...props} />
|
<div style={{ width: "100%", display: "flex", alignItems: "center" }}>
|
||||||
|
<TextField
|
||||||
|
value={filter}
|
||||||
|
onChange={(e) => setFilter(e.target.value)}
|
||||||
|
autoFocus
|
||||||
|
InputProps={{ startAdornment: <Search />, spellCheck: false }}
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
<Typography marginLeft="1em">Servers/page:</Typography>
|
||||||
|
<Select value={serversPerPage} onChange={changeServersPerPage}>
|
||||||
|
<MenuItem value={10}>10</MenuItem>
|
||||||
|
<MenuItem value={15}>15</MenuItem>
|
||||||
|
<MenuItem value={20}>20</MenuItem>
|
||||||
|
<MenuItem value={100}>100</MenuItem>
|
||||||
|
</Select>
|
||||||
|
<Typography marginLeft="1em">Scripts/page:</Typography>
|
||||||
|
<Select value={scriptsPerPage} onChange={changeScriptsPerPage}>
|
||||||
|
<MenuItem value={10}>10</MenuItem>
|
||||||
|
<MenuItem value={15}>15</MenuItem>
|
||||||
|
<MenuItem value={20}>20</MenuItem>
|
||||||
|
<MenuItem value={100}>100</MenuItem>
|
||||||
|
</Select>
|
||||||
|
<Typography
|
||||||
|
marginLeft="auto"
|
||||||
|
marginRight="1em"
|
||||||
|
>{`${firstServerNumber}-${lastServerNumber} of ${serverData.length}`}</Typography>
|
||||||
|
<IconButton onClick={() => changePage(0)} disabled={page === 0}>
|
||||||
|
<FirstPage />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton onClick={() => changePage(page - 1)} disabled={page === 0}>
|
||||||
|
<KeyboardArrowLeft />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton onClick={() => changePage(page + 1)} disabled={page === lastPage}>
|
||||||
|
<KeyboardArrowRight />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton onClick={() => changePage(lastPage)} disabled={page === lastPage}>
|
||||||
|
<LastPage />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
<List dense={true}>
|
||||||
|
{dataToShow.map(([hostname, scripts]) => (
|
||||||
|
<ServerAccordion key={hostname} hostname={hostname} scripts={scripts} />
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,9 @@ import Tab from "@mui/material/Tab";
|
|||||||
|
|
||||||
import { ActiveScriptsPage } from "./ActiveScriptsPage";
|
import { ActiveScriptsPage } from "./ActiveScriptsPage";
|
||||||
import { RecentScriptsPage } from "./RecentScriptsPage";
|
import { RecentScriptsPage } from "./RecentScriptsPage";
|
||||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
|
||||||
import { useRerender } from "../React/hooks";
|
import { useRerender } from "../React/hooks";
|
||||||
|
|
||||||
interface IProps {
|
export function ActiveScriptsRoot(): React.ReactElement {
|
||||||
workerScripts: Map<number, WorkerScript>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function ActiveScriptsRoot(props: IProps): React.ReactElement {
|
|
||||||
const [tab, setTab] = useState<"active" | "recent">("active");
|
const [tab, setTab] = useState<"active" | "recent">("active");
|
||||||
useRerender(400);
|
useRerender(400);
|
||||||
|
|
||||||
@ -29,7 +24,7 @@ export function ActiveScriptsRoot(props: IProps): React.ReactElement {
|
|||||||
<Tab label={"Recently Killed"} value={"recent"} />
|
<Tab label={"Recently Killed"} value={"recent"} />
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
{tab === "active" && <ActiveScriptsPage workerScripts={props.workerScripts} />}
|
{tab === "active" && <ActiveScriptsPage />}
|
||||||
{tab === "recent" && <RecentScriptsPage />}
|
{tab === "recent" && <RecentScriptsPage />}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -16,26 +16,30 @@ import ExpandMore from "@mui/icons-material/ExpandMore";
|
|||||||
import ExpandLess from "@mui/icons-material/ExpandLess";
|
import ExpandLess from "@mui/icons-material/ExpandLess";
|
||||||
import { ServerAccordionContent } from "./ServerAccordionContent";
|
import { ServerAccordionContent } from "./ServerAccordionContent";
|
||||||
|
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
|
||||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||||
|
|
||||||
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
|
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
|
||||||
|
import { GetServer } from "../../Server/AllServers";
|
||||||
|
|
||||||
interface IProps {
|
interface ServerAccordionProps {
|
||||||
server: BaseServer;
|
hostname: string;
|
||||||
workerScripts: WorkerScript[];
|
scripts: WorkerScript[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ServerAccordion(props: IProps): React.ReactElement {
|
export function ServerAccordion({ hostname, scripts }: ServerAccordionProps): React.ReactElement {
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
const server = props.server;
|
const server = GetServer(hostname);
|
||||||
|
if (!server) {
|
||||||
|
console.error(`Invalid server ${hostname} while displaying active scripts`);
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
// Accordion's header text
|
// Accordion's header text
|
||||||
// TODO: calculate the longest hostname length rather than hard coding it
|
// TODO: calculate the longest hostname length rather than hard coding it
|
||||||
const longestHostnameLength = 18;
|
const longestHostnameLength = 18;
|
||||||
const paddedName = `${server.hostname}${" ".repeat(longestHostnameLength)}`.slice(
|
const paddedName = `${hostname}${" ".repeat(longestHostnameLength)}`.slice(
|
||||||
0,
|
0,
|
||||||
Math.max(server.hostname.length, longestHostnameLength),
|
Math.max(hostname.length, longestHostnameLength),
|
||||||
);
|
);
|
||||||
const barOptions = {
|
const barOptions = {
|
||||||
progress: server.ramUsed / server.maxRam,
|
progress: server.ramUsed / server.maxRam,
|
||||||
@ -44,16 +48,16 @@ export function ServerAccordion(props: IProps): React.ReactElement {
|
|||||||
const headerTxt = `${paddedName} ${createProgressBarText(barOptions)}`;
|
const headerTxt = `${paddedName} ${createProgressBarText(barOptions)}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box component={Paper}>
|
<Paper>
|
||||||
<ListItemButton onClick={() => setOpen((old) => !old)}>
|
<ListItemButton onClick={() => setOpen((old) => !old)}>
|
||||||
<ListItemText primary={<Typography style={{ whiteSpace: "pre-wrap" }}>{headerTxt}</Typography>} />
|
<ListItemText primary={<Typography style={{ whiteSpace: "pre-wrap" }}>{headerTxt}</Typography>} />
|
||||||
{open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
|
{open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
<Box mx={2}>
|
<Box mx={2}>
|
||||||
<Collapse in={open} timeout={0} unmountOnExit>
|
<Collapse in={open} timeout={0} unmountOnExit>
|
||||||
<ServerAccordionContent workerScripts={props.workerScripts} />
|
<ServerAccordionContent scripts={scripts} />
|
||||||
</Collapse>
|
</Collapse>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Paper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,47 +1,56 @@
|
|||||||
|
// TODO: Probably roll this into the ServerAccordion component, no real need for a separate component
|
||||||
|
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||||
import { WorkerScriptAccordion } from "./WorkerScriptAccordion";
|
import { WorkerScriptAccordion } from "./WorkerScriptAccordion";
|
||||||
import List from "@mui/material/List";
|
import { IconButton, List, Typography } from "@mui/material";
|
||||||
import TablePagination from "@mui/material/TablePagination";
|
|
||||||
import { TablePaginationActionsAll } from "../React/TablePaginationActionsAll";
|
|
||||||
import { Settings } from "../../Settings/Settings";
|
import { Settings } from "../../Settings/Settings";
|
||||||
|
import { FirstPage, KeyboardArrowLeft, KeyboardArrowRight, LastPage } from "@mui/icons-material";
|
||||||
|
|
||||||
interface IProps {
|
interface ServerActiveScriptsProps {
|
||||||
workerScripts: WorkerScript[];
|
scripts: WorkerScript[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ServerAccordionContent(props: IProps): React.ReactElement {
|
export function ServerAccordionContent({ scripts }: ServerActiveScriptsProps): React.ReactElement {
|
||||||
const [page, setPage] = useState(0);
|
const [page, setPage] = useState(0);
|
||||||
const [rowsPerPage, setRowsPerPage] = useState(Settings.ActiveScriptsScriptPageSize);
|
if (scripts.length === 0) {
|
||||||
const handleChangePage = (event: unknown, newPage: number): void => {
|
console.error(`Attempted to display a server in active scripts when there were no matching scripts to show`);
|
||||||
setPage(newPage);
|
return <></>;
|
||||||
};
|
}
|
||||||
|
const scriptsPerPage = Settings.ActiveScriptsScriptPageSize;
|
||||||
|
const lastPage = Math.ceil(scripts.length / scriptsPerPage) - 1;
|
||||||
|
function changePage(n: number) {
|
||||||
|
if (!Number.isInteger(n) || n > lastPage || n < 0) return;
|
||||||
|
setPage(n);
|
||||||
|
}
|
||||||
|
if (page > lastPage) changePage(lastPage);
|
||||||
|
|
||||||
const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>): void => {
|
const firstScriptNumber = page * scriptsPerPage + 1;
|
||||||
Settings.ActiveScriptsScriptPageSize = parseInt(event.target.value, 10);
|
const lastScriptNumber = Math.min((page + 1) * scriptsPerPage, scripts.length);
|
||||||
setRowsPerPage(parseInt(event.target.value, 10));
|
|
||||||
setPage(0);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{props.workerScripts.length > 10 ? (
|
<div style={{ width: "100%", display: "flex", alignItems: "center" }}>
|
||||||
<TablePagination
|
<Typography
|
||||||
rowsPerPageOptions={[10, 15, 20, 100]}
|
component="span"
|
||||||
component="div"
|
marginRight="auto"
|
||||||
count={props.workerScripts.length}
|
>{`Displaying scripts ${firstScriptNumber}-${lastScriptNumber} of ${scripts.length}`}</Typography>
|
||||||
rowsPerPage={rowsPerPage}
|
<IconButton onClick={() => changePage(0)} disabled={page === 0}>
|
||||||
page={page}
|
<FirstPage />
|
||||||
onPageChange={handleChangePage}
|
</IconButton>
|
||||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
<IconButton onClick={() => changePage(page - 1)} disabled={page === 0}>
|
||||||
ActionsComponent={TablePaginationActionsAll}
|
<KeyboardArrowLeft />
|
||||||
/>
|
</IconButton>
|
||||||
) : (
|
<IconButton onClick={() => changePage(page + 1)} disabled={page === lastPage}>
|
||||||
""
|
<KeyboardArrowRight />
|
||||||
)}
|
</IconButton>
|
||||||
|
<IconButton onClick={() => changePage(lastPage)} disabled={page === lastPage}>
|
||||||
|
<LastPage />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
<List dense disablePadding>
|
<List dense disablePadding>
|
||||||
{props.workerScripts.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((ws) => (
|
{scripts.slice(page * scriptsPerPage, page * scriptsPerPage + scriptsPerPage).map((ws) => (
|
||||||
<WorkerScriptAccordion key={`${ws.pid}`} workerScript={ws} />
|
<WorkerScriptAccordion key={ws.pid} workerScript={ws} />
|
||||||
))}
|
))}
|
||||||
</List>
|
</List>
|
||||||
</>
|
</>
|
||||||
|
@ -1,135 +0,0 @@
|
|||||||
/**
|
|
||||||
* React Component for rendering the Accordion elements for all servers
|
|
||||||
* on which scripts are running
|
|
||||||
*/
|
|
||||||
import React, { useState } from "react";
|
|
||||||
|
|
||||||
import { ServerAccordion } from "./ServerAccordion";
|
|
||||||
|
|
||||||
import TextField from "@mui/material/TextField";
|
|
||||||
import List from "@mui/material/List";
|
|
||||||
import TablePagination from "@mui/material/TablePagination";
|
|
||||||
import Grid from "@mui/material/Grid";
|
|
||||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
|
||||||
import { GetServer } from "../../Server/AllServers";
|
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
|
||||||
import { Settings } from "../../Settings/Settings";
|
|
||||||
import { TablePaginationActionsAll } from "../React/TablePaginationActionsAll";
|
|
||||||
import SearchIcon from "@mui/icons-material/Search";
|
|
||||||
import { matchScriptPathUnanchored } from "../../utils/helpers/scriptKey";
|
|
||||||
import lodash from "lodash";
|
|
||||||
|
|
||||||
// Map of server hostname -> all workerscripts on that server for all active scripts
|
|
||||||
interface IServerData {
|
|
||||||
server: BaseServer;
|
|
||||||
workerScripts: WorkerScript[];
|
|
||||||
}
|
|
||||||
|
|
||||||
type IServerToScriptsMap = Record<string, IServerData | undefined>;
|
|
||||||
|
|
||||||
interface IProps {
|
|
||||||
workerScripts: Map<number, WorkerScript>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function ServerAccordions(props: IProps): React.ReactElement {
|
|
||||||
const [filter, setFilter] = useState("");
|
|
||||||
const [page, setPage] = useState(0);
|
|
||||||
const [rowsPerPage, setRowsPerPage] = useState(Settings.ActiveScriptsServerPageSize);
|
|
||||||
|
|
||||||
const handleChangePage = (event: unknown, newPage: number): void => {
|
|
||||||
setPage(newPage);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>): void => {
|
|
||||||
Settings.ActiveScriptsServerPageSize = parseInt(event.target.value, 10);
|
|
||||||
setRowsPerPage(parseInt(event.target.value, 10));
|
|
||||||
setPage(0);
|
|
||||||
};
|
|
||||||
|
|
||||||
function handleFilterChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
|
||||||
setFilter(event.target.value);
|
|
||||||
setPage(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const serverToScriptMap: IServerToScriptsMap = {};
|
|
||||||
for (const ws of props.workerScripts.values()) {
|
|
||||||
const server = GetServer(ws.hostname);
|
|
||||||
if (server == null) {
|
|
||||||
console.warn(`WorkerScript has invalid hostname: ${ws.hostname}`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = serverToScriptMap[server.hostname];
|
|
||||||
|
|
||||||
if (data === undefined) {
|
|
||||||
serverToScriptMap[server.hostname] = {
|
|
||||||
server: server,
|
|
||||||
workerScripts: [],
|
|
||||||
};
|
|
||||||
data = serverToScriptMap[server.hostname];
|
|
||||||
}
|
|
||||||
if (data !== undefined) {
|
|
||||||
// Add only scripts that correspond to the filter
|
|
||||||
if (ws.hostname.includes(filter) || ws.name.includes(filter)) {
|
|
||||||
data.workerScripts.push(ws);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match filter in the scriptname part of the key
|
|
||||||
const pattern = matchScriptPathUnanchored(lodash.escapeRegExp(filter));
|
|
||||||
const filtered = Object.values(serverToScriptMap).filter((data) => {
|
|
||||||
if (!data) return false;
|
|
||||||
if (data.server.hostname.includes(filter)) return true;
|
|
||||||
for (const k of data.server.runningScriptMap.keys()) {
|
|
||||||
if (pattern.test(k)) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Grid container>
|
|
||||||
<Grid item xs={4}>
|
|
||||||
<TextField
|
|
||||||
value={filter}
|
|
||||||
onChange={handleFilterChange}
|
|
||||||
autoFocus
|
|
||||||
InputProps={{
|
|
||||||
startAdornment: <SearchIcon />,
|
|
||||||
spellCheck: false,
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
paddingTop: "8px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={8}>
|
|
||||||
{filtered.length > 10 ? (
|
|
||||||
<TablePagination
|
|
||||||
rowsPerPageOptions={[10, 15, 20, 100]}
|
|
||||||
component="div"
|
|
||||||
count={filtered.length}
|
|
||||||
rowsPerPage={rowsPerPage}
|
|
||||||
page={page}
|
|
||||||
onPageChange={handleChangePage}
|
|
||||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
|
||||||
ActionsComponent={TablePaginationActionsAll}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
<List dense={true}>
|
|
||||||
{filtered.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((data) => {
|
|
||||||
return (
|
|
||||||
data && (
|
|
||||||
<ServerAccordion key={data.server.hostname} server={data.server} workerScripts={data.workerScripts} />
|
|
||||||
)
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</List>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
@ -51,7 +51,6 @@ import { StaneksGiftRoot } from "../CotMG/ui/StaneksGiftRoot";
|
|||||||
import { staneksGift } from "../CotMG/Helper";
|
import { staneksGift } from "../CotMG/Helper";
|
||||||
import { CharacterOverview } from "./React/CharacterOverview";
|
import { CharacterOverview } from "./React/CharacterOverview";
|
||||||
import { BladeburnerCinematic } from "../Bladeburner/ui/BladeburnerCinematic";
|
import { BladeburnerCinematic } from "../Bladeburner/ui/BladeburnerCinematic";
|
||||||
import { workerScripts } from "../Netscript/WorkerScripts";
|
|
||||||
import { Unclickable } from "../Exploits/Unclickable";
|
import { Unclickable } from "../Exploits/Unclickable";
|
||||||
import { Snackbar, SnackbarProvider } from "./React/Snackbar";
|
import { Snackbar, SnackbarProvider } from "./React/Snackbar";
|
||||||
import { LogBoxManager } from "./React/LogBoxManager";
|
import { LogBoxManager } from "./React/LogBoxManager";
|
||||||
@ -254,7 +253,7 @@ export function GameRoot(): React.ReactElement {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Page.ActiveScripts: {
|
case Page.ActiveScripts: {
|
||||||
mainPage = <ActiveScriptsRoot workerScripts={workerScripts} />;
|
mainPage = <ActiveScriptsRoot />;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Page.Hacknet: {
|
case Page.Hacknet: {
|
||||||
|
Loading…
Reference in New Issue
Block a user