Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Admin UI and minor fixes #469

Closed
wants to merge 55 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
63191cb
Replaced Icon in Daily Summary with new Icon component
marsian83 Oct 23, 2023
014bd6d
removed fontawesome as it is no longer needed - also removed redundan…
marsian83 Oct 23, 2023
8a42307
Merge branch 'main' of https://github.com/marsian83/arewefastyet
marsian83 Oct 23, 2023
0973cbb
Merge branch 'main' of https://github.com/marsian83/arewefastyet
marsian83 Oct 23, 2023
83bcc79
fix table gap of Macro Benchmark component
marsian83 Oct 23, 2023
417e2c9
Merge branch 'vitessio:main' into main
marsian83 Oct 31, 2023
395e663
Restructure layouts and add admin layout
marsian83 Oct 31, 2023
f104569
Add theme button to admin layout and added 'temp' routes for testing
marsian83 Oct 31, 2023
725c725
Added form implementation with automatic data handling
marsian83 Nov 1, 2023
cf07e17
Added icons - Person, Key
marsian83 Nov 1, 2023
d230171
Add nesting support to DataForm
marsian83 Nov 1, 2023
6373924
Added Admin Login Page
marsian83 Nov 1, 2023
1fc307f
Merge branch 'main' of https://github.com/marsian83/arewefastyet
marsian83 Nov 1, 2023
06dd918
Added license to layout/index.ts
marsian83 Nov 1, 2023
8c08d35
Added license to admin login page
marsian83 Nov 1, 2023
e5bbce2
fix transition in theme when loading first time
marsian83 Nov 1, 2023
96521f8
updated admin login page
marsian83 Nov 1, 2023
c87c676
Add nav to Admin layout and updated admin routes
marsian83 Nov 1, 2023
b787e33
Made Admin Navbar - sidenav
marsian83 Nov 1, 2023
1426e11
add pages to admin panel
marsian83 Nov 1, 2023
cd9f112
Add icon - ssidChart
marsian83 Nov 1, 2023
bb61a35
Add icon - description
marsian83 Nov 1, 2023
4e4ff91
Add icon - logout
marsian83 Nov 1, 2023
ecb77d5
add icon to logout in admin side nav
marsian83 Nov 1, 2023
b61545b
fix props requirement in DataForm
marsian83 Nov 1, 2023
5176d1e
Add Dropdown support to DataForm
marsian83 Nov 1, 2023
e0dca32
update DataForm types
marsian83 Nov 1, 2023
43f4e94
Add name prop to Dropdown
marsian83 Nov 1, 2023
7331d9b
fix button type in Dropdown
marsian83 Nov 1, 2023
f0197fe
Add request section to benchmak admin page
marsian83 Nov 1, 2023
f97bb83
Benchmarking page for admins with dummyData
marsian83 Nov 2, 2023
bf9a96f
Fix the Side Nav
marsian83 Nov 2, 2023
30fe49f
Add type declarations for later use in api calls and ts migration
marsian83 Nov 5, 2023
b80389f
Add types for env
marsian83 Nov 5, 2023
f7aa587
add package - axios
marsian83 Nov 5, 2023
b186d0f
add ts config
marsian83 Nov 6, 2023
c72cdef
add api types
marsian83 Nov 6, 2023
71cbc60
Add implementation for useFetch hook
marsian83 Nov 6, 2023
7b7308f
Add testing page for api calls
marsian83 Nov 6, 2023
94cd8bd
swithced api imeplementation method
marsian83 Nov 6, 2023
555f359
fix rendering issue for execution queue
marsian83 Nov 6, 2023
ac54625
move utils and StatusPage in ts
marsian83 Nov 7, 2023
ba57ace
implement type safe api
marsian83 Nov 7, 2023
5170090
typescript
marsian83 Nov 10, 2023
598796c
synchronization
marsian83 Nov 21, 2023
a19fa2c
Add server side functionality for admin and verification methods in c…
marsian83 Dec 13, 2023
80bd310
incorporate admin functions for delete and request
marsian83 Dec 13, 2023
329d6c3
bugfix
marsian83 Dec 13, 2023
bbfeb64
Merge branch 'vitessio:main' into main
marsian83 Dec 29, 2023
bff4ee4
Fix api endpoints for following pages
harry-sandhu May 25, 2024
cfb698b
fix remaining api endpoints
harry-sandhu May 25, 2024
5d28439
Merge suggestion from code review
marsian83 May 26, 2024
fdd9458
Suggestion from code review
marsian83 May 26, 2024
aab56fa
removed console.log in useApiCall.ts file
harry-sandhu May 26, 2024
ac86dd8
Merge branch 'main' of https://github.com/marsian83/arewefastyet
harry-sandhu May 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions go/server/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,19 @@ func (s *Server) getStatusStats(c *gin.Context) {
c.JSON(http.StatusOK, stats)
}

