1
0
mirror of https://github.com/checktheroads/hyperglass synced 2024-05-11 05:55:08 +00:00

refactor params.branding → params.web

This commit is contained in:
checktheroads
2020-01-28 09:14:47 -07:00
parent 9b9fd95061
commit 3b11cd65f2
12 changed files with 73 additions and 79 deletions

View File

@@ -144,7 +144,7 @@ try:
elif not user_config: elif not user_config:
params = _params.Params() params = _params.Params()
try: try:
params.branding.text.subtitle = params.branding.text.subtitle.format( params.web.text.subtitle = params.web.text.subtitle.format(
**params.dict(exclude={"branding", "features", "messages"}) **params.dict(exclude={"branding", "features", "messages"})
) )
except KeyError: except KeyError:
@@ -372,22 +372,20 @@ def _build_vrf_help():
content_vrf = _build_vrf_help() content_vrf = _build_vrf_help()
content_help_params = copy.copy(content_params) content_help_params = copy.copy(content_params)
content_help_params["title"] = params.branding.help_menu.title content_help_params["title"] = params.web.help_menu.title
content_help = asyncio.run( content_help = asyncio.run(
get_markdown( get_markdown(
config_path=params.branding.help_menu, config_path=params.web.help_menu,
default=DEFAULT_HELP, default=DEFAULT_HELP,
params=content_help_params, params=content_help_params,
) )
) )
content_terms_params = copy.copy(content_params) content_terms_params = copy.copy(content_params)
content_terms_params["title"] = params.branding.terms.title content_terms_params["title"] = params.web.terms.title
content_terms = asyncio.run( content_terms = asyncio.run(
get_markdown( get_markdown(
config_path=params.branding.terms, config_path=params.web.terms, default=DEFAULT_TERMS, params=content_terms_params
default=DEFAULT_TERMS,
params=content_terms_params,
) )
) )
content_credit = CREDIT content_credit = CREDIT

View File

@@ -18,16 +18,17 @@ from pydantic import validator
# Project Imports # Project Imports
from hyperglass.configuration.models._utils import HyperglassModel from hyperglass.configuration.models._utils import HyperglassModel
from hyperglass.configuration.models.branding import Branding
from hyperglass.configuration.models.docs import Docs from hyperglass.configuration.models.docs import Docs
from hyperglass.configuration.models.features import Features from hyperglass.configuration.models.features import Features
from hyperglass.configuration.models.messages import Messages from hyperglass.configuration.models.messages import Messages
from hyperglass.configuration.models.opengraph import OpenGraph from hyperglass.configuration.models.opengraph import OpenGraph
from hyperglass.configuration.models.web import Web
class Params(HyperglassModel): class Params(HyperglassModel):
"""Validation model for all configuration variables.""" """Validation model for all configuration variables."""
# Top Level Params
debug: StrictBool = False debug: StrictBool = False
developer_mode: StrictBool = False developer_mode: StrictBool = False
primary_asn: StrictStr = "65001" primary_asn: StrictStr = "65001"
@@ -50,8 +51,6 @@ class Params(HyperglassModel):
"network", "network",
"isp", "isp",
] ]
opengraph: OpenGraph = OpenGraph()
docs: Docs = Docs()
google_analytics: StrictStr = "" google_analytics: StrictStr = ""
redis_host: StrictStr = "localhost" redis_host: StrictStr = "localhost"
redis_port: StrictInt = 6379 redis_port: StrictInt = 6379
@@ -62,6 +61,13 @@ class Params(HyperglassModel):
log_file: Optional[FilePath] log_file: Optional[FilePath]
cors_origins: List[StrictStr] = [] cors_origins: List[StrictStr] = []
# Sub Level Params
docs: Docs = Docs()
features: Features = Features()
messages: Messages = Messages()
opengraph: OpenGraph = OpenGraph()
web: Web = Web()
@validator("listen_address", pre=True, always=True) @validator("listen_address", pre=True, always=True)
def validate_listen_address(cls, value, values): def validate_listen_address(cls, value, values):
"""Set default listen_address based on debug mode. """Set default listen_address based on debug mode.
@@ -118,7 +124,3 @@ class Params(HyperglassModel):
f'/tmp/hyperglass_{now.strftime(r"%Y%M%d-%H%M%S")}.log' # noqa: S108 f'/tmp/hyperglass_{now.strftime(r"%Y%M%d-%H%M%S")}.log' # noqa: S108
) )
return value return value
features: Features = Features()
branding: Branding = Branding()
messages: Messages = Messages()

