+<%
+ let controller_classes = controller_classes.join(" ");
+ let card_classes = card_classes.join(" ");
+ let body_classes = body_classes.join(" ");
+%>
+
+
+
<%+ value %>
<% if let Some(link) = link { %>
-
+
<% } %>
diff --git a/pgml-dashboard/src/components/cards/secondary/mod.rs b/pgml-dashboard/src/components/cards/secondary/mod.rs
new file mode 100644
index 000000000..0d9e12078
--- /dev/null
+++ b/pgml-dashboard/src/components/cards/secondary/mod.rs
@@ -0,0 +1,16 @@
+use pgml_components::{component, Component};
+use sailfish::TemplateOnce;
+
+#[derive(TemplateOnce, Default)]
+#[template(path = "cards/secondary/template.html")]
+pub struct Secondary {
+ value: Component,
+}
+
+impl Secondary {
+ pub fn new(value: Component) -> Secondary {
+ Secondary { value }
+ }
+}
+
+component!(Secondary);
diff --git a/pgml-dashboard/src/components/cards/secondary/secondary.scss b/pgml-dashboard/src/components/cards/secondary/secondary.scss
new file mode 100644
index 000000000..c6fd1103c
--- /dev/null
+++ b/pgml-dashboard/src/components/cards/secondary/secondary.scss
@@ -0,0 +1,6 @@
+div[data-controller="cards-secondary"] {
+ .card {
+ --bs-card-bg: transparent;
+ --bs-card-border-color: #{$neon-tint-100};
+ }
+}
diff --git a/pgml-dashboard/src/components/cards/secondary/template.html b/pgml-dashboard/src/components/cards/secondary/template.html
new file mode 100644
index 000000000..f747d5801
--- /dev/null
+++ b/pgml-dashboard/src/components/cards/secondary/template.html
@@ -0,0 +1,7 @@
+
diff --git a/pgml-dashboard/src/components/headings/gray/gray.scss b/pgml-dashboard/src/components/headings/gray/gray.scss
new file mode 100644
index 000000000..7acb19b91
--- /dev/null
+++ b/pgml-dashboard/src/components/headings/gray/gray.scss
@@ -0,0 +1,3 @@
+span[data-controller="headings-gray"] {
+ color: #{$gray-400};
+}
diff --git a/pgml-dashboard/src/components/headings/gray/mod.rs b/pgml-dashboard/src/components/headings/gray/mod.rs
new file mode 100644
index 000000000..d7e19faaf
--- /dev/null
+++ b/pgml-dashboard/src/components/headings/gray/mod.rs
@@ -0,0 +1,18 @@
+use pgml_components::component;
+use sailfish::TemplateOnce;
+
+#[derive(TemplateOnce, Default)]
+#[template(path = "headings/gray/template.html")]
+pub struct Gray {
+ value: String,
+}
+
+impl Gray {
+ pub fn new(value: impl ToString) -> Gray {
+ Gray {
+ value: value.to_string(),
+ }
+ }
+}
+
+component!(Gray);
diff --git a/pgml-dashboard/src/components/headings/gray/template.html b/pgml-dashboard/src/components/headings/gray/template.html
new file mode 100644
index 000000000..a84131c97
--- /dev/null
+++ b/pgml-dashboard/src/components/headings/gray/template.html
@@ -0,0 +1,4 @@
+
+ <%= value %>
+
diff --git a/pgml-dashboard/src/components/headings/mod.rs b/pgml-dashboard/src/components/headings/mod.rs
index d74bd77ad..714caacb7 100644
--- a/pgml-dashboard/src/components/headings/mod.rs
+++ b/pgml-dashboard/src/components/headings/mod.rs
@@ -5,6 +5,10 @@
pub mod blue;
pub use blue::Blue;
+// src/components/headings/gray
+pub mod gray;
+pub use gray::Gray;
+
// src/components/headings/green
pub mod green;
pub use green::Green;
diff --git a/pgml-dashboard/src/components/inputs/radio/radio_controller.js b/pgml-dashboard/src/components/inputs/radio/radio_controller.js
index 0c4ec6644..7a589fa01 100644
--- a/pgml-dashboard/src/components/inputs/radio/radio_controller.js
+++ b/pgml-dashboard/src/components/inputs/radio/radio_controller.js
@@ -12,6 +12,10 @@ export default class extends Controller {
e.currentTarget.classList.add("active");
e.currentTarget.ariaPressed = true;
- e.currentTarget.querySelector("input").checked = true;
+
+ const input = e.currentTarget.querySelector("input");
+
+ input.checked = true;
+ input.dispatchEvent(new Event("change"));
}
}
diff --git a/pgml-dashboard/src/components/inputs/range_group_v_2/mod.rs b/pgml-dashboard/src/components/inputs/range_group_v_2/mod.rs
index d6bc897ff..34ef2e8a9 100644
--- a/pgml-dashboard/src/components/inputs/range_group_v_2/mod.rs
+++ b/pgml-dashboard/src/components/inputs/range_group_v_2/mod.rs
@@ -2,6 +2,7 @@ use pgml_components::component;
use sailfish::TemplateOnce;
use crate::components::stimulus::{stimulus_action::StimulusActions, StimulusAction};
+use std::collections::BTreeSet;
#[derive(TemplateOnce, Default)]
#[template(path = "inputs/range_group_v_2/template.html")]
@@ -12,14 +13,26 @@ pub struct RangeGroupV2 {
step: String,
value: String,
unit: String,
+ input_unit: String,
+ input_classes: BTreeSet
,
cost_per_unit: String,
+ cost_frequency: String,
actions: StimulusActions,
}
impl RangeGroupV2 {
pub fn new() -> RangeGroupV2 {
- Self::default()
+ Self {
+ input_classes: BTreeSet::from_iter(vec!["form-control".to_string()].into_iter()),
+ ..Default::default()
+ }
+ .min("40")
+ .max("16000")
+ .unit("GB")
+ .cost_per_unit("0.20")
+ .value("40")
+ .cost_frequency("h")
}
pub fn name(mut self, name: impl ToString) -> Self {
@@ -49,7 +62,14 @@ impl RangeGroupV2 {
pub fn unit(mut self, unit: impl ToString) -> Self {
self.unit = unit.to_string();
- self
+ self.input_unit = unit.to_string();
+
+ self.with_input_classes()
+ }
+
+ pub fn input_unit(mut self, input_unit: impl ToString) -> Self {
+ self.input_unit = input_unit.to_string();
+ self.with_input_classes()
}
pub fn cost_per_unit(mut self, cost_per_unit: impl ToString) -> Self {
@@ -57,10 +77,26 @@ impl RangeGroupV2 {
self
}
+ pub fn cost_frequency(mut self, cost_frequency: impl ToString) -> Self {
+ self.cost_frequency = cost_frequency.to_string();
+ self
+ }
+
pub fn action(mut self, action: StimulusAction) -> Self {
self.actions.push(action);
self
}
+
+ fn with_input_classes(mut self) -> Self {
+ if !self.input_unit.is_empty() {
+ self.input_classes
+ .insert("inputs-range-group-v-2-with-unit".to_string());
+ } else {
+ self.input_classes.remove("inputs-range-group-v-2-with-unit");
+ }
+
+ self
+ }
}
component!(RangeGroupV2);
diff --git a/pgml-dashboard/src/components/inputs/range_group_v_2/range_group_v_2.scss b/pgml-dashboard/src/components/inputs/range_group_v_2/range_group_v_2.scss
index 6cdb8e18d..ed9fa8ca6 100644
--- a/pgml-dashboard/src/components/inputs/range_group_v_2/range_group_v_2.scss
+++ b/pgml-dashboard/src/components/inputs/range_group_v_2/range_group_v_2.scss
@@ -5,11 +5,33 @@ div[data-controller="inputs-range-group-v-2"] {
}
input[type="text"] {
- padding-right: 30px;
+ &.inputs-range-group-v-2-with-unit {
+ padding-right: 0;
+ border-right: 0;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ }
}
- .inputs-range-group-v-2-unit {
- margin-left: -33px;
+ span.inputs-range-group-v-2-unit {
color: #{$gray-400};
+ background: #{$input-bg};
+ height: 100%;
+ padding: #{$input-padding-y} #{$input-padding-x};
+ border: #{$input-border-width} solid #{$input-border-color};
+
+ border-top-right-radius: var(--bs-border-radius);
+ border-bottom-right-radius: var(--bs-border-radius);
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ border-left: 0;
+ transition: #{$input-transition};
+
+ &.focused {
+ background: #{$input-focus-bg};
+ box-shadow: #{$input-focus-box-shadow};
+ border-color: #{$input-focus-border-color};
+ border-width: #{$input-border-width};
+ }
}
}
diff --git a/pgml-dashboard/src/components/inputs/range_group_v_2/range_group_v_2_controller.js b/pgml-dashboard/src/components/inputs/range_group_v_2/range_group_v_2_controller.js
index 6c454eee4..b87b5240f 100644
--- a/pgml-dashboard/src/components/inputs/range_group_v_2/range_group_v_2_controller.js
+++ b/pgml-dashboard/src/components/inputs/range_group_v_2/range_group_v_2_controller.js
@@ -1,7 +1,7 @@
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
- static targets = ["input", "range"];
+ static targets = ["input", "range", "unit"];
onInputInput(e) {
const value = parseInt(e.currentTarget.value);
@@ -14,6 +14,22 @@ export default class extends Controller {
}
}
+ onInputFocusIn(e) {
+ if (this.hasUnitTarget) {
+ this.unitTarget.classList.add("focused");
+ }
+ }
+
+ onInputBlur(e) {
+ if (this.hasUnitTarget) {
+ this.unitTarget.classList.remove("focused");
+ }
+ }
+
+ onUnitClick(e) {
+ this.inputTarget.focus();
+ }
+
onRangeInput(e) {
this.inputTarget.value = e.currentTarget.value;
}
diff --git a/pgml-dashboard/src/components/inputs/range_group_v_2/template.html b/pgml-dashboard/src/components/inputs/range_group_v_2/template.html
index c5a5ff47b..a3547087c 100644
--- a/pgml-dashboard/src/components/inputs/range_group_v_2/template.html
+++ b/pgml-dashboard/src/components/inputs/range_group_v_2/template.html
@@ -1,3 +1,9 @@
+ <%
+ use itertools::Itertools;
+
+ let input_classes = input_classes.into_iter().join(" ");
+%>
+
-
- <%= unit %>
+ <% if !input_unit.is_empty() { %>
+
+ <%= input_unit %>
+ <% } %>
@@ -34,7 +46,7 @@
$
- <%= cost_per_unit %>/hr
+ <%= cost_per_unit %>/<%= cost_frequency %>