Move static outside HTML. Start work on TypeScript bundle
It's not strictly HTML, so that's just correct. This is just worth doing while building the new TypeScript bundle
3
.gitignore
vendored
|
|
@ -3,12 +3,11 @@ cmd/geocode-test/geocode-test
|
||||||
cmd/passwordgen/passwordgen
|
cmd/passwordgen/passwordgen
|
||||||
districts/
|
districts/
|
||||||
flogo.log
|
flogo.log
|
||||||
html/static/css/bootstrap.css
|
|
||||||
html/static/css/bootstrap.css.map
|
|
||||||
nidus-sync
|
nidus-sync
|
||||||
nidus-sync.log
|
nidus-sync.log
|
||||||
result
|
result
|
||||||
stadia/cmd/bulk-geocode/bulk-geocode
|
stadia/cmd/bulk-geocode/bulk-geocode
|
||||||
stadia/cmd/reverse-geocode/reverse-geocode
|
stadia/cmd/reverse-geocode/reverse-geocode
|
||||||
stadia/cmd/structured-geocode/structured-geocode
|
stadia/cmd/structured-geocode/structured-geocode
|
||||||
|
static/gen/
|
||||||
tmp/
|
tmp/
|
||||||
|
|
|
||||||
|
|
@ -93,10 +93,11 @@ esbuild ts/main.ts --bundle --outfile=html/static/bundle.js --format=iife --mini
|
||||||
```
|
```
|
||||||
|
|
||||||
The only page that works right now is `https://sync.nidus.cloud/template-test`
|
The only page that works right now is `https://sync.nidus.cloud/template-test`
|
||||||
|
|
||||||
### watchexec
|
### watchexec
|
||||||
|
|
||||||
For iterating on styles
|
For iterating on styles
|
||||||
|
|
||||||
```
|
```
|
||||||
watchexec -e scss sass scss/custom.scss:html/static/css/bootstrap.css
|
watchexec -e scss sass scss/custom.scss:static/gen/css/bootstrap.css
|
||||||
```
|
```
|
||||||
|
|
|
||||||
29
default.nix
|
|
@ -12,10 +12,14 @@ pkgs.buildGoModule rec {
|
||||||
vendorHash = "sha256-zXjryPAJYpc80cqYtrcp//i6OQi5V5QwhaKQYYfrlL8=";
|
vendorHash = "sha256-zXjryPAJYpc80cqYtrcp//i6OQi5V5QwhaKQYYfrlL8=";
|
||||||
|
|
||||||
buildInputs = [ pkgs.proj ];
|
buildInputs = [ pkgs.proj ];
|
||||||
nativeBuildInputs = [ pkgs.pkg-config pkgs.dart-sass ];
|
nativeBuildInputs = [
|
||||||
|
pkgs.pkg-config
|
||||||
|
pkgs.dart-sass
|
||||||
|
pkgs.esbuild
|
||||||
|
];
|
||||||
|
|
||||||
preBuild = ''
|
preBuild = ''
|
||||||
|
# Compile SCSS
|
||||||
SASS_SRC_DIR="./scss"
|
SASS_SRC_DIR="./scss"
|
||||||
CSS_OUTPUT_DIR="./html/static/css/"
|
CSS_OUTPUT_DIR="./html/static/css/"
|
||||||
|
|
||||||
|
|
@ -23,5 +27,26 @@ pkgs.buildGoModule rec {
|
||||||
|
|
||||||
echo "Compiling $SASS_SRC_DIR/custom.scss to $CSS_OUTPUT_DIR/bootstrap.css..."
|
echo "Compiling $SASS_SRC_DIR/custom.scss to $CSS_OUTPUT_DIR/bootstrap.css..."
|
||||||
sass --style=compressed --trace "$SASS_SRC_DIR/custom.scss":"$CSS_OUTPUT_DIR/bootstrap.css"
|
sass --style=compressed --trace "$SASS_SRC_DIR/custom.scss":"$CSS_OUTPUT_DIR/bootstrap.css"
|
||||||
|
|
||||||
|
# Bundle TypeScript
|
||||||
|
JS_OUTPUT_DIR="./html/static/gen/js/"
|
||||||
|
mkdir -p "$JS_OUTPUT_DIR"
|
||||||
|
|
||||||
|
echo "Bundling TypeScript..."
|
||||||
|
esbuild ts/main.ts --bundle --minify --outfile="$JS_OUTPUT_DIR/bundle.js"
|
||||||
|
|
||||||
|
# Generate hash and rename bundle
|
||||||
|
BUNDLE_HASH=$(sha256sum "$JS_OUTPUT_DIR/bundle.js" | cut -c1-12)
|
||||||
|
mv "$JS_OUTPUT_DIR/bundle.js" "$JS_OUTPUT_DIR/bundle.$BUNDLE_HASH.js"
|
||||||
|
|
||||||
|
# Generate gen.go with bundle path
|
||||||
|
cat > gen.go <<EOF
|
||||||
|
package main
|
||||||
|
|
||||||
|
// Generated by Nix build - do not edit manually
|
||||||
|
const JsBundlePath = "/static/js/bundel.$BUNDLE_HASH.js"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Generated JS bundle with hash: $BUNDLE_HASH"
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Gleipnir-Technology/nidus-sync/config"
|
"github.com/Gleipnir-Technology/nidus-sync/config"
|
||||||
|
"github.com/Gleipnir-Technology/nidus-sync/static"
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
@ -19,6 +20,15 @@ import (
|
||||||
// static files from a http.FileSystem.
|
// static files from a http.FileSystem.
|
||||||
var startedTime time.Time = time.Now()
|
var startedTime time.Time = time.Now()
|
||||||
|
|
||||||
|
var localFS http.Dir
|
||||||
|
|
||||||
|
func AddStaticRoute(r chi.Router, path string) {
|
||||||
|
if localFS == "" {
|
||||||
|
localFS = http.Dir("./static")
|
||||||
|
}
|
||||||
|
fileServer(r, "/static", localFS, static.EmbeddedStaticFS, "static")
|
||||||
|
}
|
||||||
|
|
||||||
func fileServer(r chi.Router, path string, root http.FileSystem, embeddedFS embed.FS, embeddedPath string) {
|
func fileServer(r chi.Router, path string, root http.FileSystem, embeddedFS embed.FS, embeddedPath string) {
|
||||||
if strings.ContainsAny(path, "{}*") {
|
if strings.ContainsAny(path, "{}*") {
|
||||||
panic("FileServer does not permit any URL parameters.")
|
panic("FileServer does not permit any URL parameters.")
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Gleipnir-Technology/nidus-sync/static"
|
||||||
"github.com/aarondl/opt/null"
|
"github.com/aarondl/opt/null"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
|
@ -22,6 +23,8 @@ import (
|
||||||
func addFuncMap(t *template.Template) {
|
func addFuncMap(t *template.Template) {
|
||||||
funcMap := template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
"bigNumber": bigNumber,
|
"bigNumber": bigNumber,
|
||||||
|
"bundlePathCSS": bundlePathCSS,
|
||||||
|
"bundlePathJS": bundlePathJS,
|
||||||
"displayUploadStatus": displayUploadStatus,
|
"displayUploadStatus": displayUploadStatus,
|
||||||
"displayUploadType": displayUploadType,
|
"displayUploadType": displayUploadType,
|
||||||
"duration": duration,
|
"duration": duration,
|
||||||
|
|
@ -59,6 +62,12 @@ func bigNumber(n int) string {
|
||||||
|
|
||||||
return result.String()
|
return result.String()
|
||||||
}
|
}
|
||||||
|
func bundlePathCSS() string {
|
||||||
|
return static.BundlePathCSS
|
||||||
|
}
|
||||||
|
func bundlePathJS() string {
|
||||||
|
return static.BundlePathJS
|
||||||
|
}
|
||||||
func displayUploadStatus(s string) string {
|
func displayUploadStatus(s string) string {
|
||||||
switch s {
|
switch s {
|
||||||
case "committed":
|
case "committed":
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package html
|
|
||||||
|
|
||||||
import (
|
|
||||||
"embed"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:embed static/*
|
|
||||||
var EmbeddedStaticFS embed.FS
|
|
||||||
|
|
||||||
var localFS http.Dir
|
|
||||||
|
|
||||||
func AddStaticRoute(r chi.Router, path string) {
|
|
||||||
if localFS == "" {
|
|
||||||
localFS = http.Dir("./html/static")
|
|
||||||
}
|
|
||||||
fileServer(r, "/static", localFS, EmbeddedStaticFS, "static")
|
|
||||||
}
|
|
||||||
7
html/static/vendor/js/bootstrap.min.js
vendored
|
|
@ -8,8 +8,7 @@
|
||||||
<link href="/static/css/bootstrap.css" rel="stylesheet" />
|
<link href="/static/css/bootstrap.css" rel="stylesheet" />
|
||||||
<!-- Bootstrap Icons -->
|
<!-- Bootstrap Icons -->
|
||||||
<link rel="stylesheet" href="/static/vendor/css/bootstrap-icons.min.css" />
|
<link rel="stylesheet" href="/static/vendor/css/bootstrap-icons.min.css" />
|
||||||
<!-- favicon -->
|
<link rel="icon" href="/static/ico/favicon-rmo.ico" type="image/x-icon" />
|
||||||
<link rel="icon" href="/static/favicon-rmo.ico" type="image/x-icon" />
|
|
||||||
{{ block "extraheader" . }}{{ end }}
|
{{ block "extraheader" . }}{{ end }}
|
||||||
<script>
|
<script>
|
||||||
var tooltipByElementId = {};
|
var tooltipByElementId = {};
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,12 @@
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>{{ template "title" . }} - Nidus Sync</title>
|
<title>{{ template "title" . }} - Nidus Sync</title>
|
||||||
<!-- Bootstrap CSS -->
|
<link href="{{ bundlePathCSS }}" rel="stylesheet" />
|
||||||
<link href="/static/css/bootstrap.css" rel="stylesheet" />
|
|
||||||
<!-- Fontawesome Icons -->
|
<!-- Fontawesome Icons -->
|
||||||
<link rel="stylesheet" href="/static/vendor/css/bootstrap-icons.min.css" />
|
<link rel="stylesheet" href="/static/vendor/css/bootstrap-icons.min.css" />
|
||||||
<!-- favicon -->
|
<link rel="icon" href="/static/ico/favicon-sync.ico" type="image/x-icon" />
|
||||||
<link rel="icon" href="/static/favicon-sync.ico" type="image/x-icon" />
|
|
||||||
<script src="/static/js/events.js"></script>
|
<script src="/static/js/events.js"></script>
|
||||||
<script defer src="/static/js/alpine-3.15.8-min.js"></script>
|
<script src="{{ bundlePathJS }}" defer></script>
|
||||||
{{ block "extraheader" . }}{{ end }}
|
{{ block "extraheader" . }}{{ end }}
|
||||||
<script>
|
<script>
|
||||||
const USER = {{ .User.AsJSON|json }};
|
const USER = {{ .User.AsJSON|json }};
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,7 @@
|
||||||
<link href="/static/vendor/css/bootstrap.min.css" rel="stylesheet" />
|
<link href="/static/vendor/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
<!-- Bootstrap Icons -->
|
<!-- Bootstrap Icons -->
|
||||||
<link href="/static/css/bootstrap.css" rel="stylesheet" />
|
<link href="/static/css/bootstrap.css" rel="stylesheet" />
|
||||||
<!-- favicon -->
|
<link rel="icon" href="/static/ico/favicon-sync.ico" type="image/x-icon" />
|
||||||
<link rel="icon" href="/static/favicon-sync.ico" type="image/x-icon" />
|
|
||||||
{{ block "extraheader" . }}{{ end }}
|
{{ block "extraheader" . }}{{ end }}
|
||||||
{{ if not .Config.IsProductionEnvironment }}
|
{{ if not .Config.IsProductionEnvironment }}
|
||||||
<script src="/.flogo/injector.js"></script>
|
<script src="/.flogo/injector.js"></script>
|
||||||
|
|
|
||||||
6
static/gen.go
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
package static
|
||||||
|
|
||||||
|
// gen.go - checked into git
|
||||||
|
// This file is overwritten during Nix builds with hashed paths
|
||||||
|
const BundlePathCSS = "/static/gen/css/bootstrap.css"
|
||||||
|
const BundlePathJS = "/static/gen/js/bundle.js"
|
||||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 191 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
|
|
@ -3,7 +3,7 @@ class AddressDisplay extends HTMLElement {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
// Create a shadow DOM
|
// Create a shadow DOM
|
||||||
this.attachShadow({mode: "open" });
|
this.attachShadow({ mode: "open" });
|
||||||
|
|
||||||
// Initial render
|
// Initial render
|
||||||
this.render();
|
this.render();
|
||||||
|
|
@ -99,29 +99,33 @@ class AddressDisplay extends HTMLElement {
|
||||||
|
|
||||||
// Populate structured fields
|
// Populate structured fields
|
||||||
// Street Address - combine address, street, housenumber if available
|
// Street Address - combine address, street, housenumber if available
|
||||||
let addressStr = '';
|
let addressStr = "";
|
||||||
if (context.address) addressStr += context.address.address_number;
|
if (context.address) addressStr += context.address.address_number;
|
||||||
if (context.street) {
|
if (context.street) {
|
||||||
if (addressStr) addressStr += ' ';
|
if (addressStr) addressStr += " ";
|
||||||
addressStr += context.street.name;
|
addressStr += context.street.name;
|
||||||
}
|
}
|
||||||
if (addressStr === '') {
|
if (addressStr === "") {
|
||||||
addressStr = props.name || props.full_address || '-';
|
addressStr = props.name || props.full_address || "-";
|
||||||
}
|
}
|
||||||
this._streetAddress.textContent = addressStr;
|
this._streetAddress.textContent = addressStr;
|
||||||
|
|
||||||
// Post Code
|
// Post Code
|
||||||
this._postCode.textContent = context.postcode.name || '-';
|
this._postCode.textContent = context.postcode.name || "-";
|
||||||
|
|
||||||
// District (could be district, locality, or place)
|
// District (could be district, locality, or place)
|
||||||
this._district.textContent = context.district.name || context.place.name || context.locality.name || '-';
|
this._district.textContent =
|
||||||
|
context.district.name ||
|
||||||
|
context.place.name ||
|
||||||
|
context.locality.name ||
|
||||||
|
"-";
|
||||||
|
|
||||||
// Region (state, province, etc.)
|
// Region (state, province, etc.)
|
||||||
this._region.textContent = context.region.name || '-';
|
this._region.textContent = context.region.name || "-";
|
||||||
|
|
||||||
// Country
|
// Country
|
||||||
this._country.textContent = context.country.name || '-';
|
this._country.textContent = context.country.name || "-";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('address-display', AddressDisplay);
|
customElements.define("address-display", AddressDisplay);
|
||||||
|
|
@ -10,14 +10,14 @@ function getGeolocation(options) {
|
||||||
const geolocationOptions = options || {
|
const geolocationOptions = options || {
|
||||||
enableHighAccuracy: true,
|
enableHighAccuracy: true,
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
maximumAge: 0
|
maximumAge: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Call the geolocation API
|
// Call the geolocation API
|
||||||
navigator.geolocation.getCurrentPosition(
|
navigator.geolocation.getCurrentPosition(
|
||||||
position => resolve(position),
|
(position) => resolve(position),
|
||||||
error => reject(error),
|
(error) => reject(error),
|
||||||
geolocationOptions
|
geolocationOptions,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
8
static/static.go
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
package static
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed css gen file ico js vendor
|
||||||
|
var EmbeddedStaticFS embed.FS
|
||||||
4107
static/vendor/js/bootstrap.bundle.min.js
vendored
Normal file
2892
static/vendor/js/bootstrap.min.js
vendored
Normal file
10
ts/main.ts
|
|
@ -1,5 +1,12 @@
|
||||||
import Alpine from './vendor/alpinejs-3.15.8.js';
|
import Alpine from './vendor/alpinejs-3.15.8.js';
|
||||||
|
|
||||||
|
// Make Alpine available on window for inline Alpine
|
||||||
|
window.Alpine = Alpine;
|
||||||
|
|
||||||
|
// Wait for DOM to be ready, then initialize Alpine
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
Alpine.start();
|
||||||
|
});
|
||||||
interface GreetingComponent {
|
interface GreetingComponent {
|
||||||
message: string;
|
message: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -14,6 +21,3 @@ Alpine.data('greeting', (): GreetingComponent => ({
|
||||||
this.message = 'Message updated at ' + new Date().toLocaleTimeString();
|
this.message = 'Message updated at ' + new Date().toLocaleTimeString();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Alpine.start();
|
|
||||||
|
|
||||||
|
|
|
||||||