View File

@@ -19,7 +19,7 @@ from pydantic.color import Color
from hyperglass.configuration.models._utils import HyperglassModel from hyperglass.configuration.models._utils import HyperglassModel
class Branding(HyperglassModel): class Web(HyperglassModel):
"""Validation model for params.branding.""" """Validation model for params.branding."""
class Colors(HyperglassModel): class Colors(HyperglassModel):

View File

@@ -48,7 +48,7 @@ class Query(BaseModel):
params.messages.invalid_field, params.messages.invalid_field,
level="warning", level="warning",
input=value, input=value,
field=params.branding.text.query_location, field=params.web.text.query_location,
) )
return value return value

View File

@@ -3,13 +3,15 @@ import { Flex, useColorMode, useTheme } from "@chakra-ui/core";
import { FiCode } from "react-icons/fi"; import { FiCode } from "react-icons/fi";
import { GoLinkExternal } from "react-icons/go"; import { GoLinkExternal } from "react-icons/go";
import format from "string-format"; import format from "string-format";
import useConfig from "~/components/HyperglassProvider";
import FooterButton from "~/components/FooterButton"; import FooterButton from "~/components/FooterButton";
import FooterContent from "~/components/FooterContent"; import FooterContent from "~/components/FooterContent";
format.extend(String.prototype, {}); format.extend(String.prototype, {});
export default ({ general, help, extLink, credit, terms, content }) => { const Footer = () => {
const theme = useTheme(); const theme = useTheme();
const config = useConfig();
const { colorMode } = useColorMode(); const { colorMode } = useColorMode();
const footerBg = { light: theme.colors.blackAlpha[50], dark: theme.colors.whiteAlpha[100] }; const footerBg = { light: theme.colors.blackAlpha[50], dark: theme.colors.whiteAlpha[100] };
const footerColor = { light: theme.colors.black, dark: theme.colors.white }; const footerColor = { light: theme.colors.black, dark: theme.colors.white };
@@ -20,9 +22,9 @@ export default ({ general, help, extLink, credit, terms, content }) => {
const [helpVisible, showHelp] = useState(false); const [helpVisible, showHelp] = useState(false);
const [termsVisible, showTerms] = useState(false); const [termsVisible, showTerms] = useState(false);
const [creditVisible, showCredit] = useState(false); const [creditVisible, showCredit] = useState(false);
const extUrl = extLink.url.includes("{primary_asn}") const extUrl = config.external_link.url.includes("{primary_asn}")
? extLink.url.format({ primary_asn: general.primary_asn }) ? config.external_link.url.format({ primary_asn: config.primary_asn })
: extLink.url || "/"; : config.external_link.url || "/";
const handleCollapse = i => { const handleCollapse = i => {
if (i === "help") { if (i === "help") {
showTerms(false); showTerms(false);
@@ -40,31 +42,31 @@ export default ({ general, help, extLink, credit, terms, content }) => {
}; };
return ( return (
<> <>
{help.enable && ( {config.help.enable && (
<FooterContent <FooterContent
isOpen={helpVisible} isOpen={helpVisible}
content={content.help_menu} content={config.content.help_menu}
title={help.title} title={config.help.title}
bg={footerBg[colorMode]} bg={footerBg[colorMode]}
borderColor={contentBorder[colorMode]} borderColor={contentBorder[colorMode]}
side="left" side="left"
/> />
)} )}
{terms.enable && ( {config.terms.enable && (
<FooterContent <FooterContent
isOpen={termsVisible} isOpen={termsVisible}
content={content.terms} content={config.content.terms}
title={terms.title} title={config.terms.title}
bg={footerBg[colorMode]} bg={footerBg[colorMode]}
borderColor={contentBorder[colorMode]} borderColor={contentBorder[colorMode]}
side="left" side="left"
/> />
)} )}
{credit.enable && ( {config.credit.enable && (
<FooterContent <FooterContent
isOpen={creditVisible} isOpen={creditVisible}
content={content.credit} content={config.content.credit}
title={credit.title} title={config.credit.title}
bg={footerBg[colorMode]} bg={footerBg[colorMode]}
borderColor={contentBorder[colorMode]} borderColor={contentBorder[colorMode]}
side="right" side="right"
@@ -82,14 +84,14 @@ export default ({ general, help, extLink, credit, terms, content }) => {
color={footerColor[colorMode]} color={footerColor[colorMode]}
justifyContent="space-between" justifyContent="space-between"
> >
{terms.enable && ( {config.terms.enable && (
<FooterButton side="left" onClick={() => handleCollapse("terms")}> <FooterButton side="left" onClick={() => handleCollapse("terms")}>
{terms.title} {config.terms.title}
</FooterButton> </FooterButton>
)} )}
{help.enable && ( {config.help.enable && (
<FooterButton side="left" onClick={() => handleCollapse("help")}> <FooterButton side="left" onClick={() => handleCollapse("help")}>
{help.title} {config.help.title}
</FooterButton> </FooterButton>
)} )}
<Flex <Flex
@@ -100,12 +102,12 @@ export default ({ general, help, extLink, credit, terms, content }) => {
marginRight="auto" marginRight="auto"
p={0} p={0}
/> />
{credit.enable && ( {config.credit.enable && (
<FooterButton side="right" onClick={() => handleCollapse("credit")}> <FooterButton side="right" onClick={() => handleCollapse("credit")}>
<FiCode /> <FiCode />
</FooterButton> </FooterButton>
)} )}
{extLink.enable && ( {config.external_link.enable && (
<FooterButton <FooterButton
as="a" as="a"
href={extUrl} href={extUrl}
@@ -115,10 +117,13 @@ export default ({ general, help, extLink, credit, terms, content }) => {
rightIcon={GoLinkExternal} rightIcon={GoLinkExternal}
size="xs" size="xs"
> >
{extLink.title} {config.external_link.title}
</FooterButton> </FooterButton>
)} )}
</Flex> </Flex>
</> </>
); );
}; };
Footer.displayName = "Footer";
export default Footer;

View File

@@ -21,16 +21,14 @@ const formSchema = config =>
query_location: yup query_location: yup
.array() .array()
.of(yup.string()) .of(yup.string())
.required( .required(config.messages.no_input.format({ field: config.web.text.query_location })),
config.messages.no_input.format({ field: config.branding.text.query_location })
),
query_type: yup query_type: yup
.string() .string()
.required(config.messages.no_input.format({ field: config.branding.text.query_type })), .required(config.messages.no_input.format({ field: config.web.text.query_type })),
query_vrf: yup.string(), query_vrf: yup.string(),
query_target: yup query_target: yup
.string() .string()
.required(config.messages.no_input.format({ field: config.branding.text.query_target })) .required(config.messages.no_input.format({ field: config.web.text.query_target }))
}); });
const FormRow = ({ children, ...props }) => ( const FormRow = ({ children, ...props }) => (
@@ -121,14 +119,14 @@ const HyperglassForm = React.forwardRef(
<form onSubmit={handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
<FormRow> <FormRow>
<FormField <FormField
label={config.branding.text.query_location} label={config.web.text.query_location}
name="query_location" name="query_location"
error={errors.query_location} error={errors.query_location}
> >
<QueryLocation onChange={handleChange} locations={config.networks} /> <QueryLocation onChange={handleChange} locations={config.networks} />
</FormField> </FormField>
<FormField <FormField
label={config.branding.text.query_type} label={config.web.text.query_type}
name="query_type" name="query_type"
error={errors.query_type} error={errors.query_type}
labelAddOn={ labelAddOn={
@@ -141,19 +139,19 @@ const HyperglassForm = React.forwardRef(
<FormRow> <FormRow>
{availVrfs.length > 0 && ( {availVrfs.length > 0 && (
<FormField <FormField
label={config.branding.text.query_vrf} label={config.web.text.query_vrf}
name="query_vrf" name="query_vrf"
error={errors.query_vrf} error={errors.query_vrf}
> >
<QueryVrf <QueryVrf
placeholder={config.branding.text.query_vrf} placeholder={config.web.text.query_vrf}
vrfs={availVrfs} vrfs={availVrfs}
onChange={handleChange} onChange={handleChange}
/> />
</FormField> </FormField>
)} )}
<FormField <FormField
label={config.branding.text.query_target} label={config.web.text.query_target}
name="query_target" name="query_target"
error={errors.query_target} error={errors.query_target}
fieldAddOn={ fieldAddOn={
@@ -168,7 +166,7 @@ const HyperglassForm = React.forwardRef(
> >
<QueryTarget <QueryTarget
name="query_target" name="query_target"
placeholder={config.branding.text.query_target} placeholder={config.web.text.query_target}
register={register} register={register}
resolveTarget={["ping", "traceroute", "bgp_route"].includes( resolveTarget={["ping", "traceroute", "bgp_route"].includes(
queryType queryType

View File

@@ -14,7 +14,7 @@ const HyperglassContext = createContext(null);
export const HyperglassProvider = ({ config, children }) => { export const HyperglassProvider = ({ config, children }) => {
const value = useMemo(() => config, [config]); const value = useMemo(() => config, [config]);
const userTheme = value && makeTheme(value.branding); const userTheme = value && makeTheme(value.web);
const theme = value ? userTheme : defaultTheme; const theme = value ? userTheme : defaultTheme;
return ( return (
<HyperglassContext.Provider value={value}> <HyperglassContext.Provider value={value}>

View File

@@ -27,7 +27,7 @@ const Layout = () => {
setSubmitting(false); setSubmitting(false);
}; };
const headerHeight = const headerHeight =
config.branding.text.title_mode === "all" config.web.text.title_mode === "all"
? headerHeightAll[isSubmitting] ? headerHeightAll[isSubmitting]
: headerHeightDefault[isSubmitting]; : headerHeightDefault[isSubmitting];
return ( return (
@@ -83,15 +83,8 @@ const Layout = () => {
)} )}
</AnimatePresence> </AnimatePresence>
</Flex> </Flex>
<Footer <Footer />
general={config.general} {config.developer_mode && <Debugger />}
content={config.content}
terms={config.branding.terms}
help={config.branding.help_menu}
credit={config.branding.credit}
extLink={config.branding.external_link}
/>
{config.general.developer_mode && <Debugger />}
</Flex> </Flex>
</> </>
); );

View File

@@ -8,10 +8,10 @@ export default () => {
const config = useConfig(); const config = useConfig();
const theme = useTheme(); const theme = useTheme();
const [location, setLocation] = useState({}); const [location, setLocation] = useState({});
const title = config?.general.org_name || "hyperglass"; const title = config?.org_name || "hyperglass";
const description = config?.general.site_description || "The modern looking glass."; const description = config?.site_description || "The modern looking glass.";
const siteName = `${title} - ${description}`; const siteName = `${title} - ${description}`;
const keywords = config?.general.site_keywords || [ const keywords = config?.site_keywords || [
"hyperglass", "hyperglass",
"looking glass", "looking glass",
"lg", "lg",
@@ -27,15 +27,13 @@ export default () => {
"network", "network",
"isp" "isp"
]; ];
const author = config?.general.org_name || "Matt Love, matt@hyperglass.io"; const author = config?.org_name || "Matt Love, matt@hyperglass.io";
const language = config?.general.language || "en"; const language = config?.language || "en";
const currentYear = new Date().getFullYear(); const currentYear = new Date().getFullYear();
const copyright = config const copyright = config ? `${currentYear} ${config.org_name}` : `${currentYear} hyperglass`;
? `${currentYear} ${config.general.org_name}` const ogImage = config?.opengraph.image || null;
: `${currentYear} hyperglass`; const ogImageHeight = config?.opengraph.height || null;
const ogImage = config?.general.opengraph.image || null; const ogImageWidth = config?.opengraph.width || null;
const ogImageHeight = config?.general.opengraph.height || null;
const ogImageWidth = config?.general.opengraph.width || null;
const primaryFont = googleFontUrl(theme.fonts.body); const primaryFont = googleFontUrl(theme.fonts.body);
const monoFont = googleFontUrl(theme.fonts.mono); const monoFont = googleFontUrl(theme.fonts.mono);
useEffect(() => { useEffect(() => {

View File

@@ -66,7 +66,7 @@ const ResolvedTarget = React.forwardRef(({ target, setTarget, formQueryTarget },
<Tag> <Tag>
<Tooltip <Tooltip
hasArrow hasArrow
label={config.branding.text.fqdn_tooltip.format({ protocol: "IPv4" })} label={config.web.text.fqdn_tooltip.format({ protocol: "IPv4" })}
placement="bottom" placement="bottom"
> >
<Button <Button
@@ -98,7 +98,7 @@ const ResolvedTarget = React.forwardRef(({ target, setTarget, formQueryTarget },
<Tag> <Tag>
<Tooltip <Tooltip
hasArrow hasArrow
label={config.branding.text.fqdn_tooltip.format({ protocol: "IPv6" })} label={config.web.text.fqdn_tooltip.format({ protocol: "IPv6" })}
placement="bottom" placement="bottom"
> >
<Button <Button

View File

@@ -75,7 +75,7 @@ const Results = ({ queryLocation, queryType, queryVrf, queryTarget, setSubmittin
animate={labelAnimate.left[mediaSize]} animate={labelAnimate.left[mediaSize]}
transition={{ duration: 0.3, delay: 0.3 }} transition={{ duration: 0.3, delay: 0.3 }}
exit={{ opacity: 0, x: -100 }} exit={{ opacity: 0, x: -100 }}
label={config.branding.text.query_type} label={config.web.text.query_type}
value={config.features[queryType].display_name} value={config.features[queryType].display_name}
valueBg={theme.colors.cyan[500]} valueBg={theme.colors.cyan[500]}
fontSize={["xs", "sm", "sm", "sm"]} fontSize={["xs", "sm", "sm", "sm"]}
@@ -85,7 +85,7 @@ const Results = ({ queryLocation, queryType, queryVrf, queryTarget, setSubmittin
animate={labelAnimate.center[mediaSize]} animate={labelAnimate.center[mediaSize]}
transition={{ duration: 0.3, delay: 0.3 }} transition={{ duration: 0.3, delay: 0.3 }}
exit={{ opacity: 0, scale: 0.5 }} exit={{ opacity: 0, scale: 0.5 }}
label={config.branding.text.query_target} label={config.web.text.query_target}
value={queryTarget} value={queryTarget}
valueBg={theme.colors.teal[600]} valueBg={theme.colors.teal[600]}
fontSize={["xs", "sm", "sm", "sm"]} fontSize={["xs", "sm", "sm", "sm"]}
@@ -95,7 +95,7 @@ const Results = ({ queryLocation, queryType, queryVrf, queryTarget, setSubmittin
animate={labelAnimate.right[mediaSize]} animate={labelAnimate.right[mediaSize]}
transition={{ duration: 0.3, delay: 0.3 }} transition={{ duration: 0.3, delay: 0.3 }}
exit={{ opacity: 0, x: 100 }} exit={{ opacity: 0, x: 100 }}
label={config.branding.text.query_vrf} label={config.web.text.query_vrf}
value={matchedVrf.display_name} value={matchedVrf.display_name}
valueBg={theme.colors.blue[500]} valueBg={theme.colors.blue[500]}
fontSize={["xs", "sm", "sm", "sm"]} fontSize={["xs", "sm", "sm", "sm"]}
@@ -131,7 +131,7 @@ const Results = ({ queryLocation, queryType, queryVrf, queryTarget, setSubmittin
transition={{ duration: 0.3, delay: i * 0.3 }} transition={{ duration: 0.3, delay: i * 0.3 }}
exit={{ opacity: 0, y: 300 }} exit={{ opacity: 0, y: 300 }}
key={loc} key={loc}
timeout={config.general.request_timeout * 1000} timeout={config.request_timeout * 1000}
device={config.devices[loc]} device={config.devices[loc]}
queryLocation={loc} queryLocation={loc}
queryType={queryType} queryType={queryType}

View File

@@ -71,9 +71,9 @@ const btnJustify = {
false: ["flex-start", "center"] false: ["flex-start", "center"]
}; };
export default React.forwardRef(({ onClick, isSubmitting, ...props }, ref) => { export default React.forwardRef(({ onClick, isSubmitting, ...props }, ref) => {
const { branding } = useConfig(); const { web } = useConfig();
const { mediaSize } = useMedia(); const { mediaSize } = useMedia();
const titleMode = branding.text.title_mode; const titleMode = web.text.title_mode;
const MatchedMode = modeMap[titleMode]; const MatchedMode = modeMap[titleMode];
return ( return (
<Button <Button
@@ -90,8 +90,8 @@ export default React.forwardRef(({ onClick, isSubmitting, ...props }, ref) => {
<MatchedMode <MatchedMode
mediaSize={mediaSize} mediaSize={mediaSize}
showSubtitle={!isSubmitting} showSubtitle={!isSubmitting}
text={branding.text} text={web.text}
logo={branding.logo} logo={web.logo}
/> />
</Button> </Button>
); );