Merge pull request #340 from AppFlowy-IO/rename_workspace

feat: added rename workspace
This commit is contained in:
Zack 2024-02-22 13:27:57 +08:00 committed by GitHub
commit 0dd9e3f12c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 139 additions and 13 deletions

View File

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "\n UPDATE public.af_workspace\n SET workspace_name = $1\n WHERE workspace_id = $2\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Uuid"
]
},
"nullable": []
},
"hash": "21195760ea7ed2dc4eda1dc2bd0eed9afcc63651ba6e67e7db675307e3b87821"
}

View File

@ -2,7 +2,7 @@ use crate::notify::{ClientToken, TokenStateReceiver};
use anyhow::Context;
use brotli::CompressorReader;
use gotrue_entity::dto::AuthProvider;
use shared_entity::dto::workspace_dto::CreateWorkspaceParam;
use shared_entity::dto::workspace_dto::{CreateWorkspaceParam, PatchWorkspaceParam};
use std::fmt::{Display, Formatter};
use std::io::Read;
@ -540,6 +540,19 @@ impl Client {
.into_data()
}
#[instrument(level = "debug", skip_all, err)]
pub async fn patch_workspace(&self, params: PatchWorkspaceParam) -> Result<(), AppResponseError> {
let url = format!("{}/api/workspace", self.base_url);
let resp = self
.http_client_with_auth(Method::PATCH, &url)
.await?
.json(&params)
.send()
.await?;
log_request_id(&resp);
AppResponse::<()>::from_response(resp).await?.into_error()
}
#[instrument(level = "debug", skip_all, err)]
pub async fn get_workspaces(&self) -> Result<AFWorkspaces, AppResponseError> {
let url = format!("{}/api/workspace", self.base_url);

View File

@ -49,6 +49,30 @@ pub async fn insert_user_workspace(
Ok(workspace)
}
#[inline]
pub async fn rename_workspace(
tx: &mut Transaction<'_, sqlx::Postgres>,
workspace_id: &Uuid,
new_workspace_name: &str,
) -> Result<(), AppError> {
let res = sqlx::query!(
r#"
UPDATE public.af_workspace
SET workspace_name = $1
WHERE workspace_id = $2
"#,
new_workspace_name,
workspace_id,
)
.execute(tx.deref_mut())
.await?;
if res.rows_affected() != 1 {
tracing::error!("Failed to rename workspace, workspace_id: {}", workspace_id);
}
Ok(())
}
/// Checks whether a user, identified by a UUID, is an 'Owner' of a workspace, identified by its
/// workspace_id.
#[inline]

View File

@ -82,3 +82,9 @@ pub struct BlobMetadata {
pub struct CreateWorkspaceParam {
pub workspace_name: Option<String>,
}
#[derive(Serialize, Deserialize)]
pub struct PatchWorkspaceParam {
pub workspace_id: Uuid,
pub workspace_name: Option<String>,
}

11
script
View File

@ -1,11 +0,0 @@
#!/usr/bin/env bash
# The commit you want to revert to (exclusive)
TARGET_COMMIT=5e7794646a4dce935b27541d60aa9084574ba6b8
# Revert all commits from HEAD back to TARGET_COMMIT
for commit in $(git rev-list --reverse $TARGET_COMMIT..HEAD); do
git revert --no-commit $commit
done
git commit -m "Reverted to state before $TARGET_COMMIT"

View File

@ -50,6 +50,7 @@ pub fn workspace_scope() -> Scope {
.service(web::resource("")
.route(web::get().to(list_workspace_handler))
.route(web::post().to(create_workpace_handler))
.route(web::patch().to(patch_workpace_handler))
)
.service(web::resource("/{workspace_id}")
.route(web::delete().to(delete_workspace_handler))
@ -134,6 +135,23 @@ async fn create_workpace_handler(
Ok(AppResponse::Ok().with_data(new_workspace).into())
}
// Adds a workspace for user, if success, return the workspace id
#[instrument(skip_all, err)]
async fn patch_workpace_handler(
_uuid: UserUuid,
state: Data<AppState>,
params: Json<PatchWorkspaceParam>,
) -> Result<Json<AppResponse<()>>> {
let params = params.into_inner();
workspace::ops::patch_workspace(
&state.pg_pool,
&params.workspace_id,
params.workspace_name.as_deref(),
)
.await?;
Ok(AppResponse::Ok().into())
}
async fn delete_workspace_handler(
_user_id: UserUuid,
workspace_id: web::Path<Uuid>,

View File

@ -5,7 +5,7 @@ use database::pg_row::{AFWorkspaceMemberRow, AFWorkspaceRow};
use database::user::select_uid_from_email;
use database::workspace::{
delete_from_workspace, delete_workspace_members, insert_user_workspace,
insert_workspace_member_with_txn, select_all_user_workspaces, select_workspace,
insert_workspace_member_with_txn, rename_workspace, select_all_user_workspaces, select_workspace,
select_workspace_member_list, update_updated_at_of_workspace, upsert_workspace_member,
};
use database_entity::dto::{AFAccessLevel, AFRole, AFWorkspace};
@ -35,6 +35,19 @@ pub async fn create_workspace_for_user(
Ok(new_workspace)
}
pub async fn patch_workspace(
pg_pool: &PgPool,
workspace_id: &Uuid,
workspace_name: Option<&str>,
) -> Result<(), AppResponseError> {
let mut tx = pg_pool.begin().await?;
if let Some(workspace_name) = workspace_name {
rename_workspace(&mut tx, workspace_id, workspace_name).await?;
}
tx.commit().await?;
Ok(())
}
pub async fn get_all_user_workspaces(
pg_pool: &PgPool,
user_uuid: &Uuid,

View File

@ -2,6 +2,7 @@ use client_api_test_util::generate_unique_registered_user_client;
use database_entity::dto::AFRole;
use shared_entity::dto::workspace_dto::CreateWorkspaceMember;
use shared_entity::dto::workspace_dto::CreateWorkspaceParam;
use shared_entity::dto::workspace_dto::PatchWorkspaceParam;
#[tokio::test]
async fn add_and_delete_workspace_for_user() {
@ -72,3 +73,50 @@ async fn add_and_delete_workspace_for_non_owner_user() {
let member_workspaces = member.get_workspaces().await.unwrap();
assert_eq!(member_workspaces.0.len(), 1);
}
#[tokio::test]
async fn test_workspace_rename() {
let (c, _user) = generate_unique_registered_user_client().await;
let workspace_id = c
.get_workspaces()
.await
.unwrap()
.0
.first()
.unwrap()
.workspace_id;
let desired_new_name = "tom's workspace";
{
c.patch_workspace(PatchWorkspaceParam {
workspace_id,
workspace_name: Some(desired_new_name.to_string()),
})
.await
.expect("Failed to rename workspace");
let workspaces = c.get_workspaces().await.expect("Failed to get workspaces");
let actual_new_name = &workspaces
.0
.first()
.expect("No workspace found")
.workspace_name;
assert_eq!(actual_new_name, desired_new_name);
}
{
c.patch_workspace(PatchWorkspaceParam {
workspace_id,
workspace_name: None,
})
.await
.expect("Failed to rename workspace");
let workspaces = c.get_workspaces().await.expect("Failed to get workspaces");
let actual_new_name = &workspaces
.0
.first()
.expect("No workspace found")
.workspace_name;
assert_eq!(actual_new_name, desired_new_name);
}
}