Skip to content

Commit

Permalink
Merge pull request #1554 from dappnode/pablo/add-rollups-tab
Browse files Browse the repository at this point in the history
Add rollups tab
  • Loading branch information
pablomendezroyo authored Sep 25, 2023
2 parents a5eb997 + 1b6743e commit 2fbc993
Show file tree
Hide file tree
Showing 53 changed files with 1,921 additions and 331 deletions.
4 changes: 2 additions & 2 deletions packages/admin-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
},
"dependencies": {
"@dappnode/common": "^0.1.0",
"@dappnode/eventbus": "^0.1.0",
"@dappnode/dappmanager": "^0.1.0",
"@dappnode/types": "^0.1.25",
"@dappnode/eventbus": "^0.1.0",
"@dappnode/types": "^0.1.26",
"@reduxjs/toolkit": "^1.3.5",
"@types/clipboard": "^2.0.7",
"@types/node": "^18.11.18",
Expand Down
157 changes: 84 additions & 73 deletions packages/admin-ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,102 +15,113 @@ import { Login } from "./start-pages/Login";
import { Register } from "./start-pages/Register";
import { NoConnection } from "start-pages/NoConnection";
// Types
import { Theme, UsageMode } from "types";
import { AppContextIface, Theme, UiModuleStatus } from "types";

export const UsageContext = React.createContext({
usage: "advanced",
toggleUsage: () => {}
});

export const ThemeContext = React.createContext({
export const AppContext = React.createContext<AppContextIface>({
theme: "light",
toggleTheme: () => {}
stakersModuleStatus: "enabled",
rollupsModuleStatus: "disabled",
toggleTheme: () => {},
toggleStakersModuleStatus: () => {},
toggleRollupsModuleStatus: () => {}
});

const useLocalStorage = <T extends string>(
key: string,
initialValue: T
): [T, React.Dispatch<React.SetStateAction<T>>] => {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
// Assert that either the item or initialValue is of type T
return (item as T) || initialValue;
} catch (error) {
return initialValue;
}
});

useEffect(() => {
window.localStorage.setItem(key, storedValue);
}, [key, storedValue]);

return [storedValue, setStoredValue];
};

function MainApp({ username }: { username: string }) {
// App is the parent container of any other component.
// If this re-renders, the whole app will. So DON'T RERENDER APP!
// Check ONCE what is the status of the VPN and redirect to the login page.

const [screenWidth, setScreenWidth] = useState(window.screen.width);

//const storedUsage = localStorage.getItem("usage");
const storedTheme = localStorage.getItem("theme");
//const initialUsage = storedUsage === "advanced" ? "advanced" : "basic";
const initialUsage = "advanced";
const initialTheme =
storedTheme === "light" || storedTheme === "dark" ? storedTheme : "light";

const [theme, setTheme] = useState<Theme>(initialTheme);
const [usage, setUsage] = useState<UsageMode>(initialUsage);

const toggleTheme = () => {
setTheme(curr => (curr === "light" ? "dark" : "light"));
};

const toggleUsage = () => {
setUsage(curr => (curr === "basic" ? "advanced" : "basic"));
};

useEffect(() => {
localStorage.setItem("theme", theme);
}, [theme]);

useEffect(() => {
localStorage.setItem("usage", usage);
}, [usage]);
const [screenWidth, setScreenWidth] = useState(window.innerWidth);
const [theme, setTheme] = useLocalStorage<Theme>("theme", "light");
const [stakersModuleStatus, setStakersModuleStatus] = useLocalStorage<
UiModuleStatus
>("stakersModuleStatus", "enabled");
const [rollupsModuleStatus, setRollupsModuleStatus] = useLocalStorage<
UiModuleStatus
>("rollupsModuleStatus", "disabled");

useEffect(() => {
const handleResize = () => setScreenWidth(window.innerWidth);
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, [screenWidth]);
}, []);

// Scroll to top on pathname change
const screenLocation = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [screenLocation.pathname]);

const appContext: AppContextIface = {
theme,
stakersModuleStatus,
rollupsModuleStatus,
toggleTheme: () =>
setTheme((curr: Theme) => (curr === "light" ? "dark" : "light")),
toggleStakersModuleStatus: () =>
setStakersModuleStatus((curr: UiModuleStatus) =>
curr === "enabled" ? "disabled" : "enabled"
),
toggleRollupsModuleStatus: () =>
setRollupsModuleStatus((curr: UiModuleStatus) =>
curr === "enabled" ? "disabled" : "enabled"
)
};

