Skip to content

Commit

Permalink
feat: add publish info to publish outline items (#1156)
Browse files Browse the repository at this point in the history
  • Loading branch information
khorshuheng authored Jan 12, 2025
1 parent 505b4ca commit a5d94a0
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 14 deletions.
1 change: 1 addition & 0 deletions .github/workflows/integration_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ jobs:
- name: Build Docker Images
run: |
export DOCKER_DEFAULT_PLATFORM=linux/amd64
cp deploy.env .env
docker compose build appflowy_cloud appflowy_worker admin_frontend
- name: Push docker images to docker hub
Expand Down

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

7 changes: 7 additions & 0 deletions libs/database/src/pg_row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -686,3 +686,10 @@ impl From<AFQuickNoteRow> for QuickNote {
}
}
}

pub struct AFPublishViewWithPublishInfo {
pub view_id: Uuid,
pub publish_name: String,
pub publisher_email: String,
pub publish_timestamp: DateTime<Utc>,
}
30 changes: 30 additions & 0 deletions libs/database/src/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use database_entity::dto::{
use sqlx::{Executor, PgPool, Postgres};
use uuid::Uuid;

use crate::pg_row::AFPublishViewWithPublishInfo;

pub async fn select_user_is_collab_publisher_for_all_views(
pg_pool: &PgPool,
user_uuid: &Uuid,
Expand Down Expand Up @@ -678,3 +680,31 @@ pub async fn select_published_view_ids_for_workspace<'a, E: Executor<'a, Databas

Ok(res)
}

pub async fn select_published_view_ids_with_publish_info_for_workspace<
'a,
E: Executor<'a, Database = Postgres>,
>(
executor: E,
workspace_id: Uuid,
) -> Result<Vec<AFPublishViewWithPublishInfo>, AppError> {
let res = sqlx::query_as!(
AFPublishViewWithPublishInfo,
r#"
SELECT
apc.view_id,
apc.publish_name,
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
WHERE workspace_id = $1
AND unpublished_at IS NULL
"#,
workspace_id,
)
.fetch_all(executor)
.await?;

Ok(res)
}
9 changes: 9 additions & 0 deletions libs/shared-entity/src/dto/workspace_dto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,11 +389,20 @@ pub struct PublishedView {
pub icon: Option<ViewIcon>,
pub layout: ViewLayout,
pub is_published: bool,
#[serde(flatten)]
pub info: Option<PublishedViewInfo>,
/// contains fields like `is_space`, and font information
pub extra: Option<serde_json::Value>,
pub children: Vec<PublishedView>,
}

#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct PublishedViewInfo {
pub publisher_email: String,
pub publish_name: String,
pub publish_timestamp: DateTime<Utc>,
}

#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct AFDatabase {
pub id: String,
Expand Down
31 changes: 24 additions & 7 deletions src/biz/collab/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use database::collab::select_last_updated_database_row_ids;
use database::collab::select_workspace_database_oid;
use database::collab::{CollabStorage, GetCollabOrigin};
use database::publish::select_published_view_ids_for_workspace;
use database::publish::select_published_view_ids_with_publish_info_for_workspace;
use database::publish::select_workspace_id_for_publish_namespace;
use database_entity::dto::QueryCollab;
use database_entity::dto::QueryCollabResult;
Expand All @@ -46,6 +47,7 @@ use shared_entity::dto::workspace_dto::AFInsertDatabaseField;
use shared_entity::dto::workspace_dto::DatabaseRowUpdatedItem;
use shared_entity::dto::workspace_dto::FavoriteFolderView;
use shared_entity::dto::workspace_dto::FolderViewMinimal;
use shared_entity::dto::workspace_dto::PublishedViewInfo;
use shared_entity::dto::workspace_dto::RecentFolderView;
use shared_entity::dto::workspace_dto::TrashFolderView;
use sqlx::PgPool;
Expand Down Expand Up @@ -457,13 +459,28 @@ pub async fn get_published_view(
&workspace_id.to_string(),
)
.await?;
let publish_view_ids = select_published_view_ids_for_workspace(pg_pool, workspace_id).await?;
let publish_view_ids: HashSet<String> = publish_view_ids
.into_iter()
.map(|id| id.to_string())
.collect();
let published_view: PublishedView =
collab_folder_to_published_outline(&workspace_id.to_string(), &folder, &publish_view_ids)?;
let publish_view_ids_with_publish_info =
select_published_view_ids_with_publish_info_for_workspace(pg_pool, workspace_id).await?;
let publish_view_id_to_info_map: HashMap<String, PublishedViewInfo> =
publish_view_ids_with_publish_info
.into_iter()
.map(|pv| {
(
pv.view_id.to_string(),
PublishedViewInfo {
publisher_email: pv.publisher_email.clone(),
publish_name: pv.publish_name.clone(),
publish_timestamp: pv.publish_timestamp,
},
)
})
.collect();

let published_view: PublishedView = collab_folder_to_published_outline(
&workspace_id.to_string(),
&folder,
&publish_view_id_to_info_map,
)?;
Ok(published_view)
}

Expand Down
17 changes: 10 additions & 7 deletions src/biz/collab/publish_outline.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::collections::HashSet;
use std::collections::{HashMap, HashSet};

use app_error::AppError;
use collab_folder::Folder;
use shared_entity::dto::workspace_dto::PublishedView;
use shared_entity::dto::workspace_dto::{PublishedView, PublishedViewInfo};

use super::folder_view::{to_dto_view_icon, to_dto_view_layout};

Expand All @@ -11,7 +11,7 @@ use super::folder_view::{to_dto_view_icon, to_dto_view_layout};
pub fn collab_folder_to_published_outline(
root_view_id: &str,
folder: &Folder,
publish_view_ids: &HashSet<String>,
publish_view_id_to_info_map: &HashMap<String, PublishedViewInfo>,
) -> Result<PublishedView, AppError> {
let mut unviewable = HashSet::new();
for trash_view in folder.get_all_trash_sections() {
Expand All @@ -24,7 +24,7 @@ pub fn collab_folder_to_published_outline(
root_view_id,
folder,
&unviewable,
publish_view_ids,
publish_view_id_to_info_map,
0,
max_depth,
)
Expand All @@ -39,7 +39,7 @@ fn to_publish_view(
view_id: &str,
folder: &Folder,
unviewable: &HashSet<String>,
publish_view_ids: &HashSet<String>,
publish_view_id_to_info_map: &HashMap<String, PublishedViewInfo>,
depth: u32,
max_depth: u32,
) -> Option<PublishedView> {
Expand All @@ -65,6 +65,8 @@ fn to_publish_view(
serde_json::Value::Null
})
});
// If pruned_view is not empty, then one or more of the children is published.
// Hence, this view should be included in the published outline, even if it is not published itself.
let pruned_view: Vec<PublishedView> = view
.children
.iter()
Expand All @@ -74,13 +76,13 @@ fn to_publish_view(
&child_view_id.id,
folder,
unviewable,
publish_view_ids,
publish_view_id_to_info_map,
depth + 1,
max_depth,
)
})
.collect();
let is_published = publish_view_ids.contains(view_id);
let is_published = publish_view_id_to_info_map.contains_key(view_id);
if parent_view_id.is_empty() || is_published || !pruned_view.is_empty() {
Some(PublishedView {
view_id: view.id.clone(),
Expand All @@ -93,6 +95,7 @@ fn to_publish_view(
layout: to_dto_view_layout(&view.layout),
extra,
children: pruned_view,
info: publish_view_id_to_info_map.get(view_id).cloned(),
})
} else {
None
Expand Down

0 comments on commit a5d94a0

Please sign in to comment.