streamable ftbuild logs

This commit is contained in:
Bobby
2021-06-17 21:30:28 +10:00
parent baaf859d2d
commit 5b55b9f9f3
5 changed files with 233 additions and 9 deletions

View File

@@ -19,6 +19,7 @@
"@monaco-editor/react": "^4.1.0",
"@tinymce/tinymce-react": "^3.4.0",
"algoliasearch": "^4.8.6",
"ansi-to-react": "^6.1.5",
"chroma-js": "^2.1.0",
"csv-parse": "^4.15.3",
"date-fns": "^2.19.0",
@@ -30,6 +31,7 @@
"json2csv": "^5.0.6",
"jszip": "^3.6.0",
"lodash": "^4.17.21",
"moment": "^2.29.1",
"query-string": "^6.8.3",
"react": "^16.9.0",
"react-beautiful-dnd": "^13.0.0",

View File

@@ -142,15 +142,17 @@ export default function SparksEditor() {
</>
}
actions={{
primary:showForceSave ? {
children: "Force Save",
onClick: handleSave,
}:{
children: "Save Changes",
onClick: handleSave,
disabled:!isSparksValid || localSparks === tableState?.config.sparks ,
},
primary: showForceSave
? {
children: "Force Save",
onClick: handleSave,
}
: {
children: "Save Changes",
onClick: handleSave,
disabled:
!isSparksValid || localSparks === tableState?.config.sparks,
},
secondary: {
children: "Cancel",
onClick: handleClose,

View File

@@ -0,0 +1,192 @@
import React, { useState } from "react";
import useRouter from "hooks/useRouter";
import useTable from "hooks/useFiretable/useTable";
import { useFiretableContext } from "contexts/FiretableContext";
import _camelCase from "lodash/camelCase";
import _get from "lodash/get";
import _find from "lodash/find";
import _sortBy from "lodash/sortBy";
import moment from "moment";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import { Chip } from "@material-ui/core";
import Modal from "components/Modal";
import { makeStyles } from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";
import Box from "@material-ui/core/Box";
import LogsIcon from "@material-ui/icons/QueryBuilder";
import TableHeaderButton from "./TableHeaderButton";
import Ansi from "ansi-to-react";
import PropTypes from "prop-types";
function a11yProps(index) {
return {
id: `vertical-tab-${index}`,
"aria-controls": `vertical-tabpanel-${index}`,
};
}
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
backgroundColor: theme.palette.background.paper,
display: "flex",
height: "80vh",
},
tabs: {
borderRight: `1px solid ${theme.palette.divider}`,
},
logPanel: {
width: "100%",
},
logEntryWrapper: {
overflowY: "scroll",
maxHeight: "100%",
},
logNumber: {
float: "left",
width: "3em",
textAlign: "right",
paddingRight: "1em",
},
logEntry: {
lineBreak: "anywhere",
paddingLeft: "3em",
whiteSpace: "break-spaces",
userSelect: "text",
},
}));
LogPanel.propTypes = {
logs: PropTypes.array,
index: PropTypes.any.isRequired,
value: PropTypes.any.isRequired,
};
function LogRow({ logString, index }) {
const classes = useStyles();
return (
<Box>
<Typography variant="body2" className={classes.logNumber}>
{index}
</Typography>
<Typography variant="body2" className={classes.logEntry}>
<Ansi>{logString.replaceAll("\\n", "\n").replaceAll("\\t", "\t")}</Ansi>
</Typography>
</Box>
);
}
function LogPanel(props) {
const { logs, value, index, ...other } = props;
const classes = useStyles();
return (
<div
role="tabpanel"
hidden={value !== index}
id={`vertical-tabpanel-${index}`}
aria-labelledby={`vertical-tab-${index}`}
className={classes.logPanel}
{...other}
>
{value === index && (
<Box p={3} className={classes.logEntryWrapper}>
{logs?.map((log, index) => {
return <LogRow logString={log} index={index} />;
})}
</Box>
)}
</div>
);
}
export default function TableLogs() {
const router = useRouter();
const { tableState } = useFiretableContext();
const classes = useStyles();
const [open, setOpen] = useState(false);
const [tabIndex, setTabIndex] = React.useState(0);
const tableCollection = decodeURIComponent(router.match.params.id);
const ftBuildStreamID =
"_FIRETABLE_/settings/schema/" +
tableCollection
.split("/")
.filter(function (_, i) {
// replace IDs with subTables that appears at even indexes
return i % 2 === 0;
})
.join("/subTables/");
const [collectionState] = useTable({
path: `${ftBuildStreamID}/ftBuildLogs`,
orderBy: [{ key: "startTimeStamp", direction: "desc" }],
});
const handleTabChange = (event, newValue) => {
setTabIndex(newValue);
};
const handleClose = () => {
setOpen(false);
};
return (
<>
<TableHeaderButton
title="Table Logs"
onClick={() => setOpen(true)}
icon={<LogsIcon />}
/>
{open && !!tableState && (
<Modal
onClose={handleClose}
maxWidth="xl"
fullWidth
title={
<>
Build Logs <Chip label="ALPHA" size="small" />
</>
}
children={
<>
<div className={classes.root}>
<Tabs
orientation="vertical"
variant="scrollable"
value={tabIndex}
onChange={handleTabChange}
className={classes.tabs}
>
{collectionState.rows.map((value, index) => (
<Tab
label={moment(value.startTimeStamp).format(
"MMMM D YYYY h:mm:ssa"
)}
{...a11yProps(index)}
/>
))}
</Tabs>
{collectionState.rows.map((logEntry, index) => (
<LogPanel
value={tabIndex}
index={index}
logs={logEntry?.fullLog}
/>
))}
</div>
</>
}
/>
)}
</>
);
}

