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
|
||||
districts/
|
||||
flogo.log
|
||||
html/static/css/bootstrap.css
|
||||
html/static/css/bootstrap.css.map
|
||||
nidus-sync
|
||||
nidus-sync.log
|
||||
result
|
||||
stadia/cmd/bulk-geocode/bulk-geocode
|
||||
stadia/cmd/reverse-geocode/reverse-geocode
|
||||
stadia/cmd/structured-geocode/structured-geocode
|
||||
static/gen/
|
||||
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`
|
||||
|
||||
### watchexec
|
||||
|
||||
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=";
|
||||
|
||||
buildInputs = [ pkgs.proj ];
|
||||
nativeBuildInputs = [ pkgs.pkg-config pkgs.dart-sass ];
|
||||
nativeBuildInputs = [
|
||||
pkgs.pkg-config
|
||||
pkgs.dart-sass
|
||||
pkgs.esbuild
|
||||
];
|
||||
|
||||
preBuild = ''
|
||||
|
||||
# Compile SCSS
|
||||
SASS_SRC_DIR="./scss"
|
||||
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..."
|
||||
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"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/config"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/static"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
|
@ -19,6 +20,15 @@ import (
|
|||
// static files from a http.FileSystem.
|
||||
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) {
|
||||
if strings.ContainsAny(path, "{}*") {
|
||||
panic("FileServer does not permit any URL parameters.")
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/static"
|
||||
"github.com/aarondl/opt/null"
|
||||
"github.com/google/uuid"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
|
@ -22,6 +23,8 @@ import (
|
|||
func addFuncMap(t *template.Template) {
|
||||
funcMap := template.FuncMap{
|
||||
"bigNumber": bigNumber,
|
||||
"bundlePathCSS": bundlePathCSS,
|
||||
"bundlePathJS": bundlePathJS,
|
||||
"displayUploadStatus": displayUploadStatus,
|
||||
"displayUploadType": displayUploadType,
|
||||
"duration": duration,
|
||||
|
|
@ -59,6 +62,12 @@ func bigNumber(n int) string {
|
|||
|
||||
return result.String()
|
||||
}
|
||||
func bundlePathCSS() string {
|
||||
return static.BundlePathCSS
|
||||
}
|
||||
func bundlePathJS() string {
|
||||
return static.BundlePathJS
|
||||
}
|
||||
func displayUploadStatus(s string) string {
|
||||
switch s {
|
||||
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" />
|
||||
<!-- Bootstrap Icons -->
|
||||
<link rel="stylesheet" href="/static/vendor/css/bootstrap-icons.min.css" />
|
||||
<!-- favicon -->
|
||||
<link rel="icon" href="/static/favicon-rmo.ico" type="image/x-icon" />
|
||||
<link rel="icon" href="/static/ico/favicon-rmo.ico" type="image/x-icon" />
|
||||
{{ block "extraheader" . }}{{ end }}
|
||||
<script>
|
||||
var tooltipByElementId = {};
|
||||
|
|
|
|||
|
|
@ -4,14 +4,12 @@
|
|||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>{{ template "title" . }} - Nidus Sync</title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="/static/css/bootstrap.css" rel="stylesheet" />
|
||||
<link href="{{ bundlePathCSS }}" rel="stylesheet" />
|
||||
<!-- Fontawesome Icons -->
|
||||
<link rel="stylesheet" href="/static/vendor/css/bootstrap-icons.min.css" />
|
||||
<!-- favicon -->
|
||||
<link rel="icon" href="/static/favicon-sync.ico" type="image/x-icon" />
|
||||
<link rel="icon" href="/static/ico/favicon-sync.ico" type="image/x-icon" />
|
||||
<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 }}
|
||||
<script>
|
||||
const USER = {{ .User.AsJSON|json }};
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@
|
|||
<link href="/static/vendor/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<!-- Bootstrap Icons -->
|
||||
<link href="/static/css/bootstrap.css" rel="stylesheet" />
|
||||
<!-- favicon -->
|
||||
<link rel="icon" href="/static/favicon-sync.ico" type="image/x-icon" />
|
||||
<link rel="icon" href="/static/ico/favicon-sync.ico" type="image/x-icon" />
|
||||
{{ block "extraheader" . }}{{ end }}
|
||||
{{ if not .Config.IsProductionEnvironment }}
|
||||
<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();
|
||||
|
||||
// Create a shadow DOM
|
||||
this.attachShadow({mode: "open" });
|
||||
this.attachShadow({ mode: "open" });
|
||||
|
||||
// Initial render
|
||||
this.render();
|
||||
|
|
@ -96,32 +96,36 @@ class AddressDisplay extends HTMLElement {
|
|||
// Extract context data from properties
|
||||
const props = location.properties;
|
||||
const context = props.context || {};
|
||||
|
||||
|
||||
// Populate structured fields
|
||||
// Street Address - combine address, street, housenumber if available
|
||||
let addressStr = '';
|
||||
let addressStr = "";
|
||||
if (context.address) addressStr += context.address.address_number;
|
||||
if (context.street) {
|
||||
if (addressStr) addressStr += ' ';
|
||||
addressStr += context.street.name;
|
||||
if (addressStr) addressStr += " ";
|
||||
addressStr += context.street.name;
|
||||
}
|
||||
if (addressStr === '') {
|
||||
addressStr = props.name || props.full_address || '-';
|
||||
if (addressStr === "") {
|
||||
addressStr = props.name || props.full_address || "-";
|
||||
}
|
||||
this._streetAddress.textContent = addressStr;
|
||||
|
||||
|
||||
// Post Code
|
||||
this._postCode.textContent = context.postcode.name || '-';
|
||||
|
||||
this._postCode.textContent = context.postcode.name || "-";
|
||||
|
||||
// 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.)
|
||||
this._region.textContent = context.region.name || '-';
|
||||
|
||||
this._region.textContent = context.region.name || "-";
|
||||
|
||||
// Country
|
||||
this._country.textContent = context.country.name || '-';
|
||||
this._country.textContent = context.country.name || "-";
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('address-display', AddressDisplay);
|
||||
customElements.define("address-display", AddressDisplay);
|
||||
|
|
@ -5,19 +5,19 @@ function getGeolocation(options) {
|
|||
reject(new Error("Geolocation is not supported by your browser"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Default options if none provided
|
||||
const geolocationOptions = options || {
|
||||
enableHighAccuracy: true,
|
||||
timeout: 5000,
|
||||
maximumAge: 0
|
||||
maximumAge: 0,
|
||||
};
|
||||
|
||||
|
||||
// Call the geolocation API
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
position => resolve(position),
|
||||
error => reject(error),
|
||||
geolocationOptions
|
||||
(position) => resolve(position),
|
||||
(error) => reject(error),
|
||||
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';
|
||||
|
||||
// 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 {
|
||||
message: string;
|
||||
name: string;
|
||||
|
|
@ -14,6 +21,3 @@ Alpine.data('greeting', (): GreetingComponent => ({
|
|||
this.message = 'Message updated at ' + new Date().toLocaleTimeString();
|
||||
}
|
||||
}));
|
||||
|
||||
Alpine.start();
|
||||
|
||||
|
|
|
|||