return (
<UsageContext.Provider value={{ usage, toggleUsage }}>
<ThemeContext.Provider value={{ theme, toggleTheme }}>
<div className="body" id={theme}>
<SideBar screenWidth={screenWidth} />
<TopBar
username={username}
theme={theme}
toggleUsage={toggleUsage}
toggleTheme={toggleTheme}
/>
<div id="main">
<ErrorBoundary>
<NotificationsMain />
</ErrorBoundary>
<Routes>
{Object.values(pages).map(({ RootComponent, rootPath }) => (
<Route
key={rootPath}
path={rootPath}
element={
<ErrorBoundary>
<RootComponent />
</ErrorBoundary>
}
/>
))}
{/* Redirection for routes with hashes */}
{/* 404 routes redirect to dashboard or default page */}
<Route path="*" element={<DefaultRedirect />} />
</Routes>
</div>

{/* Place here non-page components */}
<Welcome />
<ToastContainer />
<AppContext.Provider value={appContext}>
<div className="body" id={theme}>
<SideBar screenWidth={screenWidth} />
<TopBar username={username} appContext={appContext} />
<div id="main">
<ErrorBoundary>
<NotificationsMain />
</ErrorBoundary>
<Routes>
{/** Provide the app context only to the dashboard (where the modules switch is handled) */}
{Object.values(pages).map(({ RootComponent, rootPath }) => (
<Route
key={rootPath}
path={rootPath}
element={
<ErrorBoundary>
<RootComponent />
</ErrorBoundary>
}
/>
))}
{/* Redirection for routes with hashes */}
{/* 404 routes redirect to dashboard or default page */}
<Route path="*" element={<DefaultRedirect />} />
</Routes>
</div>
</ThemeContext.Provider>
</UsageContext.Provider>

{/* Place here non-page components */}
<Welcome />
<ToastContainer />
</div>
</AppContext.Provider>
);
}

Expand Down
128 changes: 122 additions & 6 deletions packages/admin-ui/src/__mock-backend__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,11 @@ export const otherCalls: Omit<Routes, keyof typeof namedSpacedCalls> = {
ethProvider: "http://geth.dappnode:8545",
fullnodeDomainTarget: "geth.dnp.dappnode.eth",
newFeatureIds: [
"repository",
"repository-fallback",
"system-auto-updates",
"enable-ethical-metrics",
"change-host-password"
//"repository",
//"repository-fallback",
//"system-auto-updates",
//"enable-ethical-metrics",
//"change-host-password"
]
}),
natRenewalEnable: async () => {},
Expand All @@ -252,7 +252,123 @@ export const otherCalls: Omit<Routes, keyof typeof namedSpacedCalls> = {
mail: "@example.com",
isEnabled: true
}),
disableEthicalMetrics: async () => {}
disableEthicalMetrics: async () => {},
optimismConfigGet: async () => ({
executionClients: [
{
status: "ok",
dnpName: "op-geth.dnp.dappnode.eth",
avatarUrl: "",
isInstalled: true,
isUpdated: true,
isRunning: true,
data: {
dnpName: "package",
reqVersion: "0.1.0",
semVersion: "0.1.0",
imageFile: {
hash: "QM..",
source: "ipfs",
size: 123
},
warnings: {},
signedSafe: true,
metadata: {
name: "geth.dnp.dappnode.eth",
description: "Go implementation of ethereum. Execution client",
shortDescription: "Go implementation of ethereum",
version: "0.1.0"
}
},
isSelected: true,
enableHistorical: true
},
{
status: "ok",
dnpName: "op-erigon.dnp.dappnode.eth",
avatarUrl: "",
isInstalled: true,
isUpdated: true,
isRunning: true,
data: {
dnpName: "package",
reqVersion: "0.1.0",
semVersion: "0.1.0",
imageFile: {
hash: "QM..",
source: "ipfs",
size: 123
},
warnings: {},
signedSafe: true,
metadata: {
name: "geth.dnp.dappnode.eth",
description: "Go implementation of ethereum. Execution client",
shortDescription: "Go implementation of ethereum",
version: "0.1.0"
}
},
isSelected: false,
enableHistorical: false
}
],
rollup: {
status: "ok",
dnpName: "op-node.dnp.dappnode.eth",
avatarUrl: "",
isInstalled: false,
isUpdated: false,
isRunning: true,
data: {
dnpName: "package",
reqVersion: "0.1.0",
semVersion: "0.1.0",
imageFile: {
hash: "QM..",
source: "ipfs",
size: 123
},
warnings: {},
signedSafe: true,
metadata: {
name: "geth.dnp.dappnode.eth",
description: "Go implementation of ethereum. Execution client",
shortDescription: "Go implementation of ethereum",
version: "0.1.0"
}
},
isSelected: false,
mainnetRpcUrl: ""
},
archive: {
status: "ok",
dnpName: "op-l2geth.dnp.dappnode.eth",
avatarUrl: "",
isInstalled: false,
isUpdated: false,
isRunning: true,
data: {
dnpName: "package",
reqVersion: "0.1.0",
semVersion: "0.1.0",
imageFile: {
hash: "QM..",
source: "ipfs",
size: 123
},
warnings: {},
signedSafe: true,
metadata: {
name: "geth.dnp.dappnode.eth",
description: "Go implementation of ethereum. Execution client",
shortDescription: "Go implementation of ethereum",
version: "0.1.0"
}
},
isSelected: true
}
}),
optimismConfigSet: async () => {}
};

export const calls: Routes = {
Expand Down
Loading

0 comments on commit 2fbc993

Please sign in to comment.