Skip to content

Commit

Permalink
Merge pull request #921 from AppFlowy-IO/list-templates-publish-info
Browse files Browse the repository at this point in the history
feat: add publish info to list templates
  • Loading branch information
khorshuheng authored Oct 23, 2024
2 parents 30ff066 + 23e1da2 commit 1e7a0ab
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 21 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 44 additions & 11 deletions libs/database-entity/src/dto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1344,22 +1344,22 @@ pub struct TemplateWithPublishInfo {
pub publish_info: PublishInfo,
}

impl TemplateWithPublishInfo {
pub fn from_template_and_publish_info(template: &Template, publish_info: &PublishInfo) -> Self {
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.clone(),
description: template.description.clone(),
about: template.about.clone(),
view_url: template.view_url.clone(),
categories: template.categories.clone(),
creator: template.creator.clone(),
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.clone(),
publish_info: publish_info.clone(),
related_templates: template.related_templates,
publish_info,
}
}
}
Expand All @@ -1378,9 +1378,42 @@ pub struct TemplateMinimal {
pub is_featured: bool,
}

#[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,
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<TemplateMinimal>,
pub templates: Vec<TemplateMinimalWithPublishInfo>,
}

#[derive(Serialize, Deserialize, Debug)]
Expand Down
26 changes: 26 additions & 0 deletions libs/database/src/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,32 @@ pub async fn select_default_published_view_id<'a, E: Executor<'a, Database = Pos
Ok(res)
}

pub async fn select_published_collab_info_for_view_ids<'a, E: Executor<'a, Database = Postgres>>(
executor: E,
view_ids: &[Uuid],
) -> Result<Vec<PublishInfo>, AppError> {
let res = sqlx::query_as!(
PublishInfo,
r#"
SELECT
aw.publish_namespace AS namespace,
apc.publish_name,
apc.view_id,
au.email AS publisher_email,
apc.created_at AS publish_timestamp
FROM af_published_collab apc
JOIN af_user au ON apc.published_by = au.uid
JOIN af_workspace aw ON apc.workspace_id = aw.workspace_id
WHERE apc.view_id = ANY($1);
"#,
view_ids,
)
.fetch_all(executor)
.await?;

Ok(res)
}

pub async fn select_published_collab_info<'a, E: Executor<'a, Database = Postgres>>(
executor: E,
view_id: &Uuid,
Expand Down
2 changes: 1 addition & 1 deletion src/api/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ async fn list_templates_handler(
state: Data<AppState>,
) -> Result<JsonAppResponse<Templates>> {
let data = data.into_inner();
let template_summary_list = get_templates(
let template_summary_list = get_templates_with_publish_info(
&state.pg_pool,
data.category_id,
data.is_featured,
Expand Down
38 changes: 29 additions & 9 deletions src/biz/template/ops.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use std::{ops::DerefMut, path::Path};
use std::{collections::HashMap, ops::DerefMut, path::Path};

use actix_multipart::form::bytes::Bytes as MPBytes;
use anyhow::Context;
use app_error::ErrorCode;
use aws_sdk_s3::primitives::ByteStream;
use database::{
file::{s3_client_impl::AwsS3BucketClientImpl, BucketClient, ResponseBlob},
publish::select_published_collab_info,
publish::{select_published_collab_info, select_published_collab_info_for_view_ids},
template::*,
};
use database_entity::dto::{
AccountLink, Template, TemplateCategory, TemplateCategoryType, TemplateCreator, TemplateHomePage,
TemplateMinimal, TemplateWithPublishInfo,
AccountLink, PublishInfo, Template, TemplateCategory, TemplateCategoryType, TemplateCreator,
TemplateHomePage, TemplateMinimalWithPublishInfo, TemplateWithPublishInfo,
};
use shared_entity::response::AppResponseError;
use sqlx::PgPool;
Expand Down Expand Up @@ -229,13 +229,13 @@ pub async fn update_template(
Ok(updated_template)
}

pub async fn get_templates(
pub async fn get_templates_with_publish_info(
pg_pool: &PgPool,
category_id: Option<Uuid>,
is_featured: Option<bool>,
is_new_template: Option<bool>,
name_contains: Option<&str>,
) -> Result<Vec<TemplateMinimal>, AppResponseError> {
) -> Result<Vec<TemplateMinimalWithPublishInfo>, AppResponseError> {
let templates = select_templates(
pg_pool,
category_id,
Expand All @@ -245,7 +245,28 @@ pub async fn get_templates(
None,
)
.await?;
Ok(templates)
let view_ids = templates.iter().map(|t| t.view_id).collect::<Vec<Uuid>>();
let publish_info_for_views =
select_published_collab_info_for_view_ids(pg_pool, &view_ids).await?;
let mut publish_info_map = publish_info_for_views
.into_iter()
.map(|info| (info.view_id, info))
.collect::<HashMap<Uuid, PublishInfo>>();
let templates_with_publish_info: Vec<TemplateMinimalWithPublishInfo> = templates
.into_iter()
.filter_map(|template| {
publish_info_map
.remove(&template.view_id)
.map(|pub_info| TemplateMinimalWithPublishInfo::from((template, pub_info)))
})
.collect();
if templates_with_publish_info.len() != view_ids.len() {
return Err(AppResponseError::new(
ErrorCode::Internal,
"one or more templates does not have a publish info",
));
}
Ok(templates_with_publish_info)
}

pub async fn get_template_with_publish_info(
Expand All @@ -254,8 +275,7 @@ pub async fn get_template_with_publish_info(
) -> 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_and_publish_info(&template, &pub_info);
let template_with_pub_info = TemplateWithPublishInfo::from((template, pub_info));
Ok(template_with_pub_info)
}

Expand Down
9 changes: 9 additions & 0 deletions tests/workspace/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,15 @@ async fn test_template_crud() {
assert_eq!(templates.len(), 2);
assert!(view_ids.contains(&published_view_ids[2]));
assert!(view_ids.contains(&published_view_ids[3]));
assert_eq!(
templates[0]
.publish_info
.namespace
.as_ref()
.unwrap()
.to_string(),
published_view_namespace.clone()
);

let featured_templates = guest_client
.get_templates(None, Some(true), None, Some(template_name_prefix.clone()))
Expand Down

0 comments on commit 1e7a0ab

Please sign in to comment.