feat: add publish info to template home page

This commit is contained in:
khorshuheng 2024-10-25 17:30:56 +08:00
parent 359d686b27
commit 3c0258b42a
3 changed files with 119 additions and 81 deletions

View File

@ -1329,41 +1329,11 @@ pub struct Template {
#[derive(Serialize, Deserialize, Debug)]
pub struct TemplateWithPublishInfo {
pub view_id: Uuid,
pub created_at: DateTime<Utc>,
pub last_updated_at: DateTime<Utc>,
pub name: String,
pub description: String,
pub about: String,
pub view_url: String,
pub categories: Vec<TemplateCategory>,
pub creator: TemplateCreator,
pub is_new_template: bool,
pub is_featured: bool,
pub related_templates: Vec<TemplateMinimal>,
#[serde(flatten)]
pub template: Template,
pub publish_info: PublishInfo,
}
impl From<(Template, PublishInfo)> for TemplateWithPublishInfo {
fn from((template, publish_info): (Template, PublishInfo)) -> Self {
Self {
view_id: template.view_id,
created_at: template.created_at,
last_updated_at: template.last_updated_at,
name: template.name,
description: template.description,
about: template.about,
view_url: template.view_url,
categories: template.categories,
creator: template.creator,
is_new_template: template.is_new_template,
is_featured: template.is_featured,
related_templates: template.related_templates,
publish_info,
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TemplateMinimal {
pub view_id: Uuid,
@ -1380,37 +1350,11 @@ pub struct TemplateMinimal {
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TemplateMinimalWithPublishInfo {
pub view_id: Uuid,
pub created_at: DateTime<Utc>,
pub last_updated_at: DateTime<Utc>,
pub name: String,
pub description: String,
pub view_url: String,
pub creator: TemplateCreatorMinimal,
pub categories: Vec<TemplateCategoryMinimal>,
pub is_new_template: bool,
pub is_featured: bool,
#[serde(flatten)]
pub template: TemplateMinimal,
pub publish_info: PublishInfo,
}
impl From<(TemplateMinimal, PublishInfo)> for TemplateMinimalWithPublishInfo {
fn from((template, publish_info): (TemplateMinimal, PublishInfo)) -> Self {
Self {
view_id: template.view_id,
created_at: template.created_at,
last_updated_at: template.last_updated_at,
name: template.name,
description: template.description,
view_url: template.view_url,
creator: template.creator,
categories: template.categories,
is_new_template: template.is_new_template,
is_featured: template.is_featured,
publish_info,
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Templates {
pub templates: Vec<TemplateMinimalWithPublishInfo>,
@ -1457,11 +1401,17 @@ pub struct TemplateGroup {
pub templates: Vec<TemplateMinimal>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct TemplateGroupWithPublishInfo {
pub category: TemplateCategoryMinimal,
pub templates: Vec<TemplateMinimalWithPublishInfo>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct TemplateHomePage {
pub featured_templates: Vec<TemplateMinimal>,
pub new_templates: Vec<TemplateMinimal>,
pub template_groups: Vec<TemplateGroup>,
pub featured_templates: Vec<TemplateMinimalWithPublishInfo>,
pub new_templates: Vec<TemplateMinimalWithPublishInfo>,
pub template_groups: Vec<TemplateGroupWithPublishInfo>,
}
#[derive(Serialize, Deserialize, Debug)]

View File

@ -1,4 +1,8 @@
use std::{collections::HashMap, ops::DerefMut, path::Path};
use std::{
collections::{HashMap, HashSet},
ops::DerefMut,
path::Path,
};
use actix_multipart::form::bytes::Bytes as MPBytes;
use anyhow::Context;
@ -11,7 +15,8 @@ use database::{
};
use database_entity::dto::{
AccountLink, PublishInfo, Template, TemplateCategory, TemplateCategoryType, TemplateCreator,
TemplateHomePage, TemplateMinimalWithPublishInfo, TemplateWithPublishInfo,
TemplateGroupWithPublishInfo, TemplateHomePage, TemplateMinimalWithPublishInfo,
TemplateWithPublishInfo,
};
use shared_entity::response::AppResponseError;
use sqlx::PgPool;
@ -257,7 +262,10 @@ pub async fn get_templates_with_publish_info(
.filter_map(|template| {
publish_info_map
.remove(&template.view_id)
.map(|pub_info| TemplateMinimalWithPublishInfo::from((template, pub_info)))
.map(|publish_info| TemplateMinimalWithPublishInfo {
template,
publish_info,
})
})
.collect();
if templates_with_publish_info.len() != view_ids.len() {
@ -274,9 +282,12 @@ pub async fn get_template_with_publish_info(
view_id: Uuid,
) -> Result<TemplateWithPublishInfo, AppResponseError> {
let template = select_template_view_by_id(pg_pool, view_id).await?;
let pub_info = select_published_collab_info(pg_pool, &view_id).await?;
let template_with_pub_info = TemplateWithPublishInfo::from((template, pub_info));
Ok(template_with_pub_info)
let publish_info = select_published_collab_info(pg_pool, &view_id).await?;
let template_with_publish_info = TemplateWithPublishInfo {
template,
publish_info,
};
Ok(template_with_publish_info)
}
pub async fn delete_template(pg_pool: &PgPool, view_id: Uuid) -> Result<(), AppResponseError> {
@ -296,10 +307,81 @@ pub async fn get_template_homepage(
select_templates(pg_pool, None, Some(true), None, None, Some(per_count)).await?;
let new_templates =
select_templates(pg_pool, None, None, Some(true), None, Some(per_count)).await?;
let template_groups_view_ids = template_groups
.iter()
.flat_map(|group| group.templates.iter().map(|t| t.view_id))
.collect::<HashSet<Uuid>>();
let feature_templates_view_ids = featured_templates
.iter()
.map(|t| t.view_id)
.collect::<HashSet<Uuid>>();
let new_templates_view_ids = new_templates
.iter()
.map(|t| t.view_id)
.collect::<HashSet<Uuid>>();
let mut all_view_ids: HashSet<Uuid> = HashSet::new();
all_view_ids.extend(&template_groups_view_ids);
all_view_ids.extend(&feature_templates_view_ids);
all_view_ids.extend(&new_templates_view_ids);
let all_view_ids: Vec<Uuid> = all_view_ids.into_iter().collect();
let publish_info_for_views: Vec<PublishInfo> =
select_published_collab_info_for_view_ids(pg_pool, &all_view_ids).await?;
let publish_info_map = publish_info_for_views
.into_iter()
.map(|info| (info.view_id, info))
.collect::<HashMap<Uuid, PublishInfo>>();
let template_groups_with_publish_info = template_groups
.into_iter()
.map(|group| {
let templates_with_publish_info = group
.templates
.into_iter()
.filter_map(|template| {
publish_info_map.get(&template.view_id).map(|publish_info| {
TemplateMinimalWithPublishInfo {
template,
publish_info: publish_info.clone(),
}
})
})
.collect();
TemplateGroupWithPublishInfo {
category: group.category.clone(),
templates: templates_with_publish_info,
}
})
.collect();
let featured_templates_with_publish_info = featured_templates
.into_iter()
.filter_map(|template| {
publish_info_map
.get(&template.view_id)
.map(|publish_info| TemplateMinimalWithPublishInfo {
template,
publish_info: publish_info.clone(),
})
})
.collect();
let new_templates_with_publish_info = new_templates
.into_iter()
.filter_map(|template| {
publish_info_map
.get(&template.view_id)
.map(|publish_info| TemplateMinimalWithPublishInfo {
template,
publish_info: publish_info.clone(),
})
})
.collect();
let homepage = TemplateHomePage {
template_groups,
featured_templates,
new_templates,
template_groups: template_groups_with_publish_info,
featured_templates: featured_templates_with_publish_info,
new_templates: new_templates_with_publish_info,
};
Ok(homepage)
}

View File

@ -357,7 +357,7 @@ async fn test_template_crud() {
.await
.unwrap()
.templates;
let view_ids: HashSet<Uuid> = templates.iter().map(|t| t.view_id).collect();
let view_ids: HashSet<Uuid> = templates.iter().map(|t| t.template.view_id).collect();
assert_eq!(templates.len(), 2);
assert!(view_ids.contains(&published_view_ids[2]));
assert!(view_ids.contains(&published_view_ids[3]));
@ -376,7 +376,10 @@ async fn test_template_crud() {
.await
.unwrap()
.templates;
let featured_view_ids: HashSet<Uuid> = featured_templates.iter().map(|t| t.view_id).collect();
let featured_view_ids: HashSet<Uuid> = featured_templates
.iter()
.map(|t| t.template.view_id)
.collect();
assert_eq!(featured_templates.len(), 2);
assert!(featured_view_ids.contains(&published_view_ids[0]));
assert!(featured_view_ids.contains(&published_view_ids[1]));
@ -386,7 +389,7 @@ async fn test_template_crud() {
.await
.unwrap()
.templates;
let new_view_ids: HashSet<Uuid> = new_templates.iter().map(|t| t.view_id).collect();
let new_view_ids: HashSet<Uuid> = new_templates.iter().map(|t| t.template.view_id).collect();
assert_eq!(new_templates.len(), 2);
assert!(new_view_ids.contains(&published_view_ids[0]));
assert!(new_view_ids.contains(&published_view_ids[2]));
@ -395,12 +398,15 @@ async fn test_template_crud() {
.get_template(published_view_ids[3])
.await
.unwrap();
assert_eq!(template.view_id, published_view_ids[3]);
assert_eq!(template.creator.id, creator_2.id);
assert_eq!(template.categories.len(), 1);
assert_eq!(template.categories[0].id, category_2.id);
assert_eq!(template.related_templates.len(), 1);
assert_eq!(template.related_templates[0].view_id, published_view_ids[0]);
assert_eq!(template.template.view_id, published_view_ids[3]);
assert_eq!(template.template.creator.id, creator_2.id);
assert_eq!(template.template.categories.len(), 1);
assert_eq!(template.template.categories[0].id, category_2.id);
assert_eq!(template.template.related_templates.len(), 1);
assert_eq!(
template.template.related_templates[0].view_id,
published_view_ids[0]
);
assert_eq!(
template.publish_info.namespace.unwrap(),
published_view_namespace.clone()