Restyle and support logs.
This commit is contained in:
parent
02e2053bdf
commit
a40bb93abb
@ -41,5 +41,9 @@
|
|||||||
"last 1 firefox version",
|
"last 1 firefox version",
|
||||||
"last 1 safari version"
|
"last 1 safari version"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
||||||
|
"prettier": "^3.2.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
83
src/App.tsx
83
src/App.tsx
@ -1,53 +1,64 @@
|
|||||||
import {
|
import {QueryClient, QueryClientProvider, useQuery, useQueryClient,} from '@tanstack/react-query'
|
||||||
useQuery,
|
import React, {useState} from "react";
|
||||||
useMutation,
|
import {fetchAllStatuses, fetchLogs} from './utils/data-utils';
|
||||||
useQueryClient,
|
import Modal from './Modal'
|
||||||
QueryClient,
|
|
||||||
QueryClientProvider,
|
|
||||||
} from '@tanstack/react-query'
|
|
||||||
import {fetchAllStatuses} from './utils/data-utils';
|
|
||||||
|
|
||||||
// Create a client
|
// Create a client
|
||||||
const queryClient = new QueryClient()
|
const queryClient = new QueryClient()
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (// Provide the client to your App
|
||||||
// Provide the client to your App
|
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<center>
|
<StatusTable/>
|
||||||
<StatusTable />
|
</QueryClientProvider>)
|
||||||
</center>
|
|
||||||
</QueryClientProvider>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function StatusTable() {
|
function StatusTable() {
|
||||||
// Access the client
|
// Access the client
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
const [logId, setLogId] = useState("");
|
||||||
|
|
||||||
// Queries
|
// Queries
|
||||||
const query = useQuery({ queryKey: ['allStatus'], queryFn: fetchAllStatuses })
|
const query = useQuery({queryKey: ['allStatus'], queryFn: fetchAllStatuses})
|
||||||
|
const queryLog = useQuery({queryKey: ['log', logId], queryFn: () => fetchLogs(logId)});
|
||||||
|
|
||||||
return (
|
return (<div>
|
||||||
<table id="all-status">
|
{logId && (<Modal open={true}>
|
||||||
<tr>
|
<button className="close" onClick={() => setLogId("")}>CLOSE</button>
|
||||||
<th>URL</th>
|
<div className="log-data">
|
||||||
<th>Application</th>
|
<pre>{queryLog.data}</pre>
|
||||||
<th>Status</th>
|
</div>
|
||||||
<th>Last Update</th>
|
</Modal>)}
|
||||||
<th>Request ID</th>
|
<div id="all-status">
|
||||||
</tr>
|
{query.data?.map((status: any) => <div className={status.lastState.toLowerCase() + " status-row"}>
|
||||||
{query.data?.map((status: any) =>
|
<div className="status-line">
|
||||||
<tr className={"tr-status " + status.lastState.toLowerCase()}>
|
<span className="status-key">Request ID:</span>
|
||||||
<td className="td-url">{status.deployment && <a href={status.url}>{status.url}</a>}</td>
|
<span className="status-value">{status.id}</span>
|
||||||
<td className="td-app-crn">{status.app}</td>
|
</div>
|
||||||
<td className="td-status">{status.lastState}</td>
|
<div className="status-line">
|
||||||
<td className="td-last-update">{status.lastUpdate}</td>
|
<span className="status-key">Application:</span>
|
||||||
<td className="td-id">{status.id}</td>
|
<span className="status-value">{status.app}</span>
|
||||||
</tr>
|
</div>
|
||||||
)}
|
{status.deployment && <div className="status-line">
|
||||||
</table>
|
<span className="status-key">URL:</span>
|
||||||
)
|
<span className="status-value"><a href={status.url}>{status.url}</a></span>
|
||||||
|
</div>}
|
||||||
|
<div className="status-line">
|
||||||
|
<span className="status-key">Last Update:</span>
|
||||||
|
<span className="status-value">{status.lastUpdate}</span>
|
||||||
|
</div>
|
||||||
|
<div className="status-line">
|
||||||
|
<span className="status-key">Last State:</span>
|
||||||
|
<span className="status-value">{(status.logAvailable &&
|
||||||
|
<button className={"button-" + status.lastState.toLowerCase()}
|
||||||
|
onClick={() => {
|
||||||
|
queryClient.invalidateQueries({queryKey: ["log"]}).then(() => setLogId(status.id))
|
||||||
|
}}>{status.lastState}
|
||||||
|
</button>) || status.lastState}</span>
|
||||||
|
</div>
|
||||||
|
</div>)}
|
||||||
|
</div>
|
||||||
|
</div>)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
37
src/Modal.tsx
Normal file
37
src/Modal.tsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import {Component} from "react";
|
||||||
|
|
||||||
|
const MODAL_STYLES = {
|
||||||
|
position: "absolute" as "absolute",
|
||||||
|
backgroundColor: "#FFF",
|
||||||
|
marginTop: "2em",
|
||||||
|
padding: "2em",
|
||||||
|
zIndex: "1000",
|
||||||
|
width: "75%",
|
||||||
|
height: "85%",
|
||||||
|
borderRadius: ".5em",
|
||||||
|
};
|
||||||
|
const OVERLAY_STYLE = {
|
||||||
|
position: "fixed" as "fixed",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
top: "0",
|
||||||
|
left: "0",
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
backgroundColor: "rgba(0,0,0, .8)",
|
||||||
|
zIndex: "1000",
|
||||||
|
};
|
||||||
|
|
||||||
|
class Modal extends Component<{ open: any, children: any }> {
|
||||||
|
render() {
|
||||||
|
let {open, children} = this.props;
|
||||||
|
if (!open) return null;
|
||||||
|
return (<>
|
||||||
|
<div style={OVERLAY_STYLE}>
|
||||||
|
<div style={MODAL_STYLES}>{children}</div>
|
||||||
|
</div>
|
||||||
|
</>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Modal;
|
@ -5,6 +5,7 @@ body {
|
|||||||
sans-serif;
|
sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
@ -12,41 +13,60 @@ code {
|
|||||||
monospace;
|
monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
#all-status {
|
#all-status {
|
||||||
width: 85%;
|
margin: auto;
|
||||||
|
min-width: 50%;
|
||||||
|
max-width: 75%;
|
||||||
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#all-status td {
|
.log-data {
|
||||||
padding: 0.3em;
|
overflow: auto;
|
||||||
|
color: grey;
|
||||||
|
background-color: black;
|
||||||
|
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
|
||||||
|
width: 98%;
|
||||||
|
height: 95%;
|
||||||
|
padding: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
.status-row {
|
||||||
border-collapse:separate;
|
width: auto;
|
||||||
border:solid lightblue 1px;
|
background-color: white;
|
||||||
border-radius:6px;
|
padding: 1em;
|
||||||
|
margin: 1em;
|
||||||
|
border-radius: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
td, th {
|
.status-key {
|
||||||
border-left:solid lightblue 1px;
|
font-weight: bold;
|
||||||
border-top:solid lightblue 1px;
|
margin-right: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
.status-value {
|
||||||
border-top: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
td:first-child, th:first-child {
|
|
||||||
border-left: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.deployed {
|
.deployed {
|
||||||
background-color: #ddffdd;
|
background-color: #ddffdd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button-deployed {
|
||||||
|
background-color: lawngreen;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
background-color: #ffdddd;
|
background-color: #ffdddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button-error {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
.cancelled {
|
.cancelled {
|
||||||
background-color: #efefef;
|
background-color: #efefef;
|
||||||
text-color: #dddddd;
|
text-color: #dddddd;
|
||||||
@ -64,18 +84,3 @@ td:first-child, th:first-child {
|
|||||||
.deploying {
|
.deploying {
|
||||||
background-color: #fff1dd;
|
background-color: #fff1dd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tr-status {
|
|
||||||
font-size: small;
|
|
||||||
font-family: 'Courier New', Courier, monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
.td-id {
|
|
||||||
font-size: xx-small;
|
|
||||||
}
|
|
||||||
|
|
||||||
.td-last-update{
|
|
||||||
}
|
|
||||||
|
|
||||||
.td-status{
|
|
||||||
}
|
|
@ -6,3 +6,16 @@ export const fetchAllStatuses = async () => {
|
|||||||
}
|
}
|
||||||
return await res.json();
|
return await res.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const fetchLogs = async (id: string) => {
|
||||||
|
if (!id) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
let url = `http://localhost:9555/log/${id}`
|
||||||
|
const res = await fetch(url);
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Network response was not ok')
|
||||||
|
}
|
||||||
|
return await res.text();
|
||||||
|
}
|
32
yarn.lock
32
yarn.lock
@ -87,7 +87,7 @@
|
|||||||
"@jridgewell/trace-mapping" "^0.3.17"
|
"@jridgewell/trace-mapping" "^0.3.17"
|
||||||
jsesc "^2.5.1"
|
jsesc "^2.5.1"
|
||||||
|
|
||||||
"@babel/helper-annotate-as-pure@^7.22.5":
|
"@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.22.5":
|
||||||
version "7.22.5"
|
version "7.22.5"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882"
|
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882"
|
||||||
integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==
|
integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==
|
||||||
@ -127,6 +127,21 @@
|
|||||||
"@babel/helper-split-export-declaration" "^7.22.6"
|
"@babel/helper-split-export-declaration" "^7.22.6"
|
||||||
semver "^6.3.1"
|
semver "^6.3.1"
|
||||||
|
|
||||||
|
"@babel/helper-create-class-features-plugin@^7.21.0":
|
||||||
|
version "7.23.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.10.tgz#25d55fafbaea31fd0e723820bb6cc3df72edf7ea"
|
||||||
|
integrity sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-annotate-as-pure" "^7.22.5"
|
||||||
|
"@babel/helper-environment-visitor" "^7.22.20"
|
||||||
|
"@babel/helper-function-name" "^7.23.0"
|
||||||
|
"@babel/helper-member-expression-to-functions" "^7.23.0"
|
||||||
|
"@babel/helper-optimise-call-expression" "^7.22.5"
|
||||||
|
"@babel/helper-replace-supers" "^7.22.20"
|
||||||
|
"@babel/helper-skip-transparent-expression-wrappers" "^7.22.5"
|
||||||
|
"@babel/helper-split-export-declaration" "^7.22.6"
|
||||||
|
semver "^6.3.1"
|
||||||
|
|
||||||
"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.15", "@babel/helper-create-regexp-features-plugin@^7.22.5":
|
"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.15", "@babel/helper-create-regexp-features-plugin@^7.22.5":
|
||||||
version "7.22.15"
|
version "7.22.15"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1"
|
resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1"
|
||||||
@ -380,6 +395,16 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703"
|
||||||
integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==
|
integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==
|
||||||
|
|
||||||
|
"@babel/plugin-proposal-private-property-in-object@^7.21.11":
|
||||||
|
version "7.21.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz#69d597086b6760c4126525cfa154f34631ff272c"
|
||||||
|
integrity sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-annotate-as-pure" "^7.18.6"
|
||||||
|
"@babel/helper-create-class-features-plugin" "^7.21.0"
|
||||||
|
"@babel/helper-plugin-utils" "^7.20.2"
|
||||||
|
"@babel/plugin-syntax-private-property-in-object" "^7.14.5"
|
||||||
|
|
||||||
"@babel/plugin-syntax-async-generators@^7.8.4":
|
"@babel/plugin-syntax-async-generators@^7.8.4":
|
||||||
version "7.8.4"
|
version "7.8.4"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d"
|
||||||
@ -7676,6 +7701,11 @@ prelude-ls@~1.1.2:
|
|||||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||||
integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==
|
integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==
|
||||||
|
|
||||||
|
prettier@^3.2.5:
|
||||||
|
version "3.2.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368"
|
||||||
|
integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==
|
||||||
|
|
||||||
pretty-bytes@^5.3.0, pretty-bytes@^5.4.1:
|
pretty-bytes@^5.3.0, pretty-bytes@^5.4.1:
|
||||||
version "5.6.0"
|
version "5.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
|
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
|
||||||
|
Loading…
Reference in New Issue
Block a user