feat: api to get database fields
This commit is contained in:
parent
9e067e618b
commit
2da78b351f
|
|
@ -4,7 +4,7 @@ use app_error::AppError;
|
|||
use bytes::Bytes;
|
||||
use chrono::{DateTime, Utc};
|
||||
use client_api_entity::workspace_dto::{
|
||||
AFDatabase, AFDatabaseRow, AFDatabaseRowDetail, DatabaseRowUpdatedItem,
|
||||
AFDatabase, AFDatabaseField, AFDatabaseRow, AFDatabaseRowDetail, DatabaseRowUpdatedItem,
|
||||
ListDatabaseRowDetailParam, ListDatabaseRowUpdatedParam,
|
||||
};
|
||||
use client_api_entity::{
|
||||
|
|
@ -192,6 +192,24 @@ impl Client {
|
|||
AppResponse::from_response(resp).await?.into_data()
|
||||
}
|
||||
|
||||
pub async fn get_database_fields(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
database_id: &str,
|
||||
) -> Result<Vec<AFDatabaseField>, AppResponseError> {
|
||||
let url = format!(
|
||||
"{}/api/workspace/{}/database/{}/fields",
|
||||
self.base_url, workspace_id, database_id
|
||||
);
|
||||
let resp = self
|
||||
.http_client_with_auth(Method::GET, &url)
|
||||
.await?
|
||||
.send()
|
||||
.await?;
|
||||
log_request_id(&resp);
|
||||
AppResponse::from_response(resp).await?.into_data()
|
||||
}
|
||||
|
||||
pub async fn list_database_row_ids_updated(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
|
|
|
|||
|
|
@ -344,12 +344,6 @@ pub struct AFDatabase {
|
|||
pub views: Vec<FolderViewMinimal>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct AFDatabaseField {
|
||||
pub name: String,
|
||||
pub field_type: String,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AFDatabaseRow {
|
||||
pub id: String,
|
||||
|
|
@ -360,3 +354,11 @@ pub struct AFDatabaseRowDetail {
|
|||
pub id: String,
|
||||
pub cells: HashMap<String, HashMap<String, serde_json::Value>>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct AFDatabaseField {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub field_type: String,
|
||||
pub is_primary: bool,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -261,6 +261,10 @@ pub fn workspace_scope() -> Scope {
|
|||
web::resource("/{workspace_id}/database/{database_id}/row")
|
||||
.route(web::get().to(list_database_row_id_handler)),
|
||||
)
|
||||
.service(
|
||||
web::resource("/{workspace_id}/database/{database_id}/fields")
|
||||
.route(web::get().to(get_database_fields_handler)),
|
||||
)
|
||||
.service(
|
||||
web::resource("/{workspace_id}/database/{database_id}/row/updated")
|
||||
.route(web::get().to(list_database_row_id_updated_handler)),
|
||||
|
|
@ -1906,6 +1910,28 @@ async fn list_database_row_id_handler(
|
|||
Ok(Json(AppResponse::Ok().with_data(db_rows)))
|
||||
}
|
||||
|
||||
async fn get_database_fields_handler(
|
||||
user_uuid: UserUuid,
|
||||
path_param: web::Path<(String, String)>,
|
||||
state: Data<AppState>,
|
||||
) -> Result<Json<AppResponse<Vec<AFDatabaseField>>>> {
|
||||
let (workspace_id, db_id) = path_param.into_inner();
|
||||
let uid = state.user_cache.get_user_uid(&user_uuid).await?;
|
||||
state
|
||||
.workspace_access_control
|
||||
.enforce_action(&uid, &workspace_id, Action::Read)
|
||||
.await?;
|
||||
|
||||
let db_fields = biz::collab::ops::get_database_fields(
|
||||
&state.collab_access_control_storage,
|
||||
&workspace_id,
|
||||
&db_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Json(AppResponse::Ok().with_data(db_fields)))
|
||||
}
|
||||
|
||||
async fn list_database_row_id_updated_handler(
|
||||
user_uuid: UserUuid,
|
||||
path_param: web::Path<(String, String)>,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ use database::publish::select_workspace_id_for_publish_namespace;
|
|||
use database_entity::dto::QueryCollabResult;
|
||||
use database_entity::dto::{QueryCollab, QueryCollabParams};
|
||||
use shared_entity::dto::workspace_dto::AFDatabase;
|
||||
use shared_entity::dto::workspace_dto::AFDatabaseField;
|
||||
use shared_entity::dto::workspace_dto::AFDatabaseRow;
|
||||
use shared_entity::dto::workspace_dto::AFDatabaseRowDetail;
|
||||
use shared_entity::dto::workspace_dto::DatabaseRowUpdatedItem;
|
||||
|
|
@ -444,26 +445,8 @@ pub async fn list_database_row_ids(
|
|||
workspace_uuid_str: &str,
|
||||
database_uuid_str: &str,
|
||||
) -> Result<Vec<AFDatabaseRow>, AppError> {
|
||||
let db_collab = get_latest_collab(
|
||||
collab_storage,
|
||||
GetCollabOrigin::Server,
|
||||
workspace_uuid_str,
|
||||
database_uuid_str,
|
||||
CollabType::Database,
|
||||
)
|
||||
.await?;
|
||||
let db_body = DatabaseBody::from_collab(
|
||||
&db_collab,
|
||||
Arc::new(NoPersistenceDatabaseCollabService),
|
||||
None,
|
||||
)
|
||||
.ok_or_else(|| {
|
||||
AppError::Internal(anyhow::anyhow!(
|
||||
"Failed to create database body from collab, db_collab_id: {}",
|
||||
database_uuid_str,
|
||||
))
|
||||
})?;
|
||||
|
||||
let (db_collab, db_body) =
|
||||
get_database_body(collab_storage, workspace_uuid_str, database_uuid_str).await?;
|
||||
// get any view_id
|
||||
let txn = db_collab.transact();
|
||||
let iid = db_body.get_inline_view_id(&txn);
|
||||
|
|
@ -483,6 +466,27 @@ pub async fn list_database_row_ids(
|
|||
Ok(db_rows)
|
||||
}
|
||||
|
||||
pub async fn get_database_fields(
|
||||
collab_storage: &CollabAccessControlStorage,
|
||||
workspace_uuid_str: &str,
|
||||
database_uuid_str: &str,
|
||||
) -> Result<Vec<AFDatabaseField>, AppError> {
|
||||
let (db_collab, db_body) =
|
||||
get_database_body(collab_storage, workspace_uuid_str, database_uuid_str).await?;
|
||||
|
||||
let all_fields = db_body.fields.get_all_fields(&db_collab.transact());
|
||||
let mut acc = Vec::with_capacity(all_fields.len());
|
||||
for field in all_fields {
|
||||
acc.push(AFDatabaseField {
|
||||
id: field.id,
|
||||
name: field.name,
|
||||
field_type: format!("{:?}", FieldType::from(field.field_type)),
|
||||
is_primary: field.is_primary,
|
||||
});
|
||||
}
|
||||
Ok(acc)
|
||||
}
|
||||
|
||||
pub async fn list_database_row_ids_updated(
|
||||
collab_storage: &CollabAccessControlStorage,
|
||||
pg_pool: &PgPool,
|
||||
|
|
@ -736,3 +740,30 @@ fn add_to_selection_from_type_options(
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
async fn get_database_body(
|
||||
collab_storage: &CollabAccessControlStorage,
|
||||
workspace_uuid_str: &str,
|
||||
database_uuid_str: &str,
|
||||
) -> Result<(Collab, DatabaseBody), AppError> {
|
||||
let db_collab = get_latest_collab(
|
||||
collab_storage,
|
||||
GetCollabOrigin::Server,
|
||||
workspace_uuid_str,
|
||||
database_uuid_str,
|
||||
CollabType::Database,
|
||||
)
|
||||
.await?;
|
||||
let db_body = DatabaseBody::from_collab(
|
||||
&db_collab,
|
||||
Arc::new(NoPersistenceDatabaseCollabService),
|
||||
None,
|
||||
)
|
||||
.ok_or_else(|| {
|
||||
AppError::Internal(anyhow::anyhow!(
|
||||
"Failed to create database body from collab, db_collab_id: {}",
|
||||
database_uuid_str,
|
||||
))
|
||||
})?;
|
||||
Ok((db_collab, db_body))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use client_api_test::generate_unique_registered_user_client;
|
||||
use collab_entity::CollabType;
|
||||
use database_entity::dto::QueryCollabParams;
|
||||
use shared_entity::dto::workspace_dto::AFDatabaseField;
|
||||
use shared_entity::dto::workspace_dto::CreateWorkspaceParam;
|
||||
use shared_entity::dto::workspace_dto::PatchWorkspaceParam;
|
||||
|
||||
|
|
@ -24,6 +25,48 @@ async fn workspace_list_database() {
|
|||
.unwrap();
|
||||
assert_eq!(db_row_ids.len(), 5, "{:?}", db_row_ids);
|
||||
}
|
||||
{
|
||||
let mut db_fields = c
|
||||
.get_database_fields(&workspace_id, &todos_db.id)
|
||||
.await
|
||||
.unwrap();
|
||||
db_fields.sort();
|
||||
|
||||
let expected = vec![
|
||||
AFDatabaseField {
|
||||
id: "3AE6iK".to_string(),
|
||||
name: "Last modified".to_string(),
|
||||
field_type: "LastEditedTime".to_string(),
|
||||
is_primary: false,
|
||||
},
|
||||
AFDatabaseField {
|
||||
id: "KinVda".to_string(),
|
||||
name: "Tasks".to_string(),
|
||||
field_type: "Checklist".to_string(),
|
||||
is_primary: false,
|
||||
},
|
||||
AFDatabaseField {
|
||||
id: "SqwRg1".to_string(),
|
||||
name: "Status".to_string(),
|
||||
field_type: "SingleSelect".to_string(),
|
||||
is_primary: false,
|
||||
},
|
||||
AFDatabaseField {
|
||||
id: "phVRgL".to_string(),
|
||||
name: "Description".to_string(),
|
||||
field_type: "RichText".to_string(),
|
||||
is_primary: true,
|
||||
},
|
||||
AFDatabaseField {
|
||||
id: "wdX8DG".to_string(),
|
||||
name: "Multiselect".to_string(),
|
||||
field_type: "MultiSelect".to_string(),
|
||||
is_primary: false,
|
||||
},
|
||||
];
|
||||
|
||||
assert_eq!(db_fields, expected, "{:#?}", db_fields);
|
||||
}
|
||||
{
|
||||
let db_row_ids = c
|
||||
.list_database_row_ids_updated(&workspace_id, &todos_db.id, None)
|
||||
|
|
@ -31,7 +74,6 @@ async fn workspace_list_database() {
|
|||
.unwrap();
|
||||
assert_eq!(db_row_ids.len(), 5, "{:?}", db_row_ids);
|
||||
}
|
||||
|
||||
{
|
||||
let db_row_ids = c
|
||||
.list_database_row_ids(&workspace_id, &todos_db.id)
|
||||
|
|
|
|||
Loading…
Reference in New Issue