Replit Commit

This commit is contained in:
Dunemask 2022-05-05 12:35:47 +00:00
commit f49f965a42
41 changed files with 32720 additions and 0 deletions

23
src/Dashboard.jsx Normal file
View file

@ -0,0 +1,23 @@
import { useContext } from "react";
// Import Contexts
import { JobProvider } from "./ctx/JobContext.jsx";
import { ViewProvider } from "./ctx/ViewContext.jsx";
import { StoreProvider } from "./ctx/StoreContext.jsx";
// Import Views
import Views from "./Views.jsx";
export default function Dashboard() {
return (
<div className="qualiteer">
<JobProvider>
<StoreProvider>
<ViewProvider>
<Views />
</ViewProvider>
</StoreProvider>
</JobProvider>
</div>
);
}

95
src/Views.jsx Normal file
View file

@ -0,0 +1,95 @@
import { useContext, useState } from "react";
import ViewContext from "./ctx/ViewContext.jsx";
import * as React from 'react';
import AppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
import Toolbar from '@mui/material/Toolbar';
import IconButton from '@mui/material/IconButton';
import Typography from '@mui/material/Typography';
import Menu from '@mui/material/Menu';
import MenuIcon from '@mui/icons-material/Menu';
import Container from '@mui/material/Container';
import Avatar from '@mui/material/Avatar';
import Button from '@mui/material/Button';
import Tooltip from '@mui/material/Tooltip';
import MenuItem from '@mui/material/MenuItem';
import Drawer from '@mui/material/Drawer';
import ListItem from '@mui/material/ListItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import List from '@mui/material/List';
import ListItemButton from '@mui/material/ListItemButton';
import NotificationsIcon from '@mui/icons-material/Notifications';
import WorkIcon from '@mui/icons-material/Work';
import FormatListBulletedIcon from '@mui/icons-material/FormatListBulleted';
import SettingsIcon from '@mui/icons-material/Settings';
import ErrorIcon from '@mui/icons-material/Error';
const pages = ["failing", "alerting", "jobs", "tests", "settings"];
const icons = [ErrorIcon , NotificationsIcon, WorkIcon,FormatListBulletedIcon, SettingsIcon];
export default function Views() {
const [view, setView] = useState(pages[0]);
const [drawerOpen, setDrawer] = React.useState(false);
const toggleDrawer = () => setDrawer(!drawerOpen);
const closeDrawer = () => setDrawer(false);
const openPage = (e) => setView(e.target.outerText.toLowerCase());
return (
<AppBar position="static" color="secondary">
<Container maxWidth="xl">
<Toolbar disableGutters>
<Drawer
open={drawerOpen}
onClose={closeDrawer}
> <Box
sx={{ width: 250 }}
role="presentation"
>
<List>
{pages.map((text, index) => (
<ListItemButton key={text} onClick={openPage} selected={view===text}>
<ListItemIcon>
{/*icons[index]*/}
</ListItemIcon>
<ListItemText primary={text.charAt(0).toUpperCase() + text.slice(1)} />
</ListItemButton>
))}
</List></Box>
</Drawer>
<IconButton
size="large"
edge="start"
color="inherit"
aria-label="menu"
sx={{ mr: 2 }}
onClick={toggleDrawer}
>
<MenuIcon />
</IconButton>
<Typography
variant="h6"
noWrap
component="div"
sx={{ mr: 2, display: { xs: 'none', md: 'flex' } }}
>
{view.charAt(0).toUpperCase() + view.slice(1)}
</Typography>
<Typography
variant="h6"
noWrap
component="div"
sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}
>
{view.charAt(0).toUpperCase() + view.slice(1)}
</Typography>
<Box sx={{ flexGrow: 0 }}>
<Avatar alt="Remy Sharp" src="/assets/QA.jpg" />
</Box>
</Toolbar>
</Container>
</AppBar>
);
}

57
src/ctx/JobContext.jsx Normal file
View file

