feat: Adds ability to toggle an employee's active status (#3)
Reviewed-on: #3
This commit is contained in:
@@ -37,6 +37,7 @@ public extension DatabaseClient.Employees {
|
|||||||
guard let model = try await EmployeeModel.find(id, on: database) else {
|
guard let model = try await EmployeeModel.find(id, on: database) else {
|
||||||
throw NotFoundError()
|
throw NotFoundError()
|
||||||
}
|
}
|
||||||
|
database.logger.debug("Applying updates to employee: \(updates)")
|
||||||
try model.applyUpdate(updates)
|
try model.applyUpdate(updates)
|
||||||
try await model.save(on: database)
|
try await model.save(on: database)
|
||||||
return try model.toDTO()
|
return try model.toDTO()
|
||||||
@@ -170,8 +171,10 @@ final class EmployeeModel: Model, @unchecked Sendable {
|
|||||||
if let lastName = updates.lastName {
|
if let lastName = updates.lastName {
|
||||||
self.lastName = lastName
|
self.lastName = lastName
|
||||||
}
|
}
|
||||||
if let active = updates.active {
|
// NB: When html forms are submitted with a checkbox then active is nil
|
||||||
self.active = active
|
// in the update context.
|
||||||
|
if active, updates.active == nil || updates.active == false {
|
||||||
|
active = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,8 +128,8 @@ public extension PurchaseOrder {
|
|||||||
/// given parameters.
|
/// given parameters.
|
||||||
enum SearchContext: Sendable, Equatable {
|
enum SearchContext: Sendable, Equatable {
|
||||||
case customer(String)
|
case customer(String)
|
||||||
case vendor(VendorBranch.ID)
|
|
||||||
case employee(Employee.ID)
|
case employee(Employee.ID)
|
||||||
|
case vendor(VendorBranch.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ extension SiteRoute.View.EmployeeRoute {
|
|||||||
return try await render(mainPage, isHtmxRequest, EmployeeForm(shouldShow: true))
|
return try await render(mainPage, isHtmxRequest, EmployeeForm(shouldShow: true))
|
||||||
|
|
||||||
case let .select(context: context):
|
case let .select(context: context):
|
||||||
return try await context.toHTML(employees: employees.fetchAll())
|
return try await context.toHTML(employees: employees.fetchAll(.active))
|
||||||
|
|
||||||
case .index:
|
case .index:
|
||||||
return try await mainPage(EmployeeForm())
|
return try await mainPage(EmployeeForm())
|
||||||
|
|||||||
@@ -42,6 +42,20 @@ struct EmployeeForm: HTML {
|
|||||||
.placeholder("Last Name"), .required
|
.placeholder("Last Name"), .required
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if let employee {
|
||||||
|
div(.class("row"), .style("margin: 20px; float: left;")) {
|
||||||
|
label(.for("active"), .style("margin-right: 15px;")) { h2 { "Active" } }
|
||||||
|
if employee.active {
|
||||||
|
input(
|
||||||
|
.type(.checkbox), .id("active"), .name("active"), .checked
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
input(
|
||||||
|
.type(.checkbox), .id("active"), .name("active")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
div(.class("btn-row")) {
|
div(.class("btn-row")) {
|
||||||
button(.type(.submit), .class("btn-primary")) {
|
button(.type(.submit), .class("btn-primary")) {
|
||||||
buttonLabel
|
buttonLabel
|
||||||
@@ -59,6 +73,18 @@ struct EmployeeForm: HTML {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if employee != nil {
|
||||||
|
h3 {
|
||||||
|
i {
|
||||||
|
span(.class("primary"), .style("padding-right: 15px;")) {
|
||||||
|
"Note:"
|
||||||
|
}
|
||||||
|
span(.class("secondary")) {
|
||||||
|
"It is better to mark an employee as in-active instead of deleting them."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import Elementary
|
||||||
|
import ElementaryHTMX
|
||||||
|
import SharedModels
|
||||||
|
|
||||||
|
struct PurchaseOrderFilter: HTML, Sendable {
|
||||||
|
|
||||||
|
var content: some HTML {
|
||||||
|
form(
|
||||||
|
.id("filter-form")
|
||||||
|
) {
|
||||||
|
input(.type(.text), .name("id"), .placeholder("Filter: (12345)"), .required)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@ struct ViewControllerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
func employeeViews() async throws {
|
func employeeViews() async throws {
|
||||||
try await withSnapshotTesting(record: record) {
|
try await withSnapshotTesting(record: .missing) {
|
||||||
try await withDependencies {
|
try await withDependencies {
|
||||||
$0.viewController = .liveValue
|
$0.viewController = .liveValue
|
||||||
$0.database.employees = .mock
|
$0.database.employees = .mock
|
||||||
|
|||||||
@@ -8,9 +8,15 @@
|
|||||||
<div class="col-2"></div>
|
<div class="col-2"></div>
|
||||||
<input type="text" class="col-5" name="lastName" value="McTestface" placeholder="Last Name" required>
|
<input type="text" class="col-5" name="lastName" value="McTestface" placeholder="Last Name" required>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row" style="margin: 20px; float: left;">
|
||||||
|
<label for="active" style="margin-right: 15px;">
|
||||||
|
<h2>Active</h2></label>
|
||||||
|
<input type="checkbox" id="active" name="active" checked>
|
||||||
|
</div>
|
||||||
<div class="btn-row">
|
<div class="btn-row">
|
||||||
<button type="submit" class="btn-primary">Update</button>
|
<button type="submit" class="btn-primary">Update</button>
|
||||||
<button class="danger" hx-confirm="Are you sure you want to delete this employee?" hx-delete="/api/v1/employees/00000000-0000-0000-0000-000000000000" hx-target="#employee-00000000-0000-0000-0000-000000000000" hx-swap="outerHTML transition:true swap:1s">Delete</button>
|
<button class="danger" hx-confirm="Are you sure you want to delete this employee?" hx-delete="/api/v1/employees/00000000-0000-0000-0000-000000000000" hx-target="#employee-00000000-0000-0000-0000-000000000000" hx-swap="outerHTML transition:true swap:1s">Delete</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<h3><i><span class="primary" style="padding-right: 15px;">Note:</span><span class="secondary">It is better to mark an employee as in-active instead of deleting them.</span></i></h3>
|
||||||
</div>
|
</div>
|
||||||
Reference in New Issue
Block a user