Skip to content

Commit

Permalink
Refactor the BE
Browse files Browse the repository at this point in the history
  • Loading branch information
KinyaElGrande committed Oct 24, 2023
1 parent 5bf4e6d commit 4c95f59
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 35 deletions.
11 changes: 11 additions & 0 deletions server/.env.example
Expand Up @@ -1319,3 +1319,14 @@
# Type: string
# Default: #162425
# AVATAR_INITIALS_COLOR=#162425

###############################################################################
###############################################################################
# webapp
#

###############################################################################
# Path to custom SCSS source files directory
# Type: string
# Default: <no value>
# WEBAPP_SCSS_DIR_PATH=<no value>
1 change: 1 addition & 0 deletions server/app/app.cue
Expand Up @@ -41,6 +41,7 @@ corteza: schema.#platform & {
options.workflow,
options.discovery,
options.attachment,
options.webapp,
]

// platform resources
Expand Down
15 changes: 15 additions & 0 deletions server/app/options/webapp.cue
@@ -0,0 +1,15 @@
package options

import (
"github.com/cortezaproject/corteza/server/codegen/schema"
)

webapp: schema.#optionsGroup & {
handle: "webapp"

options: {
SCSS_dir_path: {
description: "Path to custom SCSS source files directory"
}
}
}
2 changes: 1 addition & 1 deletion server/app/servers.go
Expand Up @@ -57,7 +57,7 @@ func (app *CortezaApp) mountHttpRoutes(r chi.Router) {
return
}

r.Route(options.CleanBase(ho.WebappBaseUrl), webapp.MakeWebappServer(app.Log, ho, app.Opt.Auth, app.Opt.Discovery, app.Opt.Sentry))
r.Route(options.CleanBase(ho.WebappBaseUrl), webapp.MakeWebappServer(app.Log, ho, app.Opt.Auth, app.Opt.Discovery, app.Opt.Sentry, app.Opt.Webapp))