View File

@@ -18,6 +18,7 @@ import Filters from "../Filters";
import ImportCSV from "./ImportCsv";
import Export from "./Export";
import TableSettings from "./TableSettings";
import TableLogs from "./TableLogs";
import HiddenFields from "../HiddenFields";
import Sparks from "./Sparks";
import ReExecute from "./ReExecute";
@@ -219,6 +220,10 @@ export default function TableHeader({
</Grid>
)}
<Grid item>
<TableLogs />
</Grid>
<Grid item>
<TableSettings />
</Grid>

View File

@@ -3109,6 +3109,11 @@ alphanum-sort@^1.0.0:
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=
anser@^1.4.1:
version "1.4.10"
resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.10.tgz#befa3eddf282684bd03b63dcda3927aef8c2e35b"
integrity sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==
ansi-align@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f"
@@ -3192,6 +3197,14 @@ ansi-styles@^4.1.0:
"@types/color-name" "^1.1.1"
color-convert "^2.0.1"
ansi-to-react@^6.1.5:
version "6.1.5"
resolved "https://registry.yarnpkg.com/ansi-to-react/-/ansi-to-react-6.1.5.tgz#00ca9e4f566b468f0aa6a213f34b752b3e7121a9"
integrity sha512-u7fkGMK+p6keOtgExruUDVmEnTBAWizlHJXzx9eJxw4rCVE6omzm0Gw4BQmB9oUPr0WriYf7Wyprms8uL8eL5Q==
dependencies:
anser "^1.4.1"
escape-carriage "^1.3.0"
ansicolors@~0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979"
@@ -5921,6 +5934,11 @@ escalade@^3.1.0:
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
escape-carriage@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/escape-carriage/-/escape-carriage-1.3.0.tgz#71006b2d4da8cb6828686addafcb094239c742f3"
integrity sha512-ATWi5MD8QlAGQOeMgI8zTp671BG8aKvAC0M7yenlxU4CRLGO/sKthxVUyjiOFKjHdIo+6dZZUNFgHFeVEaKfGQ==
escape-goat@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675"
@@ -10136,6 +10154,11 @@ mkdirp@^1.0.3:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
moment@^2.29.1:
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
monaco-editor@^0.21.2:
version "0.21.2"
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.21.2.tgz#37054e63e480d51a2dd17d609dcfb192304d5605"