Skip to content

Commit

Permalink
Merge pull request PelicanPlatform#624 from CannonLock/fix-config-page
Browse files Browse the repository at this point in the history
Update the config page to consume {Value: <>, Type: <>} ConfigValue[]
  • Loading branch information
haoming29 authored Jan 9, 2024
2 parents cc216be + 021d8d2 commit a569faa
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 59 deletions.
122 changes: 70 additions & 52 deletions web_ui/frontend/app/config/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ import {
Typography,
Skeleton,
Link,
Container, Tooltip
Container,
Tooltip
} from "@mui/material";
import React, {useEffect, useState} from "react";
import {OverridableStringUnion} from "@mui/types";
import {Variant} from "@mui/material/styles/createTypography";
import {TypographyPropsVariantOverrides} from "@mui/material/Typography";
import TextField from "@mui/material/TextField";
import {AppRegistration, ArrowDropDown, ArrowDropUp, AssistantDirection, TripOrigin} from '@mui/icons-material';
import {fontSize} from "@mui/system"
import {isLoggedIn} from "@/helpers/login";
import {Sidebar} from "@/components/layout/Sidebar";
import Image from "next/image";
Expand All @@ -51,15 +51,20 @@ import IconButton from "@mui/material/IconButton";
type duration = number | `${number}${"ns" | "us" | "µs" | "ms" |"s" | "m" | "h"}`;

export type Config = {
[key: string]: ConfigValue
[key: string]: ConfigValue | Config
}

type ConfigValue = Config | string | number | boolean | null | string[] | number[] | duration
interface ConfigValue {
Type: "bool" | "time.Duration" | "[]string" | "int" | "string"
Value: Config | string | number | boolean | null | string[] | number[] | duration
}

const isConfig = (value: ConfigValue | Config): boolean => {
return (value as Config)?.Type === undefined
}

