feat: Adds page header styles, starts an Alert component.
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
--text-3xl: 1.875rem;
|
||||
--text-3xl--line-height: calc(2.25 / 1.875);
|
||||
--font-weight-bold: 700;
|
||||
--radius-sm: 0.25rem;
|
||||
--radius-md: 0.375rem;
|
||||
--radius-lg: 0.5rem;
|
||||
--ease-out: cubic-bezier(0, 0, 0.2, 1);
|
||||
@@ -5379,6 +5380,9 @@
|
||||
.my-6 {
|
||||
margin-block: calc(var(--spacing) * 6);
|
||||
}
|
||||
.my-auto {
|
||||
margin-block: auto;
|
||||
}
|
||||
.label {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
display: inline-flex;
|
||||
@@ -6893,6 +6897,12 @@
|
||||
margin-inline-end: calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-x-reverse)));
|
||||
}
|
||||
}
|
||||
.gap-y-4 {
|
||||
row-gap: calc(var(--spacing) * 4);
|
||||
}
|
||||
.gap-y-6 {
|
||||
row-gap: calc(var(--spacing) * 6);
|
||||
}
|
||||
.overflow-auto {
|
||||
overflow: auto;
|
||||
}
|
||||
@@ -7005,6 +7015,9 @@
|
||||
.rounded-selector {
|
||||
border-radius: var(--radius-selector);
|
||||
}
|
||||
.rounded-sm {
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
.rounded-t-box {
|
||||
border-top-left-radius: var(--radius-box);
|
||||
border-top-right-radius: var(--radius-box);
|
||||
@@ -7177,6 +7190,14 @@
|
||||
border-style: var(--tw-border-style);
|
||||
border-width: 1px;
|
||||
}
|
||||
.border-2 {
|
||||
border-style: var(--tw-border-style);
|
||||
border-width: 2px;
|
||||
}
|
||||
.border-y {
|
||||
border-block-style: var(--tw-border-style);
|
||||
border-block-width: 1px;
|
||||
}
|
||||
.border-t {
|
||||
border-top-style: var(--tw-border-style);
|
||||
border-top-width: 1px;
|
||||
@@ -7307,6 +7328,12 @@
|
||||
.border-gray-200 {
|
||||
border-color: var(--color-gray-200);
|
||||
}
|
||||
.border-primary {
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
.border-secondary {
|
||||
border-color: var(--color-secondary);
|
||||
}
|
||||
.menu-active {
|
||||
:where(:not(ul, details, .menu-title, .btn))& {
|
||||
@layer daisyui.l1.l2 {
|
||||
@@ -7467,9 +7494,15 @@
|
||||
.bg-base-300 {
|
||||
background-color: var(--color-base-300);
|
||||
}
|
||||
.bg-primary {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
.bg-red-500 {
|
||||
background-color: var(--color-red-500);
|
||||
}
|
||||
.bg-secondary {
|
||||
background-color: var(--color-secondary);
|
||||
}
|
||||
.bg-white {
|
||||
background-color: var(--color-white);
|
||||
}
|
||||
@@ -7761,6 +7794,9 @@
|
||||
.p-4 {
|
||||
padding: calc(var(--spacing) * 4);
|
||||
}
|
||||
.p-6 {
|
||||
padding: calc(var(--spacing) * 6);
|
||||
}
|
||||
.menu-title {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
padding-inline: calc(0.25rem * 3);
|
||||
@@ -8554,6 +8590,12 @@
|
||||
.text-primary {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
.text-primary-content {
|
||||
color: var(--color-primary-content);
|
||||
}
|
||||
.text-secondary-content {
|
||||
color: var(--color-secondary-content);
|
||||
}
|
||||
.text-slate-900 {
|
||||
color: var(--color-slate-900);
|
||||
}
|
||||
|
||||
28
Sources/Styleguide/Alert.swift
Normal file
28
Sources/Styleguide/Alert.swift
Normal file
@@ -0,0 +1,28 @@
|
||||
import Elementary
|
||||
|
||||
public struct Alert<Content: HTML>: HTML {
|
||||
|
||||
let inner: Content
|
||||
|
||||
public init(@HTMLBuilder content: () -> Content) {
|
||||
self.inner = content()
|
||||
}
|
||||
|
||||
public var body: some HTML<HTMLTag.div> {
|
||||
div(.class("flex space-x-2")) {
|
||||
SVG(.triangleAlert)
|
||||
inner
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Alert: Sendable where Content: Sendable {}
|
||||
|
||||
extension Alert where Content == p<HTMLText> {
|
||||
|
||||
public init(_ description: String) {
|
||||
self.init {
|
||||
p { description }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,7 @@ public struct EditButton: HTML, Sendable {
|
||||
}
|
||||
|
||||
public var body: some HTML<HTMLTag.button> {
|
||||
button(.class("btn hover:btn-success"), .type(type)) {
|
||||
button(.class("btn"), .type(type)) {
|
||||
div(.class("flex")) {
|
||||
if let title {
|
||||
span(.class("pe-2")) { title }
|
||||
@@ -83,7 +83,7 @@ public struct PlusButton: HTML, Sendable {
|
||||
public var body: some HTML<HTMLTag.button> {
|
||||
button(
|
||||
.type(.button),
|
||||
.class("btn btn-primary btn-circle text-xl")
|
||||
.class("btn")
|
||||
) { SVG(.circlePlus) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,4 +45,8 @@ extension HTML where Tag: HTMLTrait.Attributes.Global {
|
||||
public func badge() -> _AttributedElement<Self> {
|
||||
attributes(.class("badge badge-lg badge-outline font-bold"))
|
||||
}
|
||||
|
||||
public func hidden(when shouldHide: Bool) -> _AttributedElement<Self> {
|
||||
attributes(.class("hidden"), when: shouldHide)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
import Elementary
|
||||
|
||||
public struct PageTitleRow<Content: HTML>: HTML, Sendable where Content: Sendable {
|
||||
|
||||
let inner: Content
|
||||
|
||||
public init(@HTMLBuilder content: () -> Content) {
|
||||
self.inner = content()
|
||||
}
|
||||
|
||||
public var body: some HTML<HTMLTag.div> {
|
||||
div(
|
||||
.class(
|
||||
"""
|
||||
flex justify-between bg-secondary border-2 border-primary rounded-sm shadow-sm
|
||||
p-6 w-full
|
||||
"""
|
||||
)
|
||||
) {
|
||||
inner
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct PageTitle: HTML, Sendable {
|
||||
|
||||
let title: String
|
||||
|
||||
@@ -33,6 +33,7 @@ extension SVG {
|
||||
case squareFunction
|
||||
case squarePen
|
||||
case trash
|
||||
case triangleAlert
|
||||
case user
|
||||
case wind
|
||||
|
||||
@@ -135,6 +136,10 @@ extension SVG {
|
||||
return """
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trash2-icon lucide-trash-2"><path d="M10 11v6"/><path d="M14 11v6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
|
||||
"""
|
||||
case .triangleAlert:
|
||||
return """
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-triangle-alert-icon lucide-triangle-alert"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>
|
||||
"""
|
||||
case .user:
|
||||
return """
|
||||
<svg class="h-[1em] opacity-50" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
import Elementary
|
||||
|
||||
public struct Tooltip<Inner: HTML & Sendable>: HTML, Sendable {
|
||||
extension HTML {
|
||||
|
||||
public func tooltip(
|
||||
_ tip: String,
|
||||
position: TooltipPosition = .default
|
||||
) -> Tooltip<Self> {
|
||||
Tooltip(tip, position: position) {
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct Tooltip<Inner: HTML>: HTML {
|
||||
|
||||
let tooltip: String
|
||||
let position: TooltipPosition
|
||||
@@ -26,6 +38,8 @@ public struct Tooltip<Inner: HTML & Sendable>: HTML, Sendable {
|
||||
}
|
||||
}
|
||||
|
||||
extension Tooltip: Sendable where Inner: Sendable {}
|
||||
|
||||
public enum TooltipPosition: String, CaseIterable, Sendable {
|
||||
|
||||
public static let `default` = Self.left
|
||||
|
||||
@@ -31,13 +31,12 @@ struct ComponentPressureLossesView: HTML, Sendable {
|
||||
th { "Value" }
|
||||
th {
|
||||
div(.class("flex justify-end mx-auto")) {
|
||||
Tooltip("Add Component Loss") {
|
||||
PlusButton()
|
||||
.attributes(
|
||||
.class("btn-ghost text-2xl me-2"),
|
||||
.showModal(id: ComponentLossForm.id())
|
||||
)
|
||||
}
|
||||
PlusButton()
|
||||
.attributes(
|
||||
.class("btn-primary text-2xl me-2"),
|
||||
.showModal(id: ComponentLossForm.id())
|
||||
)
|
||||
.tooltip("Add component loss")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@ import ElementaryHTMX
|
||||
import ManualDCore
|
||||
import Styleguide
|
||||
|
||||
// TODO: Add trunk size table.
|
||||
|
||||
struct DuctSizingView: HTML, Sendable {
|
||||
|
||||
@Environment(ProjectViewValue.$projectID) var projectID
|
||||
@@ -14,32 +12,40 @@ struct DuctSizingView: HTML, Sendable {
|
||||
|
||||
var body: some HTML {
|
||||
div(.class("space-y-4")) {
|
||||
PageTitle { "Duct Sizes" }
|
||||
PageTitleRow {
|
||||
div(.class("space-y-4")) {
|
||||
PageTitle("Duct Sizes")
|
||||
|
||||
if rooms.count == 0 {
|
||||
p(.class("text-error italic")) {
|
||||
"Must complete all the previous sections to display duct sizing calculations."
|
||||
}
|
||||
} else {
|
||||
RoomsTable(rooms: rooms)
|
||||
div(.class("divider mb-6")) {}
|
||||
}
|
||||
|
||||
Row {
|
||||
h2(.class("text-2xl font-bold")) {
|
||||
"Trunk / Runout Sizes"
|
||||
}
|
||||
|
||||
PlusButton()
|
||||
.attributes(
|
||||
.class("me-6"),
|
||||
.showModal(id: TrunkSizeForm.id())
|
||||
Alert(
|
||||
"""
|
||||
Must complete all the previous sections to display duct sizing calculations.
|
||||
"""
|
||||
)
|
||||
.hidden(when: rooms.count > 0)
|
||||
.attributes(.class("text-error font-bold italic"))
|
||||
}
|
||||
}
|
||||
|
||||
if trunks.count > 0 {
|
||||
div(.class("divider -mt-2")) {}
|
||||
TrunkTable(trunks: trunks, rooms: rooms)
|
||||
if rooms.count != 0 {
|
||||
RoomsTable(rooms: rooms)
|
||||
|
||||
PageTitleRow {
|
||||
PageTitle {
|
||||
"Trunk / Runout Sizes"
|
||||
}
|
||||
|
||||
PlusButton()
|
||||
.attributes(
|
||||
.class("btn-primary"),
|
||||
.showModal(id: TrunkSizeForm.id())
|
||||
)
|
||||
.tooltip("Add trunk / runout")
|
||||
}
|
||||
|
||||
if trunks.count > 0 {
|
||||
TrunkTable(trunks: trunks, rooms: rooms)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TrunkSizeForm(rooms: rooms, dismiss: true)
|
||||
|
||||
@@ -21,13 +21,14 @@ struct EffectiveLengthsView: HTML, Sendable {
|
||||
|
||||
var body: some HTML {
|
||||
div(.class("space-y-4")) {
|
||||
Row {
|
||||
PageTitleRow {
|
||||
PageTitle { "Equivalent Lengths" }
|
||||
PlusButton()
|
||||
.attributes(
|
||||
.class("btn-ghost me-4"),
|
||||
.class("btn-primary"),
|
||||
.showModal(id: EffectiveLengthForm.id(nil))
|
||||
)
|
||||
.tooltip("Add equivalent length")
|
||||
}
|
||||
.attributes(.class("pb-6"))
|
||||
|
||||
|
||||
@@ -12,16 +12,15 @@ struct EquipmentInfoView: HTML, Sendable {
|
||||
.id("equipmentInfo")
|
||||
) {
|
||||
|
||||
Row {
|
||||
PageTitle { "Equipment Info" }
|
||||
PageTitleRow {
|
||||
PageTitle { "Equipment Details" }
|
||||
|
||||
Tooltip("Edit equipment info") {
|
||||
EditButton()
|
||||
.attributes(
|
||||
.class("btn-ghost"),
|
||||
.showModal(id: EquipmentInfoForm.id)
|
||||
)
|
||||
}
|
||||
EditButton()
|
||||
.attributes(
|
||||
.class("btn-primary"),
|
||||
.showModal(id: EquipmentInfoForm.id)
|
||||
)
|
||||
.tooltip("Edit equipment details")
|
||||
}
|
||||
|
||||
if let equipmentInfo {
|
||||
|
||||
@@ -42,60 +42,75 @@ struct FrictionRateView: HTML, Sendable {
|
||||
|
||||
var body: some HTML {
|
||||
div(.class("space-y-6")) {
|
||||
div(.class("grid grid-cols-2 px-4")) {
|
||||
PageTitleRow {
|
||||
div(.class("grid grid-cols-2 px-4 gap-y-4")) {
|
||||
|
||||
PageTitle { "Friction Rate" }
|
||||
PageTitle { "Friction Rate" }
|
||||
|
||||
div(.class("space-y-4 justify-end")) {
|
||||
div(.class("space-y-4 justify-end")) {
|
||||
|
||||
if let frictionRateDesignValue {
|
||||
LabeledContent("Friction Rate Design Value") {
|
||||
Badge(number: frictionRateDesignValue, digits: 2)
|
||||
.attributes(.class("\(badgeColor)"))
|
||||
if let frictionRateDesignValue {
|
||||
LabeledContent("Friction Rate Design Value") {
|
||||
Badge(number: frictionRateDesignValue, digits: 2)
|
||||
.attributes(.class("\(badgeColor)"))
|
||||
}
|
||||
.attributes(.class("justify-end"))
|
||||
}
|
||||
|
||||
if let availableStaticPressure {
|
||||
LabeledContent("Available Static Pressure") {
|
||||
Badge(number: availableStaticPressure, digits: 2)
|
||||
}
|
||||
.attributes(.class("justify-end"))
|
||||
}
|
||||
.attributes(.class("justify-end"))
|
||||
}
|
||||
|
||||
if let availableStaticPressure {
|
||||
LabeledContent("Available Static Pressure") {
|
||||
Badge(number: availableStaticPressure, digits: 2)
|
||||
div(.class("text-error font-bold italic col-span-2")) {
|
||||
Alert {
|
||||
p {
|
||||
"Must complete previous sections."
|
||||
}
|
||||
}
|
||||
.attributes(.class("justify-end"))
|
||||
.hidden(
|
||||
when: availableStaticPressure != nil && frictionRateDesignValue != nil
|
||||
)
|
||||
|
||||
Alert {
|
||||
p {
|
||||
"No component pressures losses"
|
||||
}
|
||||
}
|
||||
.hidden(when: componentLosses.totalComponentPressureLoss > 0)
|
||||
|
||||
Alert {
|
||||
p(.class("block")) {
|
||||
"Calculated friction rate is below 0.02. The fan may not deliver the required CFM."
|
||||
br()
|
||||
" * Increase the blower speed"
|
||||
br()
|
||||
" * Increase the blower size"
|
||||
br()
|
||||
" * Decrease the Total Effective Length (TEL)"
|
||||
}
|
||||
}
|
||||
.hidden(when: !showLowErrors)
|
||||
|
||||
Alert {
|
||||
p(.class("block")) {
|
||||
"Calculated friction rate is above 0.18. The fan may deliver too many CFM."
|
||||
br()
|
||||
" * Decrease the blower speed"
|
||||
br()
|
||||
" * Decreae the blower size"
|
||||
br()
|
||||
" * Increase the Total Effective Length (TEL)"
|
||||
}
|
||||
}
|
||||
.hidden(when: !showHighErrors)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div(.class("text-error italic")) {
|
||||
p {
|
||||
"No component pressures losses"
|
||||
}
|
||||
.attributes(.class("hidden"), when: componentLosses.totalComponentPressureLoss > 0)
|
||||
|
||||
p {
|
||||
"Calculated friction rate is below 0.02. The fan may not deliver the required CFM."
|
||||
br()
|
||||
" * Increase the blower speed"
|
||||
br()
|
||||
" * Increase the blower size"
|
||||
br()
|
||||
" * Decrease the Total Effective Length (TEL)"
|
||||
}
|
||||
.attributes(.class("hidden"), when: !showLowErrors)
|
||||
|
||||
p {
|
||||
"Calculated friction rate is above 0.18. The fan may deliver too many CFM."
|
||||
br()
|
||||
" * Decrease the blower speed"
|
||||
br()
|
||||
" * Decreae the blower size"
|
||||
br()
|
||||
" * Increase the Total Effective Length (TEL)"
|
||||
}
|
||||
.attributes(.class("hidden"), when: !showHighErrors)
|
||||
}
|
||||
|
||||
div(.class("divider")) {}
|
||||
|
||||
ComponentPressureLossesView(
|
||||
componentPressureLosses: componentLosses, projectID: projectID
|
||||
)
|
||||
|
||||
@@ -82,7 +82,7 @@ public struct MainPage<Inner: HTML>: SendableHTMLDocument where Inner: Sendable
|
||||
|
||||
public var body: some HTML {
|
||||
div(.class("flex flex-col min-h-screen min-w-full")) {
|
||||
main(.class("overflow-auto grow")) {
|
||||
main(.class("grow")) {
|
||||
inner
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,15 @@ struct ProjectDetail: HTML, Sendable {
|
||||
|
||||
var body: some HTML {
|
||||
div {
|
||||
Row {
|
||||
h1(.class("text-3xl font-bold")) { "Project" }
|
||||
PageTitleRow {
|
||||
PageTitle { "Project" }
|
||||
|
||||
EditButton()
|
||||
.attributes(
|
||||
.class("btn-ghost"),
|
||||
.class("btn-primary"),
|
||||
.on(.click, "projectForm.showModal()")
|
||||
)
|
||||
.tooltip("Edit project", position: .left)
|
||||
}
|
||||
|
||||
table(.class("table table-zebra text-lg")) {
|
||||
|
||||
@@ -13,63 +13,58 @@ struct RoomsView: HTML, Sendable {
|
||||
|
||||
var body: some HTML {
|
||||
div(.class("flex w-full flex-col")) {
|
||||
Row {
|
||||
PageTitle { "Room Loads" }
|
||||
PageTitleRow {
|
||||
div(.class("flex grid grid-cols-3 w-full gap-y-4")) {
|
||||
|
||||
div(.class("flex justify-end items-end -my-2")) {
|
||||
Tooltip("Project wide sensible heat ratio", position: .left) {
|
||||
button(
|
||||
.class(
|
||||
"""
|
||||
justify-end items-end p-4
|
||||
hover:bg-neutral hover:text-white hover:rounded-lg
|
||||
"""
|
||||
),
|
||||
.showModal(id: SHRForm.id)
|
||||
) {
|
||||
LabeledContent {
|
||||
div(.class("flex justify-end items-end space-x-4")) {
|
||||
Label {
|
||||
div(.class("col-span-2")) {
|
||||
PageTitle { "Room Loads" }
|
||||
}
|
||||
|
||||
div(.class("flex justify-end grow")) {
|
||||
Tooltip("Project wide sensible heat ratio", position: .left) {
|
||||
button(
|
||||
.class(
|
||||
"""
|
||||
btn btn-primary text-lg font-bold py-2
|
||||
"""
|
||||
),
|
||||
.showModal(id: SHRForm.id)
|
||||
) {
|
||||
div(.class("flex grow justify-end items-end space-x-4")) {
|
||||
span {
|
||||
"Sensible Heat Ratio"
|
||||
}
|
||||
.attributes(.class("me-8"), when: sensibleHeatRatio == nil)
|
||||
}
|
||||
} content: {
|
||||
if let sensibleHeatRatio {
|
||||
Badge(number: sensibleHeatRatio)
|
||||
} else {
|
||||
SVG(.squarePen)
|
||||
if let sensibleHeatRatio {
|
||||
Badge(number: sensibleHeatRatio)
|
||||
} else {
|
||||
Badge { "set" }
|
||||
}
|
||||
}
|
||||
}
|
||||
.attributes(.class("border border-error"), when: sensibleHeatRatio == nil)
|
||||
}
|
||||
.attributes(.class("border rounded-lg border-error"), when: sensibleHeatRatio == nil)
|
||||
}
|
||||
|
||||
div(.class("flex items-end space-x-4 font-bold")) {
|
||||
span(.class("text-lg")) { "Heating Total" }
|
||||
Badge(number: rooms.heatingTotal, digits: 0)
|
||||
.attributes(.class("badge-error"))
|
||||
}
|
||||
|
||||
div(.class("flex justify-center items-end space-x-4 my-auto font-bold")) {
|
||||
span(.class("text-lg")) { "Cooling Total" }
|
||||
Badge(number: rooms.coolingTotal, digits: 0)
|
||||
.attributes(.class("badge-success"))
|
||||
}
|
||||
|
||||
div(.class("flex grow justify-end items-end space-x-4 me-4 my-auto font-bold")) {
|
||||
span(.class("text-lg")) { "Cooling Sensible" }
|
||||
Badge(number: rooms.coolingSensible(shr: sensibleHeatRatio), digits: 0)
|
||||
.attributes(.class("badge-info"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div(.class("flex flex-wrap justify-between mt-6")) {
|
||||
div(.class("flex items-end space-x-4")) {
|
||||
Label { "Heating Total" }
|
||||
Badge(number: rooms.heatingTotal, digits: 0)
|
||||
.attributes(.class("badge-error"))
|
||||
}
|
||||
|
||||
div(.class("flex items-end space-x-4")) {
|
||||
Label { "Cooling Total" }
|
||||
Badge(number: rooms.coolingTotal, digits: 0)
|
||||
.attributes(.class("badge-success"))
|
||||
}
|
||||
|
||||
div(.class("flex justify-end items-end space-x-4 me-4")) {
|
||||
Label { "Cooling Sensible" }
|
||||
Badge(number: rooms.coolingSensible(shr: sensibleHeatRatio), digits: 0)
|
||||
.attributes(.class("badge-info"))
|
||||
}
|
||||
}
|
||||
// .attributes(.class("mt-6 me-4"))
|
||||
|
||||
div(.class("divider")) {}
|
||||
|
||||
SHRForm(projectID: projectID, sensibleHeatRatio: sensibleHeatRatio)
|
||||
|
||||
table(.class("table table-zebra text-lg"), .id("roomsTable")) {
|
||||
@@ -101,7 +96,7 @@ struct RoomsView: HTML, Sendable {
|
||||
Tooltip("Add Room") {
|
||||
PlusButton()
|
||||
.attributes(
|
||||
.class("btn-ghost mx-auto"),
|
||||
.class("btn-primary mx-auto"),
|
||||
.showModal(id: RoomForm.id())
|
||||
)
|
||||
.attributes(.class("tooltip-left"))
|
||||
|
||||
Reference in New Issue
Block a user