Skip to content

Commit 0842673

Browse files
Dan blog search (#1359)
1 parent 55890e1 commit 0842673

File tree

28 files changed

+569
-202
lines changed

28 files changed

+569
-202
lines changed

pgml-dashboard/src/api/cms.rs

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ use crate::{
2121
use serde::{Deserialize, Serialize};
2222
use std::fmt;
2323

24+
use crate::components::cards::blog::article_preview;
25+
use sailfish::TemplateOnce;
26+
2427
lazy_static! {
2528
pub static ref BLOG: Collection = Collection::new(
2629
"Blog",
@@ -120,6 +123,25 @@ impl Document {
120123
Document { ..Default::default() }
121124
}
122125

126+
// make a document from a uri of form <blog || docs || careers>/< path and file name >
127+
pub async fn from_url(url: &str) -> anyhow::Result<Document, std::io::Error> {
128+
let doc_type = match url.split('/').collect::<Vec<&str>>().get(1) {
129+
Some(&"blog") => Some(DocType::Blog),
130+
Some(&"docs") => Some(DocType::Docs),
131+
Some(&"careers") => Some(DocType::Careers),
132+
_ => None,
133+
};
134+
135+
let path = match doc_type {
136+
Some(DocType::Blog) => BLOG.url_to_path(url),
137+
Some(DocType::Docs) => DOCS.url_to_path(url),
138+
Some(DocType::Careers) => CAREERS.url_to_path(url),
139+
_ => PathBuf::new(),
140+
};
141+
142+
Document::from_path(&path).await
143+
}
144+
123145
pub async fn from_path(path: &PathBuf) -> anyhow::Result<Document, std::io::Error> {
124146
let doc_type = match path.strip_prefix(config::cms_dir()) {
125147
Ok(path) => match path.into_iter().next() {
@@ -673,6 +695,49 @@ async fn search(query: &str, site_search: &State<crate::utils::markdown::SiteSea
673695
)
674696
}
675697

698+
#[get("/search_blog?<query>&<tag>", rank = 20)]
699+
async fn search_blog(query: &str, tag: &str, site_search: &State<crate::utils::markdown::SiteSearch>) -> ResponseOk {
700+
let tag = if tag.len() > 0 {
701+
Some(Vec::from([tag.to_string()]))
702+
} else {
703+
None
704+
};
705+
706+
// If user is not making a search return all blogs in default design.
707+
let results = if query.len() > 0 || tag.clone().is_some() {
708+
let results = site_search.search(query, Some(DocType::Blog), tag.clone()).await;
709+
710+
let results = match results {
711+
Ok(results) => results
712+
.into_iter()
713+
.map(|document| article_preview::DocMeta::from_document(document))
714+
.collect::<Vec<article_preview::DocMeta>>(),
715+
Err(_) => Vec::new(),
716+
};
717+
718+
results
719+
} else {
720+
let mut results = Vec::new();
721+
722+
for url in BLOG.get_all_urls() {
723+
let doc = Document::from_url(&url).await.unwrap();
724+
725+
results.push(article_preview::DocMeta::from_document(doc));
726+
}
727+
728+
results
729+
};
730+
731+
let is_search = query.len() > 0 || tag.is_some();
732+
733+
ResponseOk(
734+
crate::components::pages::blog::blog_search::Response::new()
735+
.pattern(results, is_search)
736+
.render_once()
737+
.unwrap(),
738+
)
739+
}
740+
676741
#[get("/blog/.gitbook/assets/<path>", rank = 10)]
677742
pub async fn get_blog_asset(path: &str) -> Option<NamedFile> {
678743
BLOG.get_asset(path).await
@@ -751,13 +816,25 @@ async fn blog_landing_page(cluster: &Cluster) -> Result<ResponseOk, crate::respo
751816
.theme(Theme::Docs)
752817
.footer(cluster.context.marketing_footer.to_string());
753818

754-
Ok(ResponseOk(
755-
layout.render(
756-
crate::components::pages::blog::LandingPage::new(cluster)
757-
.index(&BLOG)
758-
.await,
759-
),
760-
))
819+
let mut index = Vec::new();
820+
821+
let urls = BLOG.get_all_urls();
822+
823+
for url in urls {
824+
let doc = Document::from_url(&url).await.unwrap();
825+
let meta = article_preview::DocMeta::from_document(doc);
826+
index.push(meta)
827+
}
828+
829+
let featured_cards = index
830+
.clone()
831+
.into_iter()
832+
.filter(|x| x.featured)
833+
.collect::<Vec<article_preview::DocMeta>>();
834+
835+
Ok(ResponseOk(layout.render(
836+
crate::components::pages::blog::LandingPage::new(cluster).featured_cards(featured_cards),
837+
)))
761838
}
762839

763840
#[get("/docs")]
@@ -806,7 +883,8 @@ pub fn routes() -> Vec<Route> {
806883
get_docs,
807884
get_docs_asset,
808885
get_user_guides,
809-
search
886+
search,
887+
search_blog
810888
]
811889
}
812890

@@ -880,8 +958,9 @@ This is the end of the markdown
880958

881959
async fn rocket() -> Rocket<Build> {
882960
dotenv::dotenv().ok();
961+
883962
rocket::build()
884-
// .manage(crate::utils::markdown::SearchIndex::open().unwrap())
963+
// .manage(crate::utils::markdown::SiteSearch::new().await.expect("Error initializing site search"))
885964
.mount("/", crate::api::cms::routes())
886965
}
887966

pgml-dashboard/src/components/cards/blog/article_preview/article_preview_controller.js

Lines changed: 0 additions & 12 deletions
This file was deleted.

pgml-dashboard/src/components/cards/blog/article_preview/mod.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,22 @@ pub struct DocMeta {
1717
pub path: String,
1818
}
1919

20+
impl DocMeta {
21+
pub fn from_document(doc: Document) -> DocMeta {
22+
DocMeta {
23+
description: doc.description,
24+
author: doc.author,
25+
author_image: doc.author_image,
26+
featured: doc.featured,
27+
date: doc.date,
28+
tags: doc.tags,
29+
image: doc.image,
30+
title: doc.title,
31+
path: doc.url,
32+
}
33+
}
34+
}
35+
2036
#[derive(TemplateOnce)]
2137
#[template(path = "cards/blog/article_preview/template.html")]
2238
pub struct ArticlePreview {
@@ -59,18 +75,7 @@ impl ArticlePreview {
5975

6076
pub async fn from_path(path: &str) -> ArticlePreview {
6177
let doc = Document::from_path(&PathBuf::from(path)).await.unwrap();
62-
63-
let meta = DocMeta {
64-
description: doc.description,
65-
author: doc.author,
66-
author_image: doc.author_image,
67-
featured: false,
68-
date: doc.date,
69-
tags: doc.tags,
70-
image: doc.image,
71-
title: doc.title,
72-
path: doc.url,
73-
};
78+
let meta = DocMeta::from_document(doc);
7479
ArticlePreview::new(&meta)
7580
}
7681
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
div {
2+
@mixin loading-dot($delay, $initial) {
3+
width: 30px;
4+
height: 30px;
5+
opacity: $initial;
6+
border-radius: 30px;
7+
background-color: #{$gray-100};
8+
animation: opacity 3s infinite linear;
9+
animation-delay: $delay;
10+
}
11+
12+
.loading-dot-1 {
13+
@include loading-dot(0s, 0.1);
14+
}
15+
16+
.loading-dot-2 {
17+
@include loading-dot(0.5s, 0.2);
18+
}
19+
20+
.loading-dot-3 {
21+
@include loading-dot(1s, 0.3);
22+
}
23+
24+
@keyframes opacity {
25+
0% {
26+
opacity: 0.1;
27+
}
28+
29+
75% {
30+
opacity: 1;
31+
}
32+
33+
100% {
34+
opacity: 0.1;
35+
}
36+
}
37+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use pgml_components::component;
2+
use sailfish::TemplateOnce;
3+
4+
#[derive(TemplateOnce, Default)]
5+
#[template(path = "loading/dots/template.html")]
6+
pub struct Dots {}
7+
8+
impl Dots {
9+
pub fn new() -> Dots {
10+
Dots {}
11+
}
12+
}
13+
14+
component!(Dots);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<div class="d-flex flex-row gap-3">
2+
<div class="loading-dot-1">
3+
</div>
4+
<div class="loading-dot-2">
5+
</div>
6+
<div class="loading-dot-3">
7+
</div>
8+
</div>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
div[data-controller="loading-message"] {}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use sailfish::TemplateOnce;
2+
use pgml_components::component;
3+
4+
#[derive(TemplateOnce, Default)]
5+
#[template(path = "loading/message/template.html")]
6+
pub struct Message {
7+
message: String,
8+
}
9+
10+
impl Message {
11+
pub fn new() -> Message {
12+
Message {
13+
message: String::from("Loading..."),
14+
}
15+
}
16+
17+
pub fn message(mut self, message: &str) -> Message {
18+
self.message = String::from(message);
19+
self
20+
}
21+
}
22+
23+
component!(Message);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<% use crate::components::loading::Dots; %>
2+
<div class="d-flex flex-column justify-content-center align-items-center w-100 gap-3">
3+
<%+ Dots::new() %>
4+
<h6 class="fw-semibold"><%- message %></h6>
5+
</div>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// This file is automatically generated.
2+
// You shouldn't modify it manually.
3+
4+
// src/components/loading/dots
5+
pub mod dots;
6+
pub use dots::Dots;
7+
8+
// src/components/loading/message
9+
pub mod message;
10+
pub use message::Message;

0 commit comments

Comments
 (0)