forked from mirrors/thatmattlove-hyperglass
add favicon generation, closes #45
This commit is contained in:
parent
49ec2d8a6f
commit
85e764c661
18 changed files with 3298 additions and 1457 deletions
235
docs/docs/ui.mdx
235
docs/docs/ui.mdx
|
|
@ -1,235 +0,0 @@
|
|||
---
|
||||
id: ui
|
||||
title: Web UI
|
||||
sidebar_label: Web UI
|
||||
keywords: [hyperglass, looking glass, web ui, gui, theme, colors, branding]
|
||||
description: hyperglass Web UI Configuration
|
||||
---
|
||||
|
||||
import Link from "@docusaurus/Link";
|
||||
import R from "../src/components/Required";
|
||||
import MiniNote from "../src/components/MiniNote";
|
||||
import Code from "../src/components/JSXCode";
|
||||
import Color from "../src/components/Color";
|
||||
import Font from "../src/components/Font";
|
||||
import PageLink from "../src/components/PageLink";
|
||||
|
||||
<div class="table--full-width" />
|
||||
|
||||
The `web` subsection contains multiple subsections of its own, should you wish to customize various aspects of the UI:
|
||||
|
||||
| Section | Description | All Options |
|
||||
| :-------------- | :----------------------------- | :-----------------------------------------: |
|
||||
| `credit` | Developer credit & GitHub Link | <PageLink to="#credit">➡️</PageLink> |
|
||||
| `dns_provider` | DNS over HTTPS Provider | <PageLink to="#dns_provider">➡️</PageLink> |
|
||||
| `external_link` | Link to external site | <PageLink to="#external_link">➡️</PageLink> |
|
||||
| `greeting` | Greeting Modal | <PageLink to="#greeting">➡️</PageLink> |
|
||||
| `logo` | Logo & Favicons | <PageLink to="#logo">➡️</PageLink> |
|
||||
| `opengraph` | [OpenGraph](https://ogp.me/) | <PageLink to="#opengraph">➡️</PageLink> |
|
||||
| `terms` | Terms & Conditions | <PageLink to="#terms">➡️</PageLink> |
|
||||
| `theme` | Colors & Fonts | <PageLink to="#theme">➡️</PageLink> |
|
||||
|
||||
## `credit`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :-------- | :-----: | :-----: | :--------------------------------------------------------------------------------------- |
|
||||
| `enable` | Boolean | `true` | Enable or disable the display of developer credit & link to hyperglass GitHub repository |
|
||||
|
||||
:::note From the developer
|
||||
If your organization's policy allows, and you don't mind, I request that you keep `credit` enabled. Remember: my goal for this project is get more networks to use looking glasses to make all of our lives easier. Because it's primarily other network operators who will use this tool to begin with, I'd love for any operators that use your looking glass to know where they can get their own.
|
||||
:::
|
||||
|
||||
## `dns_provider`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :-------- | :----: | :------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `name` | String | `'cloudflare'` | DNS over HTTPS provider for in-browser DNS resolution. Cloudflare & Google supported. <MiniNote>Must be <Code>cloudflare</Code> or <Code>google</Code></MiniNote> |
|
||||
|
||||
## `external_link`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :-------- | :-----: | :---------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `enable` | Boolean | `true` | Enable or disable the display of an external link |
|
||||
| `title` | String | `'PeeringDB'` | Link title/label |
|
||||
| `url` | String | `'https://www.peeringdb.com/asn/{primary_asn}'` | Target URL. `{primary_asn}` will be replaced with the `primary_asn` value from <Link to="/docs/configuration#global-settings">Global Settings</Link> |
|
||||
|
||||
## `greeting`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :--------- | :-----: | :----------- | :------------------------------------------------------------------------------------------- |
|
||||
| `enable` | Boolean | `false` | Enable or disable the greeting modal. |
|
||||
| `file` | String | | Path to a [markdown](https://www.markdownguide.org/) file containing the modal body content. |
|
||||
| `title` | String | `'Welcome'` | Modal title. |
|
||||
| `button` | String | `'Continue'` | Button text. |
|
||||
| `required` | Boolean | `false` | If `true` the user must click the button in order to submit a query. |
|
||||
|
||||
## `logo`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :-------- | :-----: | :------------------------------ | :------------------------------------------- |
|
||||
| `light` | String | `'images/hyperglass-dark.png'` | Path to logo that will be used in light mode |
|
||||
| `dark` | String | `'images/hyperglass-light.png'` | Path to logo that will be used in dark mode |
|
||||
| `width` | Integer | `384` | Maximum logo width in pixels |
|
||||
| `height` | Integer | | Maximum logo height in pixels |
|
||||
|
||||
## `opengraph`
|
||||
|
||||
If you're not familiar with [OpenGraph](https://ogp.me/), it's the thing that generates the pretty pictures, titles, and descriptions for links when you post them to sites/tools such as Facebook, Twitter, Slack, etc.
|
||||
|
||||
By default, no Opengraph image is set. If you define one with `image`, hyperglass will try to determine the image's dimensions automatically. Or, you can override those dimensions with the `width` and `height` parameters.
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :-------- | :-----: | :---------------------- |
|
||||
| `image` | String | Path to opengraph image |
|
||||
| `width` | Integer | Opengraph image width |
|
||||
| `height` | Integer | Opengraph image height |
|
||||
|
||||
## `terms`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :-------- | :-----: | :-------- | :-------------------------------------------------------------------------------------------- |
|
||||
| `enable` | Boolean | `true` | Enable or display the display of terms & conditions |
|
||||
| `file` | String | | Path to a plain text or markdown file with content to override the default terms & conditions |
|
||||
| `title` | String | `'Terms'` | Terms & conditions title |
|
||||
|
||||
## `text`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :--------------- | :----: | :------------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `cache_prefix` | String | `'Results cached for '` | Text displayed with the cache timeout countdown. |
|
||||
| `cache_icon` | String | `'Cached Response from {time}'` | Text displayed when a user hovers over the lightning bolt icon, which is displayed when a response from the server was a cached response. `{time}` is replaced with the _original_ query's timestamp. |
|
||||
| `completed_time` | String | `'Completed in {seconds}'` | Text displayed when a user hovers over the success icon for a query result. `{seconds}` will be replaced with 'n seconds' where n is the time a query took to complete. |
|
||||
| `fqdn_tooltip` | String | `'Use {protocol}'` | Text displayed when a user hovers over the IPv4 or IPv6 button on an FQDN target resolved by DNS. `{protocol}` is replaced with the relevant IP protocol. |
|
||||
| `query_location` | String | `'Location'` | Query Location (router) form label. |
|
||||
| `query_target` | String | `'Target'` | Query Target (IP/hostname/community/AS Path) form label. |
|
||||
| `query_type` | String | `'Query Type'` | Query Type (BGP Route, Ping, Traceroute, etc.) form label. |
|
||||
| `query_vrf` | String | `'Routing Table'` | Query VRF form label. |
|
||||
| `subtitle` | String | `'Network Looking Glass'` | Subtitle text. value. |
|
||||
| `title` | String | `'hyperglass'` | Title text. |
|
||||
| `title_mode` | String | `'text_only'` | Set the title mode. <MiniNote>Must be <Code>text_only</Code>, <Code>logo_only</Code>, <Code>logo_subtitle</Code>, or <Code>all</Code></MiniNote> |
|
||||
|
||||
:::note Title Mode
|
||||
The `title_mode` parameter behaves in the following manner:
|
||||
|
||||
| Mode | Behavior |
|
||||
| --------------- | ------------------------------------------------------------------ |
|
||||
| `text_only` | Shows the `title` and `subtitle` only. |
|
||||
| `logo_only` | Shows the <Link to="#logo">`logo`</Link> only. |
|
||||
| `logo_subtitle` | Shows the <Link to="#logo">`logo`</Link> and `subtitle` only. |
|
||||
| `all` | Shows the <Link to="#logo">`logo`</Link>, `title`, and `subtitle`. |
|
||||
|
||||
:::
|
||||
|
||||
## `theme`
|
||||
|
||||
### Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :------------------- | :----: | :----------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `default_color_mode` | String | Sets the default color mode. Must be `light` or `dark`. If no default mode is specified, hyperglass will use the browser's preferred color mode. |
|
||||
|
||||
### Sections
|
||||
|
||||
| Section | Description | All Options |
|
||||
| :------- | :----------- | :----------------------------------: |
|
||||
| `colors` | Theme colors | <PageLink to="#colors">➡️</PageLink> |
|
||||
| `fonts` | Theme fonts | <PageLink to="#fonts">➡️</PageLink> |
|
||||
|
||||
#### `colors`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :---------- | :----: | :--------------------- | :------------------------------------- |
|
||||
| `primary` | String | | Primary accent color |
|
||||
| `secondary` | String | | Secondary accent color |
|
||||
| `success` | String | | Success message/status color |
|
||||
| `warning` | String | | Warning message/status color |
|
||||
| `error` | String | | Error message/status color |
|
||||
| `danger` | String | | Danger message/status color |
|
||||
| `black` | String | <Color hex="#262626"/> | Used as background color in dark mode |
|
||||
| `white` | String | <Color hex="#f7f7f7"/> | Used as background color in light mode |
|
||||
| `red` | String | <Color hex="#d84b4b"/> | Used as `danger` color if undefined |
|
||||
| `orange` | String | <Color hex="#ff6b35"/> | Used as `error` color if undefined |
|
||||
| `yellow` | String | <Color hex="#edae49"/> | Used as `warning` color if undefined |
|
||||
| `green` | String | <Color hex="#35b246"/> | Used as `success` color if undefined |
|
||||
| `cyan` | String | <Color hex="#118ab2"/> | Used as `primary` color if undefined |
|
||||
| `blue` | String | <Color hex="#314cb6"/> | Used as `secondary` color if undefined |
|
||||
| `teal` | String | <Color hex="#35b299"/> | |
|
||||
| `pink` | String | <Color hex="#f2607d"/> | |
|
||||
| `purple` | String | <Color hex="#8d30b5"/> | |
|
||||
| `gray` | String | <Color hex="#c1c7cc"/> | |
|
||||
|
||||
#### `fonts`
|
||||
|
||||
Currently, only [Google Fonts](https://fonts.google.com/) are supported.
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :-------- | :----: | :----------------------- | :-------------------------------------- |
|
||||
| `body` | String | <Font name='Nunito'/> | Main body font |
|
||||
| `mono` | String | <Font name='Fira Code'/> | Monospace font, used for command output |
|
||||
|
||||
## Example
|
||||
|
||||
```yaml title="hyperglass.yaml"
|
||||
web:
|
||||
credit:
|
||||
enable: true
|
||||
dns_provider:
|
||||
name: google
|
||||
url: https://dns.google/resolve
|
||||
external_link:
|
||||
enable: true
|
||||
title: PeeringDB
|
||||
url: https://www.peeringdb.com/asn/{primary_asn}
|
||||
help_menu:
|
||||
enable: true
|
||||
file: null
|
||||
title: Help
|
||||
logo:
|
||||
dark: /images/hyperglass-light.png
|
||||
favicons: ui/images/favicons/
|
||||
height: null
|
||||
light: /images/hyperglass-dark.png
|
||||
width: 384
|
||||
opengraph:
|
||||
height: 1132
|
||||
image: /images/hyperglass-opengraph.png
|
||||
width: 7355
|
||||
terms:
|
||||
enable: true
|
||||
file: null
|
||||
title: Terms
|
||||
text:
|
||||
cache: Results will be cached for 2 minutes.
|
||||
fqdn_tooltip: "Use {protocol}"
|
||||
query_location: Location
|
||||
query_target: Target
|
||||
query_type: Query Type
|
||||
query_vrf: Routing Table
|
||||
subtitle: AS65001
|
||||
title: hyperglass
|
||||
title_mode: text_only
|
||||
theme:
|
||||
default_color_mode: light
|
||||
colors:
|
||||
black: "#262626"
|
||||
blue: "#314cb6"
|
||||
cyan: "#118ab2"
|
||||
danger: "#d84b4b"
|
||||
error: "#ff6b35"
|
||||
gray: "#c1c7cc"
|
||||
green: "#35b246"
|
||||
orange: "#ff6b35"
|
||||
pink: "#f2607d"
|
||||
primary: "#118ab2"
|
||||
purple: "#8d30b5"
|
||||
red: "#d84b4b"
|
||||
secondary: "#314cb6"
|
||||
success: "#35b246"
|
||||
teal: "#35b299"
|
||||
warning: "#edae49"
|
||||
white: "#f7f7f7"
|
||||
yellow: "#edae49"
|
||||
fonts:
|
||||
body: Nunito
|
||||
mono: Fira Code
|
||||
```
|
||||
83
docs/docs/ui/configuration.mdx
Normal file
83
docs/docs/ui/configuration.mdx
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
---
|
||||
id: configuration
|
||||
title: UI Configuration
|
||||
sidebar_label: Configuration
|
||||
keywords: [hyperglass, looking glass, web ui, gui, theme, colors, branding]
|
||||
description: Customize the Web UI
|
||||
---
|
||||
|
||||
import Link from "@docusaurus/Link";
|
||||
import R from "../../src/components/Required";
|
||||
import MiniNote from "../../src/components/MiniNote";
|
||||
import Code from "../../src/components/JSXCode";
|
||||
import PageLink from "../../src/components/PageLink";
|
||||
|
||||
<div class="table--full-width" />
|
||||
|
||||
The `web` subsection contains multiple subsections of its own, should you wish to customize various aspects of the UI:
|
||||
|
||||
| Section | Description | All Options |
|
||||
| :-------------- | :----------------------------- | :-----------------------------------------: |
|
||||
| `credit` | Developer credit & GitHub Link | <PageLink to="#credit">➡️</PageLink> |
|
||||
| `dns_provider` | DNS over HTTPS Provider | <PageLink to="#dns_provider">➡️</PageLink> |
|
||||
| `external_link` | Link to external site | <PageLink to="#external_link">➡️</PageLink> |
|
||||
| `greeting` | Greeting Modal | <PageLink to="#greeting">➡️</PageLink> |
|
||||
| `logo` | Logo & Favicons | <PageLink to="logo">➡️</PageLink> |
|
||||
| `opengraph` | [OpenGraph](https://ogp.me/) | <PageLink to="#opengraph">➡️</PageLink> |
|
||||
| `terms` | Terms & Conditions | <PageLink to="#terms">➡️</PageLink> |
|
||||
| `text` | Text, title, & names | <PageLink to="text">➡️</PageLink> |
|
||||
| `theme` | Colors & Fonts | <PageLink to="theme">➡️</PageLink> |
|
||||
|
||||
## `credit`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :-------- | :-----: | :-----: | :--------------------------------------------------------------------------------------- |
|
||||
| `enable` | Boolean | `true` | Enable or disable the display of developer credit & link to hyperglass GitHub repository |
|
||||
|
||||
:::note From the developer
|
||||
If your organization's policy allows, and you don't mind, I request that you keep `credit` enabled. Remember: my goal for this project is get more networks to use looking glasses to make all of our lives easier. Because it's primarily other network operators who will use this tool to begin with, I'd love for any operators that use your looking glass to know where they can get their own.
|
||||
:::
|
||||
|
||||
## `dns_provider`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :-------- | :----: | :------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `name` | String | `'cloudflare'` | DNS over HTTPS provider for in-browser DNS resolution. Cloudflare & Google supported. <MiniNote>Must be <Code>cloudflare</Code> or <Code>google</Code></MiniNote> |
|
||||
|
||||
## `external_link`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :-------- | :-----: | :---------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `enable` | Boolean | `true` | Enable or disable the display of an external link |
|
||||
| `title` | String | `'PeeringDB'` | Link title/label |
|
||||
| `url` | String | `'https://www.peeringdb.com/asn/{primary_asn}'` | Target URL. `{primary_asn}` will be replaced with the `primary_asn` value from <Link to="/docs/configuration#global-settings">Global Settings</Link> |
|
||||
|
||||
## `greeting`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :--------- | :-----: | :----------- | :------------------------------------------------------------------------------------------- |
|
||||
| `enable` | Boolean | `false` | Enable or disable the greeting modal. |
|
||||
| `file` | String | | Path to a [markdown](https://www.markdownguide.org/) file containing the modal body content. |
|
||||
| `title` | String | `'Welcome'` | Modal title. |
|
||||
| `button` | String | `'Continue'` | Button text. |
|
||||
| `required` | Boolean | `false` | If `true` the user must click the button in order to submit a query. |
|
||||
|
||||
## `opengraph`
|
||||
|
||||
If you're not familiar with [OpenGraph](https://ogp.me/), it's the thing that generates the pretty pictures, titles, and descriptions for links when you post them to sites/tools such as Facebook, Twitter, Slack, etc.
|
||||
|
||||
By default, no Opengraph image is set. If you define one with `image`, hyperglass will try to determine the image's dimensions automatically. Or, you can override those dimensions with the `width` and `height` parameters.
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :-------- | :-----: | :---------------------- |
|
||||
| `image` | String | Path to opengraph image |
|
||||
| `width` | Integer | Opengraph image width |
|
||||
| `height` | Integer | Opengraph image height |
|
||||
|
||||
## `terms`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :-------- | :-----: | :-------- | :-------------------------------------------------------------------------------------------- |
|
||||
| `enable` | Boolean | `true` | Enable or display the display of terms & conditions |
|
||||
| `file` | String | | Path to a plain text or markdown file with content to override the default terms & conditions |
|
||||
| `title` | String | `'Terms'` | Terms & conditions title |
|
||||
74
docs/docs/ui/example.mdx
Normal file
74
docs/docs/ui/example.mdx
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
---
|
||||
id: example
|
||||
title: Example UI Configuration
|
||||
sidebar_label: Example
|
||||
keywords:
|
||||
[hyperglass, looking glass, web ui, gui, theme, colors, branding, example]
|
||||
description: See how to the hyperglass UI should be configured.
|
||||
---
|
||||
|
||||
## Example
|
||||
|
||||
```yaml title="hyperglass.yaml"
|
||||
web:
|
||||
credit:
|
||||
enable: true
|
||||
dns_provider:
|
||||
name: cloudflare
|
||||
external_link:
|
||||
enable: true
|
||||
title: PeeringDB
|
||||
url: https://www.peeringdb.com/asn/{primary_asn}
|
||||
help_menu:
|
||||
enable: true
|
||||
file: null
|
||||
title: Help
|
||||
logo:
|
||||
dark: /home/ubuntu/hyperglass/hyperglass-light.png
|
||||
light: /home/ubuntu/hyperglass/hyperglass-dark.png
|
||||
favicon: /home/ubuntu/hyperglass/icon.png
|
||||
height: null
|
||||
width: 384
|
||||
opengraph:
|
||||
height: 1132
|
||||
image: /images/hyperglass-opengraph.png
|
||||
width: 7355
|
||||
terms:
|
||||
enable: true
|
||||
file: null
|
||||
title: Terms
|
||||
text:
|
||||
cache: Results will be cached for 2 minutes.
|
||||
fqdn_tooltip: "Use {protocol}"
|
||||
query_location: Location
|
||||
query_target: Target
|
||||
query_type: Query Type
|
||||
query_vrf: Routing Table
|
||||
subtitle: AS65001
|
||||
title: hyperglass
|
||||
title_mode: text_only
|
||||
theme:
|
||||
default_color_mode: light
|
||||
colors:
|
||||
black: "#262626"
|
||||
blue: "#314cb6"
|
||||
cyan: "#118ab2"
|
||||
danger: "#d84b4b"
|
||||
error: "#ff6b35"
|
||||
gray: "#c1c7cc"
|
||||
green: "#35b246"
|
||||
orange: "#ff6b35"
|
||||
pink: "#f2607d"
|
||||
primary: "#118ab2"
|
||||
purple: "#8d30b5"
|
||||
red: "#d84b4b"
|
||||
secondary: "#314cb6"
|
||||
success: "#35b246"
|
||||
teal: "#35b299"
|
||||
warning: "#edae49"
|
||||
white: "#f7f7f7"
|
||||
yellow: "#edae49"
|
||||
fonts:
|
||||
body: Nunito
|
||||
mono: Fira Code
|
||||
```
|
||||
99
docs/docs/ui/logo.mdx
Normal file
99
docs/docs/ui/logo.mdx
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
---
|
||||
id: logo
|
||||
title: Logo
|
||||
sidebar_label: Logo
|
||||
keywords: [hyperglass, looking glass, web ui, gui, branding, logo]
|
||||
description: Customize the Logo & Favicon
|
||||
---
|
||||
|
||||
## `logo`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :-------- | :-----: | :-------------- | :-------------------------------------------- |
|
||||
| `light` | String | hyperglass logo | Path to logo that will be used in light mode |
|
||||
| `dark` | String | hyperglass logo | Path to logo that will be used in dark mode |
|
||||
| `favicon` | String | hyperglass icon | Path to logo that will be used as the favicon |
|
||||
| `width` | Integer | `384` | Maximum logo width in pixels |
|
||||
| `height` | Integer | | Maximum logo height in pixels |
|
||||
|
||||
### Favicon
|
||||
|
||||
It's very easy to customize the favicon imaged used by hyperglass. If you're not familiar with the term, the favicon is the icon used by the browser in tabs, windows, or bookmarks:
|
||||
|
||||

|
||||
|
||||
During the [UI build process](setup.mdx#ui-build) hyperglass automatically generates favicon files in all of the many formats required for cross-platform, cross-browser support.
|
||||
|
||||
#### Supported Formats
|
||||
|
||||
- `.jpg`
|
||||
- `.jpeg`
|
||||
- `.png`
|
||||
- `.svg`
|
||||
|
||||
:::caution Icon File Size
|
||||
Generating the favicons is very CPU-intensive, and therefore has the tendency of timing out if the icon file is very large. If you receive a timeout error when starting hyperglass or running the `hyperglass build-ui` command, try reducing the size of the icon file. **File sizes of around 200 MB** have been known to succeed without too much overhead.
|
||||
:::
|
||||
|
||||
The following icons types are generated:
|
||||
|
||||
```
|
||||
android-chrome-36x36.png
|
||||
android-chrome-48x48.png
|
||||
android-chrome-72x72.png
|
||||
android-chrome-96x96.png
|
||||
android-chrome-144x144.png
|
||||
android-chrome-192x192.png
|
||||
android-chrome-256x256.png
|
||||
android-chrome-384x384.png
|
||||
android-chrome-512x512.png
|
||||
apple-touch-icon-57x57.png
|
||||
apple-touch-icon-60x60.png
|
||||
apple-touch-icon-72x72.png
|
||||
apple-touch-icon-76x76.png
|
||||
apple-touch-icon-114x114.png
|
||||
apple-touch-icon-120x120.png
|
||||
apple-touch-icon-144x144.png
|
||||
apple-touch-icon-152x152.png
|
||||
apple-touch-icon-167x167.png
|
||||
apple-touch-icon-180x180.png
|
||||
apple-touch-icon-1024x1024.png
|
||||
apple-touch-icon-precomposed.png
|
||||
apple-touch-icon.png
|
||||
apple-touch-startup-image-640x1136.png
|
||||
apple-touch-startup-image-750x1334.png
|
||||
apple-touch-startup-image-828x1792.png
|
||||
apple-touch-startup-image-1125x2436.png
|
||||
apple-touch-startup-image-1136x640.png
|
||||
apple-touch-startup-image-1242x2208.png
|
||||
apple-touch-startup-image-1242x2688.png
|
||||
apple-touch-startup-image-1334x750.png
|
||||
apple-touch-startup-image-1536x2048.png
|
||||
apple-touch-startup-image-1620x2160.png
|
||||
apple-touch-startup-image-1668x2224.png
|
||||
apple-touch-startup-image-1668x2388.png
|
||||
apple-touch-startup-image-1792x828.png
|
||||
apple-touch-startup-image-2048x1536.png
|
||||
apple-touch-startup-image-2048x2732.png
|
||||
apple-touch-startup-image-2160x1620.png
|
||||
apple-touch-startup-image-2208x1242.png
|
||||
apple-touch-startup-image-2224x1668.png
|
||||
apple-touch-startup-image-2388x1668.png
|
||||
apple-touch-startup-image-2436x1125.png
|
||||
apple-touch-startup-image-2688x1242.png
|
||||
apple-touch-startup-image-2732x2048.png
|
||||
coast-228x228.png
|
||||
favicon-16x16.png
|
||||
favicon-32x32.png
|
||||
favicon-48x48.png
|
||||
favicon.ico
|
||||
firefox_app_60x60.png
|
||||
firefox_app_128x128.png
|
||||
firefox_app_512x512.png
|
||||
mstile-70x70.png
|
||||
mstile-144x144.png
|
||||
mstile-150x150.png
|
||||
mstile-310x150.png
|
||||
mstile-310x310.png
|
||||
yandex-browser-50x50.png
|
||||
```
|
||||
BIN
docs/docs/ui/screenshot-favicons.jpg
Normal file
BIN
docs/docs/ui/screenshot-favicons.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
36
docs/docs/ui/text.mdx
Normal file
36
docs/docs/ui/text.mdx
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
id: text
|
||||
title: Text
|
||||
sidebar_label: Text
|
||||
keywords: [hyperglass, looking glass, web ui, gui, branding, text, messages]
|
||||
description: Customize the text used in the web UI
|
||||
---
|
||||
|
||||
## `text`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :--------------- | :----: | :------------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `cache_prefix` | String | `'Results cached for '` | Text displayed with the cache timeout countdown. |
|
||||
| `cache_icon` | String | `'Cached Response from {time}'` | Text displayed when a user hovers over the lightning bolt icon, which is displayed when a response from the server was a cached response. `{time}` is replaced with the _original_ query's timestamp. |
|
||||
| `completed_time` | String | `'Completed in {seconds}'` | Text displayed when a user hovers over the success icon for a query result. `{seconds}` will be replaced with 'n seconds' where n is the time a query took to complete. |
|
||||
| `fqdn_tooltip` | String | `'Use {protocol}'` | Text displayed when a user hovers over the IPv4 or IPv6 button on an FQDN target resolved by DNS. `{protocol}` is replaced with the relevant IP protocol. |
|
||||
| `query_location` | String | `'Location'` | Query Location (router) form label. |
|
||||
| `query_target` | String | `'Target'` | Query Target (IP/hostname/community/AS Path) form label. |
|
||||
| `query_type` | String | `'Query Type'` | Query Type (BGP Route, Ping, Traceroute, etc.) form label. |
|
||||
| `query_vrf` | String | `'Routing Table'` | Query VRF form label. |
|
||||
| `subtitle` | String | `'Network Looking Glass'` | Subtitle text. value. |
|
||||
| `title` | String | `'hyperglass'` | Title text. |
|
||||
| `title_mode` | String | `'text_only'` | Set the title mode. <MiniNote>Must be <Code>text_only</Code>, <Code>logo_only</Code>, <Code>logo_subtitle</Code>, or <Code>all</Code></MiniNote> |
|
||||
|
||||
### Title Mode
|
||||
|
||||
The `title_mode` parameter behaves in the following manner:
|
||||
|
||||
<div className="table--full-width" />
|
||||
|
||||
| Mode | Behavior |
|
||||
| --------------- | ------------------------------------------------------------------- |
|
||||
| `text_only` | Shows the [`title`](#text) and [`subtitle`](#text) only. |
|
||||
| `logo_only` | Shows the [`logo`](ui/logo) only. |
|
||||
| `logo_subtitle` | Shows the [`logo`](ui/logo) and [`subtitle`](#text) only. |
|
||||
| `all` | Shows the [`logo`](ui/logo), [`title`](#text), [`subtitle`](#text). |
|
||||
58
docs/docs/ui/theme.mdx
Normal file
58
docs/docs/ui/theme.mdx
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
id: theme
|
||||
title: Theme
|
||||
sidebar_label: Theme
|
||||
keywords: [hyperglass, looking glass, web ui, gui, branding, theme]
|
||||
description: Customize Theme
|
||||
---
|
||||
|
||||
import Color from "../../src/components/Color";
|
||||
import Font from "../../src/components/Font";
|
||||
import PageLink from "../../src/components/PageLink";
|
||||
|
||||
## `theme`
|
||||
|
||||
### Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :------------------- | :----: | :----------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `default_color_mode` | String | Sets the default color mode. Must be `light` or `dark`. If no default mode is specified, hyperglass will use the browser's preferred color mode. |
|
||||
|
||||
### Subsections
|
||||
|
||||
| Section | Description | All Options |
|
||||
| :------- | :----------- | :----------------------------------: |
|
||||
| `colors` | Theme colors | <PageLink to="#colors">➡️</PageLink> |
|
||||
| `fonts` | Theme fonts | <PageLink to="#fonts">➡️</PageLink> |
|
||||
|
||||
#### `colors`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :---------- | :----: | :--------------------- | :------------------------------------- |
|
||||
| `primary` | String | | Primary accent color |
|
||||
| `secondary` | String | | Secondary accent color |
|
||||
| `success` | String | | Success message/status color |
|
||||
| `warning` | String | | Warning message/status color |
|
||||
| `error` | String | | Error message/status color |
|
||||
| `danger` | String | | Danger message/status color |
|
||||
| `black` | String | <Color hex="#262626"/> | Used as background color in dark mode |
|
||||
| `white` | String | <Color hex="#f7f7f7"/> | Used as background color in light mode |
|
||||
| `red` | String | <Color hex="#d84b4b"/> | Used as `danger` color if undefined |
|
||||
| `orange` | String | <Color hex="#ff6b35"/> | Used as `error` color if undefined |
|
||||
| `yellow` | String | <Color hex="#edae49"/> | Used as `warning` color if undefined |
|
||||
| `green` | String | <Color hex="#35b246"/> | Used as `success` color if undefined |
|
||||
| `cyan` | String | <Color hex="#118ab2"/> | Used as `primary` color if undefined |
|
||||
| `blue` | String | <Color hex="#314cb6"/> | Used as `secondary` color if undefined |
|
||||
| `teal` | String | <Color hex="#35b299"/> | |
|
||||
| `pink` | String | <Color hex="#f2607d"/> | |
|
||||
| `purple` | String | <Color hex="#8d30b5"/> | |
|
||||
| `gray` | String | <Color hex="#c1c7cc"/> | |
|
||||
|
||||
#### `fonts`
|
||||
|
||||
Currently, only [Google Fonts](https://fonts.google.com/) are supported.
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| :-------- | :----: | :----------------------- | :-------------------------------------- |
|
||||
| `body` | String | <Font name="Nunito"/> | Main body font |
|
||||
| `mono` | String | <Font name="Fira Code"/> | Monospace font, used for command output |
|
||||
|
|
@ -188,11 +188,15 @@ def setup(unattended):
|
|||
install_path = user_path
|
||||
|
||||
ui_dir = install_path / "static" / "ui"
|
||||
images_dir = install_path / "static" / "images"
|
||||
favicon_dir = images_dir / "favicons"
|
||||
custom_dir = install_path / "static" / "custom"
|
||||
|
||||
create_dir(install_path)
|
||||
create_dir(ui_dir, parents=True)
|
||||
create_dir(custom_dir, parents=True)
|
||||
|
||||
for path in (ui_dir, images_dir, custom_dir, favicon_dir):
|
||||
create_dir(path, parents=True)
|
||||
|
||||
migrate_static_assets(install_path)
|
||||
|
||||
example_dir = WORKING_DIR.parent / "examples"
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@ from pathlib import Path
|
|||
|
||||
# Third Party
|
||||
import PIL.Image as PilImage
|
||||
from pydantic import StrictInt, StrictStr, root_validator
|
||||
from pydantic import FilePath, StrictInt, root_validator
|
||||
|
||||
# Project
|
||||
from hyperglass.models import HyperglassModel
|
||||
from hyperglass.configuration.models._utils import validate_image
|
||||
|
||||
CONFIG_PATH = Path(os.environ["hyperglass_directory"])
|
||||
DEFAULT_IMAGES = Path(__file__).parent.parent.parent / "images"
|
||||
|
||||
|
||||
class OpenGraph(HyperglassModel):
|
||||
|
|
@ -21,7 +21,7 @@ class OpenGraph(HyperglassModel):
|
|||
|
||||
width: Optional[StrictInt]
|
||||
height: Optional[StrictInt]
|
||||
image: Optional[StrictStr]
|
||||
image: FilePath = DEFAULT_IMAGES / "hyperglass-opengraph.png"
|
||||
|
||||
@root_validator
|
||||
def validate_opengraph(cls, values):
|
||||
|
|
@ -36,21 +36,15 @@ class OpenGraph(HyperglassModel):
|
|||
supported_extensions = (".jpg", ".jpeg", ".png")
|
||||
if (
|
||||
values["image"] is not None
|
||||
and Path(values["image"]).suffix not in supported_extensions
|
||||
and values["image"].suffix not in supported_extensions
|
||||
):
|
||||
raise ValueError(
|
||||
"OpenGraph image must be one of {e}".format(
|
||||
e=", ".join(supported_extensions)
|
||||
)
|
||||
)
|
||||
if values["image"] is None:
|
||||
values["image"] = "images/hyperglass-opengraph.png"
|
||||
|
||||
values["image"] = validate_image(values["image"])
|
||||
|
||||
image_file = CONFIG_PATH / "static" / values["image"]
|
||||
|
||||
with PilImage.open(image_file) as img:
|
||||
with PilImage.open(values["image"]) as img:
|
||||
width, height = img.size
|
||||
if values["width"] is None:
|
||||
values["width"] = width
|
||||
|
|
@ -78,4 +72,3 @@ class OpenGraph(HyperglassModel):
|
|||
"description": "Valid path to a JPG or PNG file to use as the OpenGraph image.",
|
||||
},
|
||||
}
|
||||
schema_extra = {"level": 3}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
# Standard Library
|
||||
from typing import Union, Optional
|
||||
from pathlib import Path
|
||||
|
||||
# Third Party
|
||||
from pydantic import (
|
||||
|
|
@ -19,9 +20,10 @@ from pydantic.color import Color
|
|||
# Project
|
||||
from hyperglass.models import HyperglassModel
|
||||
from hyperglass.constants import DNS_OVER_HTTPS, FUNC_COLOR_MAP
|
||||
from hyperglass.configuration.models._utils import validate_image
|
||||
from hyperglass.configuration.models.opengraph import OpenGraph
|
||||
|
||||
DEFAULT_IMAGES = Path(__file__).parent.parent.parent / "images"
|
||||
|
||||
|
||||
class Analytics(HyperglassModel):
|
||||
"""Validation model for Google Analytics."""
|
||||
|
|
@ -90,31 +92,11 @@ class Greeting(HyperglassModel):
|
|||
class Logo(HyperglassModel):
|
||||
"""Validation model for logo configuration."""
|
||||
|
||||
light: StrictStr = "images/hyperglass-light.png"
|
||||
dark: StrictStr = "images/hyperglass-dark.png"
|
||||
light: FilePath = DEFAULT_IMAGES / "hyperglass-light.png"
|
||||
dark: FilePath = DEFAULT_IMAGES / "hyperglass-dark.png"
|
||||
favicon: FilePath = DEFAULT_IMAGES / "icon.svg"
|
||||
width: Optional[Union[StrictInt, constr(regex=r"^([1-9][0-9]?|100)\%$")]] = "80%"
|
||||
height: Optional[Union[StrictInt, constr(regex=r"^([1-9][0-9]?|100)\%$")]]
|
||||
favicons: StrictStr = "ui/images/favicons/"
|
||||
|
||||
@validator("favicons")
|
||||
def favicons_trailing_slash(cls, value):
|
||||
"""If the favicons path does not end in a '/', append it."""
|
||||
chars = list(value)
|
||||
if chars[len(chars) - 1] != "/":
|
||||
chars.append("/")
|
||||
return "".join(chars)
|
||||
|
||||
@validator("light", "dark")
|
||||
def validate_logos(cls, value):
|
||||
"""Convert file path to URL path.
|
||||
|
||||
Arguments:
|
||||
value {FilePath} -- Path to logo file.
|
||||
|
||||
Returns:
|
||||
{str} -- Formatted logo path
|
||||
"""
|
||||
return validate_image(value)
|
||||
|
||||
|
||||
class Terms(HyperglassModel):
|
||||
|
|
|
|||
|
|
@ -1,12 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 1014 1014" style="enable-background:new 0 0 1014 1014;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FF5E5B;}
|
||||
</style>
|
||||
<g transform="translate(0.000000,1014.000000) scale(0.100000,-0.100000)">
|
||||
<path class="st0" d="M4809,10126c-2-2-51-7-109-10c-92-6-211-18-305-30c-16-3-52-8-80-11c-27-4-138-24-245-46
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1014 1014" style="enable-background:new 0 0 1014 1014;" xml:space="preserve">
|
||||
<g transform="translate(0.000000,1014.000000) scale(0.100000,-0.100000)">
|
||||
<path fill="#ff5e5b" d="M4809,10126c-2-2-51-7-109-10c-92-6-211-18-305-30c-16-3-52-8-80-11c-27-4-138-24-245-46
|
||||
c-516-102-1052-302-1491-556c-48-27-93-53-100-56c-30-14-217-138-333-220c-432-307-811-676-1130-1102c-213-283-391-582-540-905
|
||||
c-145-311-255-631-331-956c-19-82-37-167-41-189c-3-22-7-42-9-45s-6-24-9-46c-4-22-8-51-11-64c-3-14-14-92-24-175
|
||||
c-18-134-24-193-37-380c-5-75-5-429,1-520c11-199,29-383,45-470c5-27,11-69,14-92c16-128,97-477,156-668c133-435,341-881,591-1267
|
||||
|
|
@ -28,13 +22,13 @@
|
|||
c-81,11-389,93-529,141c-413,142-798,346-1145,609c-327,248-663,597-888,926c-376,548-621,1187-692,1805c-3,28-8,64-10,80
|
||||
c-25,188-25,664,0,840c3,17,7,53,10,80c29,264,110,602,211,880c292,808,844,1513,1560,1993c194,130,481,286,654,356
|
||||
c36,15,74,31,85,36c110,52,496,172,662,205c133,27,269,49,374,61c30,3,65,8,79,10s86,7,160,10c74,4,136,8,138,9
|
||||
C4972,9128,5212,9122,5336,9116z"/>
|
||||
<path class="st0" d="M3445,8398c-84-32-397-246-566-388c-223-187-442-415-652-680c-123-155-312-465-420-690
|
||||
C4972,9128,5212,9122,5336,9116z" />
|
||||
<path fill="#ff5e5b" d="M3445,8398c-84-32-397-246-566-388c-223-187-442-415-652-680c-123-155-312-465-420-690
|
||||
c-74-154-190-440-202-500c-1-3-15-50-32-105c-30-96-77-280-87-337c-3-15-11-63-20-105c-15-79-20-108-31-198c-4-27-8-60-10-73
|
||||
c-13-79-20-239-20-457c0-280,5-309,70-377c55-60,102-79,191-79c88-1,173,52,217,135c20,38,22,56,23,261c2,262,11,413,34,555
|
||||
c5,30,12,73,15,94s7,48,10,60s7,33,10,49c12,64,17,88,46,197c124,482,347,931,658,1325c151,191,360,403,534,543c40,31,74,59,77,63
|
||||
c12,13,222,159,300,208c103,65,136,94,162,145c60,117,16,265-97,332C3602,8407,3497,8418,3445,8398z"/>
|
||||
<path class="st0" d="M1691,4003c-91-33-161-138-161-241c0-74,135-389,275-641c107-195,164-243,285-244c138-1,246,98,254,232
|
||||
c4,63-12,111-73,216c-68,117-166,320-226,467c-50,124-86,172-153,204C1842,4020,1745,4023,1691,4003z"/>
|
||||
</g>
|
||||
c12,13,222,159,300,208c103,65,136,94,162,145c60,117,16,265-97,332C3602,8407,3497,8418,3445,8398z" />
|
||||
<path fill="#ff5e5b" d="M1691,4003c-91-33-161-138-161-241c0-74,135-389,275-641c107-195,164-243,285-244c138-1,246,98,254,232
|
||||
c4,63-12,111-73,216c-68,117-166,320-226,467c-50,124-86,172-153,204C1842,4020,1745,4023,1691,4003z" />
|
||||
</g>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.7 KiB |
|
|
@ -21,8 +21,6 @@ export const HyperglassProvider = ({ config, children }) => {
|
|||
const value = useMemo(() => config, [config]);
|
||||
const userTheme = value && makeTheme(value.web.theme);
|
||||
const theme = value ? userTheme : defaultTheme;
|
||||
// console.log(value);
|
||||
// console.log(theme);
|
||||
return (
|
||||
<HyperglassContext.Provider value={value}>
|
||||
<ThemeProvider theme={theme}>
|
||||
|
|
|
|||
72
hyperglass/ui/generateFavicons.js
Normal file
72
hyperglass/ui/generateFavicons.js
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
const fs = require("fs");
|
||||
const favicons = require("favicons");
|
||||
const tempy = require("tempy");
|
||||
|
||||
const defaultConfig = {
|
||||
path: "/images/favicons",
|
||||
appleStatusBarStyle: "black-translucent",
|
||||
display: "standalone",
|
||||
orientation: "any",
|
||||
scope: "/",
|
||||
icons: {
|
||||
android: true,
|
||||
appleIcon: true,
|
||||
appleStartup: true,
|
||||
coast: true,
|
||||
favicons: true,
|
||||
firefox: true,
|
||||
windows: true,
|
||||
yandex: true
|
||||
}
|
||||
};
|
||||
|
||||
const handleError = err => {
|
||||
if (err) {
|
||||
if (err.message) {
|
||||
console.error(err.message);
|
||||
return;
|
||||
}
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
const writeHtml = (path, data) => {
|
||||
fs.writeFile(path, data, handleError);
|
||||
return;
|
||||
};
|
||||
|
||||
const writeFiles = (basePath, files) => {
|
||||
files.forEach(attrs => {
|
||||
fs.writeFile(`${basePath}/${attrs.name}`, attrs.contents, handleError);
|
||||
});
|
||||
return;
|
||||
};
|
||||
|
||||
const generateFavicons = (config, appPath) => {
|
||||
const htmlFile = tempy.file({ extension: "json" });
|
||||
const callback = (err, response) => {
|
||||
handleError(err);
|
||||
writeFiles(`${appPath}/static/images/favicons`, response.images);
|
||||
writeFiles(`${appPath}/static/ui`, response.files);
|
||||
writeHtml(htmlFile, JSON.stringify(response.html));
|
||||
return;
|
||||
};
|
||||
|
||||
favicons(
|
||||
config.web.logo.favicon,
|
||||
{
|
||||
appName: config.site_title,
|
||||
appDescription: config.site_description,
|
||||
lang: config.language || "en-US",
|
||||
background: config.web.theme.colors.white,
|
||||
theme_color: config.web.theme.colors.primary,
|
||||
...defaultConfig
|
||||
},
|
||||
callback
|
||||
);
|
||||
return htmlFile;
|
||||
};
|
||||
|
||||
module.exports = generateFavicons;
|
||||
|
|
@ -2,6 +2,12 @@ const aliases = require("./.alias");
|
|||
const envVars = require("/tmp/hyperglass.env.json");
|
||||
const { configFile } = envVars;
|
||||
const config = require(String(configFile));
|
||||
const generateFavicons = require("./generateFavicons");
|
||||
|
||||
const faviconHtmlFile = generateFavicons(
|
||||
config._HYPERGLASS_CONFIG_,
|
||||
config._HYPERGLASS_APP_PATH_
|
||||
);
|
||||
|
||||
module.exports = {
|
||||
webpack(config) {
|
||||
|
|
@ -16,6 +22,7 @@ module.exports = {
|
|||
env: {
|
||||
_NODE_ENV_: config.NODE_ENV,
|
||||
_HYPERGLASS_URL_: config._HYPERGLASS_URL_,
|
||||
_HYPERGLASS_CONFIG_: config._HYPERGLASS_CONFIG_
|
||||
_HYPERGLASS_CONFIG_: config._HYPERGLASS_CONFIG_,
|
||||
_FAVICON_HTML_FILE_: faviconHtmlFile
|
||||
}
|
||||
};
|
||||
|
|
|
|||
3
hyperglass/ui/package.json
vendored
3
hyperglass/ui/package.json
vendored
|
|
@ -24,7 +24,9 @@
|
|||
"chroma-js": "^2.1.0",
|
||||
"dayjs": "^1.8.25",
|
||||
"emotion-theming": "^10.0.27",
|
||||
"favicons": "^6.1.0",
|
||||
"framer-motion": "^1.10.0",
|
||||
"html-to-react": "^1.4.3",
|
||||
"lodash": "^4.17.15",
|
||||
"next": "^9.3.1",
|
||||
"react": "^16.13.1",
|
||||
|
|
@ -39,6 +41,7 @@
|
|||
"react-textfit": "^1.1.0",
|
||||
"string-format": "^2.0.0",
|
||||
"styled-system": "^5.1.5",
|
||||
"tempy": "^0.5.0",
|
||||
"use-media": "^1.4.0",
|
||||
"yup": "^0.28.3"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,16 +1,41 @@
|
|||
import * as React from "react";
|
||||
import { createElement } from "react";
|
||||
import Head from "next/head";
|
||||
import dynamic from "next/dynamic";
|
||||
import fs from "fs";
|
||||
import { Parser } from "html-to-react";
|
||||
import Meta from "~/components/Meta";
|
||||
import Loading from "~/components/Loading";
|
||||
const LookingGlass = dynamic(() => import("~/components/LookingGlass"), {
|
||||
loading: Loading
|
||||
});
|
||||
|
||||
const Index = () => (
|
||||
<>
|
||||
<Meta />
|
||||
<LookingGlass />
|
||||
</>
|
||||
);
|
||||
const Index = ({ faviconComponents }) => {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
{faviconComponents.map((comp, i) =>
|
||||
createElement(comp.type, { key: i, ...comp.props })
|
||||
)}
|
||||
</Head>
|
||||
<Meta />
|
||||
<LookingGlass />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export async function getStaticProps(context) {
|
||||
const htmlToReact = new Parser();
|
||||
const lines = fs.readFileSync(process.env._FAVICON_HTML_FILE_, "utf-8");
|
||||
const components = JSON.parse(lines).map(elem => {
|
||||
const comp = htmlToReact.parse(elem);
|
||||
return { type: comp.type, props: comp.props };
|
||||
});
|
||||
return {
|
||||
props: {
|
||||
faviconComponents: components
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default Index;
|
||||
|
|
|
|||
3844
hyperglass/ui/yarn.lock
vendored
3844
hyperglass/ui/yarn.lock
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,12 @@
|
|||
"""Utility functions."""
|
||||
|
||||
# Standard Library
|
||||
import shutil
|
||||
from queue import Queue
|
||||
from typing import Iterable
|
||||
from pathlib import Path
|
||||
from threading import Thread
|
||||
|
||||
# Project
|
||||
from hyperglass.log import log
|
||||
|
||||
|
|
@ -37,7 +44,7 @@ def clean_name(_name):
|
|||
return _scrubbed.lower()
|
||||
|
||||
|
||||
def check_path(path, mode="r"):
|
||||
def check_path(path, mode="r", create=False):
|
||||
"""Verify if a path exists and is accessible.
|
||||
|
||||
Arguments:
|
||||
|
|
@ -50,14 +57,19 @@ def check_path(path, mode="r"):
|
|||
Returns:
|
||||
{Path|None} -- Path object if checks pass, None if not.
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
if not isinstance(path, Path):
|
||||
path = Path(path)
|
||||
|
||||
if not path.exists():
|
||||
raise FileNotFoundError(f"{str(path)} does not exist.")
|
||||
if create:
|
||||
if path.is_file():
|
||||
path.parent.mkdir(parents=True)
|
||||
else:
|
||||
path.mkdir(parents=True)
|
||||
else:
|
||||
raise FileNotFoundError(f"{str(path)} does not exist.")
|
||||
|
||||
with path.open(mode):
|
||||
result = path
|
||||
|
|
@ -95,7 +107,8 @@ async def build_ui(app_path):
|
|||
RuntimeError: Raised when any other error occurs.
|
||||
"""
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
|
||||
timeout = 60
|
||||
|
||||
ui_dir = Path(__file__).parent / "ui"
|
||||
build_dir = app_path / "static" / "ui"
|
||||
|
|
@ -113,7 +126,7 @@ async def build_ui(app_path):
|
|||
cwd=ui_dir,
|
||||
)
|
||||
|
||||
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=60)
|
||||
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=timeout)
|
||||
messages = stdout.decode("utf-8").strip()
|
||||
errors = stderr.decode("utf-8").strip()
|
||||
|
||||
|
|
@ -123,6 +136,9 @@ async def build_ui(app_path):
|
|||
await proc.wait()
|
||||
all_messages.append(messages)
|
||||
|
||||
except asyncio.TimeoutError:
|
||||
raise RuntimeError(f"{timeout} second timeout exceeded while building UI")
|
||||
|
||||
except Exception as e:
|
||||
raise RuntimeError(str(e))
|
||||
|
||||
|
|
@ -140,7 +156,6 @@ async def write_env(variables):
|
|||
"""
|
||||
from aiofile import AIOFile
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
env_file = Path("/tmp/hyperglass.env.json") # noqa: S108
|
||||
env_vars = json.dumps(variables)
|
||||
|
|
@ -213,8 +228,7 @@ async def move_files(src, dst, files): # noqa: C901
|
|||
dst {Path} -- Target destination directory
|
||||
files {Iterable} -- Iterable of files
|
||||
"""
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
from typing import Iterable
|
||||
|
||||
def error(*args, **kwargs):
|
||||
|
|
@ -267,8 +281,7 @@ async def move_files(src, dst, files): # noqa: C901
|
|||
|
||||
def migrate_static_assets(app_path):
|
||||
"""Synchronize the project assets with the installation assets."""
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
from filecmp import dircmp
|
||||
|
||||
asset_dir = Path(__file__).parent / "images"
|
||||
|
|
@ -309,7 +322,6 @@ async def check_node_modules():
|
|||
Returns:
|
||||
{bool} -- True if exists and has contents.
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
ui_path = Path(__file__).parent / "ui"
|
||||
node_modules = ui_path / "node_modules"
|
||||
|
|
@ -334,7 +346,6 @@ async def node_initial(dev_mode=False):
|
|||
{str} -- Command output
|
||||
"""
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
|
||||
ui_path = Path(__file__).parent / "ui"
|
||||
|
||||
|
|
@ -378,7 +389,7 @@ async def read_package_json():
|
|||
Returns:
|
||||
{dict} -- NPM package.json as dict
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
import json
|
||||
|
||||
package_json_file = Path(__file__).parent / "ui" / "package.json"
|
||||
|
|
@ -396,6 +407,85 @@ async def read_package_json():
|
|||
return package_json
|
||||
|
||||
|
||||
class FileCopy(Thread):
|
||||
"""Custom thread for copyfiles() function."""
|
||||
|
||||
def __init__(self, src: Path, dst: Path, queue: Queue):
|
||||
"""Initialize custom thread."""
|
||||
super().__init__()
|
||||
|
||||
if not src.exists():
|
||||
raise ValueError("{} does not exist", str(src))
|
||||
|
||||
self.src = src
|
||||
self.dst = dst
|
||||
self.queue = queue
|
||||
|
||||
def run(self):
|
||||
"""Put one object into the queue for each file."""
|
||||
try:
|
||||
try:
|
||||
shutil.copy(self.src, self.dst)
|
||||
except IOError as err:
|
||||
self.queue.put(err)
|
||||
else:
|
||||
self.queue.put(self.src)
|
||||
finally:
|
||||
pass
|
||||
|
||||
|
||||
def copyfiles(src_files: Iterable[Path], dst_files: Iterable[Path]):
|
||||
"""Copy iterable of files from source to destination with threading."""
|
||||
queue = Queue()
|
||||
threads = ()
|
||||
src_files_len = len(src_files)
|
||||
dst_files_len = len(dst_files)
|
||||
|
||||
if src_files_len != dst_files_len:
|
||||
raise ValueError(
|
||||
"The number of source files "
|
||||
+ "({}) must match the number of destination files ({}).".format(
|
||||
src_files_len, dst_files_len
|
||||
)
|
||||
)
|
||||
|
||||
for i, file in enumerate(src_files):
|
||||
file_thread = FileCopy(src=file, dst=dst_files[i], queue=queue)
|
||||
threads += (file_thread,)
|
||||
|
||||
for thread in threads:
|
||||
thread.start()
|
||||
|
||||
for _file in src_files:
|
||||
copied = queue.get()
|
||||
log.success("Copied {}", str(copied))
|
||||
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
|
||||
for i, file in enumerate(dst_files):
|
||||
if not file.exists():
|
||||
raise RuntimeError("{} was not copied to {}", str(src_files[i]), str(file))
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def migrate_images(app_path, params):
|
||||
"""Migrate images from source code to install directory."""
|
||||
images_dir = app_path / "static" / "images"
|
||||
favicon_dir = images_dir / "favicons"
|
||||
check_path(favicon_dir, create=True)
|
||||
src_files = ()
|
||||
dst_files = ()
|
||||
|
||||
for image in ("light", "dark", "favicon"):
|
||||
src = Path(params["web"]["logo"][image])
|
||||
dst = images_dir / f"{image + src.suffix}"
|
||||
src_files += (src,)
|
||||
dst_files += (dst,)
|
||||
return copyfiles(src_files, dst_files)
|
||||
|
||||
|
||||
async def build_frontend( # noqa: C901
|
||||
dev_mode, dev_url, prod_url, params, app_path, force=False
|
||||
):
|
||||
|
|
@ -426,7 +516,7 @@ async def build_frontend( # noqa: C901
|
|||
"""
|
||||
import hashlib
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
from aiofile import AIOFile
|
||||
import json
|
||||
from hyperglass.constants import __version__
|
||||
|
|
@ -439,6 +529,7 @@ async def build_frontend( # noqa: C901
|
|||
"_HYPERGLASS_CONFIG_": params,
|
||||
"_HYPERGLASS_VERSION_": __version__,
|
||||
"_HYPERGLASS_PACKAGE_JSON_": package_json,
|
||||
"_HYPERGLASS_APP_PATH_": str(app_path),
|
||||
}
|
||||
|
||||
# Set NextJS production/development mode and base URL based on
|
||||
|
|
@ -517,7 +608,7 @@ async def build_frontend( # noqa: C901
|
|||
elif dev_mode and not force:
|
||||
log.debug("Running in developer mode, did not build new UI files")
|
||||
|
||||
migrate_static_assets(app_path)
|
||||
await migrate_images(app_path, params)
|
||||
|
||||
except Exception as e:
|
||||
raise RuntimeError(str(e)) from None
|
||||
|
|
@ -528,7 +619,7 @@ async def build_frontend( # noqa: C901
|
|||
def set_app_path(required=False):
|
||||
"""Find app directory and set value to environment variable."""
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from getpass import getuser
|
||||
|
||||
matched_path = None
|
||||
|
|
@ -581,7 +672,6 @@ def import_public_key(app_path, device_name, keystring):
|
|||
{bool} -- True if file was written
|
||||
"""
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
if not isinstance(app_path, Path):
|
||||
app_path = Path(app_path)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue