React UI: Serve React UI under /new (#6229)

This makes React UI URLs look nicer than the previous
/static/graph-new/app.html, but internally still serves all React UI
files from the compiled-in static assets directory.

Also, to allow future usage of the React / Reach router, we need to
serve the main React app's index.html on certain sub-paths that
correspond to current Prometheus's UI pages, instead of trying to serve
actual files that match the provided path name.

Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
Julius Volz 2019-10-28 10:45:53 +01:00 committed by GitHub
parent 3f3986ed53
commit e8027ba515
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 48 additions and 19 deletions

2
.gitignore vendored
View file

@ -18,5 +18,5 @@ benchmark.txt
/documentation/examples/remote_storage/example_write_adapter/example_writer_adapter
npm_licenses.tar.bz2
/web/ui/static/graph-new
/web/ui/static/react
/web/ui/assets_vfsdata.go

View file

@ -16,7 +16,7 @@ DOCKER_ARCHS ?= amd64 armv7 arm64
REACT_APP_PATH = web/ui/react-app
REACT_APP_SOURCE_FILES = $(wildcard $(REACT_APP_PATH)/public/* $(REACT_APP_PATH)/src/* $(REACT_APP_PATH)/tsconfig.json)
REACT_APP_OUTPUT_DIR = web/ui/static/graph-new
REACT_APP_OUTPUT_DIR = web/ui/static/react
REACT_APP_NODE_MODULES_PATH = $(REACT_APP_PATH)/node_modules
REACT_APP_NPM_LICENSES_TARBALL = "npm_licenses.tar.bz2"

View file

@ -14,7 +14,5 @@ cd web/ui/react-app
echo "building React app"
PUBLIC_URL=. yarn build
rm -rf ../static/graph-new
mv build ../static/graph-new
# Prevent bad redirect due to Go HTTP router treating index.html specially.
mv ../static/graph-new/index.html ../static/graph-new/app.html
rm -rf ../static/react
mv build ../static/react

View file

@ -21,7 +21,7 @@ class App extends Component {
<>
<Navigation />
<Container fluid>
<Router basepath="/react">
<Router basepath="/new">
<PanelList path="/graph" />
<Alerts path="/alerts" />
<Config path="/config" />

View file

@ -17,26 +17,26 @@ const Navigation = () => {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => setIsOpen(!isOpen);
return (
<Navbar className="mb-3" dark color="dark" expand="md">
<Navbar className="mb-3" dark color="dark" expand="md">
<NavbarToggler onClick={toggle}/>
<Link className="pt-0 navbar-brand" to="/react/graph">Prometheus</Link>
<Link className="pt-0 navbar-brand" to="/new/graph">Prometheus</Link>
<Collapse isOpen={isOpen} navbar style={{ justifyContent: 'space-between' }}>
<Nav className="ml-0" navbar>
<NavItem>
<NavLink tag={Link} to="/react/alerts">Alerts</NavLink>
<NavLink tag={Link} to="/new/alerts">Alerts</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to="/react/graph">Graph</NavLink>
<NavLink tag={Link} to="/new/graph">Graph</NavLink>
</NavItem>
<UncontrolledDropdown nav inNavbar>
<DropdownToggle nav caret>Status</DropdownToggle>
<DropdownMenu>
<DropdownItem tag={Link} to="/react/status">Runtime & Build Information</DropdownItem>
<DropdownItem tag={Link} to="/react/flags">Command-Line Flags</DropdownItem>
<DropdownItem tag={Link} to="/react/config">Configuration</DropdownItem>
<DropdownItem tag={Link} to="/react/rules">Rules</DropdownItem>
<DropdownItem tag={Link} to="/react/targets">Targets</DropdownItem>
<DropdownItem tag={Link} to="/react/service-discovery">Service Discovery</DropdownItem>
<DropdownItem tag={Link} to="/new/status">Runtime & Build Information</DropdownItem>
<DropdownItem tag={Link} to="/new/flags">Command-Line Flags</DropdownItem>
<DropdownItem tag={Link} to="/new/config">Configuration</DropdownItem>
<DropdownItem tag={Link} to="/new/rules">Rules</DropdownItem>
<DropdownItem tag={Link} to="/new/targets">Targets</DropdownItem>
<DropdownItem tag={Link} to="/new/service-discovery">Service Discovery</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
<NavItem>

View file

@ -29,7 +29,7 @@
<i class="glyphicon glyphicon-unchecked"></i>
<button type="button" class="search-history" title="search previous queries">Enable query history</button>
</div>
<button type="button" class="btn btn-link btn-sm new_ui_button" onclick="window.location.pathname='{{ pathPrefix }}/static/graph-new/app.html'">Try experimental React UI</a>
<button type="button" class="btn btn-link btn-sm new_ui_button" onclick="window.location.pathname='{{ pathPrefix }}/new'">Try experimental React UI</a>
</div>
</div>

View file

@ -68,7 +68,23 @@ import (
"github.com/prometheus/prometheus/web/ui"
)
var localhostRepresentations = []string{"127.0.0.1", "localhost"}
var (
localhostRepresentations = []string{"127.0.0.1", "localhost"}
// Paths that are handled by the React / Reach router that should all be served the main React app's index.html.
reactAppPaths = []string{
"/",
"/alerts",
"/config",
"/flags",
"/graph",
"/rules",
"/service-discovery",
"/status",
"/targets",
"/version",
}
)
// withStackTrace logs the stack trace in case the request panics. The function
// will re-raise the error which will then be handled by the net/http package.
@ -334,6 +350,21 @@ func New(logger log.Logger, o *Options) *Handler {
fs.ServeHTTP(w, r)
})
router.Get("/new/*filepath", func(w http.ResponseWriter, r *http.Request) {
p := route.Param(r.Context(), "filepath")
r.URL.Path = path.Join("/static/react/", p)
for _, rp := range reactAppPaths {
if p == rp {
r.URL.Path = "/static/react/"
break
}
}
fs := server.StaticFileServer(ui.Assets)
fs.ServeHTTP(w, r)
})
if o.UserAssetsPath != "" {
router.Get("/user/*filepath", route.FileServe(o.UserAssetsPath))
}