function sortConfig (a: [string, ConfigValue], b: [string, ConfigValue]) {

let isConfig = (value: ConfigValue) => { return typeof value == 'object' && value !== null && !Array.isArray(value)}
function sortConfig (a: [string, ConfigValue | Config], b: [string, ConfigValue | Config]) {

if(isConfig(a[1]) && !isConfig(b[1])){
return 1
Expand All @@ -70,82 +75,96 @@ function sortConfig (a: [string, ConfigValue], b: [string, ConfigValue]) {
return a[0].localeCompare(b[0])
}

const ConfigDisplayFormElement = ({name, id, configValue}:{name: string, id: string[], configValue: ConfigValue}) : JSX.Element => {

interface ConfigDisplayProps {
id: string[]
name: string
value: Config | ConfigValue
level: number
}

function ConfigDisplay({id, name, value, level = 1}: ConfigDisplayProps) {

if(name != "") {
id = [...id, name]
}

let formElement = undefined

if(
typeof value === 'string' || typeof value === 'number' || value === null
){
// If the value needs to be represented as a list in a text field
if(configValue.Type && configValue.Type.includes("[]")){

// Convert empty values to a space so that the text field is not collapsed
switch (value){
case "":
value = " "
break
case null:
value = "None"
// Check for null list value
if(configValue.Value === null){
configValue.Value = []
}

formElement = <TextField
return <TextField
fullWidth
disabled
size="small"
id={`${id.join("-")}-text-input`}
label={name}
variant={"outlined"}
value={value}
value={(configValue.Value as Array<string>).join(", ")}
/>
} else if(Array.isArray(value)){
formElement = <TextField
fullWidth
disabled
size="small"
id={`${id.join("-")}-text-input`}
label={name}
variant={"outlined"}
value={value.join(", ")}
/>
} else if(typeof value === 'boolean'){
formElement = (

// If the value needs to be represented as a select box
} else if(configValue.Type === "bool"){

return (
<FormControl fullWidth>
<InputLabel id={`${id.join("-")}-number-input`}>{name}</InputLabel>
<InputLabel id={`${id.join("-")}-number-input-label`}>{name}</InputLabel>
<Select
disabled
size="small"
labelId={`${id.join("-")}-number-input-label`}
id={`${id.join("-")}-number-input`}
label={name}
value={value ? 1 : 0}
value={configValue ? 1 : 0}
>
<MenuItem value={1}>True</MenuItem>
<MenuItem value={0}>False</MenuItem>
</Select>
</FormControl>
)

// Catch all for other types and potentially undefined values
} else {

// Convert empty configValues to a space so that the text field is not collapsed
switch (configValue.Value){
case "":
configValue.Value = " "
break
case null:
configValue.Value = "None"
}

return <TextField
fullWidth
disabled
size="small"
id={`${id.join("-")}-text-input`}
label={name}
variant={"outlined"}
value={configValue.Value}
/>
}
}

if(formElement !== undefined){
interface ConfigDisplayProps {
id: string[]
name: string
value: Config | ConfigValue
level: number
}

function ConfigDisplay({id, name, value, level = 1}: ConfigDisplayProps) {

console.log("ConfigDisplay", id, name, value, level)

if(name != "") {
id = [...id, name]
}

// If this is a ConfigValue then display it
if(!isConfig(value)){
return (
<Box pt={2} id={id.join("-")}>
{formElement}
<ConfigDisplayFormElement id={id} name={name} configValue={value as ConfigValue}/>
</Box>
)
}

let subValues = Object.entries(value)
// If this is a Config then display all of its values
let subValues = Object.entries(value as Config)
subValues.sort(sortConfig)

let configDisplays = subValues.map(([k, v]) => {return <ConfigDisplay id={id} key={k} name={k} value={v} level={level+1}/>})
Expand Down Expand Up @@ -174,7 +193,6 @@ function ConfigDisplay({id, name, value, level = 1}: ConfigDisplayProps) {
variant = "h6"
}


return (
<>
{ name ? <Typography id={id.join("-")} variant={variant} component={variant} mt={2}>{name}</Typography> : undefined}
Expand All @@ -200,7 +218,7 @@ function TableOfContents({id, name, value, level = 1}: TableOfContentsProps) {
}

let subContents = undefined
if(value !== null && !Array.isArray(value) && typeof value == 'object'){
if(isConfig(value)){
let subValues = Object.entries(value)
subValues.sort(sortConfig)
subContents = subValues.map(([key, value]) => {
Expand Down
4 changes: 2 additions & 2 deletions web_ui/frontend/components/DataExportTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ export const DataExportTable = () => {

setData([{
"Type": "POSIX",
"Local Path": ["", undefined].includes(responseData?.Xrootd?.Mount) ? "NULL" : responseData?.Xrootd?.Mount,
"Namespace Prefix": ["", undefined].includes(responseData?.Origin?.NamespacePrefix) ? "NULL" : responseData?.Origin?.NamespacePrefix
"Local Path": ["", undefined].includes(responseData?.Xrootd?.Mount?.Value) ? "NULL" : responseData?.Xrootd?.Mount?.Value,
"Namespace Prefix": ["", undefined].includes(responseData?.Origin?.NamespacePrefix?.Value) ? "NULL" : responseData?.Origin?.NamespacePrefix?.Value
}])

} else {
Expand Down
12 changes: 7 additions & 5 deletions web_ui/frontend/components/FederationOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ const FederationOverview = () => {
const responseData = await response.json() as Config

setConfig({
JwkUrl: (responseData?.Federation as Config)?.NamespaceUrl as undefined | string,
NamespaceUrl: (responseData?.Federation as Config)?.NamespaceUrl as undefined | string,
DirectorUrl: (responseData?.Federation as Config)?.DirectorUrl as undefined | string,
TopologyNamespaceUrl: (responseData?.Federation as Config)?.TopologyNamespaceUrl as undefined | string,
DiscoveryUrl: (responseData?.Federation as Config)?.DiscoveryUrl as undefined | string,
JwkUrl: (responseData?.Federation as Config)?.NamespaceUrl?.Value as undefined | string,
NamespaceUrl: (responseData?.Federation as Config)?.NamespaceUrl?.Value as undefined | string,
DirectorUrl: (responseData?.Federation as Config)?.DirectorUrl?.Value as undefined | string,
TopologyNamespaceUrl: (responseData?.Federation as Config)?.TopologyNamespaceUrl?.Value as undefined | string,
DiscoveryUrl: (responseData?.Federation as Config)?.DiscoveryUrl?.Value as undefined | string,
})
} else {
console.error("Failed to fetch config for Federation Overview, response status: " + response.status)
Expand All @@ -58,6 +58,8 @@ const FederationOverview = () => {
return
}

console.log(config)

return (

<Box>
Expand Down

0 comments on commit a569faa

Please sign in to comment.