func (s *Server) validateAdminKey(c *gin.Context) {
pswd := c.Query("key")

if pswd != s.requestRunKey {
errStr := "unauthorized, wrong key"
c.JSON(http.StatusUnauthorized, &ErrorAPI{Error: errStr})
slog.Error(errStr)
return
}

c.JSON(http.StatusOK, "valid")
}

func (s *Server) requestRun(c *gin.Context) {
benchmarkType := c.Query("type")
sha := c.Query("sha")
Expand Down Expand Up @@ -395,7 +408,6 @@ func (s *Server) requestRun(c *gin.Context) {
}
currVersion := git.Version{Major: version}


configs := s.getConfigFiles()
cfg, ok := configs[strings.ToLower(benchmarkType)]
if !ok {
Expand Down Expand Up @@ -450,4 +462,3 @@ func (s *Server) deleteRun(c *gin.Context) {
}
c.JSON(http.StatusOK, "deleted")
}

1 change: 1 addition & 0 deletions go/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ func (s *Server) Run() error {
s.router.GET("/api/status/stats", s.getStatusStats)
s.router.GET("/api/run/request", s.requestRun)
s.router.GET("/api/run/delete", s.deleteRun)
s.router.GET("/api/admin/validate-key", s.validateAdminKey)

return s.router.Run(":" + s.port)
}
Expand Down
5 changes: 0 additions & 5 deletions website/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="./src/assets/logo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script
src="https://kit.fontawesome.com/053006010f.js"
crossorigin="anonymous"
></script>
<title>Vitess | Benchmark</title>

<!-- Open Graph and Twitter Card meta tags -->
Expand Down Expand Up @@ -44,7 +40,6 @@
type="image/png"
/>

<link rel="stylesheet" href="./src/assets/styles/index.css">
</head>
<body>
<div id="root"></div>
Expand Down
1 change: 1 addition & 0 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"dependencies": {
"@nivo/core": "^0.83.0",
"@nivo/line": "^0.83.0",
"axios": "^1.6.0",
"bytes": "^3.1.2",
"dotenv": "^16.1.4",
"moment": "^2.29.4",
Expand Down
36 changes: 36 additions & 0 deletions website/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright 2023 The Vitess Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import { BrowserRouter, Route, Routes } from "react-router-dom";
import React from "react";
import PublicRoute from "./pages/PublicRoute";
import { GlobalProvider } from "./contexts/GlobalContext";

function App() {
return (
<>
<GlobalProvider>
<BrowserRouter>
<Routes>
<Route path="/*" element={<PublicRoute />} />
</Routes>
</BrowserRouter>
</GlobalProvider>
</>
);
}

export default App;
Binary file removed website/src/assets/error.png
Binary file not shown.
Binary file removed website/src/assets/favicon.png
Binary file not shown.
Binary file removed website/src/assets/homeLogo.png
Binary file not shown.
Binary file removed website/src/assets/logo.png
Binary file not shown.
4 changes: 0 additions & 4 deletions website/src/assets/styles/tailwind.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ limitations under the License.
@apply m-0 p-0;
}

:root {
@apply duration-700;
}

/* Declaring Themes */
:root {
--color-primary: 231 112 2;
Expand Down
Binary file removed website/src/assets/vitess-horizontal.png
Binary file not shown.
91 changes: 91 additions & 0 deletions website/src/common/AdminSideNav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import React, { useEffect, useRef, useState } from "react";
import { NavLink } from "react-router-dom";
Comment on lines +1 to +2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Header is missing

import { twMerge } from "tailwind-merge";
import Icon from "./Icon";
import admin from "../utils/admin";

// path relative to "/admin"
const navItems = [
{ title: "Dashboard", to: "/", icon: "person" },
{ title: "Benchmarks", to: "/benchmarks", icon: "ssidChart" },
{ title: "Logs", to: "/logs", icon: "description" },
// { title: "Dummy", to: "/dummy", icon: "key" },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's remove this line if unused

] as const;

export default function AdminSideNav() {
const [width, setWidth] = useState(0);

const navRef = useRef() as React.MutableRefObject<HTMLElement>;

useEffect(() => setWidth(navRef.current.offsetWidth), []);

return (
<>
<div style={{ width }} />
<nav
ref={navRef}
className="h-screen flex flex-col p-6 bg-foreground bg-opacity-10 fixed"
>
<div className="flex items-center gap-x-1 text-3xl pl-3">
<img
src="/logo.png"
alt="vitess logo"
className="h-[1.23em] aspect-square"
/>
<h3 className="font-medium tracking-tight text-primary font-opensans relative after:absolute after:top-full after:right-1 after:content-['admin'] after:text-xs">
arewefastyet
</h3>
</div>

<div className="flex-1 flex flex-col gap-y-1 my-8">
{navItems.map((item, key) => (
<AdminNavLink
to={`/admin${item.to}`}
key={key}
className="flex gap-x-3 items-center"
icon={item.icon}
>
{item.title}
</AdminNavLink>
))}
</div>

<button
onClick={() => admin.logout()}
className="bg-red-600 text-white shadow w-full px-5 py-2 rounded-xl duration-150 flex items-center gap-x-3"
>
<Icon icon={"logout"} className="text-2xl" /> Logout
</button>
</nav>
</>
);
}

interface AdminNavLinkProps {
children?: React.ReactNode;
className?: string;
icon?: React.ComponentPropsWithoutRef<typeof Icon>["icon"];
to: string;
}

function AdminNavLink(props: AdminNavLinkProps) {
return (
<NavLink
className={({ isActive, isPending }) =>
twMerge(
"w-full px-5 py-2 rounded-xl duration-150 flex items-center gap-x-3",
isPending
? "pointer-events-none opacity-50"
: isActive
? "bg-primary pointer-events-none"
: "hover:bg-background",
props.className
)
}
to={props.to}
>
{props.icon && <Icon icon={props.icon} className="text-2xl" />}
{props.children}
</NavLink>
);
}
118 changes: 118 additions & 0 deletions website/src/common/DataForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
Copyright 2023 The Vitess Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React, { useEffect, useState } from "react";
import Dropdown from "./Dropdown";

interface ContainerProps {
children?: React.ReactNode;
onSubmit?: (data: Record<string, string>) => void;
}

//Form implementation by @marsian83 (https://github.com/marsian83)
function Container(
props: ContainerProps & Omit<React.FormHTMLAttributes<HTMLFormElement>, "onSubmit">
) {
const [data, setData] = useState<Record<string, string>>({});

function submitHandler(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
props.onSubmit && props.onSubmit(data);
}

return (
<form {...props} onSubmit={submitHandler}>
<MappedInputs setData={setData}>{props.children}</MappedInputs>
</form>
);
}

function MappedInputs(props: {
children: React.ReactNode;
setData: React.Dispatch<React.SetStateAction<Record<string, string>>>;
}) {
useEffect(() => {
React.Children.forEach(props.children, (child) => {
if (
React.isValidElement(child) &&
child.type === Input &&
child.props.type !== "submit" &&
child.props.name
) {
props.setData((p) => ({
...p,
[child.props.name]:
child.props.defaultValue || child.props.value || "",
}));
}
});
}, []);

return (
<>
{React.Children.map(props.children, (child, key) => {
if (React.isValidElement(child))
if (child.type === Input)
return React.cloneElement(child as React.ReactElement, {
key,
onChange: (event: React.ChangeEvent<HTMLInputElement>) => {
props.setData((p) => ({
...p,
[child.props.name]: event.target.value,
}));
},
});
else if (child.type === Dropdown.Container) {
return React.cloneElement(child as React.ReactElement, {
key,
onChange: (event: { value: string }) => {
props.setData((p) => ({
...p,
[child.props.name]: event.value,
}));
},
});
} else if (child.props.children)
return React.cloneElement(child as React.ReactElement, {
key,
children: (
<MappedInputs setData={props.setData}>
{child.props.children}
</MappedInputs>
),
});
return child;
})}
</>
);
}

type InputProps =
| {
type?: React.InputHTMLAttributes<HTMLInputElement>["type"];
name: string;
}
| { type: "submit"; name?: string };

type InputAttributes = React.InputHTMLAttributes<HTMLInputElement>;

function Input(props: InputProps & Partial<InputAttributes>) {
return <input {...props} />;
}

const DataForm = { Container, Input };

export default DataForm;
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";

export default function DisplayList(props) {
interface DisplayListProps {
data: Array<object>;
}

export default function DisplayList(props: DisplayListProps) {
const { data } = props;

return (
Expand All @@ -38,7 +41,7 @@ export default function DisplayList(props) {
>
{Object.keys(val).map((item, key) => (
<td className="border-b py-3 text-center" key={key}>
{val[item]}
{val[item as keyof typeof val]}
</td>
))}
</tr>
Expand Down
Loading