import Elementary import ElementaryHTMX import Fluent import SharedModels import Vapor struct PurchaseOrderTable: HTML { let page: Page let context: Context let searchContext: PurchaseOrderSearchContext? init( page: Page, context: Context = .default, searchContext: PurchaseOrderSearchContext? = nil ) { self.page = page self.context = context self.searchContext = searchContext } var content: some HTML { table(.id(.purchaseOrders())) { if page.items.count > 0 { thead { buttonRow tableHeader } tbody(.id(.purchaseOrders(.table))) { Rows(page: page) } } } } private var tableHeader: some HTML { tr { th { "PO" } th { "Work Order" } th { "Customer" } th { "Vendor" } th { "Materials" } th { "Created For" } th { if context != .search { Button.add() .attributes( .hx.get(route: .purchaseOrders(.create)), .hx.target(.float), .hx.swap(.outerHTML), .hx.pushURL(true) ) } } } } private var buttonRow: some HTML { tr { div(.class("btn-row")) { if context != .search { button( .id("btn-search"), .class("btn-primary"), .style("position: absolute; top: 80px; right: 20px;"), .hx.get(route: .purchaseOrders(.search(.context(.employee, table: true)))), .hx.target(.body), .hx.swap(.outerHTML.transition(true).swap("0.5s")), .hx.pushURL(true) ) { Img.search() } } } } } // Produces only the rows for the given page struct Rows: HTML { let page: Page var content: some HTML { for purchaseOrder in page.items { Row(purchaseOrder: purchaseOrder) } if page.metadata.pageCount > page.metadata.page { tr( // .hx.get("/purchase-orders/next?page=\(page.metadata.page + 1)&limit=\(page.metadata.per)"), .hx.get(route: .purchaseOrders(.nextPage(page.metadata))), .hx.trigger(.event(.revealed)), .hx.swap(.outerHTML.transition(true).swap("1s")), .hx.target(.this), .hx.indicator("next .htmx-indicator") ) { img(.src("/images/spinner.svg"), .class("htmx-indicator"), .width(60), .height(60)) } } } } // A single row. struct Row: HTML { let purchaseOrder: PurchaseOrder var content: some HTML { tr( .id(.purchaseOrders(.row(id: purchaseOrder.id))) ) { td { "\(purchaseOrder.id)" } td { purchaseOrder.workOrder != nil ? String(purchaseOrder.workOrder!) : "" } td { purchaseOrder.customer } td { purchaseOrder.vendorBranch.displayName } td { purchaseOrder.materials } td { purchaseOrder.createdFor.fullName } td { Button.detail() .attributes( .hx.get("/purchase-orders/\(purchaseOrder.id)"), .hx.target("#float"), .hx.swap(.outerHTML.transition(true).swap("0.5s")), .hx.pushURL(true) ) } } } } enum Context: String { case `default` case search } } private extension VendorBranch.Detail { var displayName: String { "\(vendor.name.capitalized) - \(name.capitalized)" } }