Skip to content

Commit

Permalink
feat: custom domain (AppFlowy-IO#6518)
Browse files Browse the repository at this point in the history
* feat: api for namespace setting

* feat: add publish timestamp

* feat: update api

* chore: update proto

* feat: add link impl for appflowy cloud

* feat: impl set and get default view for workspace

* chore: merge with main and update to latest cloud client api

* fix: ci build

---------

Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
  • Loading branch information
speed2exe and LucasXu0 authored Oct 23, 2024
1 parent faa95ff commit 73e8b47
Show file tree
Hide file tree
Showing 18 changed files with 424 additions and 75 deletions.
143 changes: 110 additions & 33 deletions frontend/rust-lib/Cargo.lock

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions frontend/rust-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ dashmap = "6.0.1"
# Run the script.add_workspace_members:
# scripts/tool/update_client_api_rev.sh new_rev_id
# ⚠️⚠️⚠️️
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d3e4a6870d10b04e4aedac4addb17915a7acdde2" }
client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "d3e4a6870d10b04e4aedac4addb17915a7acdde2" }
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "2f715c3136c5000d21ec27aa29897867947c9fd4" }
client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "2f715c3136c5000d21ec27aa29897867947c9fd4" }

[profile.dev]
opt-level = 0
Expand Down Expand Up @@ -142,14 +142,14 @@ rocksdb = { git = "https://github.com/rust-rocksdb/rust-rocksdb", rev = "1710120
# To switch to the local path, run:
# scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️
collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c57466ae765669d79879c7d1d3fca219044f2a16" }
collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c57466ae765669d79879c7d1d3fca219044f2a16" }
collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c57466ae765669d79879c7d1d3fca219044f2a16" }
collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c57466ae765669d79879c7d1d3fca219044f2a16" }
collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c57466ae765669d79879c7d1d3fca219044f2a16" }
collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c57466ae765669d79879c7d1d3fca219044f2a16" }
collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c57466ae765669d79879c7d1d3fca219044f2a16" }
collab-importer = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c57466ae765669d79879c7d1d3fca219044f2a16" }
collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e77fd84e0e32b4dc1dcfa271547517e5b0d8e987" }
collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e77fd84e0e32b4dc1dcfa271547517e5b0d8e987" }
collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e77fd84e0e32b4dc1dcfa271547517e5b0d8e987" }
collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e77fd84e0e32b4dc1dcfa271547517e5b0d8e987" }
collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e77fd84e0e32b4dc1dcfa271547517e5b0d8e987" }
collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e77fd84e0e32b4dc1dcfa271547517e5b0d8e987" }
collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e77fd84e0e32b4dc1dcfa271547517e5b0d8e987" }
collab-importer = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e77fd84e0e32b4dc1dcfa271547517e5b0d8e987" }

# Working directory: frontend
# To update the commit ID, run:
Expand Down
39 changes: 36 additions & 3 deletions frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use anyhow::Error;
use client_api::collab_sync::{SinkConfig, SyncObject, SyncPlugin};
use client_api::entity::ai_dto::{CompletionType, RepeatedRelatedQuestion};
use client_api::entity::search_dto::SearchDocumentResponseItem;
use client_api::entity::ChatMessageType;
use client_api::entity::workspace_dto::PublishInfoView;
use client_api::entity::{ChatMessageType, PublishInfo};
use collab::core::origin::{CollabClient, CollabOrigin};
use collab::entity::EncodedCollab;
use collab::preclude::CollabPlugin;
Expand Down Expand Up @@ -34,7 +35,7 @@ use flowy_error::{FlowyError, FlowyResult};
use flowy_folder_pub::cloud::{
FolderCloudService, FolderCollabParams, FolderData, FolderSnapshot, Workspace, WorkspaceRecord,
};
use flowy_folder_pub::entities::{PublishInfoResponse, PublishPayload};
use flowy_folder_pub::entities::PublishPayload;
use flowy_server_pub::af_cloud_config::AFCloudConfiguration;
use flowy_storage_pub::cloud::{ObjectIdentity, ObjectValue, StorageCloudService};
use flowy_storage_pub::storage::{CompletedPartRequest, CreateUploadResponse, UploadPartResponse};
Expand Down Expand Up @@ -323,7 +324,7 @@ impl FolderCloudService for ServerProvider {
.await
}

async fn get_publish_info(&self, view_id: &str) -> Result<PublishInfoResponse, Error> {
async fn get_publish_info(&self, view_id: &str) -> Result<PublishInfo, Error> {
let server = self.get_server()?;
server.folder_service().get_publish_info(view_id).await
}
Expand All @@ -348,6 +349,38 @@ impl FolderCloudService for ServerProvider {
.await
}

async fn get_default_published_view_info(
&self,
workspace_id: &str,
) -> Result<PublishInfo, Error> {
let server = self.get_server()?;
server
.folder_service()
.get_default_published_view_info(workspace_id)
.await
}

async fn set_default_published_view(
&self,
workspace_id: &str,
view_id: uuid::Uuid,
) -> Result<(), Error> {
let server = self.get_server()?;
server
.folder_service()
.set_default_published_view(workspace_id, view_id)
.await
}

/// List all published views of the current workspace.
async fn list_published_views(&self, workspace_id: &str) -> Result<Vec<PublishInfoView>, Error> {
let server = self.get_server()?;
server
.folder_service()
.list_published_views(workspace_id)
.await
}

async fn import_zip(&self, file_path: &str) -> Result<(), Error> {
self
.get_server()?
Expand Down
9 changes: 9 additions & 0 deletions frontend/rust-lib/flowy-error/src/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,15 @@ pub enum ErrorCode {

#[error("Group name is empty")]
GroupNameIsEmpty = 109,

#[error("Not available for current workspace plan")]
LimitedByWorkspacePlan = 110,

#[error("Invalid namespace")]
InvalidNamespace = 111,

#[error("Invalid publish name")]
InvalidPublishName = 112,
}

impl ErrorCode {
Expand Down
1 change: 1 addition & 0 deletions frontend/rust-lib/flowy-folder-pub/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ uuid.workspace = true
anyhow.workspace = true
serde = { version = "1.0.202", features = ["derive"] }
serde_json.workspace = true
client-api = { workspace = true }

[dev-dependencies]
tokio.workspace = true
16 changes: 14 additions & 2 deletions frontend/rust-lib/flowy-folder-pub/src/cloud.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::entities::{PublishInfoResponse, PublishPayload};
use crate::entities::PublishPayload;
pub use anyhow::Error;
use client_api::entity::{workspace_dto::PublishInfoView, PublishInfo};
use collab_entity::CollabType;
pub use collab_folder::{Folder, FolderData, Workspace};
use lib_infra::async_trait::async_trait;
Expand Down Expand Up @@ -54,14 +55,25 @@ pub trait FolderCloudService: Send + Sync + 'static {

async fn unpublish_views(&self, workspace_id: &str, view_ids: Vec<String>) -> Result<(), Error>;

async fn get_publish_info(&self, view_id: &str) -> Result<PublishInfoResponse, Error>;
async fn get_publish_info(&self, view_id: &str) -> Result<PublishInfo, Error>;

async fn set_publish_namespace(
&self,
workspace_id: &str,
new_namespace: &str,
) -> Result<(), Error>;

async fn list_published_views(&self, workspace_id: &str) -> Result<Vec<PublishInfoView>, Error>;

async fn get_default_published_view_info(&self, workspace_id: &str)
-> Result<PublishInfo, Error>;

async fn set_default_published_view(
&self,
workspace_id: &str,
view_id: uuid::Uuid,
) -> Result<(), Error>;

async fn get_publish_namespace(&self, workspace_id: &str) -> Result<String, Error>;

async fn import_zip(&self, file_path: &str) -> Result<(), Error>;
Expand Down
8 changes: 0 additions & 8 deletions frontend/rust-lib/flowy-folder-pub/src/entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,3 @@ pub enum PublishPayload {
Database(PublishDatabasePayload),
Unknown,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PublishInfoResponse {
pub view_id: String,
/// One part of publish url: /{namespace}/{publish_name}
pub namespace: Option<String>,
pub publish_name: String,
}
1 change: 1 addition & 0 deletions frontend/rust-lib/flowy-folder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
validator.workspace = true
async-trait.workspace = true
client-api = { workspace = true }
regex = "1.9.5"
futures = "0.3.30"

Expand Down
19 changes: 19 additions & 0 deletions frontend/rust-lib/flowy-folder/src/entities/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ impl From<IconType> for ViewIconTypePB {
}
}

impl From<client_api::entity::workspace_dto::IconType> for ViewIconTypePB {
fn from(val: client_api::entity::workspace_dto::IconType) -> Self {
match val {
client_api::entity::workspace_dto::IconType::Emoji => ViewIconTypePB::Emoji,
client_api::entity::workspace_dto::IconType::Url => ViewIconTypePB::Url,
client_api::entity::workspace_dto::IconType::Icon => ViewIconTypePB::Icon,
}
}
}

#[derive(Default, ProtoBuf, Debug, Clone, PartialEq, Eq)]
pub struct ViewIconPB {
#[pb(index = 1)]
Expand All @@ -57,6 +67,15 @@ impl From<ViewIcon> for ViewIconPB {
}
}

impl From<client_api::entity::workspace_dto::ViewIcon> for ViewIconPB {
fn from(val: client_api::entity::workspace_dto::ViewIcon) -> Self {
ViewIconPB {
ty: val.ty.into(),
value: val.value,
}
}
}

#[derive(Default, ProtoBuf)]
pub struct UpdateViewIconPayloadPB {
#[pb(index = 1)]
Expand Down
63 changes: 58 additions & 5 deletions frontend/rust-lib/flowy-folder/src/entities/publish.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use client_api::entity::workspace_dto::{FolderViewMinimal, PublishInfoView};
use client_api::entity::PublishInfo;
use flowy_derive::ProtoBuf;
use flowy_folder_pub::entities::PublishInfoResponse;

use super::RepeatedViewIdPB;
use super::{RepeatedViewIdPB, ViewIconPB, ViewLayoutPB};

#[derive(Default, ProtoBuf)]
pub struct PublishViewParamsPB {
Expand All @@ -21,6 +22,46 @@ pub struct UnpublishViewsPayloadPB {
pub view_ids: Vec<String>,
}

#[derive(Default, ProtoBuf)]
pub struct PublishInfoViewPB {
#[pb(index = 1)]
pub view: FolderViewMinimalPB,
#[pb(index = 2)]
pub info: PublishInfoResponsePB,
}

impl From<PublishInfoView> for PublishInfoViewPB {
fn from(info_view: PublishInfoView) -> Self {
Self {
view: info_view.view.into(),
info: info_view.info.into(),
}
}
}

#[derive(Default, ProtoBuf)]
pub struct FolderViewMinimalPB {
#[pb(index = 1)]
pub view_id: String,
#[pb(index = 2)]
pub name: String,
#[pb(index = 3, one_of)]
pub icon: Option<ViewIconPB>,
#[pb(index = 4)]
pub layout: ViewLayoutPB,
}

impl From<FolderViewMinimal> for FolderViewMinimalPB {
fn from(view: FolderViewMinimal) -> Self {
Self {
view_id: view.view_id,
name: view.name,
icon: view.icon.map(Into::into),
layout: view.layout.into(),
}
}
}

#[derive(Default, ProtoBuf)]
pub struct PublishInfoResponsePB {
#[pb(index = 1)]
Expand All @@ -29,18 +70,30 @@ pub struct PublishInfoResponsePB {
pub publish_name: String,
#[pb(index = 3, one_of)]
pub namespace: Option<String>,
#[pb(index = 4)]
pub publisher_email: String,
#[pb(index = 5)]
pub publish_timestamp_sec: i64,
}

impl From<PublishInfoResponse> for PublishInfoResponsePB {
fn from(info: PublishInfoResponse) -> Self {
impl From<PublishInfo> for PublishInfoResponsePB {
fn from(info: PublishInfo) -> Self {
Self {
view_id: info.view_id,
view_id: info.view_id.to_string(),
publish_name: info.publish_name,
namespace: info.namespace,
publisher_email: info.publisher_email,
publish_timestamp_sec: info.publish_timestamp.timestamp(),
}
}
}

#[derive(Default, ProtoBuf)]
pub struct RepeatedPublishInfoViewPB {
#[pb(index = 1)]
pub items: Vec<PublishInfoViewPB>,
}

#[derive(Default, ProtoBuf)]
pub struct SetPublishNamespacePayloadPB {
#[pb(index = 1)]
Expand Down
12 changes: 12 additions & 0 deletions frontend/rust-lib/flowy-folder/src/entities/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,18 @@ impl std::convert::From<ViewLayout> for ViewLayoutPB {
}
}

impl From<client_api::entity::workspace_dto::ViewLayout> for ViewLayoutPB {
fn from(val: client_api::entity::workspace_dto::ViewLayout) -> Self {
match val {
client_api::entity::workspace_dto::ViewLayout::Document => ViewLayoutPB::Document,
client_api::entity::workspace_dto::ViewLayout::Grid => ViewLayoutPB::Grid,
client_api::entity::workspace_dto::ViewLayout::Board => ViewLayoutPB::Board,
client_api::entity::workspace_dto::ViewLayout::Calendar => ViewLayoutPB::Calendar,
client_api::entity::workspace_dto::ViewLayout::Chat => ViewLayoutPB::Chat,
}
}
}

#[derive(Eq, PartialEq, Debug, Default, ProtoBuf, Clone)]
pub struct SectionViewsPB {
#[pb(index = 1)]
Expand Down
36 changes: 36 additions & 0 deletions frontend/rust-lib/flowy-folder/src/event_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,3 +477,39 @@ pub(crate) async fn get_publish_namespace_handler(
let namespace = folder.get_publish_namespace().await?;
data_result_ok(PublishNamespacePB { namespace })
}

#[tracing::instrument(level = "debug", skip(folder), err)]
pub(crate) async fn list_published_views_handler(
folder: AFPluginState<Weak<FolderManager>>,
) -> DataResult<RepeatedPublishInfoViewPB, FlowyError> {
let folder = upgrade_folder(folder)?;
let published_views = folder.list_published_views().await?;
let items: Vec<PublishInfoViewPB> = published_views
.into_iter()
.map(|view| view.into())
.collect();
data_result_ok(RepeatedPublishInfoViewPB { items })
}

#[tracing::instrument(level = "debug", skip(folder))]
pub(crate) async fn get_default_publish_info_handler(
folder: AFPluginState<Weak<FolderManager>>,
) -> DataResult<PublishInfoResponsePB, FlowyError> {
let folder = upgrade_folder(folder)?;
let default_published_view = folder.get_default_published_view_info().await?;
data_result_ok(default_published_view.into())
}

#[tracing::instrument(level = "debug", skip(folder))]
pub(crate) async fn set_default_publish_view_handler(
data: AFPluginData<ViewIdPB>,
folder: AFPluginState<Weak<FolderManager>>,
) -> Result<(), FlowyError> {
let folder = upgrade_folder(folder)?;
let view_id: uuid::Uuid = data.into_inner().value.parse().map_err(|err| {
tracing::error!("Failed to parse view id: {}", err);
FlowyError::invalid_data()
})?;
folder.set_default_published_view(view_id).await?;
Ok(())
}
12 changes: 12 additions & 0 deletions frontend/rust-lib/flowy-folder/src/event_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ pub fn init(folder: Weak<FolderManager>) -> AFPlugin {
.event(FolderEvent::UnpublishViews, unpublish_views_handler)
.event(FolderEvent::SetPublishNamespace, set_publish_namespace_handler)
.event(FolderEvent::GetPublishNamespace, get_publish_namespace_handler)
.event(FolderEvent::ListPublishedViews, list_published_views_handler)
.event(FolderEvent::GetDefaultPublishInfo, get_default_publish_info_handler)
.event(FolderEvent::SetDefaultPublishInfo, set_default_publish_view_handler)
}

#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
Expand Down Expand Up @@ -200,4 +203,13 @@ pub enum FolderEvent {

#[event(input = "ImportZipPB")]
ImportZipFile = 48,

#[event(output = "RepeatedPublishInfoViewPB")]
ListPublishedViews = 49,

#[event(output = "PublishInfoResponsePB")]
GetDefaultPublishInfo = 50,

#[event(input = "ViewIdPB")]
SetDefaultPublishInfo = 51,
}
Loading

0 comments on commit 73e8b47

Please sign in to comment.