@ -0,0 +1,57 @@
import React, { useReducer, createContext, useMemo } from "react";
const JobContext = createContext();
const ACTIONS = {
CREATE: "c",
UPDATE: "u",
DELETE: "d",
};
const initialState = {
jobs: [],
};
const reducer = (state, action) => {
// Current Jobs
const { jobs } = state;
var jobIndex;
// Actions
switch (action.type) {
case ACTIONS.CREATE:
jobs.push(action.job);
return { ...state, jobs };
case ACTIONS.UPDATE:
jobIndex = jobs.find((j) => j.id === (action.job.id ?? action.jobId));
jobs[jobIndex] = action.job;
return { ...state, jobs };
case ACTIONS.DELETE:
jobIndex = jobs.find((j) => j.id === action.jobId);
jobs.splice(jobIndex, 1);
return { ...state, jobs };
default:
return state;
}
};
export const JobProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, initialState);
const context = {
state,
dispatch,
jobUpdate: (job, jobId) => dispatch({ type: ACTIONS.UPDATE, jobId, job }),
jobCreate: (job) =>
dispatch({ type: ACTIONS.CREATE, job: { ...job, log: [] } }),
jobDelete: (jobId) => dispatch({ type: ACTIONS.DELETE, jobId }),
};
const contextValue = useMemo(() => context, [state, dispatch]);
return (
<JobContext.Provider value={contextValue}>{children}</JobContext.Provider>
);
};
export default JobContext;

37
src/ctx/StoreContext.jsx Normal file
View file

@ -0,0 +1,37 @@
import React, { useReducer, createContext, useMemo } from "react";
const StoreContext = createContext();
const ACTIONS = {
UPDATE: "u",
};
const initialState = {};
const reducer = (state, action) => {
// Actions
switch (action.type) {
case ACTIONS.UPDATE:
return { ...state, ...store };
default:
return state;
}
};
export const StoreProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, initialState);
const context = {
state,
dispatch,
updateStore: (store) => dispatch(state, { type: ACTIONS.UPDATE, store }),
};
const contextValue = useMemo(() => context, [state, dispatch]);
return (
<StoreContext.Provider value={contextValue}>
{children}
</StoreContext.Provider>
);
};
export default StoreContext;

32
src/ctx/ViewContext.jsx Normal file
View file

@ -0,0 +1,32 @@
import React, { useReducer, createContext, useMemo } from "react";
const ViewContext = createContext();
const ACTIONS = {
UPDATE: "u",
};
const initialState = {
activePage: "Home",
};
const reducer = (state, action) => {
// Actions
switch (action.type) {
case ACTIONS.UPDATE:
return { ...state };
default:
return state;
}
};
export const ViewProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, initialState);
const contextValue = useMemo(() => ({ state, dispatch }), [state, dispatch]);
return (
<ViewContext.Provider value={contextValue}>{children}</ViewContext.Provider>
);
};
export default ViewContext;

7
src/index.js Normal file
View file

@ -0,0 +1,7 @@
import { createRoot } from "react-dom/client";
import Dashboard from "./Dashboard.jsx";
const appRoot = document.getElementById("root");
const root = createRoot(appRoot);
root.render(<Dashboard />);

14
src/runner/JobDisplay.jsx Normal file
View file

@ -0,0 +1,14 @@
function jobDisplay({ props }) {
return (
<div className="job">
<h2>Job ID: {props.job.id}</h2>
<h3>Log: </h3>
{props.job.log.map((l, i) => (
<div className="line" key={i}>
{l}
<br />
</div>
))}
</div>
);
}

49
src/runner/JobView.jsx Normal file
View file

@ -0,0 +1,49 @@
import { useContext } from "react";
import { Initiator } from "qualiteer/web-clients";
import JobContext, { ACTIONS as jobActions } from "../../ctx/JobContext.jsx";
const cmd = `node other.js`;
export default function Test() {
const { state: jobState, dispatch: jobDispatch } = useContext(JobContext);
function onLog(d) {
const job = jobState.jobs[0];
job.log.push(d);
jobDispatch({ type: jobActions.UPDATE, jobId: jobState.jobs[0].id, job });
console.log(d);
console.log(jobState);
}
async function startJob() {
console.log("Wanting to start");
const url = "https://Qualiteer.elijahparker3.repl.co";
// Create an initiator and make a job request
const primary = new Initiator(url);
const jobRequest = { command: cmd };
const job = await primary.newJob(jobRequest, onLog, () =>
console.log("Primary Job Concluded")
);
jobDispatch({ type: jobActions.CREATE, job: { ...job, log: [] } });
console.log("Started");
}
return (
<div className="Jobs">
<h1>vv Info vv </h1>
<button onClick={startJob}>Start</button>
{jobState.jobs.map((j) =>
j.log.map((l, i) => (
<div className="line" key={i}>
{l}
<br />
</div>
))
)}
</div>
);
/*
}*/
}