cleanup script, start adding extensions
This commit is contained in:
parent
0dea110ebc
commit
ea600bc0fa
20 changed files with 2601 additions and 107 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -1,2 +1,6 @@
|
||||||
# Project exclude paths
|
# Project exclude paths
|
||||||
/tmp/
|
/tmp/
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
js/dist
|
||||||
|
js/node_modules
|
||||||
21
h/tag.go
21
h/tag.go
|
|
@ -77,12 +77,20 @@ func Attributes(attrs map[string]string) Renderable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Boost() Renderable {
|
||||||
|
return Attribute("hx-boost", "true")
|
||||||
|
}
|
||||||
|
|
||||||
func Attribute(key string, value string) Renderable {
|
func Attribute(key string, value string) Renderable {
|
||||||
return Attributes(map[string]string{key: value})
|
return Attributes(map[string]string{key: value})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TriggerChildren() Renderable {
|
func TriggerChildren() Renderable {
|
||||||
return Attribute("hx-trigger-children", "")
|
return HxExtension("trigger-children")
|
||||||
|
}
|
||||||
|
|
||||||
|
func HxExtension(value string) Renderable {
|
||||||
|
return Attribute("hx-ext", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Disabled() Renderable {
|
func Disabled() Renderable {
|
||||||
|
|
@ -108,6 +116,7 @@ func CreateTriggers(triggers ...string) []string {
|
||||||
type ReloadParams struct {
|
type ReloadParams struct {
|
||||||
Triggers []string
|
Triggers []string
|
||||||
Target string
|
Target string
|
||||||
|
Children Renderable
|
||||||
}
|
}
|
||||||
|
|
||||||
func ViewOnLoad(partial func(ctx *fiber.Ctx) *Partial) Renderable {
|
func ViewOnLoad(partial func(ctx *fiber.Ctx) *Partial) Renderable {
|
||||||
|
|
@ -121,7 +130,7 @@ func View(partial func(ctx *fiber.Ctx) *Partial, params ReloadParams) Renderable
|
||||||
"hx-get": GetPartialPath(partial),
|
"hx-get": GetPartialPath(partial),
|
||||||
"hx-trigger": strings.Join(params.Triggers, ", "),
|
"hx-trigger": strings.Join(params.Triggers, ", "),
|
||||||
"hx-target": params.Target,
|
"hx-target": params.Target,
|
||||||
}))
|
}), params.Children)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PartialWithTriggers(partial func(ctx *fiber.Ctx) *Partial, triggers ...string) Renderable {
|
func PartialWithTriggers(partial func(ctx *fiber.Ctx) *Partial, triggers ...string) Renderable {
|
||||||
|
|
@ -232,8 +241,8 @@ func Div(children ...Renderable) Renderable {
|
||||||
return Tag("div", children...)
|
return Tag("div", children...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PushUrlHeader(url string) *Headers {
|
func ReplaceUrlHeader(url string) *Headers {
|
||||||
return NewHeaders("HX-Push-Url", url)
|
return NewHeaders("HX-Replace-Url", url)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CombineHeaders(headers ...*Headers) *Headers {
|
func CombineHeaders(headers ...*Headers) *Headers {
|
||||||
|
|
@ -261,7 +270,7 @@ func PushQsHeader(ctx *fiber.Ctx, key string, value string) *Headers {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewHeaders()
|
return NewHeaders()
|
||||||
}
|
}
|
||||||
return NewHeaders("HX-Push-Url", SetQueryParams(parsed.Path, map[string]string{
|
return NewHeaders("HX-Replace-Url", SetQueryParams(parsed.Path, map[string]string{
|
||||||
key: value,
|
key: value,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
@ -409,7 +418,7 @@ func AfterRequestSetHtml(children ...Renderable) Renderable {
|
||||||
return Attribute("hx-on::after-request", `this.innerHTML = '`+html.EscapeString(serialized)+`'`)
|
return Attribute("hx-on::after-request", `this.innerHTML = '`+html.EscapeString(serialized)+`'`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Children(children []Renderable) Renderable {
|
func Children(children ...Renderable) Renderable {
|
||||||
return &Node{
|
return &Node{
|
||||||
tag: FlagChildrenList,
|
tag: FlagChildrenList,
|
||||||
children: children,
|
children: children,
|
||||||
|
|
|
||||||
3
js/.prettierignore
Normal file
3
js/.prettierignore
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
package-lock.json
|
||||||
13
js/extensions/debug.ts
Normal file
13
js/extensions/debug.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import * as htmx from "htmx.org";
|
||||||
|
|
||||||
|
htmx.defineExtension("debug", {
|
||||||
|
onEvent: function (name, evt) {
|
||||||
|
if (console.debug) {
|
||||||
|
console.debug(name, evt.target, evt);
|
||||||
|
} else if (console) {
|
||||||
|
console.log("DEBUG:", name, evt.target, evt);
|
||||||
|
} else {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
51
js/extensions/pathdeps.ts
Normal file
51
js/extensions/pathdeps.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
import * as htmx from "htmx.org";
|
||||||
|
|
||||||
|
function dependsOn(pathSpec: any, url: string) {
|
||||||
|
if (pathSpec === "ignore") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const dependencyPath = pathSpec.split("/");
|
||||||
|
const urlPath = url.split("/");
|
||||||
|
for (let i = 0; i < urlPath.length; i++) {
|
||||||
|
const dependencyElement = dependencyPath.shift();
|
||||||
|
const pathElement = urlPath[i];
|
||||||
|
if (dependencyElement !== pathElement && dependencyElement !== "*") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
dependencyPath.length === 0 ||
|
||||||
|
(dependencyPath.length === 1 && dependencyPath[0] === "")
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshPath(path: string) {
|
||||||
|
const eltsWithDeps = htmx.findAll("[path-deps]");
|
||||||
|
for (let i = 0; i < eltsWithDeps.length; i++) {
|
||||||
|
const elt = eltsWithDeps[i];
|
||||||
|
if (dependsOn(elt.getAttribute("path-deps"), path)) {
|
||||||
|
htmx.trigger(elt, "path-deps", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
htmx.defineExtension("path-deps", {
|
||||||
|
onEvent: function (name, evt) {
|
||||||
|
if (name === "htmx:beforeOnLoad") {
|
||||||
|
const config = evt.detail.requestConfig;
|
||||||
|
// mutating call
|
||||||
|
if (
|
||||||
|
config &&
|
||||||
|
config.verb !== "get" &&
|
||||||
|
evt.target != null &&
|
||||||
|
evt.target instanceof Element &&
|
||||||
|
evt.target.getAttribute("path-deps") !== "ignore"
|
||||||
|
) {
|
||||||
|
refreshPath(config.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
13
js/extensions/triggerchildren.ts
Normal file
13
js/extensions/triggerchildren.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import * as htmx from "htmx.org";
|
||||||
|
import { HtmxEvent } from "htmx.org";
|
||||||
|
|
||||||
|
htmx.defineExtension("trigger-children", {
|
||||||
|
onEvent: (name: HtmxEvent, evt: CustomEvent) => {
|
||||||
|
const target = evt.detail.target as HTMLElement;
|
||||||
|
if (target && target.children) {
|
||||||
|
Array.from(target.children).forEach((e) => {
|
||||||
|
htmx.trigger(e, name, null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
80
js/mhtml.js
80
js/mhtml.js
|
|
@ -1,80 +0,0 @@
|
||||||
window.onload = function () {
|
|
||||||
// htmx.logger = function(elt, event, data) {
|
|
||||||
// if(console) {
|
|
||||||
// console.log(elt, event, data);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// onUrlChange(window.location.href);
|
|
||||||
|
|
||||||
|
|
||||||
function triggerChildren(event) {
|
|
||||||
const target = event.detail.target
|
|
||||||
const type = event.type
|
|
||||||
if(target && target.children && target.hasAttribute('hx-trigger-children')) {
|
|
||||||
Array.from(target.children).forEach(function(element) {
|
|
||||||
htmx.trigger(element, type);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const events = ['htmx:beforeRequest', 'htmx:afterRequest', 'htmx:responseError', 'htmx:sendError',
|
|
||||||
'htmx:timeout', 'htmx:xhr:abort',
|
|
||||||
'htmx:xhr:loadstart', 'htmx:xhr:loadend', 'htmx:xhr:progress']
|
|
||||||
|
|
||||||
events.forEach(function(event) {
|
|
||||||
document.addEventListener(event, triggerChildren)
|
|
||||||
})
|
|
||||||
|
|
||||||
window.history.pushState = new Proxy(window.history.pushState, {
|
|
||||||
apply: (target, thisArg, argArray) => {
|
|
||||||
if(argArray.length > 2) {
|
|
||||||
onUrlChange(window.location.origin + argArray[2]);
|
|
||||||
}
|
|
||||||
return target.apply(thisArg, argArray);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function onUrlChange(newUrl) {
|
|
||||||
let url = new URL(newUrl);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
document.querySelectorAll('[hx-trigger]').forEach(function(element) {
|
|
||||||
const triggers = element.getAttribute('hx-trigger');
|
|
||||||
const split = triggers.split(", ");
|
|
||||||
console.log(split)
|
|
||||||
if(split.find(s => s === 'url')) {
|
|
||||||
htmx.trigger(element, "url");
|
|
||||||
} else {
|
|
||||||
for (let [key, values] of url.searchParams) {
|
|
||||||
let eventName = "qs:" + key
|
|
||||||
if (triggers.includes(eventName)) {
|
|
||||||
htmx.trigger(element, eventName);
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 50)
|
|
||||||
|
|
||||||
document.querySelectorAll('[hx-match-qp]').forEach((el) => {
|
|
||||||
let hasMatch = false;
|
|
||||||
for (let name of el.getAttributeNames()) {
|
|
||||||
if(name.startsWith("hx-match-qp-mapping:")) {
|
|
||||||
let match = name.replace("hx-match-qp-mapping:", "");
|
|
||||||
let value = url.searchParams.get(match);
|
|
||||||
if(value) {
|
|
||||||
htmx.swap(el, el.getAttribute(name), {swapStyle: 'innerHTML'})
|
|
||||||
hasMatch = true;
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!hasMatch) {
|
|
||||||
let defaultKey = el.getAttribute("hx-match-qp-default")
|
|
||||||
if(defaultKey) {
|
|
||||||
htmx.swap(el, el.getAttribute("hx-match-qp-mapping:" + defaultKey), {swapStyle: 'innerHTML'})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
80
js/mhtml.ts
Normal file
80
js/mhtml.ts
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
import * as htmx from "htmx.org";
|
||||||
|
import "./extensions/pathdeps";
|
||||||
|
import "./extensions/triggerchildren";
|
||||||
|
import "./extensions/debug";
|
||||||
|
|
||||||
|
declare module "htmx.org" {
|
||||||
|
// Example: Adding type definitions for an exported function
|
||||||
|
export function swap(
|
||||||
|
target: Element,
|
||||||
|
content: string,
|
||||||
|
spec?: {
|
||||||
|
swapStyle?: "innerHTML" | "outerHTML";
|
||||||
|
},
|
||||||
|
): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
function watchUrl(callback: (oldUrl: string, newUrl: string) => void) {
|
||||||
|
let lastUrl = window.location.href;
|
||||||
|
setInterval(() => {
|
||||||
|
if (window.location.href !== lastUrl) {
|
||||||
|
callback(lastUrl, window.location.href);
|
||||||
|
lastUrl = window.location.href;
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
watchUrl((_, newUrl) => {
|
||||||
|
onUrlChange(newUrl);
|
||||||
|
});
|
||||||
|
|
||||||
|
function onUrlChange(newUrl: string) {
|
||||||
|
let url = new URL(newUrl);
|
||||||
|
|
||||||
|
document.querySelectorAll("[hx-trigger]").forEach(function (element) {
|
||||||
|
const triggers = element.getAttribute("hx-trigger");
|
||||||
|
if (!triggers) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const split = triggers.split(", ");
|
||||||
|
if (split.find((s) => s === "url")) {
|
||||||
|
htmx.swap(element, "url");
|
||||||
|
} else {
|
||||||
|
for (let [key, values] of url.searchParams) {
|
||||||
|
let eventName = "qs:" + key;
|
||||||
|
if (triggers.includes(eventName)) {
|
||||||
|
console.log("triggering", eventName);
|
||||||
|
htmx.trigger(element, eventName, null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll("[hx-match-qp]").forEach((el) => {
|
||||||
|
let hasMatch = false;
|
||||||
|
for (let name of el.getAttributeNames()) {
|
||||||
|
if (name.startsWith("hx-match-qp-mapping:")) {
|
||||||
|
let match = name.replace("hx-match-qp-mapping:", "");
|
||||||
|
let value = url.searchParams.get(match);
|
||||||
|
if (value) {
|
||||||
|
htmx.swap(el, el.getAttribute(name) ?? "", {
|
||||||
|
swapStyle: "innerHTML",
|
||||||
|
});
|
||||||
|
hasMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasMatch) {
|
||||||
|
let defaultKey = el.getAttribute("hx-match-qp-default");
|
||||||
|
if (defaultKey) {
|
||||||
|
htmx.swap(
|
||||||
|
el,
|
||||||
|
el.getAttribute("hx-match-qp-mapping:" + defaultKey) ?? "",
|
||||||
|
{ swapStyle: "innerHTML" },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
2333
js/package-lock.json
generated
Normal file
2333
js/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
23
js/package.json
Normal file
23
js/package.json
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"name": "mhtml-js",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "mhtml.js",
|
||||||
|
"scripts": {
|
||||||
|
"watch": "tsup ./mhtml.ts --watch --config ./tsup.config.ts",
|
||||||
|
"build": "tsup ./mhtml.ts --minify --config ./tsup.config.ts",
|
||||||
|
"pretty": "prettier --write ."
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"description": "",
|
||||||
|
"dependencies": {
|
||||||
|
"htmx.org": "^1.9.12"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@swc/core": "^1.7.26",
|
||||||
|
"@types/node": "^22.5.4",
|
||||||
|
"tsup": "^8.2.4",
|
||||||
|
"typescript": "^5.6.2",
|
||||||
|
"prettier": "^3.3.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
15
js/tsconfig.json
Normal file
15
js/tsconfig.json
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES6",
|
||||||
|
"module": "es6",
|
||||||
|
"lib": ["es6", "dom"],
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"noEmit": true,
|
||||||
|
"downlevelIteration": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"strict": true,
|
||||||
|
"forceConsistentCasingInFileNames": true
|
||||||
|
},
|
||||||
|
"include": ["./*.ts"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
23
js/tsup.config.ts
Normal file
23
js/tsup.config.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { defineConfig } from "tsup";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
format: ["esm"],
|
||||||
|
entry: ["./src/mhtml.ts"],
|
||||||
|
outDir: "./dist",
|
||||||
|
dts: false,
|
||||||
|
shims: true,
|
||||||
|
skipNodeModulesBundle: true,
|
||||||
|
clean: true,
|
||||||
|
target: "es6",
|
||||||
|
platform: "browser",
|
||||||
|
outExtension: () => {
|
||||||
|
return {
|
||||||
|
js: ".js",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
minify: true,
|
||||||
|
bundle: true,
|
||||||
|
// https://github.com/egoist/tsup/issues/619
|
||||||
|
noExternal: [/(.*)/],
|
||||||
|
splitting: false,
|
||||||
|
});
|
||||||
5
justfile
5
justfile
|
|
@ -6,4 +6,7 @@ run-gen:
|
||||||
go run ./tooling/astgen
|
go run ./tooling/astgen
|
||||||
|
|
||||||
watch-gen:
|
watch-gen:
|
||||||
go run ./tooling/watch.go --command 'go run ./tooling/astgen'
|
go run ./tooling/watch.go --command 'go run ./tooling/astgen'
|
||||||
|
|
||||||
|
watch-js:
|
||||||
|
cd js && npm run build && npm run watch
|
||||||
|
|
@ -8,10 +8,10 @@ import (
|
||||||
|
|
||||||
func RootPage(children ...h.Renderable) h.Renderable {
|
func RootPage(children ...h.Renderable) h.Renderable {
|
||||||
return h.Html(
|
return h.Html(
|
||||||
|
h.HxExtension("path-deps"),
|
||||||
h.Head(
|
h.Head(
|
||||||
h.Script("https://cdn.tailwindcss.com"),
|
h.Script("https://cdn.tailwindcss.com"),
|
||||||
h.Script("https://unpkg.com/htmx.org@2.0.2"),
|
h.Script("/js/dist/mhtml.js"),
|
||||||
h.Script("/js/mhtml.js"),
|
|
||||||
),
|
),
|
||||||
h.Body(
|
h.Body(
|
||||||
partials.NavBar(),
|
partials.NavBar(),
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,11 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"mhtml/h"
|
"mhtml/h"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test(ctx *fiber.Ctx) *h.Page {
|
func Test(ctx *fiber.Ctx) *h.Page {
|
||||||
|
time.Sleep(time.Second * 1)
|
||||||
text := fmt.Sprintf("News ID: %s", ctx.Params("id"))
|
text := fmt.Sprintf("News ID: %s", ctx.Params("id"))
|
||||||
return h.NewPage(
|
return h.NewPage(
|
||||||
h.Div(h.Text(text)),
|
h.Div(h.Text(text)),
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"mhtml/h"
|
"mhtml/h"
|
||||||
"mhtml/pages/base"
|
"mhtml/pages/base"
|
||||||
"mhtml/partials/patient"
|
"mhtml/partials/patient"
|
||||||
"mhtml/partials/sheet"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func PatientsIndex(ctx *fiber.Ctx) *h.Page {
|
func PatientsIndex(ctx *fiber.Ctx) *h.Page {
|
||||||
|
|
@ -18,13 +17,10 @@ func PatientsIndex(ctx *fiber.Ctx) *h.Page {
|
||||||
h.P("Manage Patients", h.Class("text-lg font-bold")),
|
h.P("Manage Patients", h.Class("text-lg font-bold")),
|
||||||
patient.AddPatientButton(),
|
patient.AddPatientButton(),
|
||||||
),
|
),
|
||||||
h.PartialWithTriggers(patient.List, "load", "patient-added from:body", "every 5s"),
|
h.View(patient.List, h.ReloadParams{
|
||||||
h.If(
|
Triggers: h.CreateTriggers("load", "path-deps"),
|
||||||
h.GetQueryParam(ctx, "adding") == "true",
|
Children: h.Children(h.Attribute("path-deps", h.GetPartialPath(patient.Create))),
|
||||||
h.View(patient.AddPatientSheetPartial, h.ReloadParams{
|
}),
|
||||||
Triggers: h.CreateTriggers("load"),
|
|
||||||
Target: sheet.Id,
|
|
||||||
})),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,10 @@ func NavBar() h.Renderable {
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.Nav(h.Class("flex gap-4 items-center p-4 text-slate-600"),
|
return h.Nav(h.Class("flex gap-4 items-center p-4 text-slate-600"),
|
||||||
|
h.Boost(),
|
||||||
h.Children(
|
h.Children(
|
||||||
h.Map(links, func(link Link) h.Renderable {
|
h.Map(links, func(link Link) h.Renderable {
|
||||||
return h.A(link.Name, h.Href(link.Path), h.Class("cursor-pointer hover:text-blue-400"))
|
return h.A(link.Name, h.Href(link.Path), h.Class("cursor-pointer hover:text-blue-400"))
|
||||||
}),
|
})...,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ func List(ctx *fiber.Ctx) *h.Partial {
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.NewPartial(h.Div(
|
return h.NewPartial(h.Div(
|
||||||
|
h.HxExtension("debug"),
|
||||||
h.Class("mt-8"),
|
h.Class("mt-8"),
|
||||||
h.Id("patient-list"),
|
h.Id("patient-list"),
|
||||||
h.List(patients, Row),
|
h.List(patients, Row),
|
||||||
|
|
@ -41,9 +42,12 @@ func List(ctx *fiber.Ctx) *h.Partial {
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddPatientSheetPartial(ctx *fiber.Ctx) *h.Partial {
|
func AddPatientSheetPartial(ctx *fiber.Ctx) *h.Partial {
|
||||||
|
closePathQs := h.GetQueryParam(ctx, "onClosePath")
|
||||||
return h.NewPartialWithHeaders(
|
return h.NewPartialWithHeaders(
|
||||||
h.PushQsHeader(ctx, "adding", "true"),
|
h.PushQsHeader(ctx, "adding", "true"),
|
||||||
AddPatientSheet(h.CurrentPath(ctx)),
|
AddPatientSheet(
|
||||||
|
h.Ternary(closePathQs != "", closePathQs, h.CurrentPath(ctx)),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,10 +108,11 @@ func Row(patient *Patient, index int) h.Renderable {
|
||||||
|
|
||||||
func AddPatientButton() h.Renderable {
|
func AddPatientButton() h.Renderable {
|
||||||
return ui.Button(ui.ButtonProps{
|
return ui.Button(ui.ButtonProps{
|
||||||
Id: "add-patient",
|
Id: "add-patient",
|
||||||
Text: "Add Patient",
|
Text: "Add Patient",
|
||||||
Class: "bg-blue-700 text-white rounded p-2 h-12",
|
Class: "bg-blue-700 text-white rounded p-2 h-12",
|
||||||
Target: sheet.Id,
|
Trigger: "qs:adding, click",
|
||||||
Get: h.GetPartialPath(AddPatientSheetPartial),
|
Target: sheet.Id,
|
||||||
|
Get: h.GetPartialPathWithQs(AddPatientSheetPartial, "onClosePath=/patients"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ func Closed() h.Renderable {
|
||||||
|
|
||||||
func Close(ctx *fiber.Ctx) *h.Partial {
|
func Close(ctx *fiber.Ctx) *h.Partial {
|
||||||
return h.NewPartialWithHeaders(
|
return h.NewPartialWithHeaders(
|
||||||
h.Ternary(ctx.Query("path") != "", h.PushUrlHeader(ctx.Query("path")), h.NewHeaders()),
|
h.Ternary(ctx.Query("path") != "", h.ReplaceUrlHeader(ctx.Query("path")), h.NewHeaders()),
|
||||||
h.Swap(ctx, Closed()),
|
h.Swap(ctx, Closed()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ func Button(props ButtonProps) h.Renderable {
|
||||||
|
|
||||||
button := h.Button(
|
button := h.Button(
|
||||||
h.If(props.Id != "", h.Id(props.Id)),
|
h.If(props.Id != "", h.Id(props.Id)),
|
||||||
h.If(props.Children != nil, h.Children(props.Children)),
|
h.If(props.Children != nil, h.Children(props.Children...)),
|
||||||
h.If(props.Trigger != "", h.Trigger(props.Trigger)),
|
h.If(props.Trigger != "", h.Trigger(props.Trigger)),
|
||||||
h.Class("flex gap-1 items-center border p-4 rounded cursor-hover", props.Class),
|
h.Class("flex gap-1 items-center border p-4 rounded cursor-hover", props.Class),
|
||||||
h.If(props.Get != "", h.Get(props.Get)),
|
h.If(props.Get != "", h.Get(props.Get)),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue