Skip to content

Commit 46acfb0

Browse files
Dan google tag manager (#1654)
1 parent a6a60f9 commit 46acfb0

File tree

19 files changed

+161
-110
lines changed

19 files changed

+161
-110
lines changed

pgml-dashboard/src/api/deployment/deployment_models.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::{
77
responses::{Error, ResponseOk},
88
};
99

10+
use crate::components::layouts::product::Index as Product;
1011
use crate::templates::{components::NavLink, *};
1112

1213
use crate::models;
@@ -19,7 +20,7 @@ use std::collections::HashMap;
1920
// Returns models page
2021
#[get("/models")]
2122
pub async fn deployment_models(cluster: &Cluster, _connected: ConnectedCluster<'_>) -> Result<ResponseOk, Error> {
22-
let mut layout = crate::templates::WebAppBase::new("Dashboard", &cluster);
23+
let mut layout = Product::new("Dashboard", &cluster);
2324
layout.breadcrumbs(vec![NavLink::new("Models", &urls::deployment_models()).active()]);
2425

2526
let tabs = vec![tabs::Tab {
@@ -38,7 +39,7 @@ pub async fn model(cluster: &Cluster, model_id: i64, _connected: ConnectedCluste
3839
let model = models::Model::get_by_id(cluster.pool(), model_id).await?;
3940
let project = models::Project::get_by_id(cluster.pool(), model.project_id).await?;
4041

41-
let mut layout = crate::templates::WebAppBase::new("Dashboard", &cluster);
42+
let mut layout = Product::new("Dashboard", &cluster);
4243
layout.breadcrumbs(vec![
4344
NavLink::new("Models", &urls::deployment_models()),
4445
NavLink::new(&project.name, &urls::deployment_project_by_id(project.id)),

pgml-dashboard/src/api/deployment/notebooks.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::{
1111
responses::{Error, ResponseOk},
1212
};
1313

14+
use crate::components::layouts::product::Index as Product;
1415
use crate::templates::{components::NavLink, *};
1516
use crate::utils::tabs;
1617

@@ -21,7 +22,7 @@ use crate::utils::urls;
2122
// Returns notebook page
2223
#[get("/notebooks")]
2324
pub async fn notebooks(cluster: &Cluster, _connected: ConnectedCluster<'_>) -> Result<ResponseOk, Error> {
24-
let mut layout = crate::templates::WebAppBase::new("Dashboard", &cluster);
25+
let mut layout = Product::new("Dashboard", &cluster);
2526
layout.breadcrumbs(vec![NavLink::new("Notebooks", &urls::deployment_notebooks()).active()]);
2627

2728
let tabs = vec![tabs::Tab {
@@ -43,7 +44,7 @@ pub async fn notebook(
4344
) -> Result<ResponseOk, Error> {
4445
let notebook = models::Notebook::get_by_id(cluster.pool(), notebook_id).await?;
4546

46-
let mut layout = crate::templates::WebAppBase::new("Dashboard", &cluster);
47+
let mut layout = Product::new("Dashboard", &cluster);
4748
layout.breadcrumbs(vec![
4849
NavLink::new("Notebooks", &urls::deployment_notebooks()),
4950
NavLink::new(notebook.name.as_str(), &urls::deployment_notebook_by_id(notebook_id)).active(),

pgml-dashboard/src/api/deployment/projects.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::{
77
responses::{Error, ResponseOk},
88
};
99

10+
use crate::components::layouts::product::Index as Product;
1011
use crate::templates::{components::NavLink, *};
1112

1213
use crate::models;
@@ -17,7 +18,7 @@ use crate::utils::urls;
1718
// Returns the deployments projects page.
1819
#[get("/projects")]
1920
pub async fn projects(cluster: &Cluster, _connected: ConnectedCluster<'_>) -> Result<ResponseOk, Error> {
20-
let mut layout = crate::templates::WebAppBase::new("Dashboard", &cluster);
21+
let mut layout = Product::new("Dashboard", &cluster);
2122
layout.breadcrumbs(vec![NavLink::new("Projects", &urls::deployment_projects()).active()]);
2223

2324
let tabs = vec![tabs::Tab {
@@ -39,7 +40,7 @@ pub async fn project(
3940
) -> Result<ResponseOk, Error> {
4041
let project = models::Project::get_by_id(cluster.pool(), project_id).await?;
4142

42-
let mut layout = crate::templates::WebAppBase::new("Dashboard", &cluster);
43+
let mut layout = Product::new("Dashboard", &cluster);
4344
layout.breadcrumbs(vec![
4445
NavLink::new("Projects", &urls::deployment_projects()),
4546
NavLink::new(project.name.as_str(), &urls::deployment_project_by_id(project_id)).active(),

pgml-dashboard/src/api/deployment/snapshots.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::{
77
responses::{Error, ResponseOk},
88
};
99

10+
use crate::components::layouts::product::Index as Product;
1011
use crate::templates::{components::NavLink, *};
1112

1213
use crate::models;
@@ -18,7 +19,7 @@ use std::collections::HashMap;
1819
// Returns snapshots page
1920
#[get("/snapshots")]
2021
pub async fn snapshots(cluster: &Cluster, _connected: ConnectedCluster<'_>) -> Result<ResponseOk, Error> {
21-
let mut layout = crate::templates::WebAppBase::new("Dashboard", &cluster);
22+
let mut layout = Product::new("Dashboard", &cluster);
2223
layout.breadcrumbs(vec![NavLink::new("Snapshots", &urls::deployment_snapshots()).active()]);
2324

2425
let tabs = vec![tabs::Tab {
@@ -40,7 +41,7 @@ pub async fn snapshot(
4041
) -> Result<ResponseOk, Error> {
4142
let snapshot = models::Snapshot::get_by_id(cluster.pool(), snapshot_id).await?;
4243

43-
let mut layout = crate::templates::WebAppBase::new("Dashboard", &cluster);
44+
let mut layout = Product::new("Dashboard", &cluster);
4445
layout.breadcrumbs(vec![
4546
NavLink::new("Snapshots", &urls::deployment_snapshots()),
4647
NavLink::new(&snapshot.relation_name, &urls::deployment_snapshot_by_id(snapshot.id)).active(),

pgml-dashboard/src/api/deployment/uploader.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rocket::response::Redirect;
44
use rocket::route::Route;
55
use sailfish::TemplateOnce;
66

7+
use crate::components::layouts::product::Index as Product;
78
use crate::{
89
guards::Cluster,
910
guards::ConnectedCluster,
@@ -20,7 +21,7 @@ use crate::utils::urls;
2021
// Returns the uploader page.
2122
#[get("/uploader")]
2223
pub async fn uploader(cluster: &Cluster, _connected: ConnectedCluster<'_>) -> Result<ResponseOk, Error> {
23-
let mut layout = crate::templates::WebAppBase::new("Dashboard", &cluster);
24+
let mut layout = Product::new("Dashboard", &cluster);
2425
layout.breadcrumbs(vec![NavLink::new("Upload Data", &urls::deployment_uploader()).active()]);
2526

2627
let tabs = vec![tabs::Tab {

pgml-dashboard/src/components/layouts/docs/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::components::cms::IndexLink;
22
use crate::components::layouts::Head;
33
use crate::guards::Cluster;
44
use crate::models::User;
5-
use pgml_components::component;
5+
use pgml_components::{component, Component};
66
use sailfish::TemplateOnce;
77

88
#[derive(TemplateOnce, Default, Clone)]
@@ -13,23 +13,26 @@ pub struct Docs {
1313
user: Option<User>,
1414
content: Option<String>,
1515
index: Vec<IndexLink>,
16+
body_components: Vec<Component>,
1617
}
1718

1819
impl Docs {
1920
pub fn new(title: &str, context: Option<&Cluster>) -> Docs {
20-
let (head, footer, user) = match context.as_ref() {
21+
let (head, footer, user, body_components) = match context.as_ref() {
2122
Some(context) => (
2223
Head::new().title(&title).context(&context.context.head_items),
2324
Some(context.context.marketing_footer.clone()),
2425
Some(context.context.user.clone()),
26+
context.context.body_components.clone(),
2527
),
26-
None => (Head::new().title(&title), None, None),
28+
None => (Head::new().title(&title), None, None, Vec::new()),
2729
};
2830

2931
Docs {
3032
head,
3133
footer,
3234
user,
35+
body_components,
3336
..Default::default()
3437
}
3538
}

pgml-dashboard/src/components/layouts/docs/template.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
<html lang="en-US">
88
<%+ head %>
99
<body data-bs-theme="dark" data-theme="docs">
10+
<% for component in body_components {%>
11+
<%+ component %>
12+
<% } %>
1013
<div class="border-bottom" data-controller="layouts-docs">
1114
<%+ MarketingNavbar::new(user).style_alt() %>
1215

pgml-dashboard/src/components/layouts/marketing/base/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::components::notifications::marketing::AlertBanner;
33
use crate::guards::Cluster;
44
use crate::models::User;
55
use crate::Notification;
6-
use pgml_components::component;
6+
use pgml_components::{component, Component};
77
use sailfish::TemplateOnce;
88
use std::fmt;
99

@@ -35,19 +35,21 @@ pub struct Base {
3535
pub user: Option<User>,
3636
pub theme: Theme,
3737
pub no_transparent_nav: bool,
38+
pub body_components: Vec<Component>,
3839
}
3940

4041
impl Base {
4142
pub fn new(title: &str, context: Option<&Cluster>) -> Base {
4243
let title = format!("{} - PostgresML", title);
4344

44-
let (head, footer, user) = match context.as_ref() {
45+
let (head, footer, user, body_components) = match context.as_ref() {
4546
Some(context) => (
4647
Head::new().title(&title).context(&context.context.head_items),
4748
Some(context.context.marketing_footer.clone()),
4849
Some(context.context.user.clone()),
50+
context.context.body_components.clone(),
4951
),
50-
None => (Head::new().title(&title), None, None),
52+
None => (Head::new().title(&title), None, None, Vec::new()),
5153
};
5254

5355
Base {
@@ -56,6 +58,7 @@ impl Base {
5658
alert_banner: AlertBanner::from_notification(Notification::next_alert(context)),
5759
user,
5860
no_transparent_nav: false,
61+
body_components,
5962
..Default::default()
6063
}
6164
}

pgml-dashboard/src/components/layouts/marketing/base/template.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
behavior: 'instant'
1414
});
1515
</script>
16+
<!-- global items (scripts, no rendering items) that need to be placed in body. -->
17+
<% for component in body_components {%>
18+
<%+ component %>
19+
<% } %>
1620
<main>
1721
<%+ alert_banner %>
1822

pgml-dashboard/src/components/layouts/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ pub use head::Head;
1111

1212
// src/components/layouts/marketing
1313
pub mod marketing;
14+
15+
// src/components/layouts/product
16+
pub mod product;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
div[data-controller="layouts-product-index"] {}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
use pgml_components::component;
2+
use sailfish::TemplateOnce;
3+
4+
use pgml_components::Component;
5+
6+
pub use crate::components::{self, cms::index_link::IndexLink, NavLink, StaticNav, StaticNavLink};
7+
use crate::{Notification, NotificationLevel};
8+
use components::notifications::product::ProductBanner;
9+
10+
use crate::components::layouts::Head;
11+
use crate::models::Cluster;
12+
13+
#[derive(TemplateOnce, Default, Clone)]
14+
#[template(path = "layouts/product/index/template.html")]
15+
pub struct Index<'a> {
16+
pub content: Option<String>,
17+
pub breadcrumbs: Vec<NavLink<'a>>,
18+
pub head: Head,
19+
pub dropdown_nav: StaticNav,
20+
pub product_left_nav: StaticNav,
21+
pub body_components: Vec<Component>,
22+
pub cluster: Cluster,
23+
pub product_banners_high: Vec<ProductBanner>,
24+
pub product_banner_medium: ProductBanner,
25+
pub product_banner_marketing: ProductBanner,
26+
}
27+
28+
impl<'a> Index<'a> {
29+
pub fn new(title: &str, context: &crate::guards::Cluster) -> Self {
30+
let head = Head::new().title(title).context(&context.context.head_items);
31+
let cluster = context.context.cluster.clone();
32+
33+
let all_product_high_level = context
34+
.notifications
35+
.clone()
36+
.unwrap_or_else(|| vec![])
37+
.into_iter()
38+
.filter(|n: &Notification| n.level == NotificationLevel::ProductHigh)
39+
.enumerate()
40+
.map(|(i, n)| ProductBanner::from_notification(Some(&n)).set_show_modal_on_load(i == 0))
41+
.collect::<Vec<ProductBanner>>();
42+
43+
Index {
44+
head,
45+
cluster,
46+
dropdown_nav: context.context.dropdown_nav.clone(),
47+
product_left_nav: context.context.product_left_nav.clone(),
48+
product_banners_high: all_product_high_level,
49+
product_banner_medium: ProductBanner::from_notification(Notification::next_product_of_level(
50+
context,
51+
NotificationLevel::ProductMedium,
52+
)),
53+
product_banner_marketing: ProductBanner::from_notification(Notification::next_product_of_level(
54+
context,
55+
NotificationLevel::ProductMarketing,
56+
)),
57+
body_components: context.context.body_components.clone(),
58+
..Default::default()
59+
}
60+
}
61+
62+
pub fn breadcrumbs(&mut self, breadcrumbs: Vec<NavLink<'a>>) -> &mut Self {
63+
self.breadcrumbs = breadcrumbs.to_owned();
64+
self
65+
}
66+
67+
pub fn disable_upper_nav(&mut self) -> &mut Self {
68+
let links: Vec<StaticNavLink> = self
69+
.product_left_nav
70+
.links
71+
.iter()
72+
.map(|item| item.to_owned().disabled(true))
73+
.collect();
74+
self.product_left_nav = StaticNav { links };
75+
self
76+
}
77+
78+
pub fn content(&mut self, content: &str) -> &mut Self {
79+
self.content = Some(content.to_owned());
80+
self
81+
}
82+
83+
pub fn body_components(&mut self, components: Vec<Component>) -> &mut Self {
84+
self.body_components.extend(components);
85+
self
86+
}
87+
88+
pub fn render<T>(&mut self, template: T) -> String
89+
where
90+
T: sailfish::TemplateOnce,
91+
{
92+
self.content = Some(template.render_once().unwrap());
93+
(*self).clone().into()
94+
}
95+
}
96+
97+
impl<'a> From<Index<'a>> for String {
98+
fn from(layout: Index) -> String {
99+
layout.render_once().unwrap()
100+
}
101+
}
102+
103+
component!(Index, 'a);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// This file is automatically generated.
2+
// You shouldn't modify it manually.
3+
4+
// src/components/layouts/product/index
5+
pub mod index;
6+
pub use index::Index;

pgml-dashboard/src/guards.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ impl Cluster {
6262
},
6363
marketing_footer: MarketingFooter::new().render_once().unwrap(),
6464
head_items: None,
65+
body_components: Vec::new(),
6566
},
6667
notifications: None,
6768
}

pgml-dashboard/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@ use guards::Cluster;
2626
use responses::{Error, Response, ResponseOk};
2727
use templates::{components::StaticNav, *};
2828

29+
use crate::components::layouts::product::Index as Product;
2930
use crate::components::tables::serverless_models::{ServerlessModels, ServerlessModelsTurbo};
3031
use crate::components::tables::serverless_pricing::{ServerlessPricing, ServerlessPricingTurbo};
3132
use crate::utils::cookies::{NotificationCookie, Notifications};
3233
use crate::utils::urls;
3334
use chrono;
35+
use pgml_components::Component;
3436
use std::collections::hash_map::DefaultHasher;
3537
use std::hash::{Hash, Hasher};
3638

@@ -53,6 +55,7 @@ pub struct Context {
5355
pub product_left_nav: StaticNav,
5456
pub marketing_footer: String,
5557
pub head_items: Option<String>,
58+
pub body_components: Vec<Component>,
5659
}
5760

5861
#[derive(Debug, Clone, Default)]
@@ -323,7 +326,7 @@ pub async fn dashboard(tab: Option<&str>, id: Option<i64>) -> Redirect {
323326

324327
#[get("/playground")]
325328
pub async fn playground(cluster: &Cluster) -> Result<ResponseOk, Error> {
326-
let mut layout = crate::templates::WebAppBase::new("Playground", &cluster);
329+
let mut layout = Product::new("Playground", &cluster);
327330
Ok(ResponseOk(layout.render(templates::Playground {})))
328331
}
329332

0 commit comments

Comments
 (0)