feat: add name filtering
This commit is contained in:
parent
288fd59d3b
commit
787e6beb0d
|
|
@ -1,7 +1,7 @@
|
|||
use crate::http::log_request_id;
|
||||
use crate::{blocking_brotli_compress, Client};
|
||||
use app_error::AppError;
|
||||
use client_api_entity::workspace_dto::AFDatabase;
|
||||
use client_api_entity::workspace_dto::{AFDatabase, ListDatabaseParam};
|
||||
use client_api_entity::{
|
||||
BatchQueryCollabParams, BatchQueryCollabResult, CreateCollabParams, DeleteCollabParams,
|
||||
QueryCollab, UpdateCollabWebParams,
|
||||
|
|
@ -145,11 +145,13 @@ impl Client {
|
|||
pub async fn list_databases(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
name_filter: Option<String>,
|
||||
) -> Result<Vec<AFDatabase>, AppResponseError> {
|
||||
let url = format!("{}/api/workspace/{}/database", self.base_url, workspace_id);
|
||||
let resp = self
|
||||
.http_client_with_auth(Method::GET, &url)
|
||||
.await?
|
||||
.query(&ListDatabaseParam { name_filter })
|
||||
.send()
|
||||
.await?;
|
||||
log_request_id(&resp);
|
||||
|
|
|
|||
|
|
@ -263,6 +263,11 @@ pub struct QueryWorkspaceParam {
|
|||
pub include_member_count: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Deserialize, Serialize)]
|
||||
pub struct ListDatabaseParam {
|
||||
pub name_filter: Option<String>, // logic: if database name contains
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Deserialize, Serialize)]
|
||||
pub struct QueryWorkspaceFolder {
|
||||
pub depth: Option<u32>,
|
||||
|
|
@ -284,7 +289,7 @@ pub struct PublishedView {
|
|||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AFDatabase {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub names: Vec<String>,
|
||||
pub fields: Vec<AFDatabaseField>,
|
||||
}
|
||||
|
||||
|
|
@ -293,3 +298,9 @@ pub struct AFDatabaseField {
|
|||
pub name: String,
|
||||
pub field_type: String,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct AFDatabaseMeta {
|
||||
pub name: String,
|
||||
pub icon: String,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1801,7 +1801,9 @@ async fn list_database_handler(
|
|||
user_uuid: UserUuid,
|
||||
workspace_id: web::Path<String>,
|
||||
state: Data<AppState>,
|
||||
query: web::Query<ListDatabaseParam>,
|
||||
) -> Result<Json<AppResponse<Vec<AFDatabase>>>> {
|
||||
let name_filter = query.into_inner().name_filter;
|
||||
let uid = state.user_cache.get_user_uid(&user_uuid).await?;
|
||||
let workspace_id = workspace_id.into_inner();
|
||||
let dbs = biz::collab::ops::list_database(
|
||||
|
|
@ -1809,6 +1811,7 @@ async fn list_database_handler(
|
|||
&state.collab_access_control_storage,
|
||||
uid,
|
||||
workspace_id,
|
||||
name_filter,
|
||||
)
|
||||
.await?;
|
||||
Ok(Json(AppResponse::Ok().with_data(dbs)))
|
||||
|
|
|
|||
|
|
@ -363,6 +363,7 @@ pub async fn list_database(
|
|||
collab_storage: &CollabAccessControlStorage,
|
||||
uid: i64,
|
||||
workspace_uuid_str: String,
|
||||
name_filter: Option<String>,
|
||||
) -> Result<Vec<AFDatabase>, AppError> {
|
||||
let workspace_uuid: Uuid = workspace_uuid_str.as_str().parse()?;
|
||||
let ws_db_oid = select_workspace_database_oid(pg_pool, &workspace_uuid).await?;
|
||||
|
|
@ -416,28 +417,35 @@ pub async fn list_database(
|
|||
Arc::new(NoPersistenceDatabaseCollabService),
|
||||
None,
|
||||
) {
|
||||
Some(db_body) => match db_body.metas.get_inline_view_id(&txn) {
|
||||
Some(iid) => match db_body.views.get_view(&txn, &iid) {
|
||||
Some(iview) => {
|
||||
let name = iview.name;
|
||||
Some(db_body) => {
|
||||
let db_views = db_body.views.get_all_views_meta(&txn);
|
||||
let names = db_views
|
||||
.iter()
|
||||
.map(|v| v.name.clone())
|
||||
.filter(|name| !name.is_empty())
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
let db_fields = db_body.fields.get_all_fields(&txn);
|
||||
let mut af_fields: Vec<AFDatabaseField> = Vec::with_capacity(db_fields.len());
|
||||
for db_field in db_fields {
|
||||
af_fields.push(AFDatabaseField {
|
||||
name: db_field.name,
|
||||
field_type: format!("{:?}", FieldType::from(db_field.field_type)),
|
||||
});
|
||||
}
|
||||
af_databases.push(AFDatabase {
|
||||
id: db_body.get_database_id(&txn),
|
||||
name,
|
||||
fields: af_fields,
|
||||
});
|
||||
},
|
||||
None => tracing::warn!("Failed to get inline view: {}", iid),
|
||||
},
|
||||
None => tracing::error!("Failed to get inline view id for database: {}", oid),
|
||||
// if there exists a name filter,
|
||||
// there must be at least one view name that contains the filter
|
||||
if let Some(name_filter) = &name_filter {
|
||||
if !names.iter().any(|name| name.contains(name_filter)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let db_fields = db_body.fields.get_all_fields(&txn);
|
||||
let mut af_fields: Vec<AFDatabaseField> = Vec::with_capacity(db_fields.len());
|
||||
for db_field in db_fields {
|
||||
af_fields.push(AFDatabaseField {
|
||||
name: db_field.name,
|
||||
field_type: format!("{:?}", FieldType::from(db_field.field_type)),
|
||||
});
|
||||
}
|
||||
af_databases.push(AFDatabase {
|
||||
id: db_body.get_database_id(&txn),
|
||||
names,
|
||||
fields: af_fields,
|
||||
});
|
||||
},
|
||||
None => tracing::error!("Failed to create db_body from db_collab, oid: {}", oid),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -8,33 +8,63 @@ use shared_entity::dto::workspace_dto::PatchWorkspaceParam;
|
|||
#[tokio::test]
|
||||
async fn workspace_list_database() {
|
||||
let (c, _user) = generate_unique_registered_user_client().await;
|
||||
let workspace_id = c.get_workspaces().await.unwrap()[0].workspace_id;
|
||||
let dbs = c.list_databases(&workspace_id.to_string()).await.unwrap();
|
||||
assert_eq!(dbs.len(), 1);
|
||||
let workspace_id = c.get_workspaces().await.unwrap()[0]
|
||||
.workspace_id
|
||||
.to_string();
|
||||
|
||||
let db = &dbs[0];
|
||||
{
|
||||
let dbs = c.list_databases(&workspace_id, None).await.unwrap();
|
||||
assert_eq!(dbs.len(), 1);
|
||||
|
||||
assert_eq!(db.name, "");
|
||||
assert!(db.fields.contains(&AFDatabaseField {
|
||||
name: "Last modified".to_string(),
|
||||
field_type: "LastEditedTime".to_string(),
|
||||
}));
|
||||
assert!(db.fields.contains(&AFDatabaseField {
|
||||
name: "Multiselect".to_string(),
|
||||
field_type: "MultiSelect".to_string(),
|
||||
}));
|
||||
assert!(db.fields.contains(&AFDatabaseField {
|
||||
name: "Tasks".to_string(),
|
||||
field_type: "Checklist".to_string(),
|
||||
}));
|
||||
assert!(db.fields.contains(&AFDatabaseField {
|
||||
name: "Status".to_string(),
|
||||
field_type: "SingleSelect".to_string(),
|
||||
}));
|
||||
assert!(db.fields.contains(&AFDatabaseField {
|
||||
name: "Description".to_string(),
|
||||
field_type: "RichText".to_string(),
|
||||
}));
|
||||
let db = &dbs[0];
|
||||
|
||||
assert_eq!(db.names.len(), 2);
|
||||
assert!(db.names.contains(&String::from("Untitled")));
|
||||
assert!(db.names.contains(&String::from("Grid")));
|
||||
|
||||
assert!(db.fields.contains(&AFDatabaseField {
|
||||
name: "Last modified".to_string(),
|
||||
field_type: "LastEditedTime".to_string(),
|
||||
}));
|
||||
assert!(db.fields.contains(&AFDatabaseField {
|
||||
name: "Multiselect".to_string(),
|
||||
field_type: "MultiSelect".to_string(),
|
||||
}));
|
||||
assert!(db.fields.contains(&AFDatabaseField {
|
||||
name: "Tasks".to_string(),
|
||||
field_type: "Checklist".to_string(),
|
||||
}));
|
||||
assert!(db.fields.contains(&AFDatabaseField {
|
||||
name: "Status".to_string(),
|
||||
field_type: "SingleSelect".to_string(),
|
||||
}));
|
||||
assert!(db.fields.contains(&AFDatabaseField {
|
||||
name: "Description".to_string(),
|
||||
field_type: "RichText".to_string(),
|
||||
}));
|
||||
}
|
||||
|
||||
{
|
||||
let dbs = c
|
||||
.list_databases(&workspace_id, Some(String::from("nomatch")))
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(dbs.len(), 0);
|
||||
}
|
||||
{
|
||||
let dbs = c
|
||||
.list_databases(&workspace_id, Some(String::from("ntitle")))
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(dbs.len(), 1);
|
||||
}
|
||||
{
|
||||
let dbs = c
|
||||
.list_databases(&workspace_id, Some(String::from("rid")))
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(dbs.len(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
|
|
|||
Loading…
Reference in New Issue