app.Log.Info(
"client web applications enabled",
Expand Down
20 changes: 10 additions & 10 deletions server/assets/embed.go
Expand Up @@ -67,26 +67,26 @@ func fromPath(path string) (assets fs.FS, err error) {
return
}

func DirFileNames(dir string) (names []string, err error) {
files, err := fs.ReadDir(ff, "src/"+dir)
func DirEntries(dir string) (fileNames, subDirs []string, err error) {
dirEntries, err := fs.ReadDir(ff, "src/"+dir)
if err != nil {
// something is seriously wrong, we might as well panic
panic(err)
return nil, nil, err
}

for _, file := range files {
fileInfo, err := file.Info()
for _, dirEntry := range dirEntries {
fileInfo, err := dirEntry.Info()
if err != nil {
return nil, err
return nil, nil, err
}

// if the file is a directory skip it
// if the entry is a directory skip it
if fileInfo.IsDir() {
subDirs = append(subDirs, dirEntry.Name())
continue
}

names = append(names, file.Name())
fileNames = append(fileNames, dirEntry.Name())
}

return names, nil
return fileNames, subDirs, err
}
29 changes: 29 additions & 0 deletions server/pkg/options/options.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions server/pkg/options/options.go
Expand Up @@ -29,6 +29,7 @@ type (
Discovery DiscoveryOpt
Apigw ApigwOpt
Attachment AttachmentOpt
Webapp WebappOpt
}
)

Expand Down Expand Up @@ -61,5 +62,6 @@ func Init() *Options {
Discovery: *Discovery(),
Apigw: *Apigw(),
Attachment: *Attachment(),
Webapp: *Webapp(),
}
}
82 changes: 60 additions & 22 deletions server/pkg/sass/processor.go
Expand Up @@ -17,7 +17,15 @@ import (

var stylesheet = newStylesheetCache()

func GenerateCSS(brandingSass, customCSS string) (string, error) {
// GenerateCSS takes care of creating CSS for webapps by reading SASS content from embedded assets,
// combining it with brandingSass and customCSS, and then transpiling it using the dart-sass compiler.
//
// If dart sass isn't installed on the host machine, it will default to css content from the minified-custom.css which is
// generated from [Boostrap, bootstrap-vue and custom variables sass content].
// If dart isn't installed on the host machine, customCustom css will continue to function, but without sass support.
//
// In case of an error, it will return default css and log out the error
func GenerateCSS(brandingSass, customCSS, sassDirPath string) (string, error) {
var (
stringsBuilder strings.Builder

Expand All @@ -29,8 +37,8 @@ func GenerateCSS(brandingSass, customCSS string) (string, error) {
return stylesheet.get("css"), nil
}

// if dart sass is not installed, or when the SCSS transpiler creation and startup process fails.
// return contents from minified-custom.css
// if dart sass is not installed, or when the sass transpiler creation and startup process fails.
// return contents from default css
if transpiler == nil {
stringsBuilder.WriteString(defaultCSS())
if customCSS != "" {
Expand All @@ -53,7 +61,8 @@ func GenerateCSS(brandingSass, customCSS string) (string, error) {
if brandingSass != "" {
err := jsonToSass(brandingSass, &stringsBuilder)
if err != nil {
return "", err
logger.Default().Error("failed to unmarshal branding sass variables", zap.Error(err))
return defaultCSS(), err
}
}

Expand All @@ -68,11 +77,19 @@ func GenerateCSS(brandingSass, customCSS string) (string, error) {
}

// get Boostrap, bootstrap-vue and custom variables sass content
scssFromAssets, err := readSassFiles()
mainSass, err := readSassFiles("scss")
if err != nil {
return "", err
return defaultCSS(), err
}
stringsBuilder.WriteString(mainSass)

if sassDirPath != "" {
customSass, err := readSassFiles(sassDirPath)
if err != nil {
return defaultCSS(), err
}
stringsBuilder.WriteString(customSass)
}
stringsBuilder.WriteString(scssFromAssets)

if customCSS != "" {
//Custom CSS editor selector block
Expand All @@ -85,10 +102,9 @@ func GenerateCSS(brandingSass, customCSS string) (string, error) {
Source: stringsBuilder.String(),
}
execute, err := transpiler.Execute(args)
// if there's an error during compilation process, return contents from minified-custom.css
if err != nil {
logger.Default().Error("Sass syntax error", zap.Error(err))

// return contents from minified-custom.css
return defaultCSS(), err
}

Expand All @@ -110,40 +126,62 @@ func dartSass() *godartsass.Transpiler {
})

if err != nil {
logger.Default().Info("dart sass is not installed in your system", zap.Error(err))
logger.Default().Warn("dart sass is not installed in your system", zap.Error(err))
return nil
}

return transpiler
}

// readSassFiles reads SASS files from assets and converts them to a string
func readSassFiles() (string, error) {
// readSassFiles reads SASS contents from provided embedded directory and subdirectories then converts them to a string
func readSassFiles(dirPath string) (string, error) {
var stringsBuilder strings.Builder

assetFiles := assets.Files(logger.Default(), "")
fileNames, err := assets.DirFileNames("scss")
filenames, subDirs, err := assets.DirEntries(dirPath)
if err != nil {
logger.Default().Error("failed to read assets/scss file names", zap.Error(err))
logger.Default().Error(fmt.Sprintf("failed to read assets/src/%s entries", dirPath), zap.Error(err))
return "", err
}

for _, fileName := range fileNames {
open, err := assetFiles.Open("scss/" + fileName)
if len(filenames) > 0 {
err := readSassContents(dirPath, filenames, &stringsBuilder)
if err != nil {
logger.Default().Error(fmt.Sprintf("failed to open asset %s file", fileName), zap.Error(err))
return "", err
}
}

if len(subDirs) > 0 {
for _, subDir := range subDirs {
sassContents, err := readSassFiles(dirPath + "/" + subDir)
if err != nil {
return "", err
}
stringsBuilder.WriteString(sassContents)
}
}

return stringsBuilder.String(), nil
}

func readSassContents(dirPath string, filenames []string, stringsBuilder *strings.Builder) error {
assetFiles := assets.Files(logger.Default(), "")

for _, fileName := range filenames {
open, err := assetFiles.Open(dirPath + "/" + fileName)
if err != nil {
logger.Default().Error(fmt.Sprintf("failed to open asset %s file", fileName), zap.Error(err))
return err
}

reader := bufio.NewReader(open)
_, err = io.Copy(&stringsBuilder, reader)
_, err = io.Copy(stringsBuilder, reader)
if err != nil {
logger.Default().Error(fmt.Sprintf("failed to copy scss content from %s", fileName), zap.Error(err))
return "", err
logger.Default().Error(fmt.Sprintf("failed to copy sass content from %s", fileName), zap.Error(err))
return err
}
}

return stringsBuilder.String(), nil
return nil
}

func defaultCSS() string {
Expand Down
7 changes: 5 additions & 2 deletions server/pkg/webapp/serve.go
Expand Up @@ -27,6 +27,7 @@ type (
webappBaseUrl string
discoveryApiBaseUrl string
sentryUrl string
scssDirPath string
settings *types.AppSettings
}
)
Expand All @@ -35,7 +36,7 @@ var (
baseHrefMatcher = regexp.MustCompile(`<base\s+href="?.+?"?\s*\/?>`)
)

func MakeWebappServer(log *zap.Logger, httpSrvOpt options.HttpServerOpt, authOpt options.AuthOpt, discoveryOpt options.DiscoveryOpt, sentryOpt options.SentryOpt) func(r chi.Router) {
func MakeWebappServer(log *zap.Logger, httpSrvOpt options.HttpServerOpt, authOpt options.AuthOpt, discoveryOpt options.DiscoveryOpt, sentryOpt options.SentryOpt, webappOpt options.WebappOpt) func(r chi.Router) {
var (
apiBaseUrl = options.CleanBase(httpSrvOpt.BaseUrl, httpSrvOpt.ApiBaseUrl)
webappSentryUrl = sentryOpt.WebappDSN
Expand Down Expand Up @@ -73,6 +74,7 @@ func MakeWebappServer(log *zap.Logger, httpSrvOpt options.HttpServerOpt, authOpt
discoveryApiBaseUrl: discoveryApiBaseUrl,
sentryUrl: webappSentryUrl,
settings: service.CurrentSettings,
scssDirPath: webappOpt.SCSSDirPath,
})
r.Get(webBaseUrl+"*", serveIndex(httpSrvOpt, appIndexHTMLs[app], fs))
}
Expand All @@ -86,6 +88,7 @@ func MakeWebappServer(log *zap.Logger, httpSrvOpt options.HttpServerOpt, authOpt
discoveryApiBaseUrl: discoveryApiBaseUrl,
sentryUrl: webappSentryUrl,
settings: service.CurrentSettings,
scssDirPath: webappOpt.SCSSDirPath,
})
r.Get(webBaseUrl+"*", serveIndex(httpSrvOpt, appIndexHTMLs[""], fs))
}
Expand Down Expand Up @@ -149,7 +152,7 @@ func serveConfig(r chi.Router, config webappConfig) {
r.Get(options.CleanBase(config.appUrl, "custom.css"), func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "text/css")

stylesheet, err := sass.GenerateCSS(config.settings.UI.BrandingSASS, config.settings.UI.CustomCSS)
stylesheet, err := sass.GenerateCSS(config.settings.UI.BrandingSASS, config.settings.UI.CustomCSS, config.scssDirPath)
if err != nil {
logger.Default().Error("failed to generate CSS", zap.Error(err))
}
Expand Down

0 comments on commit 4c95f59

Please sign in to comment.