Просмотр исходного кода

Merge branch 'refactor-frontend-path'

Kailash Nadh 3 лет назад
Родитель
Сommit
a97d81a8dc
7 измененных файлов с 39 добавлено и 37 удалено
  1. 4 4
      Makefile
  2. 15 22
      cmd/handlers.go
  3. 14 5
      cmd/init.go
  4. 1 1
      frontend/public/index.html
  5. 0 0
      frontend/public/static/favicon.png
  6. 1 1
      frontend/src/api/index.js
  7. 4 4
      frontend/vue.config.js

+ 4 - 4
Makefile

@@ -23,7 +23,7 @@ STATIC := config.toml.sample \
 	schema.sql queries.sql \
 	static/public:/public \
 	static/email-templates \
-	frontend/dist/frontend:/frontend \
+	frontend/dist:/admin \
 	i18n:/i18n
 
 .PHONY: build
@@ -40,14 +40,14 @@ $(FRONTEND_YARN_MODULES): frontend/package.json frontend/yarn.lock
 $(BIN): $(shell find . -type f -name "*.go")
 	CGO_ENABLED=0 go build -o ${BIN} -ldflags="-s -w -X 'main.buildString=${BUILDSTR}' -X 'main.versionString=${VERSION}'" cmd/*.go
 
-# Run the backend in dev mode. The frontend assets in dev mode are loaded from disk from frontend/dist/frontend.
+# Run the backend in dev mode. The frontend assets in dev mode are loaded from disk from frontend/dist.
 .PHONY: run
 run:
-	CGO_ENABLED=0 go run -ldflags="-s -w -X 'main.buildString=${BUILDSTR}' -X 'main.versionString=${VERSION}' -X 'main.frontendDir=frontend/dist/frontend'" cmd/*.go
+	CGO_ENABLED=0 go run -ldflags="-s -w -X 'main.buildString=${BUILDSTR}' -X 'main.versionString=${VERSION}' -X 'main.frontendDir=frontend/dist'" cmd/*.go
 
 # Build the JS frontend into frontend/dist.
 $(FRONTEND_DIST): $(FRONTEND_DEPS)
-	export VUE_APP_VERSION="${VERSION}" && cd frontend && $(YARN) build && mv dist/favicon.png dist/frontend/favicon.png
+	export VUE_APP_VERSION="${VERSION}" && cd frontend && $(YARN) build
 	touch --no-create $(FRONTEND_DIST)
 
 

+ 15 - 22
cmd/handlers.go

@@ -4,6 +4,7 @@ import (
 	"crypto/subtle"
 	"net/http"
 	"net/url"
+	"path"
 	"regexp"
 	"strconv"
 
@@ -37,7 +38,7 @@ var (
 )
 
 // registerHandlers registers HTTP handlers.
-func registerHTTPHandlers(e *echo.Echo, app *App) {
+func initHTTPHandlers(e *echo.Echo, app *App) {
 	// Group of private handlers with BasicAuth.
 	var g *echo.Group
 
@@ -48,7 +49,15 @@ func registerHTTPHandlers(e *echo.Echo, app *App) {
 		g = e.Group("", middleware.BasicAuth(basicAuth))
 	}
 
-	g.GET("/", handleIndexPage)
+	// Admin JS app views.
+	// /admin/static/* file server is registered in initHTTPServer().
+	g.GET("/", func(c echo.Context) error {
+		return c.Redirect(http.StatusPermanentRedirect, path.Join(adminRoot, ""))
+	})
+	g.GET(path.Join(adminRoot, ""), handleAdminPage)
+	g.GET(path.Join(adminRoot, "/*"), handleAdminPage)
+
+	// API endpoints.
 	g.GET("/api/health", handleHealthCheck)
 	g.GET("/api/config", handleGetServerConfig)
 	g.GET("/api/lang/:lang", handleGetI18nLang)
@@ -125,21 +134,6 @@ func registerHTTPHandlers(e *echo.Echo, app *App) {
 	g.PUT("/api/templates/:id/default", handleTemplateSetDefault)
 	g.DELETE("/api/templates/:id", handleDeleteTemplate)
 
-	// Static admin views.
-	g.GET("/lists", handleIndexPage)
-	g.GET("/lists/forms", handleIndexPage)
-	g.GET("/subscribers", handleIndexPage)
-	g.GET("/subscribers/lists/:listID", handleIndexPage)
-	g.GET("/subscribers/import", handleIndexPage)
-	g.GET("/subscribers/bounces", handleIndexPage)
-	g.GET("/campaigns", handleIndexPage)
-	g.GET("/campaigns/new", handleIndexPage)
-	g.GET("/campaigns/media", handleIndexPage)
-	g.GET("/campaigns/templates", handleIndexPage)
-	g.GET("/campaigns/:campignID", handleIndexPage)
-	g.GET("/settings", handleIndexPage)
-	g.GET("/settings/logs", handleIndexPage)
-
 	if app.constants.BounceWebhooksEnabled {
 		// Private authenticated bounce endpoint.
 		g.POST("/webhooks/bounce", handleBounceWebhook)
@@ -171,17 +165,16 @@ func registerHTTPHandlers(e *echo.Echo, app *App) {
 	e.GET("/health", handleHealthCheck)
 }
 
-// handleIndex is the root handler that renders the Javascript frontend.
-func handleIndexPage(c echo.Context) error {
+// handleAdminPage is the root handler that renders the Javascript admin frontend.
+func handleAdminPage(c echo.Context) error {
 	app := c.Get("app").(*App)
 
-	b, err := app.fs.Read("/frontend/index.html")
+	b, err := app.fs.Read(path.Join(adminRoot, "/index.html"))
 	if err != nil {
 		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
 	}
 
-	c.Response().Header().Set("Content-Type", "text/html")
-	return c.String(http.StatusOK, string(b))
+	return c.HTMLBlob(http.StatusOK, b)
 }
 
 // handleHealthCheck is a healthcheck endpoint that returns a 200 response.

+ 14 - 5
cmd/init.go

@@ -39,6 +39,9 @@ import (
 
 const (
 	queryFilePath = "queries.sql"
+
+	// Root URI of the admin frontend.
+	adminRoot = "/admin"
 )
 
 // constants contains static, constant config values required by the app.
@@ -129,9 +132,9 @@ func initFS(appDir, frontendDir, staticDir, i18nDir string) stuffbin.FileSystem
 		}
 
 		frontendFiles = []string{
-			// The app's frontend assets are accessible at /frontend/js/* during runtime.
-			// These paths are joined with frontendDir.
-			"./:/frontend",
+			// Admin frontend's static assets accessible at /admin/* during runtime.
+			// These paths are sourced from frontendDir.
+			"./:/admin",
 		}
 
 		staticFiles = []string{
@@ -574,15 +577,21 @@ func initHTTPServer(app *App) *echo.Echo {
 
 	// Initialize the static file server.
 	fSrv := app.fs.FileServer()
+
+	// Public (subscriber) facing static files.
 	srv.GET("/public/*", echo.WrapHandler(fSrv))
-	srv.GET("/frontend/*", echo.WrapHandler(fSrv))
+
+	// Admin (frontend) facing static files.
+	srv.GET("/admin/static/*", echo.WrapHandler(fSrv))
+
+	// Public (subscriber) facing media upload files.
 	if ko.String("upload.provider") == "filesystem" {
 		srv.Static(ko.String("upload.filesystem.upload_uri"),
 			ko.String("upload.filesystem.upload_path"))
 	}
 
 	// Register all HTTP handlers.
-	registerHTTPHandlers(srv, app)
+	initHTTPHandlers(srv, app)
 
 	// Start the server.
 	go func() {

+ 1 - 1
frontend/public/index.html

@@ -4,7 +4,7 @@
     <meta charset="utf-8" />
     <meta http-equiv="X-UA-Compatible" content="IE=edge" />
     <meta name="viewport" content="width=device-width,initial-scale=1.0" />
-    <link rel="icon" href="<%= BASE_URL %>frontend/favicon.png" />
+    <link rel="icon" href="<%= BASE_URL %>static/favicon.png" />
     <link href="https://fonts.googleapis.com/css?family=Inter:400,600" rel="stylesheet" />
     <title><%= htmlWebpackPlugin.options.title %></title>
   </head>

+ 0 - 0
frontend/public/favicon.png → frontend/public/static/favicon.png


+ 1 - 1
frontend/src/api/index.js

@@ -6,7 +6,7 @@ import store from '../store';
 import { models } from '../constants';
 
 const http = axios.create({
-  baseURL: process.env.BASE_URL,
+  baseURL: process.env.VUE_APP_API_URL || '/',
   withCredentials: false,
   responseType: 'json',
 

+ 4 - 4
frontend/vue.config.js

@@ -1,5 +1,5 @@
 module.exports = {
-  publicPath: '/',
+  publicPath: '/admin',
   outputDir: 'dist',
 
   // This is to make all static file requests generated by Vue to go to
@@ -7,10 +7,10 @@ module.exports = {
   // directory and moves all the static files in it. The physical directory
   // and the URI for assets are tightly coupled. This is handled in the Go app
   // by using stuffbin aliases.
-  assetsDir: 'frontend',
+  assetsDir: 'static',
 
   // Move the index.html file from dist/index.html to dist/frontend/index.html
-  indexPath: './frontend/index.html',
+  // indexPath: './frontend/index.html',
 
   productionSourceMap: false,
   filenameHashing: true,
@@ -26,7 +26,7 @@ module.exports = {
   devServer: {
     port: process.env.LISTMONK_FRONTEND_PORT || 8080,
     proxy: {
-      '^/(api|webhooks|subscription|public)': {
+      '^/(api|webhooks|subscription|public)|$': {
         target: process.env.LISTMONK_API_URL || 'http://127.0.0.1:9000'
       }
     }