feat: Adds api route tests. Tested user interface works as expected, still needs some work on vendors form.
This commit is contained in:
@@ -169,10 +169,12 @@ enum IDKey: CustomStringConvertible {
|
||||
}
|
||||
|
||||
enum Vendor: CustomStringConvertible {
|
||||
case form
|
||||
case row(id: SharedModels.Vendor.ID)
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .form: return "form"
|
||||
case let .row(id): return "\(id)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,15 +52,23 @@ struct LoggedIn: HTML {
|
||||
let next: String?
|
||||
var content: some HTML {
|
||||
div(
|
||||
.hx.get(next ?? ViewRoute.router.path(for: .purchaseOrder(.index))),
|
||||
.hx.get(nextRoute ?? ViewRoute.router.path(for: .purchaseOrder(.index))),
|
||||
.hx.pushURL(true),
|
||||
.hx.target("body"),
|
||||
.hx.target(.body),
|
||||
.hx.trigger(.event(.revealed)),
|
||||
.hx.indicator(".hx-indicator")
|
||||
) {
|
||||
Img.spinner().attributes(.class("hx-indicator"))
|
||||
}
|
||||
}
|
||||
|
||||
// HACK: to get search route to work after login.
|
||||
var nextRoute: String? {
|
||||
if let next, next.contains("search") {
|
||||
return ViewRoute.router.path(for: .purchaseOrder(.search(.index(context: .employee, table: true))))
|
||||
}
|
||||
return next
|
||||
}
|
||||
}
|
||||
|
||||
struct RouteHeaderView: HTML {
|
||||
|
||||
@@ -45,7 +45,7 @@ struct PurchaseOrderTable: HTML {
|
||||
if context != .search {
|
||||
Button.add()
|
||||
.attributes(
|
||||
.hx.get(route: .purchaseOrder(.index)), .hx.target(.id(.float)),
|
||||
.hx.get(route: .purchaseOrder(.form)), .hx.target(.id(.float)),
|
||||
.hx.swap(.outerHTML), .hx.pushURL(true)
|
||||
)
|
||||
}
|
||||
@@ -79,9 +79,12 @@ struct PurchaseOrderTable: HTML {
|
||||
for purchaseOrder in page.items {
|
||||
Row(purchaseOrder: purchaseOrder)
|
||||
}
|
||||
if page.metadata.pageCount > page.metadata.page {
|
||||
// We set page to 0 when we're on search, but have not completed the search
|
||||
// form yet, so don't add the infinite scroll row / trigger otherwise it will
|
||||
// load the first page, which is not what we want, but we need the empty table
|
||||
// to be available once the search form is completed.
|
||||
if page.metadata.page > 0, page.metadata.pageCount > page.metadata.page {
|
||||
tr(
|
||||
// .hx.get("/purchase-orders/next?page=\(page.metadata.page + 1)&limit=\(page.metadata.per)"),
|
||||
.hx.get(route: .purchaseOrder(.page(page: page.metadata.page + 1, limit: page.metadata.per))),
|
||||
.hx.trigger(.event(.revealed)),
|
||||
.hx.swap(.outerHTML.transition(true).swap("1s")),
|
||||
|
||||
@@ -23,7 +23,7 @@ struct UserForm: HTML, Sendable {
|
||||
.hx.post(context.targetURL),
|
||||
.hx.pushURL(context.pushURL),
|
||||
.hx.target(context.target),
|
||||
.hx.swap(.outerHTML),
|
||||
.hx.swap(context == .create ? .afterBegin.transition(true).swap("0.5s") : .outerHTML),
|
||||
.hx.on(
|
||||
.afterRequest,
|
||||
.ifSuccessful(.resetForm, .toggleContent(.float))
|
||||
@@ -92,12 +92,12 @@ struct UserForm: HTML, Sendable {
|
||||
}
|
||||
}
|
||||
|
||||
var target: String {
|
||||
var target: HXTarget {
|
||||
switch self {
|
||||
case .create:
|
||||
return "next table"
|
||||
return .id(.user(.table))
|
||||
case .login:
|
||||
return "body"
|
||||
return .body
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import Vapor
|
||||
struct EmployeeSelect: HTML {
|
||||
|
||||
let employees: [Employee]?
|
||||
let context: SelectContext
|
||||
let context: ViewRoute.SelectContext
|
||||
|
||||
var content: some HTML {
|
||||
if let employees {
|
||||
@@ -18,7 +18,7 @@ struct EmployeeSelect: HTML {
|
||||
.attributes(.style("margin-left: 15px;"), when: context == .purchaseOrderSearch)
|
||||
} else {
|
||||
div(
|
||||
.hx.get("/select/employee?context=\(context.rawValue)"),
|
||||
.hx.get(route: .employee(.select(context: context))),
|
||||
.hx.target("this"),
|
||||
.hx.swap(.outerHTML.transition(true).swap("0.5s")),
|
||||
.hx.indicator("next .hx-indicator"),
|
||||
@@ -42,11 +42,11 @@ struct EmployeeSelect: HTML {
|
||||
|
||||
struct VendorBranchSelect: HTML {
|
||||
let branches: [VendorBranch.Detail]?
|
||||
let context: SelectContext
|
||||
let context: ViewRoute.SelectContext
|
||||
|
||||
var content: some HTML {
|
||||
if let branches {
|
||||
select(.name("vendorBranchID"), .class(context.classString)) {
|
||||
select(.name("vendorBranchID"), .class("col-4")) {
|
||||
for branch in branches {
|
||||
option(.value(branch.id.uuidString)) { "\(branch.vendor.name) - \(branch.name)" }
|
||||
}
|
||||
@@ -54,8 +54,8 @@ struct VendorBranchSelect: HTML {
|
||||
.attributes(.style("margin-left: 15px;"), when: context == .purchaseOrderSearch)
|
||||
} else {
|
||||
div(
|
||||
.hx.get("/select/vendor-branches?context=\(context.rawValue)"),
|
||||
.hx.target("this"),
|
||||
.hx.get(route: .vendorBranch(.select(context: context))),
|
||||
.hx.target(.this),
|
||||
.hx.swap(.outerHTML.transition(true).swap("0.5s")),
|
||||
.hx.indicator("next .hx-indicator"),
|
||||
.hx.trigger(.event(.revealed)),
|
||||
@@ -75,10 +75,11 @@ struct VendorBranchSelect: HTML {
|
||||
}
|
||||
}
|
||||
|
||||
enum SelectContext: String, Codable, Content {
|
||||
case purchaseOrderForm
|
||||
case purchaseOrderSearch
|
||||
// enum SelectContext: String, Codable, Content {
|
||||
// case purchaseOrderForm
|
||||
// case purchaseOrderSearch
|
||||
|
||||
extension ViewRoute.SelectContext {
|
||||
var classString: String {
|
||||
switch self {
|
||||
case .purchaseOrderForm: return "col-3"
|
||||
|
||||
@@ -26,15 +26,15 @@ struct VendorDetail: HTML {
|
||||
|
||||
// TODO: What route for here??
|
||||
var branchForm: some HTML {
|
||||
// TODO: Add hidden input field with vendor id.
|
||||
form(
|
||||
.id("branch-form"),
|
||||
.hx.post("/vendors/\(vendor.id)/branches"),
|
||||
.id(.branch(.form)),
|
||||
.hx.post("/vendors/branches"),
|
||||
.hx.target("#branches"),
|
||||
.hx.swap(.beforeEnd),
|
||||
.hx.on(.afterRequest, .ifSuccessful(.resetForm))
|
||||
// .custom(name: "hx-on::after-request", value: "if(event.detail.successful) this.reset();")
|
||||
) {
|
||||
input(.type(.hidden), .name("vendorID"), .value(vendor.id.uuidString))
|
||||
input(
|
||||
.type(.text), .class("col-9"), .name("name"), .placeholder("Add branch..."), .required,
|
||||
// FIX: route
|
||||
|
||||
@@ -40,7 +40,7 @@ struct VendorForm: HTML {
|
||||
|
||||
func makeForm(vendor: Vendor?) -> some HTML {
|
||||
form(
|
||||
.id("vendor-form"),
|
||||
.id(.vendor(.form)),
|
||||
vendor != nil ? .hx.put(route: targetURL) : .hx.post(route: targetURL),
|
||||
.hx.target("#content"),
|
||||
.hx.swap(.outerHTML)
|
||||
@@ -63,7 +63,7 @@ struct VendorForm: HTML {
|
||||
.style("font-size: 1.25em; padding: 10px 20px; border-radius: 10px;"),
|
||||
.hx.delete(route: .vendor(.delete(id: vendor.id))),
|
||||
.hx.confirm("Are you sure you want to delete this vendor?"),
|
||||
.hx.target("#vendor_\(vendor.id)"),
|
||||
.hx.target(.id(.vendor(.row(id: vendor.id)))),
|
||||
.hx.swap(.outerHTML.transition(true).swap("1s")),
|
||||
.custom(
|
||||
name: "hx-on::after-request",
|
||||
|
||||
Reference in New Issue
Block a user