Skip to content

Commit a5d94a0

Browse files
authored
feat: add publish info to publish outline items (#1156)
1 parent 505b4ca commit a5d94a0

File tree

7 files changed

+121
-14
lines changed

7 files changed

+121
-14
lines changed

.github/workflows/integration_test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ jobs:
4646
- name: Build Docker Images
4747
run: |
4848
export DOCKER_DEFAULT_PLATFORM=linux/amd64
49+
cp deploy.env .env
4950
docker compose build appflowy_cloud appflowy_worker admin_frontend
5051
5152
- name: Push docker images to docker hub

.sqlx/query-4787139d2189fc33ac25ac07bb9f585f578bde4cd3f75a7da95aa849a25bca9d.json

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libs/database/src/pg_row.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,3 +686,10 @@ impl From<AFQuickNoteRow> for QuickNote {
686686
}
687687
}
688688
}
689+
690+
pub struct AFPublishViewWithPublishInfo {
691+
pub view_id: Uuid,
692+
pub publish_name: String,
693+
pub publisher_email: String,
694+
pub publish_timestamp: DateTime<Utc>,
695+
}

libs/database/src/publish.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use database_entity::dto::{
55
use sqlx::{Executor, PgPool, Postgres};
66
use uuid::Uuid;
77

8+
use crate::pg_row::AFPublishViewWithPublishInfo;
9+
810
pub async fn select_user_is_collab_publisher_for_all_views(
911
pg_pool: &PgPool,
1012
user_uuid: &Uuid,
@@ -678,3 +680,31 @@ pub async fn select_published_view_ids_for_workspace<'a, E: Executor<'a, Databas
678680

679681
Ok(res)
680682
}
683+
684+
pub async fn select_published_view_ids_with_publish_info_for_workspace<
685+
'a,
686+
E: Executor<'a, Database = Postgres>,
687+
>(
688+
executor: E,
689+
workspace_id: Uuid,
690+
) -> Result<Vec<AFPublishViewWithPublishInfo>, AppError> {
691+
let res = sqlx::query_as!(
692+
AFPublishViewWithPublishInfo,
693+
r#"
694+
SELECT
695+
apc.view_id,
696+
apc.publish_name,
697+
au.email AS publisher_email,
698+
apc.created_at AS publish_timestamp
699+
FROM af_published_collab apc
700+
JOIN af_user au ON apc.published_by = au.uid
701+
WHERE workspace_id = $1
702+
AND unpublished_at IS NULL
703+
"#,
704+
workspace_id,
705+
)
706+
.fetch_all(executor)
707+
.await?;
708+
709+
Ok(res)
710+
}

libs/shared-entity/src/dto/workspace_dto.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,11 +389,20 @@ pub struct PublishedView {
389389
pub icon: Option<ViewIcon>,
390390
pub layout: ViewLayout,
391391
pub is_published: bool,
392+
#[serde(flatten)]
393+
pub info: Option<PublishedViewInfo>,
392394
/// contains fields like `is_space`, and font information
393395
pub extra: Option<serde_json::Value>,
394396
pub children: Vec<PublishedView>,
395397
}
396398

399+
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
400+
pub struct PublishedViewInfo {
401+
pub publisher_email: String,
402+
pub publish_name: String,
403+
pub publish_timestamp: DateTime<Utc>,
404+
}
405+
397406
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
398407
pub struct AFDatabase {
399408
pub id: String,

src/biz/collab/ops.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use database::collab::select_last_updated_database_row_ids;
3434
use database::collab::select_workspace_database_oid;
3535
use database::collab::{CollabStorage, GetCollabOrigin};
3636
use database::publish::select_published_view_ids_for_workspace;
37+
use database::publish::select_published_view_ids_with_publish_info_for_workspace;
3738
use database::publish::select_workspace_id_for_publish_namespace;
3839
use database_entity::dto::QueryCollab;
3940
use database_entity::dto::QueryCollabResult;
@@ -46,6 +47,7 @@ use shared_entity::dto::workspace_dto::AFInsertDatabaseField;
4647
use shared_entity::dto::workspace_dto::DatabaseRowUpdatedItem;
4748
use shared_entity::dto::workspace_dto::FavoriteFolderView;
4849
use shared_entity::dto::workspace_dto::FolderViewMinimal;
50+
use shared_entity::dto::workspace_dto::PublishedViewInfo;
4951
use shared_entity::dto::workspace_dto::RecentFolderView;
5052
use shared_entity::dto::workspace_dto::TrashFolderView;
5153
use sqlx::PgPool;
@@ -457,13 +459,28 @@ pub async fn get_published_view(
457459
&workspace_id.to_string(),
458460
)
459461
.await?;
460-
let publish_view_ids = select_published_view_ids_for_workspace(pg_pool, workspace_id).await?;
461-
let publish_view_ids: HashSet<String> = publish_view_ids
462-
.into_iter()
463-
.map(|id| id.to_string())
464-
.collect();
465-
let published_view: PublishedView =
466-
collab_folder_to_published_outline(&workspace_id.to_string(), &folder, &publish_view_ids)?;
462+
let publish_view_ids_with_publish_info =
463+
select_published_view_ids_with_publish_info_for_workspace(pg_pool, workspace_id).await?;
464+
let publish_view_id_to_info_map: HashMap<String, PublishedViewInfo> =
465+
publish_view_ids_with_publish_info
466+
.into_iter()
467+
.map(|pv| {
468+
(
469+
pv.view_id.to_string(),
470+
PublishedViewInfo {
471+
publisher_email: pv.publisher_email.clone(),
472+
publish_name: pv.publish_name.clone(),
473+
publish_timestamp: pv.publish_timestamp,
474+
},
475+
)
476+
})
477+
.collect();
478+
479+
let published_view: PublishedView = collab_folder_to_published_outline(
480+
&workspace_id.to_string(),
481+
&folder,
482+
&publish_view_id_to_info_map,
483+
)?;
467484
Ok(published_view)
468485
}
469486

src/biz/collab/publish_outline.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use std::collections::HashSet;
1+
use std::collections::{HashMap, HashSet};
22

33
use app_error::AppError;
44
use collab_folder::Folder;
5-
use shared_entity::dto::workspace_dto::PublishedView;
5+
use shared_entity::dto::workspace_dto::{PublishedView, PublishedViewInfo};
66

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

@@ -11,7 +11,7 @@ use super::folder_view::{to_dto_view_icon, to_dto_view_layout};
1111
pub fn collab_folder_to_published_outline(
1212
root_view_id: &str,
1313
folder: &Folder,
14-
publish_view_ids: &HashSet<String>,
14+
publish_view_id_to_info_map: &HashMap<String, PublishedViewInfo>,
1515
) -> Result<PublishedView, AppError> {
1616
let mut unviewable = HashSet::new();
1717
for trash_view in folder.get_all_trash_sections() {
@@ -24,7 +24,7 @@ pub fn collab_folder_to_published_outline(
2424
root_view_id,
2525
folder,
2626
&unviewable,
27-
publish_view_ids,
27+
publish_view_id_to_info_map,
2828
0,
2929
max_depth,
3030
)
@@ -39,7 +39,7 @@ fn to_publish_view(
3939
view_id: &str,
4040
folder: &Folder,
4141
unviewable: &HashSet<String>,
42-
publish_view_ids: &HashSet<String>,
42+
publish_view_id_to_info_map: &HashMap<String, PublishedViewInfo>,
4343
depth: u32,
4444
max_depth: u32,
4545
) -> Option<PublishedView> {
@@ -65,6 +65,8 @@ fn to_publish_view(
6565
serde_json::Value::Null
6666
})
6767
});
68+
// If pruned_view is not empty, then one or more of the children is published.
69+
// Hence, this view should be included in the published outline, even if it is not published itself.
6870
let pruned_view: Vec<PublishedView> = view
6971
.children
7072
.iter()
@@ -74,13 +76,13 @@ fn to_publish_view(
7476
&child_view_id.id,
7577
folder,
7678
unviewable,
77-
publish_view_ids,
79+
publish_view_id_to_info_map,
7880
depth + 1,
7981
max_depth,
8082
)
8183
})
8284
.collect();
83-
let is_published = publish_view_ids.contains(view_id);
85+
let is_published = publish_view_id_to_info_map.contains_key(view_id);
8486
if parent_view_id.is_empty() || is_published || !pruned_view.is_empty() {
8587
Some(PublishedView {
8688
view_id: view.id.clone(),
@@ -93,6 +95,7 @@ fn to_publish_view(
9395
layout: to_dto_view_layout(&view.layout),
9496
extra,
9597
children: pruned_view,
98+
info: publish_view_id_to_info_map.get(view_id).cloned(),
9699
})
97100
} else {
98101
None

0 commit comments

Comments
 (0)